메타에디터 빌드 1490 - 페이지 3

 
fxsaber :
예, 결정할 수 없습니다. SL과 TP는 MT 서버만의 본질입니다.
가장 신뢰할 수 있는 방법 (브로커가 주석 형식을 변경하지 않는 경우 및 이것은 있을 법하지 않은 이벤트)입니다.
 

작동 방식은 다음과 같습니다.

void OnTradeTransaction ( const MqlTradeTransaction &trans,
                         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);
           }
        }
     }
  }
 
실제 작업 버전(테스터용 아님)
void OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest &Request, const MqlTradeResult &Result )
{
   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." );    
  }
}
 
fxsaber :
실제 작업 버전(테스터용 아님)
void OnTradeTransaction ( const MqlTradeTransaction &Trans, const MqlTradeRequest &Request, const MqlTradeResult &Result )
{
   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." );    
  }
}
테스터에서 확인했는데 안되고, 실생활에서도 안 되는 것 같아요. 확인을 하고 있는 포지션이 더 이상 존재하지 않기 때문입니다.
 
Andrey Dik :
테스터에서 확인해봤는데 안되고, 실생활에서도 안 되는 것 같아요. 체크를 하고 있는 포지션이 더 이상 존재하지 않기 때문입니다.
이것은 테스터에서 만들어진 인위적인 오류입니다(속도가 전혀 느려지지 않도록). 논리적으로 모든 것이 맞습니다.
 
void OnTick ()
{
   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


뻔뻔한 거짓말, 위치는 그대로!
 
Andrey Dik :

포지션 ID별 거래 내역 선택이 깨진 것 같습니다.

OrderSend 이후에 이런 일이 발생하면 문제가 없습니다.
 
fxsaber :
OrderSend 이후에 이런 일이 발생하면 문제가 없습니다.
아니요, 전혀 정상이 아닙니다. 어쨌든 포지션이 있는데, 이는 "인생"에 참여한 거래가 있음을 의미합니다. 그런데 이미 포지션이 있는 상태에서 어드바이저를 던져도 코드가 거래를 보지 않는게 더 이상한데, 이것은 로그에서 보는 것이고, 포지션의 개수 가 정해져 있고, 심볼로 포지션이 선택되고, 그러나 그것에 거래가 없습니다 ...
 
Andrey Dik :
아니요, 전혀 정상이 아닙니다. 어쨌든 "인생"에 참여한 거래가 있음을 의미하는 위치가 있습니다. 그런데 이미 포지션이 있는 상태에서 어드바이저를 던져도 코드에서 트랜잭션이 보이지 않는게 더 이상하네요...
Renat는 괜찮다고 합니다. 논쟁하지 마십시오! 다음은 OrderSend에 대한 솔루션입니다.

거래, 자동 거래 시스템 및 거래 전략 테스트에 관한 포럼

OrderSend를 사용하여 MT5에서 올바르게 작동하는 방법

fxsaber , 2016.11.19 23:59

여기 라이브러리에서 동기화된 OrderSendSync를 제거했습니다.
uint OrderSend_MaxPause = 1000000 ; // максимальное время на синхронизацию в мкс.

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에서 해당 메시지를 기다리십시오.

 
fxsaber :
Renat는 괜찮다고 합니다. 논쟁하지 마십시오! 다음은 OrderSend에 대한 솔루션입니다.

이 OrderSend를 사용하면 그러한 문제가 발생하지 않습니다.

또는 OnTradeTransaction에서 해당 메시지를 기다리십시오.

아니, 정상이 아니다.

입장이 있습니다. 우리는 고문을 차트에 던졌습니다. 선택한 포지션에 대한 거래 내역이 없습니다 . 여기서 정상이란?

사유: