Функции StartTrading() и StopTrading()
В прошлом выпуске я привел исходные коды двух функций: StartTrading() и StopTrading().
В этом выпуске я расскажу о том, что делают эти функции и как использовать.
В выпуске "Как избежать ошибок, если несколько экспертов торгуют одновременно" я приводил исходный код функции WaitUntilTradingIsAllowed(), которая ждет, пока освободится торговый поток, т.е. когда другой эксперт закончит торговать. После этого функция WaitUntilTradingIsAllowed() возвращает управление эксперту, из которого она была вызвана. Это будет сигналом того, что торговый поток освободился и можно торговать.
Теоретически возможна ситуация, когда сразу несколько экспертов ждут освобождения торгового потока и в момент его освобождения в каждом из них функция WaitUntilTradingIsAllowed() завершится практически одновременно. В этом случае сразу несколько экспертов попытается совершить торговую операцию в один и тот же момент времени. В результате только у одного эксперта это получится, а остальные эксперты вернут ошибку ERR_TRADE_CONTEXT_BUSY (146).
Для того, чтобы избежать этого, есть очень простой (благодаря наличию функции GlobalVariableSetOnCondition) выход. Мы создаем объект (глобальную переменную "TradeIsAllowed"), который будет иметь значение 0, если торговый поток свободен и торговать можно, и значение 1, если другой эксперт в этот момент уже торгует.
Таким образом, перед тем, как совершить торговую операцию, надо вызвать функцию StartTrading(). Вначале эта функция проверит, существует ли глобальная переменная с именем "TradeIsAllowed". Если она не существует, то создаст ее и присвоит ей значение 0 ("торговать можно"). Если же такая глобальная переменная уже существует, то мы сразу переходим к проверке ее значения.
Мы пытаемся в бесконечном цикле изменить значение глобальной переменной "TradeIsAllowed" на 1. При этом мы это делаем, используя функцию GlobalVariableSetOnCondition():
// Если удалось изменить значение глобальной переменной, то обновим данные // о текущих курсах и вернем 0 if (GlobalVariableSetOnCondition(GLOB_VAR_NAME, 1, 0)) { RefreshRates(); return(0); }
Эта функция изменит значение глобальной переменной на 1 ("торговать другим нельзя") только в том случае, если ее текущее значение равно 0 ("торговый поток свободен"). Таким образом, если у нас несколько экспертов ждут освобождения торгового потока, то изменить глобальную переменную сможет только один из них. Остальные это сделать не смогут, т.к. в момент вызова ими функции GlobalVariableSetOnCondition() значение переменной уже будет не равно 0. В этом случае другие эксперты "заснут" на 0.1 секунды (команда Sleep) и будут повторять свои попытки дождаться освобождения торгового потока снова и снова, до тех пор, пока цель не будет достигнута или пока эксперт не будет остановлен (см. функцию IsStopped) или торговля экспертов не будет запрещена на уровне настроек терминала (см. функцию IsExpertEnabled).
После того, как Ваш эксперт, который вызвал функцию StartTrading(), закончит торговать, не забудьте сразу же вызвать функцию StopTrading().
Эта функция просто устанавливает значение глобальной переменной "TradeIsAllowed" в 0 ("торговый поток свободен").
Пример использования функций StartTrading() и StopTrading() в эксперте:
... StartTrading(); // мы захватили торговый поток - можно и поторговать OrderSend(Symbol(),OP_BUY,1,Ask,3,Bid-25*Point,Ask+25*Point,"My order #"+counter,16384,0,Green); // освободим за собой торговый поток StopTrading(); ...
Если же Вы забудете вызвать функцию StopTrading(), то значение глоабльной переменной "TradeIsAllowed" останется равной 1, и ни один эксперт не сможет больше торговать.
В следующем выпуске я расскажу о том, как получить значение глобальной переменной с помощью функции GlobalVariableGet().
Все статьи по теме "Пишем советников для MetaTrader 4".
- Механическая торговая система - миф или реальность?
- С чего начать при написании советника:
- Создаем нового советника - Настраиваем параметры. - Язык MetaQuotes Language 4: