Добрый День Нужен совет по мультивалютному советнику

 
Почему считает, что позиция открыта сразу после отправки лимитного ордера, когда по истории сделок видно, что ордер исполняется лишь через время на бэктесте. 

Почему при попытке получения времени открытия позиции через историю (HistoryOrderGetInteger) возвращается 0?



       MqlTradeRequest request={};
       
                        
                           request.action   =TRADE_ACTION_PENDING;                                                       
                           request.magic        =MagicNumber;                           // MagicNumber ордера
                           request.symbol       =symbol;                              // символ
                           request.volume       =MathFloor((ObyomVprocentahL/100 * AccountInfoDouble(ACCOUNT_EQUITY)) / (SymbolInfoDouble(symbol,SYMBOL_TRADE_CONTRACT_SIZE) * SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN) * SymbolInfoDouble(symbol,SYMBOL_ASK))) * SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);     // !!! Поскольку покупка не всегда будет только лишь по текущему ASK, но и по цене с проскальзыванием, нужно написать значение ASK+Slipage
                           if (SLmnozhitelATR != 0)
                              {
                               request.sl       =NormalizePrice(SymbolInfoDouble(symbol,SYMBOL_BID) - (SLmnozhitelATRL* Atr[1]),symbol);
                              }
                           if (TPmnozhitelATR != 0)
                              {
                               request.tp       =NormalizePrice(SymbolInfoDouble(symbol,SYMBOL_BID) + (TPmnozhitelATRL * Atr[1]),symbol);
                              }
                                    
                        
                              request.price        = NormalizePrice(SymbolInfoDouble(symbol,SYMBOL_ASK) - (PunktiBoleeNizkogoVhoda * SymbolInfoDouble(symbol,SYMBOL_POINT)),symbol);              // !!! Здесь можно улучшить выставление не в текущий БИД, а в (БИД + 1 пункт) если следующий пункт свободен
                              request.type         = ORDER_TYPE_BUY_LIMIT;
                              request.type_filling = ORDER_FILLING_RETURN;
                              request.type_time    = ORDER_TIME_SPECIFIED;
                              //request.expiration    = ORDER_TIME_DAY;
                              request.expiration   = TimeCurrent() + (60 * MinutNaIspolnenie);
                              
                                                                                                                                                                 // !!! ЗАМЕНИТЬ, НЕЛЬЗЯ ПОКУПАТЬ ПО РЫНКУ
                        MqlTradeResult  resultL={};
                   
                   bool success = OrderSend(request, resultL);
                   Sleep(TimeOutPosleOtpravkiOrdera);
                     if (success == true)
                        {
                        for (int i=0; i < SymbolsCount; i++)
                           {
                              if (SymbolsArray[i] == symbol) 
                              {
                                 PositionOrderID[i] = HistoryOrderGetInteger(resultL.order, ORDER_POSITION_ID);
                                 Print("order", HistoryOrderGetInteger(resultL.order, ORDER_STATE));
                              }
                           }
                         
                         Alert("Куплено ",symbol);
                         
                        }
                     if (success == false)
                        {
                         Print("ОШИБКА, Ордер не отправился= ", GetLastError());
                         Print("RETCODE результата операции = ", resultL.retcode);
                         Print(
                               "ВЫВОД result ЛОГНГ:"," ",
                               resultL.retcode,", ",          // Код результата операции 
                               resultL.deal,", ",             // Тикет сделки, если она совершена 
                               resultL.order,", ",            // Тикет ордера, если он выставлен 
                               resultL.volume,", ",           // Объем сделки, подтверждённый брокером 
                               resultL.price,", ",            // Цена в сделке, подтверждённая брокером 
                               resultL.bid,", ",              // Текущая рыночная цена предложения (цены реквота) 
                               resultL.ask,", ",              // Текущая рыночная цена спроса (цены реквота) 
                               resultL.comment,", ",          // Комментарий брокера к операции (по умолчанию заполняется расшифровкой кода возврата торгового сервера) 
                               resultL.request_id,", ",       // Идентификатор запроса, устанавливается терминалом при отправке  
                               resultL.retcode_external       // Код ответа внешней торговой системы 
                              );
          }
      }
      
   if (PositionSelect(symbol) == true)
   
      {
      printf(PositionSelect(symbol),"!!!!!!!!!!!!!");
      for (int i=0; i < SymbolsCount; i++)
         {
            if (SymbolsArray[i] == symbol) 
            {
                // ВРЕМЯ БЕРЁТСЯ 01.01.1970. ЭТО НЕ ПРАВИЛЬНО
                datetime TimeOpenPosition = HistoryDealGetInteger(PositionOrderID[i], DEAL_TIME);
                ENUM_DEAL_TYPE TypePosition = HistoryDealGetInteger(PositionOrderID[i], DEAL_TYPE);

                if (TypePosition == POSITION_TYPE_BUY)
                   {
                      if ((TimeOpenPosition + (Minutavihoda * 60)) < TimeCurrent())       //
                         {
                         Print("time ", TimeOpenPosition, Minutavihoda * 60);
                              MqlTradeRequest structRequestCloseL;
                              MqlTradeResult structResultCloseL;
                              
                              //--- обнуление значений запроса и результата
                              ZeroMemory(structRequestCloseL);
                              ZeroMemory(structResultCloseL);
                             
                               structRequestCloseL.action       = TRADE_ACTION_DEAL;   //закрытие pending 'это закрытие лимиткой               // !!! Заменить на TRADE_ACTION_CLOSE_BY   ?
                                structRequestCloseL.magic        = MagicNumber;                        // ORDER_MAGIC 
                                structRequestCloseL.symbol       = Symbol();                           // инструмент 
                                structRequestCloseL.volume       = PositionGetDouble(POSITION_VOLUME); // весь объём
                                structRequestCloseL.deviation    = Proskalzivanie;                     // допустимое отклонение от цены
                                structRequestCloseL.type_filling = ORDER_FILLING_RETURN;               // 
                                structRequestCloseL.type         = ORDER_TYPE_SELL;                    // тип ордера   //Рыночный ордер на покупку
                               
                               
                              bool successCloseL = OrderSend(structRequestCloseL,structResultCloseL);
                              Sleep(TimeOutPosleOtpravkiOrdera);
         
                                 if (successCloseL == true)
                                    {
                                     Alert("Продано ",_Symbol);
                                    }
                                 if (successCloseL == false)
                                    {
                                     Print("ОШИБКА ЗАКРЫТИЯ ПОЗИЦИИ, Ордер не отправился= ", GetLastError());         // !!! Проскакивает Ошбка закрытия позиции 4756 (Не удалось отправить торговый запрос) с Retcode 10018 (Рынок закрыт)
                                     //Print("RETCODE результата операции = ", structResultCloseL.retcode);               // Значит, нужно прописать условие чтобы попытки закрытия продолжались и после нужного часа. 
                                    }



 
min1983 Блощицын:

Почему при попытке получения времени открытия позиции через историю (HistoryOrderGetInteger) возвращается 0?

Смешались в кучу кони, люди и ...

Если вы работаете с открытой позицией,  то зачем обращаетесь к истории? Обращайтесь к свойствам позиции.

PositionSelect(symbol);// если счёт неттинг (всегда одна позиция) или хеджинг, но открыта только одна позиция
PositionGetInteger(POSITION_TIME);

Но если по каким то причинам нужно обращаться к истории, то имейте ввиду, истории позиций в МТ5 не существует, есть только история ордеров и сделок.

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

HistorySelect();
или
HistorySelectByPosition(position_id);
а уж потом
datetime TimeOpenPosition = HistoryDealGetInteger(PositionOrderID[i], DEAL_TIME);


Отдельно рекомендую почитать статью  ибо вы используете printf() не правильно.  

Изучаем PrintFormat() и берем готовые к использованию примеры
Изучаем PrintFormat() и берем готовые к использованию примеры
  • www.mql5.com
Статья будет полезна как новичкам, так и уже опытным разработчикам. В ней мы рассмотрим работу функции PrintFormat(), разберём примеры форматирования строк и напишем шаблоны для вывода различной информации в журнал терминала.
 
min1983 Блощицын:
Почему считает, что позиция открыта сразу после отправки лимитного ордера, когда по истории сделок видно, что ордер исполняется лишь через время на бэктесте. 

Ответить на этот вопрос может только экстрасенс, так как информации не достаточно.

 
понял спасибо огромное. буду сейчас побывать. 
 
void OnTick(string symbol)
  {
   HandleAtr = iATR(symbol,ATRtimeframe,ATRperiod);
   HandleVolumes        = iVolumes(symbol,PERIOD_M1,VOLUME_REAL);
   HandleAverageVolumes = iVolumes(symbol,PERIOD_D1,VOLUME_REAL);
   HandleATR            = iATR(symbol,ATRtimeframe,ATRperiod);
   MqlTick last_tick;
   SymbolInfoTick(symbol,last_tick);
  
 
   double Atr[];
   int copy = CopyBuffer(HandleAtr,0,0,3,Atr);
   if (copy <= 0) Print("Неудачная попытка получить значения индикатора ATR");
   ArraySetAsSeries(Atr,true);
   double BufferVolumes[60];
   int CopyVolumes = CopyBuffer(HandleVolumes,0,0,60,BufferVolumes);
   double Minuty5, Minuty15, Minuty60;
   double SumVolume = 0;
   
   for (int i=59; i>-1; i--)     //От последнего элемента в массиве к первому, т.к. данные из хэндла копируются в массив в обратном порядке.
       {
        SumVolume += BufferVolumes[i];
        if (i == 55) {Minuty5 = SumVolume;}
        if (i == 45) {Minuty15 = SumVolume;}
        if (i == 0)  {Minuty60 = SumVolume;}
       }
   
   double Delenie15_60 = Minuty15 / Minuty60;
   double Delenie5_15 = Minuty5 / Minuty15;
   double Delenie1_5 = BufferVolumes[0] / Minuty5;
   int ShiftDlyaBaraOtkritiaL = ChasVhodaL - ChasOtkritiyaSessii;
   MqlDateTime structVremyaVhodaL;
   TimeToStruct(TimeCurrent(),structVremyaVhodaL);
   if (
       (structVremyaVhodaL.hour >= 11)
       &&
       (Delenie15_60 > Relation15_60)
       &&
       (Delenie5_15 > Relation5_15)
       &&
       (Delenie1_5 > Relation1_5)
       &&
       (SymbolInfoDouble(symbol,SYMBOL_BID) > iOpen(symbol,PERIOD_H1,ShiftDlyaBaraOtkritiaL))   //если цена на момент входа (17:59) выше цены открытия сессии (10:00), то покупаем.
      )
      {
       
       MqlTradeRequest request={};
       
                        
                           request.action   =TRADE_ACTION_PENDING;                                                       
                           request.magic        =MagicNumber;                           // MagicNumber ордера
                           request.symbol       =symbol;                              // символ
                           request.volume       =MathFloor((ObyomVprocentahL/100 * AccountInfoDouble(ACCOUNT_EQUITY)) / (SymbolInfoDouble(symbol,SYMBOL_TRADE_CONTRACT_SIZE) * SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN) * SymbolInfoDouble(symbol,SYMBOL_ASK))) * SymbolInfoDouble(symbol,SYMBOL_VOLUME_MIN);     // !!! Поскольку покупка не всегда будет только лишь по текущему ASK, но и по цене с проскальзыванием, нужно написать значение ASK+Slipage
                           if (SLmnozhitelATR != 0)
                              {
                               request.sl       =NormalizePrice(SymbolInfoDouble(symbol,SYMBOL_BID) - (SLmnozhitelATRL* Atr[1]),symbol);
                              }
                           if (TPmnozhitelATR != 0)
                              {
                               request.tp       =NormalizePrice(SymbolInfoDouble(symbol,SYMBOL_BID) + (TPmnozhitelATRL * Atr[1]),symbol);
                              }
                                    
                        
                              request.price        = NormalizePrice(SymbolInfoDouble(symbol,SYMBOL_ASK) - (PunktiBoleeNizkogoVhoda * SymbolInfoDouble(symbol,SYMBOL_POINT)),symbol);              // !!! Здесь можно улучшить выставление не в текущий БИД, а в (БИД + 1 пункт) если следующий пункт свободен
                              request.type         = ORDER_TYPE_BUY_LIMIT;
                              request.type_filling = ORDER_FILLING_RETURN;
                              request.type_time    = ORDER_TIME_SPECIFIED;
                              //request.expiration    = ORDER_TIME_DAY;
                              request.expiration   = TimeCurrent() + (60 * MinutNaIspolnenie);
                              
                                                                                                                                                                 // !!! ЗАМЕНИТЬ, НЕЛЬЗЯ ПОКУПАТЬ ПО РЫНКУ
                        MqlTradeResult  resultL={};
                   
                   bool success = OrderSend(request, resultL);
                   Sleep(TimeOutPosleOtpravkiOrdera);
                     if (success == true)
                        {
                        for (int i=0; i < SymbolsCount; i++)
                           {
                              if (SymbolsArray[i] == symbol) 
                              {
                                 PositionOrderID[i] = HistoryOrderGetInteger(resultL.order, ORDER_POSITION_ID);
                                 Print("order", HistoryOrderGetInteger(resultL.order, ORDER_STATE));
                              }
                           }
                         
                         Alert("Куплено ",symbol);
                         
                        }
                     if (success == false)
                        {
                         Print("ОШИБКА, Ордер не отправился= ", GetLastError());
                         Print("RETCODE результата операции = ", resultL.retcode);
                         Print(
                               "ВЫВОД result ЛОГНГ:"," ",
                               resultL.retcode,", ",          // Код результата операции 
                               resultL.deal,", ",             // Тикет сделки, если она совершена 
                               resultL.order,", ",            // Тикет ордера, если он выставлен 
                               resultL.volume,", ",           // Объем сделки, подтверждённый брокером 
                               resultL.price,", ",            // Цена в сделке, подтверждённая брокером 
                               resultL.bid,", ",              // Текущая рыночная цена предложения (цены реквота) 
                               resultL.ask,", ",              // Текущая рыночная цена спроса (цены реквота) 
                               resultL.comment,", ",          // Комментарий брокера к операции (по умолчанию заполняется расшифровкой кода возврата торгового сервера) 
                               resultL.request_id,", ",       // Идентификатор запроса, устанавливается терминалом при отправке  
                               resultL.retcode_external       // Код ответа внешней торговой системы 
                              );
          }
      }
      
   if (PositionSelect(symbol) == true)
   
      {
      printf(PositionSelect(symbol),"!!!!!!!!!!!!!");
      for (int i=0; i < SymbolsCount; i++)
         {
            if (SymbolsArray[i] == symbol) 
            {
                // ВРЕМЯ БЕРЁТСЯ 01.01.1970. ЭТО НЕ ПРАВИЛЬНО
                datetime TimeOpenPosition = HistoryDealGetInteger(PositionOrderID[i], DEAL_TIME);
                ENUM_DEAL_TYPE TypePosition = HistoryDealGetInteger(PositionOrderID[i], DEAL_TYPE);

                if (TypePosition == POSITION_TYPE_BUY)
                   {
                      if ((TimeOpenPosition + (Minutavihoda * 60)) < TimeCurrent())       //Условие не "точно в эту минуту", а "в эту минуту или позже"
                         {
                         Print("time ", TimeOpenPosition, Minutavihoda * 60);
                              MqlTradeRequest structRequestCloseL;
                              MqlTradeResult structResultCloseL;
                              
                              //--- обнуление значений запроса и результата
                              ZeroMemory(structRequestCloseL);
                              ZeroMemory(structResultCloseL);
                             
                               structRequestCloseL.action       = TRADE_ACTION_DEAL;   //закрытие pending 'это закрытие лимиткой               // !!! Заменить на TRADE_ACTION_CLOSE_BY   ?
                                structRequestCloseL.magic        = MagicNumber;                        // ORDER_MAGIC 
                                structRequestCloseL.symbol       = symbol;                            // инструмент 
                                structRequestCloseL.volume       = PositionGetDouble(POSITION_VOLUME); // весь объём
                                structRequestCloseL.deviation    = Proskalzivanie;                     // допустимое отклонение от цены
                                structRequestCloseL.type_filling = ORDER_FILLING_RETURN;               // Если ордер полностью не исполнился, то оставшаяся часть будет снова выставлена  // !!! ЗАМЕНИТЬ, НЕЛЬЗЯ ПОКУПАТЬ ПО РЫНКУ
                                structRequestCloseL.type         = ORDER_TYPE_SELL;                    // тип ордера   //Рыночный ордер на покупку
                               
                               
                              bool successCloseL = OrderSend(structRequestCloseL,structResultCloseL);
                              Sleep(TimeOutPosleOtpravkiOrdera);
         
                                 if (successCloseL == true)
                                    {
                                     Alert("Продано ",symbol);
                                    }
                                 if (successCloseL == false)
                                    {
                                     Print("ОШИБКА ЗАКРЫТИЯ ПОЗИЦИИ, Ордер не отправился= ", GetLastError());         // !!! Проскакивает Ошбка закрытия позиции 4756 (Не удалось отправить торговый запрос) с Retcode 10018 (Рынок закрыт)
                                     //Print("RETCODE результата операции = ", structResultCloseL.retcode);               // Значит, нужно прописать условие чтобы попытки закрытия продолжались и после нужного часа. 
                                    }
                             
                         }
                      }
                    }
           }
         }
  }
  
   

  
//+------------------------------------------------------------------+
//| ChartEvent function                                              |
//| Эта функция в коде эксперта должна присутствовать обязательно,   |
//| даже если она пустая                                             |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,         // идентификатор события  
                  const long& lparam,   // параметр события типа long
                  const double& dparam, // параметр события типа double
                  const string& sparam) // параметр события типа string
  {
   //--- Здесь ваш код...   
  }
 
min1983 Блощицын #:

Вот целиком с условиями. Спасибо

 
min1983 Блощицын #:

Вот целиком с условиями. Спасибо

а это зачем?

Sleep
 
Renat Akhtyamov #:

а это зачем?

проверка была функции