что сложного в том, что IsTradeAllowed предупреждает Вас о том, что все попытки торговых операций будут отклонены? причём ещё на стороне клиента. мы не будем переименовывать эту функцию по историческим причинам.
что сложного в том, что IsTradeAllowed предупреждает Вас о том, что все попытки торговых операций будут отклонены? причём ещё на стороне клиента. мы не будем переименовывать эту функцию по историческим причинам.
Абсолютно ничего сложного. И историческое значение этой функции я менять не прошу.
Пусть она возвращает значение флага, как и в третьей версии, и эта функциональность вполне согласуется с ее названием.
Мне же надо знать в реальном времени, свободен или занят торговый поток. Не разрешена ли торговля, а могу ли я торговать, когда она разрешена. Я же привел пример, когда IsTradeAllowed работает некорректно. Что в этом-то сложного?
На самом деле, нужно как-то различать TradeAllowed, то есть разрешено ли торговать вообще, и TradeContextBusy, то есть открыт или занят торговый канал в текущий момент времени в реалтайм.
Почему МЫ должны это делать. Пусть терминал сам выстраивает ордера в очередь. Но это так, к слову.
Я первый :))) по совету Славы (и по его коду) ввел семафоры. Они помогают СЛАБО. По крайней мере, от кластера ошибок, любовно окрещенных трейдерами "ошибка номер 6". Вот окончательный код.
Помогает сочетание (см. код выше) таймаута и семафора. Ошибок становится меньше, просто за счет увеличения числа попыток (см. код ниже :) и пауз между ними.
Но это, конечно, обходы... Надо бы сделать ПРИНУДИТЕЛЬНУЮ ДЕИНИЦИАЛИЗАЦИЮ при выключении терминала и добавить в UninitializeReason( ) REASON_TERMINALSHUTDOWN. Проблем быть не должно.
В deinit эксперта делаем проверку UninitializeReason( ), и если она говорит, что терминал закрывается, обнуляем всё что можно =)))
Я в свое время предлагал скрип startup, исполняемый МТ при перезапуске.
Для авторизации и пользования сайтом MQL5.com необходимо разрешить использование файлов Сookie.
Пожалуйста, включите в вашем браузере данную настройку, иначе вы не сможете авторизоваться.
Вы вошли в аккаунт. Двухфакторная аутентификация отключена. Настройте её заново и отсканируйте новый QR-код или продолжите с отключённой двухфакторной аутентификацией.
Абсолютно ничего сложного. И историческое значение этой функции я менять не прошу.
Пусть она возвращает значение флага, как и в третьей версии, и эта функциональность вполне согласуется с ее названием.
Мне же надо знать в реальном времени, свободен или занят торговый поток. Не разрешена ли торговля, а могу ли я торговать, когда она разрешена. Я же привел пример, когда IsTradeAllowed работает некорректно. Что в этом-то сложного?
На самом деле, нужно как-то различать TradeAllowed, то есть разрешено ли торговать вообще, и TradeContextBusy, то есть открыт или занят торговый канал в текущий момент времени в реалтайм.
Почему МЫ должны это делать. Пусть терминал сам выстраивает ордера в очередь. Но это так, к слову.
Я первый :))) по совету Славы (и по его коду) ввел семафоры. Они помогают СЛАБО. По крайней мере, от кластера ошибок, любовно окрещенных трейдерами "ошибка номер 6". Вот окончательный код.
int init () { nBars = 0;//Bars; if(!IsTesting() && !GlobalVariableCheck(strTradeSemaphore)) GlobalVariableSet(strTradeSemaphore, 0.0); ... int deinit() { if(!IsTesting()) GlobalVariableSetOnCondition(strTradeSemaphore, 0.0, nMagic); return(0); } int start() { ... if(!IsBarEnd()) return(0); CheckTradeSemaphore(); ... if(!IsTesting()) GlobalVariableSet(strTradeSemaphore, 0.0); // ------ return(0); } string strTradeSemaphore = "TradeSemaphore"; bool IsBarEnd() { bool bIsBarEnd = false; if(nBars != Bars) { if(IsTesting() || (!IsTesting() && CurTime() > Time[0] + nMagic * nDelaySeconds)) { bIsBarEnd = true; nBars = Bars; } } return(bIsBarEnd); } // ------ void CheckTradeSemaphore() { if(!IsTesting()) { while(!IsStopped()) { GlobalVariableSetOnCondition(strTradeSemaphore, nMagic, 0.0); if(GlobalVariableGet(strTradeSemaphore) == nMagic) break; Sleep(1000); } RefreshRates(); } }Помогает сочетание (см. код выше) таймаута и семафора. Ошибок становится меньше, просто за счет увеличения числа попыток (см. код ниже :) и пауз между ними.
void Sell(string strExpertName) { dLotSize = 0.1;//GetLotSize(); if(AccountFreeMargin() < dLotSize * dInitAmount || AccountFreeMargin() < 500) return; double dTp; if(dTakeProfit == 0) dTp = 0; else dTp = Bid - dTakeProfit; int nResult; for(int nTry = 0; nTry < 5; nTry++) { SaveComment("\r\n" + Day() + "." + Month() + "." + Year() + " " + Hour() + ":" + Minute() + ":" + Seconds()); SaveComment(" Trying to sell, attempt " + nTry + "\r\n"); SaveComment("\r\nAsk: " + Ask + ", StopLoss: " + dStopLoss + ", TakeProfit: " + dTakeProfit + "\r\n"); nResult = OrderSend(Symbol(), OP_SELL, dLotSize, Bid, nSlip, Bid + dStopLoss, dTp, strExpertName, nMagic, 0, OrangeRed); Sleep(10000); if(nResult != -1) { SaveComment(" successfull\r\n"); break; } else { SaveComment(" failed, error " + GetLastError() + "\r\n"); RefreshRates(); } } if(nResult == -1) { int nError = GetLastError(); Alert(strExpertName + " sell error: " + nError + "\r\n" + Bid + ", " + dStopLoss + ", " + dTp); SaveComment(strExpertName + " sell error: " + nError + "\r\n" + Bid + ", " + dStopLoss + ", " + dTp); } }Как видно, функция будет пытаться продать 5 раз, и только если все 5 попыток провалятся, начнет выдавать алерты.
В deinit эксперта делаем проверку UninitializeReason( ), и если она говорит, что терминал закрывается, обнуляем всё что можно =)))
Я в свое время предлагал скрип startup, исполняемый МТ при перезапуске.