Как будто многопоточно работает OnTick

 

Всем добрый день.

Разбираюсь с MQL5, пишу простого эксперта для первого подхода и всё бы хорошо, но наткнулся на проблему, которая не гуглится.

Проблема следующая - при запуске бэктеста, такое ощущение, что OnTick выполняется одновременно в несколько потоков. Поэтому как дело доходит до исполнения ордера, то вместо одного ордера размещается три(!). Не могу понять почему (код ниже).

Защищаюсь от наличия нескольких ордеров глобальной переменной, которая если True, то ордера открываться не должны. Ан нет. Уже и избыточных проверок наставил, return'ов навтыкал после размещения ордеров, пробовал делать Sleep после размещения ордера (да, думал, вдруг, значение переменной hasOrders обновляется с задержкой, поэтому раз уж я выставил ордер, то подождать секунду это нормально). Уже закрадывается мысль что какой-то кусок кода выполняется на самом деле асинхронно, но не могу найти этому подтверждения.

Буду признателен за подсказку в какую сторону глядеть.

void OnTick()
  {
//---
   MqlTradeRequest request;
   MqlTradeResult result;
   MqlTradeCheckResult check;
   
   double db[]; //буффер под значения индикатора
   int elements=2;
   
   CopyBuffer(hDB,0,0,elements,db); //вызов моего кастомного индикатора выдающего сигналы на вход
   
   //hasOrder - глобальная bool переменная
   if (OrdersTotal()>0)
      hasOrder=true;
   else
      hasOrder=false;
   
   if(hasOrder)
      return;
   
   for(int i=0;i<elements;i++) {
      if(db[i]>1 && hasOrder==false) {
         printf("Signal found on %f",db[i]);

         request.symbol      =Symbol();
         request.volume      =Lots;
         request.deviation   =100;
         request.type_filling=ORDER_FILLING_FOK;
         request.type=ORDER_TYPE_BUY;
         request.action=TRADE_ACTION_DEAL;
         request.tp=SymbolInfoDouble(Symbol(),SYMBOL_ASK)+TakeProfit;
         request.sl=db[i]-StopSize;
         request.price=SymbolInfoDouble(Symbol(),SYMBOL_ASK);
         
         bool checkResult=OrderCheck(request,check);
         
         if(!checkResult) {
            printf("Error CHECKING order (%d, %s) tp: %f, sl: %f, price: %f",check.retcode,check.comment,request.tp,request.sl, request.price);
            return;
         } else {
         
            bool success=OrderSend(request,result);
            
            if(!success) {
               printf("Error placing order (%d) tp: %f, sl: %f, price: %f",result.retcode,request.tp,request.sl, request.price);
               return;
            } else {      
               printf("Order placed");
               hasOrder=true;
               return;
            }
         }
      }
   }
   
  }
 
mrzodiak:

Всем добрый день.

Разбираюсь с MQL5, пишу простого эксперта для первого подхода и всё бы хорошо, но наткнулся на проблему, которая не гуглится.

Проблема следующая - при запуске бэктеста, такое ощущение, что OnTick выполняется одновременно в несколько потоков. Поэтому как дело доходит до исполнения ордера, то вместо одного ордера размещается три(!). Не могу понять почему (код ниже).

Защищаюсь от наличия нескольких ордеров глобальной переменной, которая если True, то ордера открываться не должны. Ан нет. Уже и избыточных проверок наставил, return'ов навтыкал после размещения ордеров, пробовал делать Sleep после размещения ордера (да, думал, вдруг, значение переменной hasOrders обновляется с задержкой, поэтому раз уж я выставил ордер, то подождать секунду это нормально). Уже закрадывается мысль что какой-то кусок кода выполняется на самом деле асинхронно, но не могу найти этому подтверждения.

Буду признателен за подсказку в какую сторону глядеть.

OrdersTotal() возвращает количество ордеров, а Вы открываете позицию.

 
mrzodiak:

Всем добрый день.

Разбираюсь с MQL5, пишу простого эксперта для первого подхода и всё бы хорошо, но наткнулся на проблему, которая не гуглится.

Проблема следующая - при запуске бэктеста, такое ощущение, что OnTick выполняется одновременно в несколько потоков. Поэтому как дело доходит до исполнения ордера, то вместо одного ордера размещается три(!). Не могу понять почему (код ниже).

Защищаюсь от наличия нескольких ордеров глобальной переменной, которая если True, то ордера открываться не должны. Ан нет. Уже и избыточных проверок наставил, return'ов навтыкал после размещения ордеров, пробовал делать Sleep после размещения ордера (да, думал, вдруг, значение переменной hasOrders обновляется с задержкой, поэтому раз уж я выставил ордер, то подождать секунду это нормально). Уже закрадывается мысль что какой-то кусок кода выполняется на самом деле асинхронно, но не могу найти этому подтверждения.

Буду признателен за подсказку в какую сторону глядеть.

вместо OrdersTotal() использовать PositionsTotal()