// Подсчет комиссий и свопов указанной позиции по символу double PosTotalCommissSwap ( string symb, bool commiss, bool swap) { int posTotal = PositionsTotal (); //всего открытых позиций Print (posTotal);
//пройдем по всем открытым позициям for ( int i = posTotal - 1 ; i >= 0 ; i--) { string posSymb = PositionGetSymbol (i); Print (posSymb);
//если найдена позиция по указанному символу if (symb == posSymb) { Print ( "Позиция найдена" ); long posID = PositionGetInteger ( POSITION_IDENTIFIER );
//выберем историю сделок, относящуюся к выбранной позиции if ( HistorySelectByPosition (posID)) { int dealsTotal = HistoryDealsTotal (); //всего сделок в истории позиции Print ( "Всего сделок в позиции: " + dealsTotal); double fees = 0.0 ; //все комиссии и свопы
//пройдем по всем сделкам позиции for ( int k = 0 ; k < dealsTotal; k++) { ulong dealTicket = HistoryDealGetTicket (k); //тикет сделки
if (commiss) fees += HistoryDealGetDouble (dealTicket, DEAL_COMMISSION );
if (swap) fees += HistoryDealGetDouble (dealTicket, DEAL_SWAP ); }
아니요, 전혀 정상이 아닙니다. 어쨌든 포지션이 있는데, 이는 "인생"에 참여한 거래가 있음을 의미합니다. 그런데 이미 포지션이 있는 상태에서 어드바이저를 던져도 코드가 거래를 보지 않는게 더 이상한데, 이것은 로그에서 보는 것이고, 포지션의 개수 가 정해져 있고, 심볼로 포지션이 선택되고, 그러나 그것에 거래가 없습니다 ...
예, 결정할 수 없습니다. SL과 TP는 MT 서버만의 본질입니다.
작동 방식은 다음과 같습니다.
const MqlTradeRequest &request,
const MqlTradeResult &result)
{
if (trans.type== TRADE_TRANSACTION_DEAL_ADD )
{
datetime end= TimeCurrent ();
datetime start=end-end% PeriodSeconds ( PERIOD_D1 );
ResetLastError ();
if (! HistorySelect (start,end))
{
Print ( "Getting deals history failed. Error " , GetLastError ());
return ;
}
ulong ticket= HistoryDealGetTicket ( HistoryDealsTotal ()- 1 );
if (ticket==trans.deal)
{
if ( HistoryDealGetInteger (ticket, DEAL_ENTRY )== DEAL_ENTRY_OUT &&
( StringFind ( HistoryDealGetString (ticket, DEAL_COMMENT ), "tp" )!=- 1
|| StringFind ( HistoryDealGetString (ticket, DEAL_COMMENT ), "sl" )!=- 1 ))
{
Print ( HistoryDealGetString (ticket, DEAL_SYMBOL ), " Profit= " , HistoryDealGetDouble (ticket, DEAL_PROFIT ), " ticket=" ,ticket);
}
}
}
}
{
if ((Trans.type == TRADE_TRANSACTION_ORDER_ADD ) &&
PositionSelectByTicket (Trans.position) && OrderSelect (Trans.order) &&
( PositionGetInteger ( POSITION_TYPE ) == 1 - OrderGetInteger ( ORDER_TYPE )))
{
const double Price = OrderGetDouble ( ORDER_PRICE_OPEN );
if (Price == PositionGetDouble ( POSITION_TP ))
Print ( "Position #" + ( string )Trans.position + " - triggered TP." );
else if (Price == PositionGetDouble ( POSITION_SL ))
Print ( "Position #" + ( string )Trans.position + " - triggered SL." );
}
}
실제 작업 버전(테스터용 아님)
{
if ((Trans.type == TRADE_TRANSACTION_ORDER_ADD ) &&
PositionSelectByTicket (Trans.position) && OrderSelect (Trans.order) &&
( PositionGetInteger ( POSITION_TYPE ) == 1 - OrderGetInteger ( ORDER_TYPE )))
{
const double Price = OrderGetDouble ( ORDER_PRICE_OPEN );
if (Price == PositionGetDouble ( POSITION_TP ))
Print ( "Position #" + ( string )Trans.position + " - triggered TP." );
else if (Price == PositionGetDouble ( POSITION_SL ))
Print ( "Position #" + ( string )Trans.position + " - triggered SL." );
}
}
테스터에서 확인해봤는데 안되고, 실생활에서도 안 되는 것 같아요. 체크를 하고 있는 포지션이 더 이상 존재하지 않기 때문입니다.
{
string s = DoubleToString (PosTotalCommissSwap ( Symbol (), true , true ), 4 );
Comment (s);
}
//+------------------------------------------------------------------+
// Подсчет комиссий и свопов указанной позиции по символу
double PosTotalCommissSwap ( string symb, bool commiss, bool swap)
{
int posTotal = PositionsTotal (); //всего открытых позиций
Print (posTotal);
//пройдем по всем открытым позициям
for ( int i = posTotal - 1 ; i >= 0 ; i--)
{
string posSymb = PositionGetSymbol (i);
Print (posSymb);
//если найдена позиция по указанному символу
if (symb == posSymb)
{
Print ( "Позиция найдена" );
long posID = PositionGetInteger ( POSITION_IDENTIFIER );
//выберем историю сделок, относящуюся к выбранной позиции
if ( HistorySelectByPosition (posID))
{
int dealsTotal = HistoryDealsTotal (); //всего сделок в истории позиции
Print ( "Всего сделок в позиции: " + dealsTotal);
double fees = 0.0 ; //все комиссии и свопы
//пройдем по всем сделкам позиции
for ( int k = 0 ; k < dealsTotal; k++)
{
ulong dealTicket = HistoryDealGetTicket (k); //тикет сделки
if (commiss)
fees += HistoryDealGetDouble (dealTicket, DEAL_COMMISSION );
if (swap)
fees += HistoryDealGetDouble (dealTicket, DEAL_SWAP );
}
return (fees);
}
else
Print ( "Историю сделок выбрать не удалось" );
}
}
return ( 0.0 );
}
포지션 ID별 거래 내역 선택이 깨진 것 같습니다.
인쇄는 때때로(때로는 그렇지 않음) 씁니다.
2016.12.05 11:26:11.767 pos의 현재 커미션 받기(GBPUSD,M5) 하나
2016.12.05 11:26:11.767 pos의 현재 커미션 받기(GBPUSD,M5) GBPUSD
2016.12.05 11:26:11.767 pos의 현재 커미션 받기(GBPUSD,M5) 위치를 찾았습니다.
2016.12.05 11:26:11.767 pos의 현재 커미션 받기(GBPUSD,M5) 포지션에 있는 총 거래: 0
포지션 ID별 거래 내역 선택이 깨진 것 같습니다.
OrderSend 이후에 이런 일이 발생하면 문제가 없습니다.
아니요, 전혀 정상이 아닙니다. 어쨌든 "인생"에 참여한 거래가 있음을 의미하는 위치가 있습니다. 그런데 이미 포지션이 있는 상태에서 어드바이저를 던져도 코드에서 트랜잭션이 보이지 않는게 더 이상하네요...
거래, 자동 거래 시스템 및 거래 전략 테스트에 관한 포럼
OrderSend를 사용하여 MT5에서 올바르게 작동하는 방법
fxsaber , 2016.11.19 23:59
여기 라이브러리에서 동기화된 OrderSendSync를 제거했습니다.const bool IsTester = (:: MQLInfoInteger ( MQL_TESTER ) || :: MQLInfoInteger ( MQL_OPTIMIZATION ) ||
:: MQLInfoInteger ( MQL_VISUAL_MODE ) || :: MQLInfoInteger ( MQL_FRAME_MODE ));
bool Waiting( const bool FlagInit = false )
{
static ulong StartTime = 0 ;
if (FlagInit)
StartTime = :: GetMicrosecondCount ();
const bool Res = (:: GetMicrosecondCount () - StartTime < OrderSend_MaxPause);
if (Res)
:: Sleep ( 0 );
return (Res);
}
bool EqualPrices( const double Price1, const double Price2, const int digits)
{
return (:: NormalizeDouble (Price1 - Price2, digits) == 0 );
}
#define WHILE(A) while (!(Res = (A)) && Waiting())
bool OrderSendSync ( const MqlTradeRequest &Request, MqlTradeResult &Result )
{
bool Res = :: OrderSend (Request, Result);
if (Res && !IsTester && (Result.retcode < TRADE_RETCODE_ERROR ) && (OrderSend_MaxPause > 0 ))
{
Res = (Result.retcode == TRADE_RETCODE_DONE );
Waiting( true );
if (Request.action == TRADE_ACTION_DEAL )
{
WHILE(:: HistoryOrderSelect (Result.order))
;
Res = Res && ((( ENUM_ORDER_STATE ):: HistoryOrderGetInteger (Result.order, ORDER_STATE ) == ORDER_STATE_FILLED ) ||
(( ENUM_ORDER_STATE ):: HistoryOrderGetInteger (Result.order, ORDER_STATE ) == ORDER_STATE_PARTIAL ));
if (Res)
WHILE(:: HistoryDealSelect (Result.deal))
;
}
else if (Request.action == TRADE_ACTION_PENDING )
{
if (Res)
WHILE(:: OrderSelect (Result.order))
;
else
{
WHILE(:: HistoryOrderSelect (Result.order))
;
Res = false ;
}
}
else if (Request.action == TRADE_ACTION_SLTP )
{
if (Res)
{
bool EqualSL = false ;
bool EqualTP = false ;
const int digits = ( int ):: SymbolInfoInteger (Request.symbol, SYMBOL_DIGITS );
if ((Request.position == 0 ) ? :: PositionSelect (Request.symbol) : :: PositionSelectByTicket (Request.position))
{
EqualSL = EqualPrices(:: PositionGetDouble ( POSITION_SL ), Request.sl, digits);
EqualTP = EqualPrices(:: PositionGetDouble ( POSITION_TP ), Request.tp, digits);
}
WHILE((EqualSL && EqualTP))
if ((Request.position == 0 ) ? :: PositionSelect (Request.symbol) : :: PositionSelectByTicket (Request.position))
{
EqualSL = EqualPrices(:: PositionGetDouble ( POSITION_SL ), Request.sl, digits);
EqualTP = EqualPrices(:: PositionGetDouble ( POSITION_TP ), Request.tp, digits);
}
}
}
else if (Request.action == TRADE_ACTION_MODIFY )
{
if (Res)
{
bool EqualSL = false ;
bool EqualTP = false ;
const int digits = ( int ):: SymbolInfoInteger (Request.symbol, SYMBOL_DIGITS );
if (:: OrderSelect (Result.order))
{
EqualSL = EqualPrices(:: OrderGetDouble ( ORDER_SL ), Request.sl, digits);
EqualTP = EqualPrices(:: OrderGetDouble ( ORDER_TP ), Request.tp, digits);
}
WHILE((EqualSL && EqualTP))
if (:: OrderSelect (Result.order))
{
EqualSL = EqualPrices(:: OrderGetDouble ( ORDER_SL ), Request.sl, digits);
EqualTP = EqualPrices(:: OrderGetDouble ( ORDER_TP ), Request.tp, digits);
}
}
}
else if (Request.action == TRADE_ACTION_REMOVE )
if (Res)
WHILE(:: HistoryOrderSelect (Result.order))
;
}
return (Res);
}
#undef WHILE
이 OrderSend를 사용하면 그러한 문제가 발생하지 않습니다.
또는 OnTradeTransaction에서 해당 메시지를 기다리십시오.
Renat는 괜찮다고 합니다. 논쟁하지 마십시오! 다음은 OrderSend에 대한 솔루션입니다.
이 OrderSend를 사용하면 그러한 문제가 발생하지 않습니다.
또는 OnTradeTransaction에서 해당 메시지를 기다리십시오.
아니, 정상이 아니다.
입장이 있습니다. 우리는 고문을 차트에 던졌습니다. 선택한 포지션에 대한 거래 내역이 없습니다 . 여기서 정상이란?