//+------------------------------------------------------------------+ //| TradeContext.mqh | //| komposter | //| komposterius@mail.ru | //+------------------------------------------------------------------+ #property copyright "komposter" #property link "komposterius@mail.ru" //+------------------------------------------------------------------+ // int _IsTradeAllowed( int MaxWaiting_sec = 30 ) | // функция определяет состояние торгового потока. Коды возвратов: | // 1 - торговый поток свободен, можно торговать | // 0 - торговый поток был занят, но освободился. Торговать можно | // только после обновления рыночной информации. | // -1 - торговый поток занят, ожидание прервано пользователем | // (эксперт удалён с графика, закрыт терминал, изменился | // период и/или символ графика, ... ) | // -2 - торговый поток занят, истекло максимальное время ожидания | // (MaxWaiting_sec). Возможно, эксперту запрещена | // торговля (галочка "Разрешить эксперту торговать" в настройках | // эксперта). | // MaxWaiting_sec - время (в секундах), в течении которого функция | // будет ждать освобождения торгового потока (если он занят). | // По умолчанию = 30. | //+------------------------------------------------------------------+ int _IsTradeAllowed(int MaxWaiting_sec = 30) { // проверяем, свободен ли торговый поток if(!IsTradeAllowed()) { int StartWaitingTime = GetTickCount(); Print("Торговый поток занят! Ждём, пока он освободиться..."); // бесконечный цикл while(true) { // если эксперт был остановлен пользователем, прекращаем работу if(IsStopped()) { Print("Эксперт был остановлен пользователем!"); return(-1); } // если ожидание длится дольше времени, указанного в переменной // MaxWaiting_sec, тоже прекращаем работу if(GetTickCount() - StartWaitingTime > MaxWaiting_sec * 1000) { Print("Превышен лимит ожидания (" + MaxWaiting_sec + " сек.)!"); return(-2); } // если торговый поток освободился, if(IsTradeAllowed()) { Print("Торговый поток освободился!"); return(0); } // если ни одно из условий остановки цикла не сработало, // "ждём" 0,1 секунды и начинаем проверку сначала Sleep(100); } } else { Print("Торговый поток свободен!"); return(1); } } /* Шаблон эксперта, использующего функцию _IsTradeAllowed: int start() { // определяем необходимость входа в рынок ... // расчитываем уровни Стоп Лосс, Тейк Профит и размер лота ... // проверяем, свободен ли торговый поток int TradeAllow = _IsTradeAllowed(); if(TradeAllow < 0 ) { return(-1); } if(TradeAllow == 0) { RefreshRates(); // пересчитываем уровни Стоп Лосс и Тейк Профит ... } // открываем позицию OrderSend(.....); return(0); } */ //+------------------------------------------------------------------+ // int TradeIsBusy( int MaxWaiting_sec = 30 ) | // Функция меняет значение глобальной переменной TradeIsBusy с 0 | // на 1. | // Если в момент запуска TradeIsBusy = 1, функция ждёт, пока | // TradeIsBusy станет = 0, и только потом меняет. | // Если глобальной переменной TradeIsBusy не существует, функция | // создаёт её. | // Коды возвратов: | // 1 - успешное завершение. Глобальной переменной TradeIsBusy | // присвоено значение 1 | // -1 - в момент запуска функции TradeIsBusy = 1, ожидание было | // прервано пользователем (эксперт удалён с графика, закрыт | // терминал, изменился период и/или символ графика, ... ) | // -2 - в момент запуска функции TradeIsBusy = 1, истекло | // максимальное время ожидания (MaxWaiting_sec) | //+------------------------------------------------------------------+ int TradeIsBusy(int MaxWaiting_sec = 30) { // при тестировании нет смысла в разделении торгового потока - просто // завершаем работу функции if(IsTesting()) return(1); int _GetLastError = 0, StartWaitingTime = GetTickCount(); //+------------------------------------------------------------------+ //| Проверяем, существует ли гл. переменная и, если нет, создаём её | //+------------------------------------------------------------------+ while(true) { // если эксперт был остановлен пользователем, прекращаем работу if(IsStopped()) { Print("Эксперт был остановлен пользователем!"); return(-1); } // если ожидание длится дольше времени, указанного в // переменной MaxWaiting_sec, тоже прекращаем работу if(GetTickCount() - StartWaitingTime > MaxWaiting_sec * 1000) { Print("Превышен лимит ожидания (" + MaxWaiting_sec + " сек.)!"); return(-2); } // проверяем, существует ли гл. переменная // если она есть, выходим из этого цикла и переходим к блоку изменения // значения TradeIsBusy if(GlobalVariableCheck("TradeIsBusy")) break; else // если GlobalVariableCheck вернула FALSE, значит либо переменной нет, //либо при проверке возникла ошибка { _GetLastError = GetLastError(); // если это всё таки ошибка, выводим информацию, ждём 0,1 секунды // и начинаем проверку сначала if(_GetLastError != 0) { Print("TradeIsBusy() - GlobalVariableCheck( \"TradeIsBusy\" ) - Error #", _GetLastError); Sleep(100); continue; } } // если ошибки нет, значит глобальной переменной просто нет, пытаемся создать её // если GlobalVariableSet > 0, значит глобальная переменная успешно создана. // Выходим из ф-ции if(GlobalVariableSet("TradeIsBusy", 1.0) > 0) return(1); else // если GlobalVariableSet вернула значение <= 0, значит при создании // переменной возникла ошибка { _GetLastError = GetLastError(); // выводим информацию, ждём 0,1 секунды и начинаем попытку сначала if(_GetLastError != 0) { Print("TradeIsBusy() - GlobalVariableSet( \"TradeIsBusy\", 0.0 ) - Error #", _GetLastError); Sleep(100); continue; } } } //+------------------------------------------------------------------+ //| Если выполнение функции дошло до этого места, значит глобальная | //| переменная существует. | //| Ждём, пока TradeIsBusy станет = 0 и меняем значение TradeIsBusy | //| с 0 на 1 | //+------------------------------------------------------------------+ while(true) { // если эксперт был остановлен пользователем, прекращаем работу if(IsStopped()) { Print("Эксперт был остановлен пользователем!"); return(-1); } // если ожидание длится дольше времени, указанного в переменной // MaxWaiting_sec, тоже прекращаем работу if(GetTickCount() - StartWaitingTime > MaxWaiting_sec * 1000) { Print("Превышен лимит ожидания (" + MaxWaiting_sec + " сек.)!"); return(-2); } // пытаемся менять значение TradeIsBusy с 0 на 1 // если нам это удаётся, выходим из ф-ции, возвращая 1 - // "успешное завершение" if(GlobalVariableSetOnCondition("TradeIsBusy", 1.0, 0.0)) return(1); else // если нет, возможны 2 причины: TradeIsBusy = 1 (тогда надо ждать), // либо возникла ошибка (это мы и проверим) { _GetLastError = GetLastError(); // если это всё таки ошибка, выводим информацию и пробуем ещё раз if(_GetLastError != 0) { Print("TradeIsBusy() - GlobalVariableSetOnCondition " + "( \"TradeIsBusy\", 1.0, 0.0 ) - Error #", _GetLastError ); continue; } } // если ошибки нет, значит TradeIsBusy = 1 (другой эксперт торгует) - // выводим информацию и ждём... Comment("Ждём, пока другой эксперт закончит торговать..."); Sleep(1000); Comment(""); } } //+------------------------------------------------------------------+ // void TradeIsNotBusy() | // Функция устанавливает значение глобальной переменной | // TradeIsBusy = 0. | // Если глобальной переменной TradeIsBusy не существует, функция | // создаёт её. | //+------------------------------------------------------------------+ void TradeIsNotBusy() { int _GetLastError; // при тестировании нет смысла в разделении торгового потока - // просто завершаем работу функции if(IsTesting()) { return(0); } //---- while(true) { // если эксперт был остановлен пользователем, прекращаем работу if(IsStopped()) { Print("Эксперт был остановлен пользователем!"); return(-1); } // пытаемся установить значение гл. переменной = 0 // (или создать гл. переменную) // если GlobalVariableSet вернула значение > 0, значит всё закончилось // хорошо. Выходим из ф-ции if(GlobalVariableSet("TradeIsBusy", 0.0) > 0 ) return(1); else // если GlobalVariableSet вернула значение <= 0, значит возникла ошибка. // Выводим информацию, ждём, и пробуем ещё раз { _GetLastError = GetLastError(); if(_GetLastError != 0) Print("TradeIsNotBusy() - GlobalVariableSet( \"TradeIsBusy\", 0.0 )" + " - Error #", _GetLastError ); } Sleep(100); } } /* Шаблон эксперта, использующего функции TradeIsBusy() и TradeIsNotBusy(): #include int start() { // определяем необходимость входа в рынок ... // расчитываем уровни Стоп Лосс, Тейк Профит и размер лота ... // ждём освобождения торгового потока и занимаем его (если произошла ошибка, выходим) if(TradeIsBusy() < 0) { return(-1); } // обновляем рыночную информацию RefreshRates(); // пересчитываем уровни Стоп Лосс и Тейк Профит ... // открываем позицию OrderSend(.....); // освобождаем торговый поток TradeIsNotBusy(); eturn(0); } */ //+------------------------------------------------------------------+