OnTradeTransaction Неверный объем.

 

Здравствуйте, я разработал советник (аккаунт   Неттинг ), который использует отложенные ордера.   SellLimit и   КупитьЛимит   вместо   Собственный TakeProfit для МТ5 . Причина этого заключалась в том, чтобы избежать проскальзывания, которое происходит при использовании TP и SP MT5, поскольку они закрывают рыночные позиции, а не безадресными ордерами.


EA размещает заказы   КупитьЛимит   Это   SellLimit   на графике для входа в операцию, и когда один из этих ордеров исполняется, он размещает обратный ордер (BuyLimit или SellLimit) для выхода из операции, действуя как TakeProfit. Когда этот ордер на выход исполняется, он заменяет ордер на вход в том же месте, что и раньше, и с тем же объемом контрактов.

Оказывается, я использовал функцию   ОнТрейдТранзакция   за эту манипуляцию ордерами и все происходит корректно на ДЕМО счете и на РЕАЛЬНОМ счете с 1 объемным контрактом.

Проблема возникает, когда я пытаюсь использовать более одного объемного контракта на РЕАЛЬНОМ счете. Советник исполняет ордер на вход с 4 контрактами и иногда размещает ордер на выход только с 3 контрактами, или иногда он размещает ордер на выход с правильным количеством контрактов, но когда он исполняется, ордер на вход заменяется. В итоге контрактов становится меньше.

Я подозреваю, что в том, как я использую перечисление, может быть ошибка.   DEAL_VOLUME , однако мне не удалось определить, в чем будет заключаться логическая ошибка.

Важные моменты: 1- Баг всегда возникает при меньшем количестве контрактов, большего количества контрактов не добавлялось.
2- Ошибка не возникает на демо-счетах и на   Тестер стратегий .
3- На реальном счете иногда размещается правильное количество контрактов, а иногда возникает ошибка.
4- Если вы используете советник в течение длительного времени, всегда будет возникать ошибка, уменьшающая количество контрактов до тех пор, пока за час не останется только 1 контракт.

Ниже приведен код OnTradeTransaction (Остальная часть кода советника не имеет никакого отношения к этой функции)


 //+-------------------------------------------------------------------------+
 //| RECOLOCA A ORDEM EM CASO DE OPERAÇÃO COM LUCRO    |
 //+-------------------------------------------------------------------------+
 void OnTradeTransaction ( const MqlTradeTransaction & trans,
                         const MqlTradeRequest & request,
                         const MqlTradeResult & result)
{
 //--- get transaction type as enumeration value 
   ENUM_TRADE_TRANSACTION_TYPE type = trans.type;
 //--- if transaction is result of addition of the transaction in history 
   if (type== TRADE_TRANSACTION_DEAL_ADD && closePosition== false ) // Se closePosition == True, não precisa abrir novas ordens 
     {
       long      deal_entry        = 0 ;
       string    deal_symbol       = "" ;
       long      deal_type         = 0 ;
       double    deal_volume       = 0 ;
       double    deal_price        = 0 ;
      
       if ( HistoryDealSelect (trans.deal))
        {
         deal_entry  = HistoryDealGetInteger (trans.deal, DEAL_ENTRY );         
         deal_symbol = HistoryDealGetString (trans.deal, DEAL_SYMBOL );
         deal_type   = HistoryDealGetInteger (trans.deal, DEAL_TYPE );
         deal_volume = HistoryDealGetDouble (trans.deal, DEAL_VOLUME );
         deal_price  = HistoryDealGetDouble (trans.deal, DEAL_PRICE );         
        }
       else 
         return ;
         
          
       if (deal_symbol== Symbol ())
       {                

         //RECOLOCAÇÃO DE ORDENS ACIMA DA ABERTURA                       
             if (preco.last>=value_open)
            {
               //-- Recoloca a ordem de venda 
               if (deal_entry== DEAL_ENTRY_OUT && deal_type== DEAL_TYPE_BUY )
               {
                 trade.SellLimit(deal_volume,deal_price+take* Point (), _Symbol , 0 , 0 , 0 , 0 , "Venda Recolocada" );       
                 Print ( "■ Venda Recolocada - Contratos = " , deal_volume, " - Preço " ,deal_price+take* Point ());
               }
                     //Recoloca Saida da Venda 
                     if (deal_entry== DEAL_ENTRY_IN && deal_type== DEAL_TYPE_SELL )
                      {
                       trade.BuyLimit(deal_volume,deal_price-take* Point (), _Symbol , 0 , 0 , 0 , 0 , "Saida da Venda" );     // Saida da Venda 
                       Print ( "■ Gain da venda colocado no preço : " ,deal_price-take* Point ());
                      }                                             
            }
         //RECOLOCAÇÃO DE ORDENS ABAIXO DA ABERTURA             
             if (preco.last<value_open)
            {        
               //-- Recolca a ordem de compra 
               if (deal_entry== DEAL_ENTRY_OUT && deal_type== DEAL_TYPE_SELL )
               {
                 trade.BuyLimit(deal_volume,deal_price-take* Point (), _Symbol , 0 , 0 , 0 , 0 , "Compra Recolocada" );
                 Print ( "■ Compra Recolocada - Contratos = " ,deal_volume, " - Preço " ,deal_price-take* Point ());
               } 
                     //Recoloca Saida da Compra 
                     if (deal_entry== DEAL_ENTRY_IN && deal_type== DEAL_TYPE_BUY )
                      {               
                       trade.SellLimit(deal_volume,deal_price+take* Point (), _Symbol , 0 , 0 , 0 , 0 , "Saida da Compra" );   // Saida da Compra 
                       Print ( "■ Gain da compra colocado no preço : " ,deal_price+take* Point ());
                      }
            }
      }

Если кто-то может мне помочь и нуждается в дополнительной информации, я был бы признателен.

Documentação sobre MQL5: Elementos Básicos da Linguagem / Funções / Funções de Manipulação de Evento
Documentação sobre MQL5: Elementos Básicos da Linguagem / Funções / Funções de Manipulação de Evento
  • www.mql5.com
Funções de Manipulação de Evento - Funções - Elementos Básicos da Linguagem - Referência MQL5 - Referência sobre algorítimo/automatização de negociação na linguagem para MetaTrader 5
 
Tiago Silvano Souza Felipe:

Я подозреваю, что в том, как я использую перечисление, может быть ошибка.   DEAL_VOLUME , однако мне не удалось определить, в чем будет заключаться логическая ошибка.

Важные моменты: 1- Баг всегда возникает при меньшем количестве контрактов, большего количества контрактов не добавлялось.
2- Ошибка не возникает на демо-счетах и на   Тестер стратегий .
3- На реальном счете иногда размещается правильное количество контрактов, а иногда возникает ошибка.
4- Если вы используете советник в течение длительного времени, всегда будет возникать ошибка, уменьшающая количество контрактов до тех пор, пока за час не останется только 1 контракт.

Причина в политике заполнения ордеров ENUM_ORDER_TYPE_FILLING. У вас скорее всего ордера заполняются ORDER_FILLING_RETURN, поэтому исполняются частично как итог deal_volume != первоначальному объёму ордера,

а затем вы берёте этот частичный объём и выставляете новый ордер с этим объёмом.

trade.BuyLimit(deal_volume,deal_price-take* Point (), _Symbol , 0 , 0 , 0 , 0 , "Compra Recolocada" );

Нужно дождаться полного закрытия всей позиции, а затем при выставлении ордера использовать не deal_volume, а первоначальный объём.


Вот эти строки кода, вызывают сомнение в их целесообразности. Возможно из за них вы видите только частичное закрытие позиции.

if (preco.last>=value_open)

if (preco.last<value_open)
 
Aleksandr Slavskii # :

Причина в политике заполнения ордеров  ENUM_ORDER_TYPE_FILLING . У вас скорее всего ордера заполняются ORDER_FILLING_RETURN, поэтому исполняются частично как итог deal_volume != первоначальному объёму ордера,

а затем вы берёте этот частичный объём и выставляете новый ордер с этим объёмом.

Нужно дождаться полного закрытия всей позиции, а затем при выставлении ордера использовать не deal_volume, а первоначальный объём.


Вот эти строки кода, вызывают сомнение в их целесообразности. Возможно из за них вы видите только частичное закрытие позиции.

Спасибо за помощь. Так достаточно ли будет использовать trade.SetTypeFilling(ORDER_FILLING_FOK) в OnInit??

 
Tiago Silvano Souza Felipe #:

Спасибо за помощь. Так достаточно ли будет использовать trade.SetTypeFilling(ORDER_FILLING_FOK) в OnInit??

Использовать вместо тейк профита,  лимитный ордер с заполнением ORDER_FILLING_FOK - плохой вариант. Очень плохой.

Причина обращения: