Как правильно выяснить, что рынок закрыт? (mql4)
Если правильно, то ни одним из указанных способов, т. к. делать код для каждого брокера (у каждого свой регламент) под разные символы неудобно.
Однозначно определяется так:
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 - это массив структур.
Перевел советника в режим работы OnTimer() теперь когда рынок закрыт он этого не понимает и пытается торговать, в общем обращается к серверу и естественно получает ошибки и забивает логи журнала. GetLastError() = Рынок закрыт. Какие ещё условия проверки на выходной день или закрытый рынок можно придумать ?
тики не приходят
серверное время не меняется
if (DayOfWeek()==0 || DayOfWeek()==6) по времени компа +/- серверное время
если такая ошибка, то наверно выходные
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(); }
Если правильно, то ни одним из указанных способов, т. к. делать код для каждого брокера (у каждого свой регламент) под разные символы неудобно.
Однозначно определяется так:
1. Осуществляется любая торговая операция.
2. В ответ на операцию получаем код ошибки 132 (ERR_MARKET_CLOSED).
Далее, чтобы не пропустить открытие рынка, можно повторять торговые операции с некоторой периодичностью.
К примеру, в одном советнике, который работает с множеством символов, я сделал так:
Функция проверки возможности торговли по символу:
Функция записи символа, по которому нельзя торговать:
Как нетрудно догадаться, массив g_marketClosedSymbols - это массив структур.
Теперь вопрос к разработчикам МК, зачем делать событие которое никогда не сработает ? https://docs.mql4.com/ru/dateandtime/dayofweek
if(DayOfWeek()==0 || DayOfWeek()==6) return(0);
если работаю по тикам, то тиков нет и событие не произойдет, если работаю по таймеру то сервер выдает время прихода последнего ника к нему, то есть последние минуты пятницы и событие тоже никогда не произойдет. Получается у меня советник по таймеру, а сервер по тикам работает как и раньше, но сервер онлайн так как при отправке запроса выдает ошибку 132. Исправьте пожалуйста или чтобы на сервере время менялось по таймеру тоже или чтобы я мог проверить закрыт ли рынок без отправки торгового приказа. Это баг лютый, надеюсь на понимание и решение вопроса.
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 час |
}
Перевел советника в режим работы OnTimer() теперь когда рынок закрыт он этого не понимает и пытается торговать, в общем обращается к серверу и естественно получает ошибки и забивает логи журнала. GetLastError() = Рынок закрыт. Какие ещё условия проверки на выходной день или закрытый рынок можно придумать ?
MarketInfo(symbol,MODE_TRADEALLOWED) // не помогает, всегда возвращает True