//+----------------------------------------------------------------------------+ //| e-CloseByLossOrProfit.mq4 | //| Ким Игорь В. aka KimIV | //| http://www.kimiv.ru | //| | //+----------------------------------------------------------------------------+ #property copyright "Ким Игорь В. aka KimIV" #property link "http://www.kimiv.ru" //------- Внешние параметры советника ------------------------------------------ extern string _P_Expert="---------- Параметры советника"; extern double TargetLoss = 30; // Целевой убыток extern double TargetProfit = 60; // Целевая прибыль extern bool DeleteOrders = True; // Удалять отложенные ордера extern bool CloseTerminal = False; // Закрыть терминал extern bool ShowComment = True; // Показывать комментарий extern int NumberAccount = 0; // Номер торгового счёта extern string _P_Performance= "---------- Параметры исполнения"; extern bool UseSound = False; // Использовать звуковой сигнал extern string SoundSuccess = "ok.wav"; // Звук успеха extern string SoundError = "timeout.wav"; // Звук ошибки extern int Slippage = 3; // Проскальзывание цены extern int NumberOfTry = 5; // Количество попыток //------- Глобальные переменные советника -------------------------------------- bool gbDisabled = False; // Флаг блокировки советника bool gbNoInit = False; // Флаг неудачной инициализации color clCloseBuy = Blue; // Цвет значка закрытия покупки color clCloseSell = Red; // Цвет значка закрытия продажи color clDelete = Yellow; // Цвет значка удаления ордера //------- Поключение внешних модулей ------------------------------------------- #include #import "user32.dll" int GetParent(int hWnd); int PostMessageA(int hWnd,int Msg,int wParam,int lParam); #import #define WM_CLOSE 0x0010 //+----------------------------------------------------------------------------+ //| | //| ПРЕДОПРЕДЕЛЁННЫЕ ФУНКЦИИ | //| | //+----------------------------------------------------------------------------+ //| expert initialization function | //+----------------------------------------------------------------------------+ void init() { gbNoInit=False; if(!IsTradeAllowed()) { Message("Для нормальной работы советника необходимо\n"+ "Разрешить советнику торговать"); gbNoInit=True; return; } if(!IsLibrariesAllowed()) { Message("Для нормальной работы советника необходимо\n"+ "Разрешить импорт из внешних экспертов"); gbNoInit=True; return; } if(!IsTesting()) { if(IsExpertEnabled()) Message("Советник будет запущен следующим тиком"); else Message("Отжата кнопка \"Разрешить запуск советников\""); } } //+----------------------------------------------------------------------------+ //| expert deinitialization function | //+----------------------------------------------------------------------------+ void deinit() { if(!IsTesting()) Comment(""); } //+----------------------------------------------------------------------------+ //| expert start function | //+----------------------------------------------------------------------------+ void start() { string st; if(gbDisabled) { Message("Критическая ошибка! Советник ОСТАНОВЛЕН!"); return; } if(gbNoInit) { Message("Не удалось инициализировать советник!"); return; } if(!IsTesting()) { if(NumberAccount>0 && NumberAccount!=AccountNumber()) { Message("ЗАПРЕЩЕНА торговля на счёте "+AccountNumber()); return; } else Comment(""); } if(AccountProfit()<-TargetLoss || AccountProfit()>TargetProfit) { ClosePosFirstProfit(); if(DeleteOrders) DeleteOrders(); if(CloseTerminal) CloseTerminal(); } if(ShowComment) { st="Целевой убыток="+DoubleToStr(-TargetLoss,2)+" "+AccountCurrency()+" Текущ"; if(AccountProfit()<0) st=st+"ий убыток="; else st=st+"ая прибыль="; st=st+DoubleToStr(AccountProfit(),2)+" "+AccountCurrency()+" Целевая прибыль="+DoubleToStr(TargetProfit,2)+" "+AccountCurrency(); Comment(st); } } //+----------------------------------------------------------------------------+ //| | //| ПОЛЬЗОВАТЕЛЬСКИЕ ФУНКЦИИ | //| | //+----------------------------------------------------------------------------+ //| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru | //+----------------------------------------------------------------------------+ //| Версия : 19.12.2007 | //| Описание : Закрывает торговый терминал. | //+----------------------------------------------------------------------------+ void CloseTerminal() { Print("Сработала функция CloseTerminal()"); int hwnd=WindowHandle(Symbol(),Period()); int hwnd_parent=0; while(!IsStopped()) { hwnd=GetParent(hwnd); if(hwnd==0) break; hwnd_parent=hwnd; } if(hwnd_parent!=0) PostMessageA(hwnd_parent,WM_CLOSE,0,0); } //+----------------------------------------------------------------------------+ //| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru | //+----------------------------------------------------------------------------+ //| Версия : 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(SoundSuccess); break; } else { err=GetLastError(); if(UseSound) PlaySound(SoundError); 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())); } //+----------------------------------------------------------------------------+ //| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru | //+----------------------------------------------------------------------------+ //| Версия : 19.02.2008 | //| Описание : Закрытие позиций по рыночной цене сначала прибыльных | //+----------------------------------------------------------------------------+ //| Параметры: | //| sy - наименование инструмента ("" - любой символ, | //| NULL - текущий символ) | //| op - операция (-1 - любая позиция) | //| mn - MagicNumber (-1 - любой магик) | //+----------------------------------------------------------------------------+ void ClosePosFirstProfit(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) { if(OrderProfit()+OrderSwap()>0) ClosePosBySelect(); } } } } } // Потом все остальные k=OrdersTotal(); 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(); } } } } } //+----------------------------------------------------------------------------+ //| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru | //+----------------------------------------------------------------------------+ //| Версия : 28.11.2006 | //| Описание : Удаление ордеров | //+----------------------------------------------------------------------------+ //| Параметры: | //| sy - наименование инструмента ("" - любой символ, | //| NULL - текущий символ) | //| op - операция (-1 - любой ордер) | //| mn - MagicNumber (-1 - любой магик) | //+----------------------------------------------------------------------------+ void DeleteOrders(string sy="",int op=-1,int mn=-1) { bool fd; int err,i,it,k=OrdersTotal(),ot; if(sy=="0") sy=Symbol(); for(i=k-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(it=1; it<=NumberOfTry; it++) { if(!IsTesting() && (!IsExpertEnabled() || IsStopped())) break; while(!IsTradeAllowed()) Sleep(5000); fd=OrderDelete(OrderTicket(),clDelete); if(fd) { if(UseSound) PlaySound(SoundSuccess); break; } else { err=GetLastError(); if(UseSound) PlaySound(SoundError); Print("Error(",err,") delete order ",GetNameOP(ot),": ",ErrorDescription(err),", try ",it); Sleep(1000*5); } } } } } } } } //+----------------------------------------------------------------------------+ //| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru | //+----------------------------------------------------------------------------+ //| Версия : 01.09.2005 | //| Описание : Возвращает наименование торговой операции | //+----------------------------------------------------------------------------+ //| Параметры: | //| op - идентификатор торговой операции | //+----------------------------------------------------------------------------+ string GetNameOP(int op) { switch(op) { case OP_BUY : return("Buy"); case OP_SELL : return("Sell"); case OP_BUYLIMIT : return("BuyLimit"); case OP_SELLLIMIT: return("SellLimit"); case OP_BUYSTOP : return("BuyStop"); case OP_SELLSTOP : return("SellStop"); default : return("Unknown Operation"); } } //+----------------------------------------------------------------------------+ //| Вывод сообщения в коммент и в журнал | //+----------------------------------------------------------------------------+ void Message(string m) { Comment(m); if(StringLen(m)>0) Print(m); } //+----------------------------------------------------------------------------+