- Как добавить функцию в советнике чтобы при открытии нового ордера закрывался старый?
- Помогите написать алгоритм (фракталы)
- Помогите найти советника при закрытии ордера закрывающего другой открытый или отложенный ордер.
void OnTick() { if(isNewBar(1,0) && ExistOrders()) { DeleteOrders(); } } //=============================================================================================== //------------------------- Возвращает флаг существования ордеров ------------------------------+ //=============================================================================================== bool ExistOrders(string sy="", int op=-1, int mn=-1, datetime ot=0) { if(sy=="") sy=Symbol(); for(int i=0; i<OrdersTotal(); i++) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op)) { if(OrderType()>1 && OrderType()<6) { if(mn<0 || OrderMagicNumber()==mn) { if(ot<OrderOpenTime()) return(true); }}}}} return(false); } //=============================================================================================== //------------------------------------- Удаление ордеров ---------------------------------------+ //=============================================================================================== void DeleteOrders(string sy="", int op=-1, int mn=-1, color cl=clrOliveDrab) { bool fd=false; int ot, err=-1; if(sy=="") sy=Symbol(); for(int i=OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { ot=OrderType(); if(ot>1 && ot<6) { if((OrderSymbol()==sy || sy=="") && (op<0 || ot==op)) { if(mn<0 || OrderMagicNumber()==mn) { for(int it=1; it<=3; it++) { if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break; while(!IsTradeAllowed()) Sleep(5000); fd=OrderDelete(OrderTicket(), cl); if(fd) { PlaySound("ok.wav"); break; } else { PlaySound("timeout.wav"); } Sleep(1000*5); }}}}}}}} //=============================================================================================== //----------------------------------- Функция "Новый бар" --------------------------------------+ // при первом запуске возвращает: md: 0-true, 1-ожидает следующий бар | //=============================================================================================== bool isNewBar(int md=1,int prd=0) { static datetime tm[10]; int ft=tfA(prd); if(tm[ft]==0 && md==1) { tm[ft]=iTime(Symbol(),prd,0);} if(tm[ft]==iTime(Symbol(),prd,0)) { return(false);} tm[ft]=iTime(Symbol(),prd,0); return(true); } int tfA(int tf) { switch(tf){ case PERIOD_M1: return (0); case PERIOD_M5: return(1); case PERIOD_M15: return(2); case PERIOD_M30: return(3); case PERIOD_H1: return(4); case PERIOD_H4: return(5); case PERIOD_D1: return(6); case PERIOD_W1: return(7); case PERIOD_MN1: return(8); default: return(9);} }
Спасибо большое! Только советник перестал вообще сделки открывать. Может есть код попроще)
Это простой код.
Все функции копируете ниже фунткции OnTick()/start()
В функцию OnTick()/start() в самом низу только это:
void OnTick() { ... Здесь основной ваш код ... if(isNewBar(1,0) && ExistOrders()) { DeleteOrders(); } }
Это простой код.
Все функции копируете ниже фунткции OnTick()/start()
В функцию OnTick()/start() в самом низу только это:
Функции работают как "часы".
Вы наверное их устанавливаете на новом баре
Тогда это в самый верх
void OnTick() { if(isNewBar(1,0) && ExistOrders()) { DeleteOrders(); } ... Здесь основной ваш код ... }
Точно! Даже не думал, что от перестановки так все меняется. Спасибо!
Тут всё дело в правильности логической части выполнения действий.
Если производим какое-то действие, то его нужно делать в правильной последовательности.
Ведь если мы хотим установить ордер, то сначала нужно смотреть - а нужен ли он нам? Если нужен, то делаем расчёт в каком месте. Если нужен сейчас, тогда считаем уровни и устанавливаем.
Потому как логически не верно сначала посчитать все уровни, определить место установки и перед самой установкой выяснить, что ордер нам не нужен - достигнут лимит на количество.
Так-же и с сопровождением и удалением, нужно сначала что-то получить, чтоб что-то потратить, даже есть пословица "Давайте не будем делить шкуру неубитого медведя"
Нужно всё делать по "цепочке".
- голосов: 10
- 2015.11.09
- Vasyl Nosal
- www.mql5.com
Спасибо большое! Только советник перестал вообще сделки открывать. Может есть код попроще)
Поскольку необязательно то, что приведено или будет приведено в вашей ветке, может оказаться лично для вас удобным/понятным/полезным, то порекомендую следующее:
Если что-то неясно для себя, то Учебник от Ковалёва может помогать разобраться в чём-либо, несмотря на то, что язык программирования MQL4 изменился. В т.ч., поскольку там есть простые наглядные примеры и описания.
Т.е., сочетание знакомства с Документацией, Учебником и функциями других (на форуме или в Code Base) - помощники для разобраться и конструировать свои коды с учётом своих индивидуальных потребностей и задач (создавать что-то своё следствием).
Например, в коде выше здесь, что привёл Vitaly Muzichenko - это применены функции от Игоря Кима.
Так функцию DeleteOrders(...), в авторском исполнении, можно посмотреть здесь, здесь или на сайте Игоря Кима, к примеру. Так же, как и ExistOrders(...).
Т.е., есть две большие ветки с функциями от Игоря:
- "Полезные функции от KimIV" - там с примерами применения.
- и "Только "Полезные функции от KimIV""
Добавлю ремаркой, что те же схемы функций от Игоря Ким, полагаю, многим помогли разобраться для себя в каких-то вопросах, несмотря, например, на то, что в чём-то могут не подходить (язык MQL4 изменился со времени их публикации, компилятор мог стать строже в чём-то, и т.д). А программы Игоря Ким (KimIV) и сейчас переиздаются в Code Base другими (с указанием, конечно, реального автора - KimIV).
P./S.: Указывают источник и те, кто приводит/применяет где-либо функции Игоря Ким, их модификации (уважая чужой труд; в благодарность за то, что это самим было полезно). Как-то так.
Здравствуйте. У меня возникла немного другая проблема, но также при закрытии ордеров.
Написал человеку советника, суть стратегии в локировании ордеров, т.е. при достижении определенной прибыли по всем открытым ордерам, они закрываются. Ордера разнонаправленные, вот функция, которая определяет прибыль по ордерам и при необходимости вызывает функцию закрытия ордеров:
void OrderCloseSumProfit() //закрываем ордера по достижению необходимого суммарного профита { double _sum=0.0; //сумма профитов for(int i=OrdersTotal()-1; i>=0; i--) { if(OrderSelect(i,SELECT_BY_POS)==false) { Print("Ордер не выбран (OrderCloseSumProfit)"); continue; } if(OrderSymbol()!=symbol || OrderMagicNumber()!=magic) continue; _sum=_sum+OrderProfit()+OrderSwap()+OrderCommission(); } if(_sum<SumProfit) return; OrderStopDelete(); //закрывает стоп ордера for(int i=OrdersTotal()-1; i>=0; i--) //цикл закрытия ордеров { if(OrderSelect(i,SELECT_BY_POS)==false) { Print("Ордер не выбран (OrderCloseSumProfit-2)"); continue; } if(OrderSymbol()!=symbol || OrderMagicNumber()!=magic) continue; if(OrderType()==OP_BUY) { bool _close=OrderClose_f(OrderTicket(),OrderLots(),Bid,slippage,clrNONE); } if(OrderType()==OP_SELL) { bool _close=OrderClose_f(OrderTicket(),OrderLots(),Ask,slippage,clrNONE); } } }
Кроме этой функции нигде в советнике не вызывается функция закрытия ордеров OrderClose_f, а вот собственно и она:
bool OrderClose_f(int ticket,double lots,double price,int _slippage,color arrow_color) { bool close=false; for(int i=10; i>0; i--) { close=OrderClose(ticket,lots,price,_slippage,arrow_color); if(close==true) return(close); else { int error=GetLastError(); switch(error) { case 135: Print("Цена изменилась. Пробуем ещё раз.."); RefreshRates(); // Обновим данные continue; // На след. итерацию case 136: Print("Нет цен. Ждём новый тик.."); Sleep(500); // Задержка в цикле continue; // На след. итерацию case 146: Print("Подсистема торговли занята. Пробуем ещё.."); Sleep(500); // Простое решение RefreshRates(); // Обновим данные continue; // На след. итерацию case 2 : Print("Общая ошибка."); break; case 5 : Print("Старая версия клиентского терминала."); break; // Выход из switch case 64: Print("Счет заблокирован."); break; // Выход из switch case 133:Print("Торговля запрещена"); break; case 4109:Print("Скрипту запрещено совершать торговые операции, разрешите торговлю в терминале");// Выход из switch break; default: Print("Возникла ошибка ",error);// Другие варианты } } } return(close); }
Проблема в том, что периодически советник закрывает только один последний ордер, а остальные остаются в рынке. Заказчик при этом использует виртуальный сервер, демо счета, и несколько различных брокеров, если подобная проблема возникает, то единовременно у всех брокеров. А вот в ТЕСТЕРЕ СТРАТЕГИЙ советник работает как часы.
Когда ордера не закрываются то советник ПИШЕТ ОШИБКУ 4109. Кто сталкивался с подобной проблемой помогите пожалуйста...
- Бесплатные приложения для трейдинга
- 8 000+ сигналов для копирования
- Экономические новости для анализа финансовых рынков
Вы принимаете политику сайта и условия использования