#property copyright "Scritong" #property link "scriptong@mail.ru" // Принятые сокращения: // ФЗ - флэтовая зона //---- input parameters extern double Lots = 0.1; extern string A1 = "Период ATR"; extern int ATRPeriod = 24; // Период для расчёта ATR extern string A2 = "Погрешность при определении пробоя, в пунктах"; extern int Dist = 2; // Количество пунктов выше или ниже уровня ФЗ, которое // отступается для установки отложенных ордеров extern string OpenOrderSound = "ok.wav"; // Звуковой сигнал при открытии позиции extern int MagicNumber = 11237; // Уникальный идентификатор своих ордеров int Signal, // Текущий сигнал BuyTicket, // Идентификатор ордера BUY или BUYSTOP SellTicket, // Идентификатор ордера SELL или SELLSTOP BuyType, // Тип ордера BUY или BUYSTOP SellType; // Тип ордера SELL или SELLSTOP bool Activate, FreeMarginAlert, FatalError; double Tick, Spread, StopLevel, MinLot, MaxLot, LotStep, FreezeLevel, FlatHigh, // Максимум формирующейся ФЗ FlatEndHigh, // Максимум сформированной ФЗ FlatLow, // Минимум формирующейся ФЗ FlatEndLow, // Минимум сформированной ФЗ FlatSignHigh, // Максимум сформированного ФЗ с учетом сигнальной свечи FlatSignLow; // Минимум сформированного ФЗ с учетом сигнальной свечи datetime LastBar; // Время открытия последнего посчитанного бара //+-------------------------------------------------------------------------------------+ //| Функция инициализации эксперта | //+-------------------------------------------------------------------------------------+ int init() { FatalError = False; // - 1 - == Сбор информации об условиях торговли ======================================== Tick = MarketInfo(Symbol(), MODE_TICKSIZE); // минимальный тик Spread = ND(MarketInfo(Symbol(), MODE_SPREAD)*Point); // текущий спрэд StopLevel = ND(MarketInfo(Symbol(), MODE_STOPLEVEL)*Point); // текущий уровень стопов FreezeLevel = ND(MarketInfo(Symbol(), MODE_FREEZELEVEL)*Point); // уровень заморозки MinLot = MarketInfo(Symbol(), MODE_MINLOT); // минимальный разрешенный объем сделки MaxLot = MarketInfo(Symbol(), MODE_MAXLOT); // максимальный разрешенный объем сделки LotStep = MarketInfo(Symbol(), MODE_LOTSTEP); // шаг приращения объема сделки // - 1 - == Окончание блока ============================================================= // - 2 - == Приведение объема сделки к допустимому и проверка корректности объема ======= Lots = LotRound(Lots); // округление объема до ближайшего допустимого // - 2 - == Окончание блока ============================================================= // - 3 - ================== Проверка корректности входных параметров ==================== if (ATRPeriod < 2) { Comment("Значение ATRPeriod должно быть больше 1! Советник отключен!"); Print("Значение ATRPeriod должно быть больше 1! Советник отключен!"); return(0); } if (Dist < 0) { Comment("Значение Dist должно быть положительным! Советник отключен!"); Print("Значение Dist должно быть положительным! Советник отключен!"); return(0); } // - 3 - =========================== Окончание блока ==================================== // - 4 - ========================== Учет истории сигналов стратегии ===================== FlatHigh = 0; // инициализация значения FlatLow = 999999; // инициализация значения for (int i = Bars-4; i > 1; i--) // Расчет ведется от начала истории до текущего бара GetSignal(i); // Расчет значения сигнала // - 4 - =========================== Окончание блока ==================================== LastBar = 0; Activate = True; // Все проверки успешно завершены, возводим флаг активизации эксперта return(0); } //+-------------------------------------------------------------------------------------+ //| Функция деинициализации эксперта | //+-------------------------------------------------------------------------------------+ int deinit() { Comment(""); return(0); } //+-------------------------------------------------------------------------------------+ //| Проверка объема на корректность и округление | //+-------------------------------------------------------------------------------------+ double LotRound(double L) { return(MathRound(MathMin(MathMax(L, MinLot), MaxLot)/LotStep)*LotStep); } //+-------------------------------------------------------------------------------------+ //| Приведение значений к точности одного пункта | //+-------------------------------------------------------------------------------------+ 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 WaitForTradeContext() { int P = 0; // цикл "пока" while(IsTradeContextBusy() && P < 5) { P++; Sleep(1000); } // ------------- if(P == 5) return(False); return(True); } //+-------------------------------------------------------------------------------------+ //| "Правильное" открытие позиции | //| В отличие от OpenOrder проверяет соотношение текущих уровней и устанавливаемых | //| Возвращает: | //| 0 - нет ошибок | //| 1 - Ошибка открытия | //| 2 - Ошибка значения Price | //| 3 - Ошибка значения SL | //| 4 - Ошибка значения TP | //| 5 - Ошибка значения Lot | //+-------------------------------------------------------------------------------------+ int OpenOrderCorrect(int Type, double Lot, double Price, double SL, double TP, bool Redefinition = True) // Redefinition - при True доопределять параметры до минимально допустимых // при False - возвращать ошибку { // - 1 - == Проверка достаточности свободных средств ==================================== if(AccountFreeMarginCheck(Symbol(), OP_BUY, Lot) <= 0 || GetLastError() == 134) { if(!FreeMarginAlert) { Print("Недостаточно средств для открытия позиции. Free Margin = ", AccountFreeMargin()); FreeMarginAlert = True; } return(5); } FreeMarginAlert = False; // - 1 - == Окончание блока ============================================================= // - 2 - == Корректировка значений Price, SL и TP или возврат ошибки ==================== RefreshRates(); switch (Type) { case OP_BUY: string S = "BUY"; if (MathAbs(Price-Ask)/Point > 3) if (Redefinition) Price = ND(Ask); else return(2); if (ND(TP-Bid) <= StopLevel && TP != 0) if (Redefinition) TP = ND(Bid+StopLevel+Tick); else return(4); if (ND(Bid-SL) <= StopLevel) if (Redefinition) SL = ND(Bid-StopLevel-Tick); else return(3); break; case OP_SELL: S = "SELL"; if (MathAbs(Price-Bid)/Point > 3) if (Redefinition) Price = ND(Bid); else return(2); if (ND(Ask-TP) <= StopLevel) if (Redefinition) TP = ND(Ask-StopLevel-Tick); else return(4); if (ND(SL-Ask) <= StopLevel && SL != 0) if (Redefinition) SL = ND(Ask+StopLevel+Tick); else return(3); break; case OP_BUYSTOP: S = "BUYSTOP"; if (ND(Price-Ask) <= StopLevel) if (Redefinition) Price = ND(Ask+StopLevel+Tick); else return(2); if (ND(TP-Price) <= StopLevel && TP != 0) if (Redefinition) TP = ND(Price+StopLevel+Tick); else return(4); if (ND(Price-SL) <= StopLevel) if (Redefinition) SL = ND(Price-StopLevel-Tick); else return(3); break; case OP_SELLSTOP: S = "SELLSTOP"; if (ND(Bid-Price) <= StopLevel) if (Redefinition) Price = ND(Bid-StopLevel-Tick); else return(2); if (ND(Price-TP) <= StopLevel) if (Redefinition) TP = ND(Price-StopLevel-Tick); else return(4); if (ND(SL-Price) <= StopLevel && SL != 0) if (Redefinition) SL = ND(Price+StopLevel+Tick); else return(3); break; case OP_BUYLIMIT: S = "BUYLIMIT"; if (ND(Ask-Price) <= StopLevel) if (Redefinition) Price = ND(Ask-StopLevel-Tick); else return(2); if (ND(TP-Price) <= StopLevel && TP != 0) if (Redefinition) TP = ND(Price+StopLevel+Tick); else return(4); if (ND(Price-SL) <= StopLevel) if (Redefinition) SL = ND(Price-StopLevel-Tick); else return(3); break; case OP_SELLLIMIT: S = "SELLLIMIT"; if (ND(Price - Bid) <= StopLevel) if (Redefinition) Price = ND(Bid+StopLevel+Tick); else return(2); if (ND(Price-TP) <= StopLevel) if (Redefinition) TP = ND(Price-StopLevel-Tick); else return(4); if (ND(SL-Price) <= StopLevel && SL != 0) if (Redefinition) SL = ND(Price+StopLevel+Tick); else return(3); break; } // - 2 - == Окончание блока ============================================================= // - 3 - == Открытие ордера с ожидание торгового потока ================================= if(WaitForTradeContext()) // ожидание освобождения торгового потока { Comment("Отправлен запрос на открытие ордера ", S, " ..."); int ticket=OrderSend(Symbol(), Type, Lot, Price, 3, SL, TP, NULL, MagicNumber, 0);// открытие позиции // Попытка открытия позиции завершилась неудачей 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(1); } // --------------------------------------------- // Удачное открытие позиции Comment("Позиция ", S, " открыта успешно!"); PlaySound(OpenOrderSound); return(0); // ------------------------ } else { Comment("Время ожидания освобождения торгового потока истекло!"); return(1); } // - 3 - == Окончание блока ============================================================= } //+-------------------------------------------------------------------------------------+ //| Приведение значений к точности одного тика | //+-------------------------------------------------------------------------------------+ double NP(double A) { return(MathRound(A/Tick)*Tick); } //+-------------------------------------------------------------------------------------+ //| Генерация сигналов покупки и продажи | //+-------------------------------------------------------------------------------------+ void GetSignal(int Num) { Signal = 0; // - 1 - ============ Определение значений средней и единичной волатильностей =========== double ATR1 = iATR(NULL, 0, ATRPeriod, Num); // Последнее известное значение АТR double ATR2 = iATR(NULL, 0, ATRPeriod, Num+1); // Предпоследнее известное значение ATR double Curr1 = High[Num] - Low[Num]; // Волатильность первой свечи double Curr2 = High[Num+1] - Low[Num+1]; // Волатильность второй свечи // - 1 - =============================== Окончание блока ================================ // - 2 - ============================== Генерация сигналов ============================== // - 2.1 - ============================ Найдено начало флэта =========================== if (Curr1 < ATR1 && Curr2 > ATR2) // Падение волатильности ниже среднего уровня { FlatHigh = High[Num]; // Отмечаются начальные значения FlatLow = Low[Num]; } // - 2.1 - ============================= Окончание блока =============================== // - 2.2 - ======================== Обнаружено продолжение флэта ======================= if (Curr1 < ATR1 && Curr2 < ATR2) // Волатильность продолжает находиться ниже среднего { // уровня FlatHigh = MathMax(High[Num], FlatHigh); // Определяются экстремальные значения FlatLow = MathMin(Low[Num], FlatLow); } // - 2.2 - ============================= Окончание блока =============================== // - 2.3 - ========================= Обнаружено окончание флэта ======================== if (Curr1 > ATR1 && Curr2 < ATR2) // Рост волатильности выше среднего уровня { FlatSignHigh = MathMax(High[Num], FlatHigh); // Флэт с учетом сигнальной свечи FlatSignLow = MathMin(Low[Num], FlatLow); FlatEndHigh = FlatSignHigh; // Сформированное значение флэта FlatEndLow = FlatSignLow; // - 2.3.1 - ======================== Генерация сигнала SELL ======================== if (Open[Num] > Close[Num] && // Сигнальная свеча бычья Close[Num] < FlatHigh && // Закрылась внутри ФЗ Close[Num] > (FlatHigh+FlatLow)/2) // Но выше середины ФЗ Signal = -1; // Открытие Sell с рынка // - 2.3.1 - =========================== Окончание блока ============================ // - 2.3.2 - ======================== Генерация сигнала BUY ========================= if (Open[Num] < Close[Num] && // Сигнальная свеча медвежья Close[Num] > FlatLow && // Закрылась внутри ФЗ Close[Num] < (FlatHigh+FlatLow)/2) // Но ниже середины ФЗ Signal = 1; // Открытие Buy с рынка // - 2.3.2 - =========================== Окончание блока ============================ } // - 2.3 - ============================= Окончание блока =============================== // - 2.4 - ======================== Обнаружено продолжение тренда ====================== if (Curr1 > ATR1 && Curr2 > ATR2) // Волатильность продолжает быть выше среднего уровня { FlatEndHigh = MathMax(FlatEndHigh, High[Num]); // Отслеживается пробитие экстремумов FlatEndLow = MathMin(FlatEndLow, Low[Num]); // ФЗ для предотвращения двойного } // срабатывания уровня // - 2.4 - ============================= Окончание блока =============================== // - 2 - =============================== Окончание блока ================================ } //+-------------------------------------------------------------------------------------+ //| Закрытие заданного рыночного ордера | //+-------------------------------------------------------------------------------------+ bool CloseOrder(int Ticket) { if (OrderSelect(Ticket, SELECT_BY_TICKET) && // Существует ордер с заданным тикетом и OrderCloseTime() == 0) // ордер не закрыт if (WaitForTradeContext()) // Свободен ли торговый поток? { if (OrderType() == OP_BUY) // Если следует закрыть длинную сделку, double Price = MarketInfo(Symbol(), MODE_BID); // то применяется цена BID else // Если следует закрыть короткую сделку, Price = MarketInfo(Symbol(), MODE_ASK); // то применяется цена ASK if (!OrderClose(OrderTicket(), OrderLots(), NP(Price), 3)) // Если сделку не return(False); // удалось закрыть, то результат функции - 1 } return(True); // Можно открывать сделку } //+-------------------------------------------------------------------------------------+ //| Удаление заданного отложенного ордера | //+-------------------------------------------------------------------------------------+ bool DeleteOrder(int Ticket) { if (OrderSelect(Ticket, SELECT_BY_TICKET) && // Существует ордер с заданным тикетом и OrderCloseTime() == 0) // ордер не закрыт if (WaitForTradeContext()) // Свободен ли торговый поток? { RefreshRates(); if (OrderType() == OP_BUYSTOP) // Если следует удалить BUYSTOP if (OrderOpenPrice() - Ask <= FreezeLevel) // то проверяется удаленность цены от return(False); // ASK if (OrderType() == OP_SELLSTOP) // Если следует удалить SELLSTOP if (Bid - OrderOpenPrice() <= FreezeLevel) // то проверяется удаленность цены от return(False); // BID if (!OrderDelete(OrderTicket())) // Если сделку не удалось закрыть, return(False); // то результат функции - False } return(True); // Удаление прошло успешно } //+-------------------------------------------------------------------------------------+ //| Открытие позиций и установка ордеров | //+-------------------------------------------------------------------------------------+ bool Trade() { // - 1 - ============================= Открытие длинной позиции ========================= if (Signal > 0 && BuyType != OP_BUY) // Сигнал BUY и рыночный ордер BUY не существует { if (BuyType == OP_BUYSTOP) // Присутствует BuyStop, который необходимо удалить if (!DeleteOrder(BuyTicket)) // Если удалить не удалось, то BUY открывать нельзя return(False); if (SellType == OP_SELL) // Присутсвует Sell, который необходимо закрыть if (!CloseOrder(SellTicket)) // Если закрыть не удалось, то BUY открывать нельзя return(False); if (OpenOrderCorrect(OP_BUY, Lots, NP(Ask), // Открытие BUY NP(FlatSignLow - Dist*Point), 0) != 0) return(False); FindOrders(); // Пересчет ордеров при успешном открытии BUY } // - 1 - =============================== Окончание блока ================================ // - 2 - =========================== Открытие короткой позиции ========================== if (Signal < 0 && SellType != OP_SELL)// Сигнал SELL и рыночный ордер SELL не существует { if (SellType == OP_SELLSTOP) // Присутствует BuyStop, который необходимо удалить if (!DeleteOrder(SellTicket)) // Если удалить не удалось, то SELL открывать нельзя return(False); if (BuyType == OP_BUY) // Присутсвует Buy, который необходимо закрыть if (!CloseOrder(BuyTicket)) // Если закрыть не удалось, то SELL открывать нельзя return(False); if (OpenOrderCorrect(OP_SELL, Lots, NP(Bid), // Открытие SELL NP(FlatSignHigh + Spread + Dist*Point), 0) != 0) return(False); FindOrders(); // Пересчет ордеров при успешном открытии SELL } // - 2 - =============================== Окончание блока ================================ // - 3 - =========================== Установка ордера BuyStop =========================== if (BuyTicket < 0) // Ордеров BUY-типа нет if (FlatEndHigh > Bid) // Цена находится ниже верхней границы ФЗ { if (OpenOrderCorrect(OP_BUYSTOP, Lots, // Установка ордера BuyStop NP(FlatEndHigh + Dist*Point + Spread), NP(FlatEndLow - Dist*Point), 0) != 0) return(false); FindOrders(); // Пересчет ордеров при успешной установке } // - 3 - =============================== Окончание блока ================================ // - 4 - =========================== Установка ордера SellStop ========================== if (SellTicket < 0) // Ордеров SELL-типа нет if (FlatEndLow < Bid) // Цена находится выше нижней границы ФЗ { if (OpenOrderCorrect(OP_SELLSTOP, Lots, // Установка ордера SellStop NP(FlatEndLow - Dist*Point), NP(FlatEndHigh + Dist*Point + Spread), 0) != 0) return(false); FindOrders(); // Пересчет ордеров при успешной установке } // - 4 - =============================== Окончание блока ================================ return(True); } //+-------------------------------------------------------------------------------------+ //| Проверка расположения цен открытия отложенных ордеров и уровней стоп-приказов | //+-------------------------------------------------------------------------------------+ bool ModifyCheck() { // - 1 - ================ Проверка расположения уровней ордеров BUY-типа ================ if (BuyTicket > 0) // Если существует BUY или BUYSTOP if (OrderSelect(BuyTicket, SELECT_BY_TICKET) && // Ордер существует и OrderCloseTime() == 0) // не закрыт/не удален { double SL = 0; // Стоп изменять не нужно double Price = 0; // Цену открытия менять не нужно // - 1.1 - =============== Проверка расположения уровня стоп-приказа ============== if (MathAbs(OrderStopLoss() - FlatEndLow + Dist*Point) >= Tick) // Стоп-приказ { // нуждается в изменении SL = NP(FlatEndLow - Dist*Point); // Новый уровень стоп-приказа if (BuyType == OP_BUY && Bid - SL <= StopLevel) // Если новый уровень слишком SL = NP(Bid - StopLevel - Point); // близок к текущей цене, то корректируется if (BuyType == OP_BUYSTOP && OrderOpenPrice() - SL <= StopLevel) // Если новый SL = NP(OrderOpenPrice() - StopLevel - Point);// уровень слишком близок к цене // открытия, то изменяется на ближайший допустимый } // - 1.1 - =========================== Окончание блока ============================ // - 1.2 - ============= Проверка расположения цены открытия BUYSTOP ============== if (BuyType == OP_BUYSTOP) // Если имеем дело с ордером BUYSTOP, // то проверяем цену открытия if (MathAbs(OrderOpenPrice() - (FlatEndHigh + Dist*Point + Spread)) >= Tick) { // Цена открытия нуждается в изменении Price = NP(FlatEndHigh + Dist*Point + Spread); // Новая цена открытия if (Price - Ask <= StopLevel) // Если новая цена открытия слишком близка к Price = NP(Ask + StopLevel + Point); // текущей цене, то корректируем } // - 1.2 - =========================== Окончание блока ============================ // - 1.3 - ============ Изменение уровня стоп-приказа или цены открытия =========== if (SL != 0 || Price != 0) // Если один из уровней нуждается в изменении if (WaitForTradeContext()) // Свободен ли торговый поток? { if (SL == 0) // Если изменять не нужно, то остается старое значение SL = NP(OrderStopLoss()); if (Price == 0) // Если изменять не нужно, то остается старое значение Price = NP(OrderOpenPrice()); if (!OrderModify(OrderTicket(), Price, SL, OrderTakeProfit(), 0)) // при return(False); // неудаче функция вернет False } // - 1.3 - =========================== Окончание блока ============================ } // - 1 - =============================== Окончание блока ================================ // - 2 - =============== Проверка расположения уровней ордеров SELL-типа ================ if (SellTicket > 0) // Если существует SELL или SELLSTOP if (OrderSelect(SellTicket, SELECT_BY_TICKET) && // Ордер существует и OrderCloseTime() == 0) // не закрыт/не удален { SL = 0; // Стоп изменять не нужно Price = 0; // Цену открытия менять не нужно // - 2.1 - =============== Проверка расположения уровня стоп-приказа ============== if (MathAbs(OrderStopLoss() - (FlatEndHigh + Dist*Point + Spread)) >= Tick)// Стоп- { // приказ нуждается в изменении SL = NP(FlatEndHigh + Dist*Point + Spread); // Новый уровень стоп-приказа if (SellType == OP_SELL && SL - Ask <= StopLevel) // Если новый уровень слишком SL = NP(Ask + StopLevel + Point); // близок к текущей цене, то корректируется if (SellType == OP_SELLSTOP && SL - OrderOpenPrice() <= StopLevel) // Если новый SL = NP(OrderOpenPrice() + StopLevel + Point);// уровень слишком близок к цене // открытия, то изменяется на ближайший допустимый } // - 2.1 - =========================== Окончание блока ============================ // - 2.2 - ============= Проверка расположения цены открытия SELLSTOP ============= if (SellType == OP_SELLSTOP) // Если имеем дело с ордером SELLSTOP, // то проверяем цену открытия if (MathAbs(OrderOpenPrice() - (FlatEndLow - Dist*Point)) >= Tick) { // Цена открытия нуждается в изменении Price = NP(FlatEndLow - Dist*Point); // Новая цена открытия if (Bid - Price <= StopLevel) // Если новая цена открытия слишком близка к Price = NP(Bid - StopLevel - Point); // текущей цене, то корректируем } // - 2.2 - =========================== Окончание блока ============================ // - 2.3 - ============ Изменение уровня стоп-приказа или цены открытия =========== if (SL != 0 || Price != 0) // Если один из уровней нуждается в изменении if (WaitForTradeContext()) // Свободен ли торговый поток? { if (SL == 0) // Если изменять не нужно, то остается старое значение SL = NP(OrderStopLoss()); if (Price == 0) // Если изменять не нужно, то остается старое значение Price = NP(OrderOpenPrice()); if (!OrderModify(OrderTicket(), Price, SL, OrderTakeProfit(), 0)) // при return(False); // неудаче функция вернет False } // - 2.3 - =========================== Окончание блока ============================ } // - 2 - =============================== Окончание блока ================================ return(True); // Все действия завершены успешно - результат True } //+-------------------------------------------------------------------------------------+ //| Функция поиска своих ордеров | //+-------------------------------------------------------------------------------------+ void FindOrders() { BuyTicket = -1; SellTicket = -1; // Пока не нашли, считаем, что ни одного ордера нет BuyType = -1; SellType = -1; for (int i = OrdersTotal()-1; i >= 0; i--) // Используется весь список ордеров if (OrderSelect(i, SELECT_BY_POS)) // Убедимся, что ордер выбран if (OrderMagicNumber() == MagicNumber && // Ордер открыт экспертом, OrderSymbol() == Symbol()) // который прикреплен к текущей валютной паре { if (MathMod(OrderType(), 2) == 0) // Ордер BUY-типа { BuyTicket = OrderTicket(); // Сохраняем тикет BuyType = OrderType(); // Сохраняем тип } else // Ордер SELL-типа { SellTicket = OrderTicket(); // Сохраняем тикет SellType = OrderType(); // Сохраняем тип } } } //+-------------------------------------------------------------------------------------+ //| Функция start эксперта | //+-------------------------------------------------------------------------------------+ int start() { // - 1 - ========================== Можно ли работать эксперту? ========================= if (!Activate || FatalError) return(0); // - 1 - ================================ Окончание блока =============================== // - 2 - ========================== Контроль открытия нового бара ======================= if (LastBar == Time[0]) return(0); // - 2 - ================================ Окончание блока =============================== // - 3 - ============================== Поиск своих ордеров ============================= FindOrders(); // - 3 - ================================ Окончание блока =============================== // - 4 - ========================== Расчет сигналов открытия и закрытия ================= GetSignal(1); // - 4 - ================================ Окончание блока =============================== // - 5 - ================== Выполнение операций открытия и закрытия позиций ============= if (!Trade()) return(0); // - 5 - ================================ Окончание блока =============================== // - 6 - = Проверка расположения цен открытия отложенных ордеров и уровней стоп-приказов= if (!ModifyCheck()) return(0); // - 6 - ================================ Окончание блока =============================== LastBar = Time[0]; return(0); }