//+------------------------------------------------------------------+ //| 2 river v_2_0.mq4 | //| Kapanin Alexander | //| http://www.metaquotes.net | //+------------------------------------------------------------------+ #property copyright "Kapanin Alexander" #property link "http://www.metaquotes.net" extern int Period_MA= 20; extern int Method_MA= 3; extern int Shift_MA=0; extern double Lots=0.5; extern bool UseSound = True; // Использовать звуковой сигнал //------- Глобальные переменные -----------------------------------------------+ bool gbDisabled = False; // Флаг блокировки советника color clOpenBuy = LightBlue; // Цвет значка открытия покупки color clOpenSell = LightCoral; // Цвет значка открытия продажи color clDelete = Yellow; // Цвет значка удаление ордера color clCloseBuy = LightBlue; color clCloseSell = LightCoral; color clModifyBuy = Aqua; // Цвет значка модификации покупки color clModifySell = Tomato; // Цвет значка модификации продажи int Slippage = 3; // Проскальзывание цены int NumberOfTry = 5; // Количество торговых попыток string NameFileSound = "expert.wav"; // Наименование звукового файла datetime Today=0; //------- Подключение внешних модулей -----------------------------------------+ #include // Стандартная библиотека //+------------------------------------------------------------------+ //| expert initialization function | //+------------------------------------------------------------------+ int init() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| expert deinitialization function | //+------------------------------------------------------------------+ int deinit() { //---- //---- return(0); } //+------------------------------------------------------------------+ //| expert start function | //+------------------------------------------------------------------+ int start() { //SetHLine(Yellow); //…проверим открытие новой свечи if(Time[0]==Today) return(0); Today=Time[0]; /* double FracUp=FindNearFractal(NULL,0,MODE_UPPER); double FracDown=FindNearFractal(NULL,0,MODE_LOWER); if (ExistPositions(NULL,OP_BUY)){ for(int i=OrdersTotal()-1;i>=0;i--) if (OrderSelect(i, SELECT_BY_TICKET)) ModifyOrder(-1,FracDown,clModifyBuy); } if (ExistPositions(NULL,OP_SELL)){ for(int i1=OrdersTotal()-1;i1>=0;i1--) if (OrderSelect(i1, SELECT_BY_TICKET)) ModifyOrder(-1,FracUp,clModifySell); } */ for(int i=OrdersTotal()-1;i>=0;i--) if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(ExistPositions(NULL,OP_BUY)&& Bid>OrderOpenPrice()) { ModifyOrder(-1,Low[1],-1,clModifyBuy); Print("ОРДЕР ",OrderTicket()," : изменен SL на ",Low[1]); } if(ExistPositions(NULL,OP_SELL)&& AskMA_Hi) && (Close[1]>Open[1])) { if(ExistOrders(NULL, OP_BUYSTOP) || ExistPositions(NULL, OP_BUY)) return(0); if(ExistPositions(NULL, OP_SELL)) ClosePositions(NULL, OP_SELL); if(ExistOrders(NULL, OP_SELLSTOP)) DeleteOrders(NULL, OP_SELLSTOP); SetOrder(NULL, OP_BUYSTOP, Lots, High[1]+14*Point, Low[1]-5*Point); } if ((Open[1]>MA_Lo)&&(Open[1]<=MA_Hi)&&(Close[1]>MA_Hi)&&(Close[1]>Open[1])) { if(ExistOrders(NULL, OP_BUYSTOP) || ExistPositions(NULL, OP_BUY)) return(0); if(ExistPositions(NULL, OP_SELL)) ClosePositions(NULL, OP_SELL); if(ExistOrders(NULL, OP_SELLSTOP)) DeleteOrders(NULL, OP_SELLSTOP); SetOrder(NULL, OP_BUYSTOP,Lots, High[1]+14*Point,MA_Lo); } // Сигнал на продажу if ((Open[1]>=MA_Hi)&&(Close[1]=MA_Lo)&&(Close[1]1) // { // ModifyOrders(-1,FracUP,0, // } return(0); } //+----------------------------------------------------------------------------+ //| Описание : Возвращает флаг существования позиций | //+----------------------------------------------------------------------------+ //| Параметры: | //| sy - наименование инструмента ("" - любой символ, | //| NULL - текущий символ) | //| op - операция (-1 - любая позиция) | //| mn - MagicNumber (-1 - любой магик) | //| ot - время открытия ( 0 - любое время открытия) | //+----------------------------------------------------------------------------+ bool ExistPositions(string sy="", int op=-1, int mn=-1, datetime ot=0) { int i, k=OrdersTotal(); if (sy=="0") sy=Symbol(); for (i=0; i1 && ty<6) { if ((OrderSymbol()==sy || sy=="") && (op<0 || ty==op)) { if (mn<0 || OrderMagicNumber()==mn) { if (ot<=OrderOpenTime()) return(True); } } } } } return(False); } //+----------------------------------------------------------------------------+ //| Описание : Закрытие позиций по рыночной цене | //+----------------------------------------------------------------------------+ //| Параметры: | //| sy - наименование инструмента ("" - любой символ, | //| NULL - текущий символ) | //| op - операция (-1 - любая позиция) | //| mn - MagicNumber (-1 - любой магик) | //+----------------------------------------------------------------------------+ void ClosePositions(string sy="", int op=-1, int mn=-1) { int i, k=OrdersTotal(); if (sy=="0") sy=Symbol(); for (i=k-1; i>=0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if ((OrderSymbol()==sy || sy=="") && (op<0 || OrderType()==op)) { if (OrderType()==OP_BUY || OrderType()==OP_SELL) { if (mn<0 || OrderMagicNumber()==mn) ClosePosBySelect(); } } } } } //+----------------------------------------------------------------------------+ //| Описание : Установка ордера. | //+----------------------------------------------------------------------------+ //| Параметры: | //| sy - наименование инструмента (NULL или "" - текущий символ) | //| op - операция | //| ll - лот | //| pp - цена | //| sl - уровень стоп | //| tp - уровень тейк | //| mn - Magic Number | //| ex - Срок истечения | //+----------------------------------------------------------------------------+ void SetOrder(string sy, int op, double ll, double pp, double sl=0, double tp=0, int mn=0, datetime ex=0) { color clOpen; datetime ot; double pa, pb, mp; int err, it, ticket, msl; string lsComm=WindowExpertName()+" "+GetNameTF(Period()); if (sy=="" || sy=="0") sy=Symbol(); msl=MarketInfo(sy, MODE_STOPLEVEL); if (op==OP_BUYLIMIT || op==OP_BUYSTOP) clOpen=clOpenBuy; else clOpen=clOpenSell; if (ex>0 && ex0) { if (UseSound) PlaySound(NameFileSound); break; } else { err=GetLastError(); if (err==128 || err==142 || err==143) { Sleep(1000*66); if (ExistOrders(sy, op, mn, ot)) { if (UseSound) PlaySound(NameFileSound); break; } Print("Error(",err,") set order: ",ErrorDescription(err),", try ",it); continue; } mp=MarketInfo(sy, MODE_POINT); pa=MarketInfo(sy, MODE_ASK); pb=MarketInfo(sy, MODE_BID); if (pa==0 && pb==0) Message("SetOrder(): Проверьте в обзоре рынка наличие символа "+sy); Print("Error(",err,") set order: ",ErrorDescription(err),", try ",it); Print("Ask=",pa," Bid=",pb," sy=",sy," ll=",ll," op=",GetNameOP(op), " pp=",pp," sl=",sl," tp=",tp," mn=",mn); // Неправильные стопы if (err==130) { switch (op) { case OP_BUYLIMIT: if (pp>pa-msl*mp) pp=pa-msl*mp; if (sl>pp-(msl+1)*mp) sl=pp-(msl+1)*mp; if (tp>0 && tppp-(msl+1)*mp) sl=pp-(msl+1)*mp; if (tp>0 && tp0 && slpp-(msl+1)*mp) tp=pp-(msl+1)*mp; break; case OP_SELLSTOP: if (pp>pb-msl*mp) pp=pb-msl*mp; if (sl>0 && slpp-(msl+1)*mp) tp=pp-(msl+1)*mp; break; } Print("SetOrder(): Скорректированы ценовые уровни"); } // Блокировка работы советника if (err==2 || err==64 || err==65 || err==133) { gbDisabled=True; break; } // Длительная пауза if (err==4 || err==131 || err==132) { Sleep(1000*300); break; } // Слишком частые запросы (8) или слишком много запросов (141) if (err==8 || err==141) Sleep(1000*100); if (err==139 || err==140 || err==148) break; // Ожидание освобождения подсистемы торговли if (err==146) while (IsTradeContextBusy()) Sleep(1000*11); // Обнуление даты истечения if (err==147) { ex=0; continue; } if (err!=135 && err!=138) Sleep(1000*7.7); } } } //+----------------------------------------------------------------------------+ //+----------------------------------------------------------------------------+ //| Описание : Удаление ордеров. Версия функции для тестов на истории. | //+----------------------------------------------------------------------------+ //| Параметры: | //| sy - наименование инструмента (NULL - текущий символ) | //| op - операция ( -1 - любой ордер) | //| mn - MagicNumber ( -1 - любой магик) | //+----------------------------------------------------------------------------+ void DeleteOrders2(string sy="", int op=-1, int mn=-1) { int i, k=OrdersTotal(), ot; if (sy=="" || sy=="0") sy=Symbol(); for (i=0; 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 (it=1; it<=NumberOfTry; it++) { if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) break; while (!IsTradeAllowed()) Sleep(5000); fd=OrderDelete(OrderTicket(), clDelete); if (fd) { if (UseSound) PlaySound(NameFileSound); break; } else { err=GetLastError(); Print("Error(",err,") delete order ",GetNameOP(ot), ": ",ErrorDescription(err),", try ",it); Sleep(1000*5); } } } } } } } } //+----------------------------------------------------------------------------+ //| Версия : 19.02.2008 | //| Описание: Закрытие одной предварительно выбранной позиции | //+----------------------------------------------------------------------------+ void ClosePosBySelect() { bool fc; color clClose; double ll, pa, pb, pp; int err, it; if (OrderType()==OP_BUY || OrderType()==OP_SELL) { for (it=1; it<=NumberOfTry; it++) { if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) break; while (!IsTradeAllowed()) Sleep(5000); RefreshRates(); pa=MarketInfo(OrderSymbol(), MODE_ASK); pb=MarketInfo(OrderSymbol(), MODE_BID); if (OrderType()==OP_BUY) { pp=pb; clClose=clCloseBuy; } else { pp=pa; clClose=clCloseSell; } ll=OrderLots(); fc=OrderClose(OrderTicket(), ll, pp, Slippage, clClose); if (fc) { if (UseSound) PlaySound(NameFileSound); break; } else { err=GetLastError(); if (err==146) while (IsTradeContextBusy()) Sleep(1000*11); Print("Error(",err,") Close ",GetNameOP(OrderType())," ", ErrorDescription(err),", try ",it); Print(OrderTicket()," Ask=",pa," Bid=",pb," pp=",pp); Print("sy=",OrderSymbol()," ll=",ll," sl=",OrderStopLoss(), " tp=",OrderTakeProfit()," mn=",OrderMagicNumber()); Sleep(1000*5); } } } else Print("Некорректная торговая операция. Close ",GetNameOP(OrderType())); } //+----------------------------------------------------------------------------+ //| Версия : 01.09.2005 | //| Описание : Возвращает наименование торговой операции | //+----------------------------------------------------------------------------+ //| Параметры: | //| op - идентификатор торговой операции | //+----------------------------------------------------------------------------+ string GetNameOP(int op) { switch (op) { case OP_BUY : return("Buy"); case OP_SELL : return("Sell"); case OP_BUYLIMIT : return("Buy Limit"); case OP_SELLLIMIT: return("Sell Limit"); case OP_BUYSTOP : return("Buy Stop"); case OP_SELLSTOP : return("Sell Stop"); default : return("Unknown Operation"); } } //+----------------------------------------------------------------------------+ //| Версия : 01.09.2005 | //| Описание : Возвращает наименование таймфрейма | //+----------------------------------------------------------------------------+ //| Параметры: | //| TimeFrame - таймфрейм (количество секунд) (0 - текущий ТФ) | //+----------------------------------------------------------------------------+ string GetNameTF(int TimeFrame=0) { if (TimeFrame==0) TimeFrame=Period(); switch (TimeFrame) { case PERIOD_M1: return("M1"); case PERIOD_M5: return("M5"); case PERIOD_M15: return("M15"); case PERIOD_M30: return("M30"); case PERIOD_H1: return("H1"); case PERIOD_H4: return("H4"); case PERIOD_D1: return("Daily"); case PERIOD_W1: return("Weekly"); case PERIOD_MN1: return("Monthly"); default: return("UnknownPeriod"); } } //+----------------------------------------------------------------------------+ //| Версия : 01.09.2005 | //| Описание : Вывод сообщения в коммент и в журнал | //+----------------------------------------------------------------------------+ //| Параметры: | //| m - текст сообщения | //+----------------------------------------------------------------------------+ void Message(string m) { Comment(m); if (StringLen(m)>0) Print(m); } //+----------------------------------------------------------------------------+ //| Версия : 28.11.2006 | //| Описание : Модификация одного предварительно выбранного ордера. | //+----------------------------------------------------------------------------+ //| Параметры: | //| pp - цена установки ордера | //| sl - ценовой уровень стопа | //| tp - ценовой уровень тейка | //| cl - цвет значка модификации | //+----------------------------------------------------------------------------+ void ModifyOrder(double pp=-1, double sl=0, double tp=0, color cl=CLR_NONE) { bool fm; double op, pa, pb, os, ot; int dg=MarketInfo(OrderSymbol(), MODE_DIGITS), er, it; if (pp<=0) pp=OrderOpenPrice(); if (sl<0 ) sl=OrderStopLoss(); if (tp<0 ) tp=OrderTakeProfit(); pp=NormalizeDouble(pp, dg); sl=NormalizeDouble(sl, dg); tp=NormalizeDouble(tp, dg); op=NormalizeDouble(OrderOpenPrice() , dg); os=NormalizeDouble(OrderStopLoss() , dg); ot=NormalizeDouble(OrderTakeProfit(), dg); if (pp!=op || sl!=os || tp!=ot) { for (it=1; it<=NumberOfTry; it++) { if (!IsTesting() && (!IsExpertEnabled() || IsStopped())) break; while (!IsTradeAllowed()) Sleep(5000); RefreshRates(); fm=OrderModify(OrderTicket(), pp, sl, tp, 0, cl); if (fm) { if (UseSound) PlaySound(NameFileSound); break; } else { er=GetLastError(); pa=MarketInfo(OrderSymbol(), MODE_ASK); pb=MarketInfo(OrderSymbol(), MODE_BID); Print("Error(",er,") modifying order: ",ErrorDescription(er),", try ",it); Print("Ask=",pa," Bid=",pb," sy=",OrderSymbol(), " op="+GetNameOP(OrderType())," pp=",pp," sl=",sl," tp=",tp); Sleep(1000*10); } } } } //+----------------------------------------------------------------------------+ //| Описание : Поиск ближайшего фрактала. | //+----------------------------------------------------------------------------+ //| Параметры: | //| sy - наименование инструмента (NULL - текущий символ) | //| tf - таймфрейм ( 0 - текущий ТФ) | //| mode - тип фрактала (MODE_LOWER|MODE_UPPER) | //+----------------------------------------------------------------------------+ double FindNearFractal(string sy="0", int tf=0, int mode=MODE_LOWER) { if (sy=="" || sy=="0") sy=Symbol(); double f=0; int d=MarketInfo(sy, MODE_DIGITS), s; if (d==0) if (StringFind(sy, "JPY")<0) d=4; else d=2; for (s=2; s<100; s++) { f=iFractals(sy, tf, mode, s); if (f!=0) return(NormalizeDouble(f, d)); } Print("FindNearFractal(): Фрактал не найден"); return(0); } //+----------------------------------------------------------------------------+ //| Описание : Возвращает количество ордеров. | //+----------------------------------------------------------------------------+ //| Параметры: | //| sy - наименование инструмента ("" - любой символ, | //| NULL - текущий символ) | //| op - операция (-1 - любой ордер) | //| mn - MagicNumber (-1 - любой магик) | //+----------------------------------------------------------------------------+ int NumberOfOrders(string sy="", int op=-1, int mn=-1) { int i, k=OrdersTotal(), ko=0, ot; if (sy=="0") sy=Symbol(); for (i=0; i1 && ot<6) { if ((OrderSymbol()==sy || sy=="") && (op<0 || ot==op)) { if (mn<0 || OrderMagicNumber()==mn) ko++; } } } } return(ko); } //+----------------------------------------------------------------------------+ //| Описание : Установка объекта OBJ_HLINE горизонтальная линия | //+----------------------------------------------------------------------------+ //| Параметры: | //| cl - цвет линии | //| nm - наименование ("" - время открытия текущего бара) | //| p1 - ценовой уровень (0 - Bid) | //| st - стиль линии (0 - простая линия) | //| wd - ширина линии (0 - по умолчанию) | //+----------------------------------------------------------------------------+ void SetHLine(color cl, string nm="", double p1=0, int st=0, int wd=1) { if (nm=="") nm=DoubleToStr(Time[0], 0); if (p1<=0) p1=Bid; if (ObjectFind(nm)<0) ObjectCreate(nm, OBJ_HLINE, 0, 0,0); ObjectSet(nm, OBJPROP_PRICE1, p1); ObjectSet(nm, OBJPROP_COLOR , cl); ObjectSet(nm, OBJPROP_STYLE , st); ObjectSet(nm, OBJPROP_WIDTH , wd); }