Скачать MetaTrader 5

Как правильно выяснить, что рынок закрыт? (mql4)

Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий
Добавляй наш канал в друзья и следи за новостями!
Vladimir Zubov
4313
Vladimir Zubov 2015.01.31 20:04 

Перевел советника в режим работы OnTimer() теперь когда рынок закрыт он этого не понимает и пытается торговать, в общем обращается к серверу и естественно получает ошибки и забивает логи журнала. GetLastError() = Рынок закрыт. Какие ещё условия проверки на выходной день или закрытый рынок можно придумать ?

   if (DayOfWeek()==0 || DayOfWeek()==6) // Не помогает, последнее время сервера 21:54 ПЯТНИЦА хотя реально сейчас суббота!
      {
         TradeEnabled = 0;
      }
   else
      {
         TradeEnabled = 1;
      } 
MarketInfo(symbol,MODE_TRADEALLOWED) // не помогает, всегда возвращает True
Alexander Bereznyak
21476
Alexander Bereznyak 2015.01.31 20:07  
добавьте паузу или запрет торговых приказов в определенное время
Vladimir Zubov
4313
Vladimir Zubov 2015.01.31 20:09  
Мне под mql4 надо, и да эксперт видит что сегодня пятница, хотя фактически суббота.
Ihor Herasko
9040
Ihor Herasko 2015.01.31 21:07  

Если правильно, то ни одним из указанных способов, т. к. делать код для каждого брокера (у каждого свой регламент) под разные символы неудобно.

Однозначно определяется так:

1. Осуществляется любая торговая операция.

2. В ответ на  операцию получаем код ошибки 132 (ERR_MARKET_CLOSED).

 

Далее, чтобы не пропустить открытие рынка, можно повторять торговые операции с некоторой периодичностью.

К примеру, в одном советнике, который работает с множеством символов, я сделал так:

bool DoTrade(ENUM_TRADE_TYPE tradeType, TradeParam &tradeParam)
{
   // Проверка возможности проведения торговой операции по символу
   if (!IsSymbolTradeAllowed(tradeParam.symbol))
      return false;
   
   bool res = true;
   int ticket = 0;
   switch (tradeType)
   {
      case TRADE_TYPE_DELETE:    res = OrderDelete(tradeParam.orderTicket);                                                                  break;
      case TRADE_TYPE_CLOSE:     res = OrderClose(tradeParam.orderTicket, tradeParam.orderVolume, tradeParam.orderCP, i_slippage);           break;
      case TRADE_TYPE_CLOSEBY:   res = OrderCloseBy(tradeParam.orderTicket, tradeParam.orderTicketCounter);                                  break;
      case TRADE_TYPE_MODIFY:    res = OrderModify(tradeParam.orderTicket, tradeParam.orderOP, tradeParam.orderSL, tradeParam.orderTP, 0);   break;
      case TRADE_TYPE_OPEN:      {
                                    tradeParam.orderTicket = OrderSend(tradeParam.symbol, tradeParam.orderType, 
                                                                       tradeParam.orderVolume, tradeParam.orderOP, 
                                                                       i_slippage, tradeParam.orderSL, tradeParam.orderTP, 
                                                                       "", tradeParam.orderMN);  
                                    res = (tradeParam.orderTicket > 0);
                                    break;
                                 }
   }
   
   int error = GetLastError();
   if (!res)
   {
      ... // обработка других ошибок
      if (error == ERR_MARKET_CLOSED || error == ERR_OFF_QUOTES)
         AddSymbolToMarketClosedList(tradeParam.symbol);
   }
      
   return res;
}

 Функция проверки возможности торговли по символу:

bool IsSymbolTradeAllowed(string symbol)
{
   if (SymbolInfoInteger(symbol, SYMBOL_TRADE_MODE) != SYMBOL_TRADE_MODE_FULL)
   {
      Alert(WindowExpertName(), ": невозможно совершить торговую операцию по символу ", symbol, ", т. к. по нему торговля запрещена!");
      AddSymbolToMarketClosedList(symbol, true);
      return false;
   }

   for (int i = g_marketSymbolsCnt - 1; i >= 0; i--)
      if (g_marketClosedSymbols[i].symbol == symbol)
         return (TimeCurrent() - g_marketClosedSymbols[i].lastRequest) > 60;
      
   return true;
}

 Функция записи символа, по которому нельзя торговать:

void AddSymbolToMarketClosedList(string symbol, bool isStopTrade = false)
{
   datetime time = TimeCurrent();
   if (isStopTrade)
      time = StringToTime("3000.01.01");

   for (int i = g_marketSymbolsCnt - 1; i >= 0; i--)
      if (g_marketClosedSymbols[i].symbol == symbol)
      {
         g_marketClosedSymbols[i].lastRequest = time;
         return;
      }
      
   if (g_marketSymbolsCnt >= MAX_SYMBOLS_AMOUNT)
      return;
      
   g_marketClosedSymbols[g_marketSymbolsCnt].symbol = symbol;
   g_marketClosedSymbols[g_marketSymbolsCnt].lastRequest = time;
   g_marketSymbolsCnt++;
}

 Как нетрудно догадаться, массив g_marketClosedSymbols - это массив структур.

pako
3309
pako 2015.01.31 23:08  
Kino:

Перевел советника в режим работы OnTimer() теперь когда рынок закрыт он этого не понимает и пытается торговать, в общем обращается к серверу и естественно получает ошибки и забивает логи журнала. GetLastError() = Рынок закрыт. Какие ещё условия проверки на выходной день или закрытый рынок можно придумать ?

тики не приходят

серверное время не меняется 

if (DayOfWeek()==0 || DayOfWeek()==6) по времени компа  +/- серверное время 

 

если такая ошибка, то наверно выходные 

Scriptong 

 2. В ответ на  операцию получаем код ошибки 132 (ERR_MARKET_CLOSED).

Alexander Puzanov
29607
Alexander Puzanov 2015.01.31 23:49  
input int       Timer_Sleep_After = 3600; // Если тиков нет уже час, знач рынок закрыт

datetime gt_Last_Tick_Time = 0;


void OnTimer() {
        if(TimeLocal() - gt_Last_Tick_Time > Timer_Sleep_After) return;
}


void OnTick() {
        gt_Last_Tick_Time = TimeLocal();
}
Vladimir Zubov
4313
Vladimir Zubov 2015.01.31 23:53  
Scriptong:

Если правильно, то ни одним из указанных способов, т. к. делать код для каждого брокера (у каждого свой регламент) под разные символы неудобно.

Однозначно определяется так:

1. Осуществляется любая торговая операция.

2. В ответ на  операцию получаем код ошибки 132 (ERR_MARKET_CLOSED).

 

Далее, чтобы не пропустить открытие рынка, можно повторять торговые операции с некоторой периодичностью.

К примеру, в одном советнике, который работает с множеством символов, я сделал так:

 Функция проверки возможности торговли по символу:

 Функция записи символа, по которому нельзя торговать:

 Как нетрудно догадаться, массив g_marketClosedSymbols - это массив структур.

Спасибо за наводку на путь истинный, но когда рынок открыт пытаться определить возможность работы с ордерами это как то всеравно не корректно, но работать будет.
Vladimir Zubov
4313
Vladimir Zubov 2015.01.31 23:54  
f2011:
Тоже спасибо, интересное решение.
Vladimir Zubov
4313
Vladimir Zubov 2015.02.01 00:02  

Теперь вопрос к разработчикам МК, зачем делать событие которое никогда не сработает ? https://docs.mql4.com/ru/dateandtime/dayofweek

if(DayOfWeek()==0 || DayOfWeek()==6) return(0);

если работаю по тикам, то тиков нет и событие не произойдет, если работаю по таймеру то сервер выдает время прихода последнего ника к нему, то есть последние минуты пятницы и событие тоже никогда не произойдет. Получается у меня советник по таймеру, а сервер по тикам работает как и раньше, но сервер онлайн так как при отправке запроса выдает ошибку 132. Исправьте пожалуйста или чтобы на сервере время менялось по таймеру тоже или чтобы я мог проверить закрыт ли рынок без отправки торгового приказа. Это баг лютый, надеюсь на понимание и решение вопроса.

DayOfWeek - Документация на MQL4
  • docs.mql4.com
DayOfWeek - Документация на MQL4
Alexey Busygin
6437
Alexey Busygin 2015.02.01 00:10  

int Weekday = TimeDayOfWeek(TimeLocal());                                                          //Локальное время  |
int Weekdays = TimeDayOfWeek(TimeCurrent());                                                       //Серверное время  |

while(IsExpertEnabled())                                                                 //До тех пор пока запушенно  |

     {
     if(Weekday!=0||Weekday!=6){Exp=true;if(Weekday==1){Info(4,Weekday,0);}}       //Если не Сбб. Воск. то разрешено  |
     if(Weekdays==0||Weekdays==6)                                                  //Если Сбб. Воск. то не разрешено  |
       {
       Exp=false;Info(5,Weekdays,0);
       if(Weekdays==6){Sleep(86400000);}                                                //Если суббота пауза 24 часа  |
       if(Weekdays==0){Sleep(3600000);}                                               //Если воскресение пауза 1 час  |
       }

Я примерно, так решил, через паузы и циклы, но это старый код, до обновления версии терминала. Сейчас есть более простые способы, нужно просто, немного почитать литературу.
Vladimir Zubov
4313
Vladimir Zubov 2015.02.01 00:12  
Опять к МК! Если сервер знает что рынок закрыт и выдает ошибку 132, другими словами дайте запрос проверки открыт рынок или нет без обращения к работе с ордерами, это важно так как определение субботы и воскресения не совсем корректно, есть праздники и раннее закрытие торговой сессии и у каждого ДЦ оно отличается.
123456789
Авторизуйтесь или зарегистрируйтесь, чтобы добавить комментарий