//+-------------------------------------------------------------------------------------+ //| AMKAandWilder_Expert.mq4 | //| Scriptong | //| | //+-------------------------------------------------------------------------------------+ #property copyright "Scriptong" #property link "scriptong@mail.ru" //---- input parameters extern double Lots = 0.1; // Объем открываемой позиции extern int TakeProfit = 2000; extern int StopLoss = 2000; extern string A3 = "Параметры индикатора AMKA"; extern int AMKAPeriod=9; // Период AMKA extern int FastEMAPeriod=2; // Период быстрой скользящей для AMKA extern int SlowEMAPeriod=30; // Период быстрой скользящей для AMKA extern double PowLevel=2.0; // Степень, в которую возводятся составляющие AMKA // 2 - среднеквадратичное значение, // 3 - среднекубическое и т. д. extern double dK = 1.0; // коэффициент для фильтра extern bool UseStdDev = True; // использовать ли среднеквадратичное отклонение? extern int AMKAPrice = 5; // Цена расчета AMKA (0 - 6) extern string A4 = "====================================="; extern string OpenOrderSound = "ok.wav"; // Звук для открытия позиции extern int MagicNumber = 17589 ; // Магик позиций советника bool Activate, FreeMarginAlert, FatalError; double Tick, Spread, StopLevel, MinLot, MaxLot, LotStep, CurRed, CurBlue; datetime LastBar; int TypeOrder, LastType, TicketOrder, Signal; //+-------------------------------------------------------------------------------------+ //| Функция инициализации эксперта | //+-------------------------------------------------------------------------------------+ int init() { //---- Activate = False; // - 1 - == Сбор информации об условиях торговли ======================================== Tick = MarketInfo(Symbol(), MODE_TICKSIZE); // минимальный тик Spread = ND(MarketInfo(Symbol(), MODE_SPREAD)*Point); // текщий спрэд StopLevel = ND(MarketInfo(Symbol(), MODE_STOPLEVEL)*Point); // текущий уровень стопов MinLot = MarketInfo(Symbol(), MODE_MINLOT); // минимальный разрешенный объем сделки MaxLot = MarketInfo(Symbol(), MODE_MAXLOT); // максимальный разрешенный объем сделки LotStep = MarketInfo(Symbol(), MODE_LOTSTEP); // шаг приращения объема сделки // - 1 - == Окончание блока ============================================================= // - 2 - == Приведение объема сделки к допустимому и проверка корректности объема ======= Lots = MathRound(Lots/LotStep)*LotStep; // округление объема до ближайшего допустимого if(Lots < MinLot || Lots > MaxLot) // объем сделки не меньше MinLot и не больше MaxLot { Comment("Параметром Lots был задан неправильный объем сделки! Советник отключен!"); return(0); } // - 2 - == Окончание блока ============================================================= LastBar = 0; CurRed = 0; CurBlue = 0; Activate = True; // Все проверки успешно завершены, возводим флаг активизации эксперта //---- return(0); } //+-------------------------------------------------------------------------------------+ //| Функция деинициализации эксперта | //+-------------------------------------------------------------------------------------+ int deinit() { //---- Comment(""); //---- return(0); } //+-------------------------------------------------------------------------------------+ //| Приведение значений к точности одного пункта | //+-------------------------------------------------------------------------------------+ double ND(double A) { return(NormalizeDouble(A, Digits)); } //+-------------------------------------------------------------------------------------+ //| Расшифровка сообщения об ошибке | //+-------------------------------------------------------------------------------------+ string ErrorToString(int Error) { switch(Error) { case 2: return("зафиксирована общая ошибка, обратитесь в техподдержку."); case 5: return("у вас старая версия терминала, обновите ее."); case 6: return("нет связи с сервером, попробуйте перезагрузить терминал."); case 64: return("счет заблокирован, обратитесь в техподдержку."); case 132: return("рынок закрыт."); case 133: return("торговля запрещена."); case 149: return("запрещено локирование."); } } //+-------------------------------------------------------------------------------------+ //| Открытие позиции | //| Возвращает: | //| True - Позиция открыта успешно | //| False - Ошибка открытия | //+-------------------------------------------------------------------------------------+ bool OpenOrder(int Type, double Price, double SL, double TP) { // Блок проверки достаточности свободных средств if(AccountFreeMarginCheck(Symbol(), OP_BUY, Lots) <= 0 || GetLastError() == 134) { if(!FreeMarginAlert) { Print("Недостаточно средств для открытия позиции. Free Margin = ", AccountFreeMargin()); FreeMarginAlert = True; } return(False); } FreeMarginAlert = False; // --------------------------------------------- switch (Type) { case OP_BUY: string S = "BUY"; break; case OP_SELL: S = "SELL"; break; case OP_BUYSTOP: S = "BUYSTOP"; break; case OP_SELLSTOP: S = "SELLSTOP"; break; case OP_BUYLIMIT: S = "BUYLIMIT"; break; case OP_SELLLIMIT: S = "SELLLIMIT"; break; } if(WaitForTradeContext()) // ожидание освобождения торгового потока { Comment("Отправлен запрос на открытие ордера ", S, " ..."); int ticket=OrderSend(Symbol(), Type, Lots, Price, 0, SL, TP, NULL, MagicNumber, 0, CLR_NONE); // открытие позиции // Попытка открытия позиции завершилась неудачей if(ticket<0) { int Error = GetLastError(); if(Error == 2 || Error == 5 || Error == 6 || Error == 64 || Error == 132 || Error == 133 || Error == 149) // список фатальных ошибок { Comment("Фатальная ошибка при открытии позиции т. к. "+ ErrorToString(Error)+" Советник отключен!"); FatalError = True; } else Comment("Ошибка открытия позиции ", S, ": ", Error); // нефатальная ошибка return(False); } // --------------------------------------------- // Удачное открытие позиции Comment("Позиция ", S, " открыта успешно!"); PlaySound(OpenOrderSound); return(True); // ------------------------ } else { Comment("Время ожидания освобождения торгового потока истекло!"); return(False); } } //+-------------------------------------------------------------------------------------+ //| Ожидание торгового потока. Если поток свободен, то результат True, иначе - False | //+-------------------------------------------------------------------------------------+ bool WaitForTradeContext() { int P = 0; // цикл "пока" while(IsTradeContextBusy() && P < 5) { P++; Sleep(1000); } // ------------- if(P == 5) return(False); return(True); } //+-------------------------------------------------------------------------------------+ //| Расчет уровней поддержки/сопротивления | //+-------------------------------------------------------------------------------------+ void GetSignal(int Bar) { Signal = 0; // - 1 - == Расчет по индикатору AMKA =================================================== double RedDot = iCustom(Symbol(), 0, "AMKA", AMKAPeriod, FastEMAPeriod, SlowEMAPeriod, PowLevel, dK, UseStdDev, AMKAPrice, 1, Bar); double BlueDot = iCustom(Symbol(), 0, "AMKA", AMKAPeriod, FastEMAPeriod, SlowEMAPeriod, PowLevel, dK, UseStdDev, AMKAPrice, 2, Bar); if (RedDot != 0 && BlueDot == 0) { CurRed = RedDot; CurBlue = 0.0; } if (BlueDot != 0 && RedDot == 0) { CurBlue = BlueDot; CurRed = 0.0; } // - 1 - == Окончание блока ============================================================= // - 3 - == Синтез сигнала ============================================================== if (CurRed != 0) if (ND(Open[Bar]) > ND(Close[Bar])) // последний бар медвежий if (ND(Close[Bar]) < ND(Low[Bar+1])) // и он выступает за границы предыдущего бара if (ND(Open[Bar+1]) < ND(Close[Bar+1])) // а второй бар бычий Signal = 1; if (CurBlue != 0) if (ND(Open[Bar]) < ND(Close[Bar])) // последний бар бычий if (ND(Close[Bar]) > ND(High[Bar+1])) // и он выступает за границы предыдущего бара if (ND(Open[Bar+1]) > ND(Close[Bar+1])) // а второй бар медвежий Signal = 2; // - 3 - == Окончание блока ============================================================= } //+-------------------------------------------------------------------------------------+ //| Закрывает все позиции типа Type. Если закрыть не удалось закрыть, то 1. | //| Если присутствует противоположная, то возвращает 2. В случае успеха 0. | //+-------------------------------------------------------------------------------------+ int CheckOrdersReal(int Type) { for (int i = OrdersTotal()-1; i >= 0; i--) if(OrderSelect(i, SELECT_BY_POS)) if(OrderSymbol() == Symbol() && OrderMagicNumber() == MagicNumber && OrderType() < 2) // поиск "своей" сделки if(OrderType() == Type) // Если позиция типа Type { if (WaitForTradeContext()) { if(Type == OP_BUY) double Pr = ND(MarketInfo(Symbol(), MODE_BID)); else Pr = ND(MarketInfo(Symbol(), MODE_ASK)); if (!OrderClose(OrderTicket(), OrderLots(), Pr, 3))// то пытаемся закрыть ее return(1); // не удалось закрыть - вернем 1 } else return(1);//вернем 1, если не удалось дождаться освобождения торгового потока } else return(2); // вернем 2, если открыта позиция, противоположная указанной return(0); // если все ОК, то вернем 0 } //+-------------------------------------------------------------------------------------+ //| Замена стандартного блока "if-else" | //+-------------------------------------------------------------------------------------+ double IF(bool Condition, double IfTrue, double IfFalse) { if (Condition) return(IfTrue); // Если условие истинно, то возвращаем значение IfTrue else return(IfFalse); // Если условие ложно, то возвращаем значение IfFalse } //+-------------------------------------------------------------------------------------+ //| Функция START эксперта | //+-------------------------------------------------------------------------------------+ int start() { // - 1 - == Разрешено ли советнику работать? =========================================== if (!Activate || FatalError) // Отключается работа советника, если функция return(0); // init завершилась с ошибкой или имела место фатальная ошибка // - 1 - == Окончание блока ============================================================ // - 2 - == Контроль открытия нового бара ============================================== if (LastBar == Time[0]) //Если открытие на данном баре уже было return(0); // то заканчиваем // - 2 - == Окончание блока ============================================================ // - 3 - == Сбор информации об условиях торговли ======================================== Spread = ND(MarketInfo(Symbol(), MODE_SPREAD)*Point); // текщий спрэд StopLevel = ND(MarketInfo(Symbol(), MODE_STOPLEVEL)*Point); // текущий уровень стопов // - 3 - == Окончание блока ============================================================ // - 4 - == Расчет текущего сигнала ===================================================== GetSignal(1); // расчет сигнала // - 4 - == Окончание блока ============================================================ double Price = 0; int Type = -1; // - 6 - == Открытие длинной позиции ==================================================== if (Signal == 1) { int Res = CheckOrdersReal(OP_SELL); RefreshRates(); if (Res == 0) // если нет открытых позиций { Price = ND(Ask); double TP = ND(IF(TakeProfit > StopLevel/Point, Price+TakeProfit*Tick, Price + StopLevel)); double SL = ND(IF(StopLoss > (StopLevel+Spread)/Point, Price-StopLoss*Tick, Price - StopLevel-Spread)); Type = OP_BUY; } if (Res == 1) return(0); // не удалось закрыть противоположную } // - 6 - == Окончание блока ============================================================ // - 7 - == Установка ордера SellStop =================================================== if (Signal == 2) { Res = CheckOrdersReal(OP_BUY); if (Res == 0) // если нет открытых позиций { RefreshRates(); Price = ND(Bid); TP = ND(IF(TakeProfit > StopLevel/Point, Price-TakeProfit*Tick, Price - StopLevel)); SL = ND(IF(StopLoss > (StopLevel+Spread)/Point, Price+StopLoss*Tick, Price + StopLevel + Spread)); Type = OP_SELL; } if (Res == 1) return(0); // не удалось закрыть противоположную } // - 7 - == Окончание блока ============================================================ if (Type >= 0) if (!OpenOrder(Type, Price, SL, TP)) // если не удалось установить ордер return(0); // то попробуем со следующим тиком LastBar = Time[0]; return(0); } //+------------------------------------------------------------------+