я использую код
if(!IsConnected())return(1); if(MarketInfo(Symbol(),MODE_TRADEALLOWED) != 1)return(1);
Если происходил рекконект и это было известно - логично взводить флаг!
затем пытаться докачать котировки и только после этого пускать обсчеты
---
при ошибках связи есть неплохие способы рекконекта было в CODEBASE!
--
по докачке котировок так же можно поискать готовые решения в CODEBASE
с контролями ! на пропуски и т п
по идее надо проконтролирвать прокачку котировок
---
сложности будут так же на переходах с пятницы на понедельник
там надо качесвенно отловить точку старта и завершения
ну или не торговать несколько баров ! по рабочему тф в понедельник
кому-то будет надо).
2 kharko: действительно, с IsConnected() всё намного проще, только эксперт приходится делать зацикленным:
int Future; datetime LastTime; // Время последнего бара int Work=0; // -1 = непреодолимая ошибка, 0 = выходной/подготовка к работе, 1 = всё работает double Time_Lost; // время разрыва связи int Time_NoGap; // количество отсутствующих подряд баров, не считаемое разрывом (зависит от ТФ, устанавливается в init()) // для 1M=15, для 5M=3, для 15M=1, для остальных ТФ=0, extern bool Close_All_Pos_Before_Holidays=true; // Если true, перед выходными все открытые советником ордера закрываются, отложенные удаляются bool All_Close=false; // Метка, что ордера действительно были закрыты (устанавливается в ф-ции закрытия ордеров) //------------------------------------------------------------------------------------------------------- int start() { while(Work!=-1) /*В ходе работы не было непреодолимых ошибок (такие м.б. объявлены из многих мест программы, напр. из ф.-ции установки ордеров)*/ { if(!IsConnected())//если нет связи { double Time_Befor=TimeCurrent();//время начала разрыва связи while(!IsConnected())//пока нет связи { Sleep(30000);//ждём 30 сек. } // связь появилась ждём первого тика double Time_After=TimeCurrent(); while(Time_After==Time_Befor)//первый тик ещё не пришёл { Sleep(10000);//ждём 10 сек. Time_After=TimeCurrent(); } // есть новый тик Time_Lost=Time_After-Time_Befor;//секунд в разрыве if(Time_Lost>=604800) { Alert("связи не было больше недели:-о)"); Alert("Необходима переустановка советника"); Close_All_Orders();//Функция, закрывающая все открытые ордера Work=-1; return; } Time_Lost=MathFloor(Time_Lost/(60*Period()));//баров в разрыве /*баров обычно пропущено Time_Lost или Time_Lost-1, иначе история недогружена или отсутствуют отдел. бары или разрыв связи был с пятницы на воскресенье*/ RefreshRates(); Sleep(30000);//Подождём пока данные обновятся int n=0; while(n<=Time_Lost) { if(Time[n]==LastTime)break;//нашли последний бар перед разрывом int Time_Gap=(Time[n]-Time[n+1])/(60*Period()); if(Time[n+1]+60*Period()!=Time[n])//подозрение на разрыв в ряду баров { if((Time[n]-1233532800)%604800<(Time[n+1]-1233532800)%604800) {//если это разрыв на выходные if(Period()==240)Time_Gap-=12; else Time_Gap-=3000/Period()-1; }//уменьшили разрыв на размер выходных } if(Time_Gap-1>Time_NoGap) Alert("Внимание: не хватает ",Time_Gap," баров в промежутке от ", TimeToStr(Time[n+1])," до ",TimeToStr(Time[n])); n++; } Future=n; }//выход из обработки ошибок связи if(MarketInfo(Symbol(),MODE_TRADEALLOWED)!=1) //если торговля не разрешена(сессия закрыта) return;//выходим if(LastTime==Time[0])//тот же бар { //блок, выполняемый на каждом тике } if(LastTime<Time[0])//новый бар { Total+=Future; while(Future>0) {//Блоки, выполняемые при появлении нового бара Future--;} LastTime=Time[0]; } if(Work==0)//первый тик после выходных {Sleep(600*1000);//ждём 10 минут после начала сессии Work=1; continue;} if(All_Close==true)Open_All_Orders(); //открываем позиции после выходных, если закрывали if(TimeDayOfWeek(TimeCurrent())==5) { if(TimeHour(TimeCurrent())==21) { if(TimeMinute(TimeCurrent())>30) {//за полчаса до закрытия на выходные if(Close_All_Pos_Before_Holidays==true) { Close_All_Orders();//Функция закрытия ордеров Work=0; Sleep(1860*1000);//ждём завершения сессии return;//выходим } } } } Sleep(10000);//ждём 10 сек. } }
Пару замечаний к коду: счёт открыт в Teletrade, и там недельная сессия обычно закрывается на первых тиках 22:00 пятницы, а открывается в
00:00 понедельника или позже(швейцарское время). Соответственно, все числа подобраны под эти данные. 1233532800-открытие 2 февраля
2009, понедельник, 00:00 (можно взять любой другой понедельник), но у брокеров в других часовых поясах это число изменится.
Также бывают дни (например, перед новым годом), когда сокращенная неделя или нестандартное закрытие в пятницу - тут эта программа не
поможет, надо всё делать самому (если есть желание закрыть позиции перед выходными, закрывать вручную). Либо писать нестандартные
даты закрытия в отдельный файл, и чтобы советник периодически считывал данные из этого файла
Обращаю внимание, что код ещё не проверен в торговле.
Также хотелось бы услышить компетентное мнение по следующим вопросам:
1) Вызов RefreshRates() является достаточным для подкачки всех пропущенных данных?
2) обновление истории происходит внутри функции RefreshRates() или после её вызова? (я в программе сделал паузу в 30 секунд после вызова
RefreshRates(), чтобы если пропущено много данных, всё обновилось; так нужна ли вообще эта пауза?)
3) К вопросу о значениии Sleep() при проверке !IsConnected() :
Бывают ли разрывы в связи размером в несколько секунд, которые не видны при обычной торговле, но учитываются терминалом, и если да, то как часто

- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования
Занялся программированием на MQL около месяца назад, сейчас пишу второй советник (первый при прогоне в тестере терял со скоростью спреда:(
По ходу дела возник вопрос по технической части, а именно:
Когда случаются разрывы в связи, и в разрыв попадает хотя бы 1 бар, то после восстановления связи этот бар тоже должен быть обсчитан.
Сначала я предполагал использовать такой код:
Однако затем я обратил внимание, что при восстановлении связи после разрыва сначала появляется один или несколько тиков последнего бара, а затем подгружается вся пропущенная история. Поэтому первый вариант кода, видимо, некорректен.
Уже при написании поста пришла идея:
Однако и здесь есть два недостатка:
- до появления новой свечи история может так и не подгрузиться
- на свечах больших таймфреймов это приведёт к большой задержке во времени
В связи с этим вопрос: существует ли более надёжный алгоритм (шаблон) кода для разрешения такой проблемы (ведь наверняка те, кто давно пишет на MQL, сталкивались с подобным)
Заранее спасибо за ответ