Вы упускаете торговые возможности:
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Регистрация
Вход
Вы принимаете политику сайта и условия использования
Если у вас нет учетной записи, зарегистрируйтесь
Абсолютно ничего сложного. И историческое значение этой функции я менять не прошу.
Пусть она возвращает значение флага, как и в третьей версии, и эта функциональность вполне согласуется с ее названием.
Мне же надо знать в реальном времени, свободен или занят торговый поток. Не разрешена ли торговля, а могу ли я торговать, когда она разрешена. Я же привел пример, когда 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, исполняемый МТ при перезапуске.