#property copyright "Copyright © HELLTEAM^Pirat" #property link "http://www.fxmania.ru" #property strict //--- DLL, необходимая для расчета времени по GMT (стандартная библиотека Windows). #import "kernel32.dll" int GetTimeZoneInformation(int& a[]); #import //--- string Copyrights = "FapTurbo ver. 52.2 News Filter Mod by HELLTEAM^Pirat"; //+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //+ //| 07/06/2011 ver. 52.2 Добавлено рыночное исполнение (см. параметр IsMarketExecution), то есть ордер открывается без sl и tp, а далее происходит модификация. //| Необходимо для NDD счетов. Также изменена функция открытия и закрытия ордеров, теперь при реквотах советник повторяет попытки открытия. Число попыток можно задать в //| параметре RequoteAttempts. //| //| При включенном IsMarketExecution должен быть включен параметр UseStopLevels, иначе будет возникать ошибка. //+ //+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ //| Советник FapTurbo ver. 52 nulled by HELLTEAM^Pirat. //| FapTurbo - популярный ночной скальпер, сайт производителя http://fapturbo.com/ru/. //| Работа эксперта основана на индикаторах iRSI с разными периодами и индикаторе МА. Помимо индикаторов также используются фильтры по времени открытия, //| фильтры волатильности, тренда и шума. //| //| Рекомендуемый дц Альпари или Инстафорекс (Работает на четырехзначных и пятизначных котировках, никаких дополнительных манипуляций, например добавления нулей, не нужно). //| Рекомендуемая пара EUR/USD m15 (на Альпари ночью макс. спред 1.5 пункта, поэтому рекомендую его или же дц Инстафорекс с фикс. спредом 3). //| Также производитель рекомендует пары EURCHF, USDCAD, GBPUSD, USDCHF и GBPCHF. //| Но я их не рекомендую, по крайней мере для Альпари, из-за большого ночного спреда. Результаты оптимизации хуже чем у пары EUR/USD //| На счет взлома. DLL полностью вырезана, причем вырезанна правильно, без косяков и погрешностей. Отличия от оригинальной //| FapTurbo ver. 52 не выявлено. Единственно, я вырезал бредовое дополнение к ver. 52, по сути в оригинальный FapTurbo //| встроили еще 1 советник. Видимо им больше нечем заняться. Дополнение сливное с огромной посадкой и минимальным кол-вом сделок (за год около 50 сделок), //| поэтому я просто вырезал его. Переменные старался называть исходя из их функционала, думаю проблем при чтении кода ни у кого не возникнет. //| //| Если советник получит положительные отзывы планируется его доработка и модификация. //| Постоянный адрес поддержки обнуленной версии FapTurbo сайт Форекс Мания http://www.fxmania.ru/, //| Конкретное обсуждение ведется на форуме http://www.fxmania.ru/forum/ //| //| Также предлагаю сотрудничество при обнулении других прибыльных советников. //| //| Данные для связи: //| //| e-mail: fxmania.ru@gmail.com //| icq: 8-345-89-91 //| skype: fxmania.ru //| //+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ extern string Name = "FapTurbo ver. 52.2 News Filter Mod by HELLTEAM^Pirat"; extern string Cop = "Copyright © HELLTEAM^Pirat"; extern string Op = "Дата оптимизации"; extern datetime Date = D'03.03.2011'; //--- Сделал чисто для себя, чтобы видеть от какой даты оптимизация (дата забивается вручную) extern string Op2 = "Оптимизация для пары"; extern string Symbol_Op = "EURUSD m15"; //--- Аналогично. //--- Основные параметры советника extern string _SP = "--------------------------------------"; //--- extern string _MM = "Настройка MM"; //--- extern double Lots = 0.1; //--- (!) Рекомендуемый лот к депо 1000 - 0.1, 0.2 extern bool UseMM = FALSE; //--- Включение функции управления капиталом (Money Management) extern double LotsRiskReductor = 5.0; //-- Процент риска от свободных ср-в депозита extern double MaxLots = 10.0; //--- Максимальный лот (При включенной ММ, выше заданного значения, объём лота повышаться не будет) extern bool TradeMicroLots = TRUE; //-- При торговле лотом от 0.01 и до 0,1 с включенной UseMM, рекомендуется включить //--- extern string _Time = "Настройки времени"; //--- extern bool UseAutoGMToffset = FALSE; //--- Автоматический расчет смещения GMT. В тестере не работает. //+--------------------------------------------------------------------------------------------------------------+ //+ //| Как правильно расчитать ManualGMToffset. //| //| Текущие время по Гринвичу смотрим на сайте http://wwp.greenwichmeantime.com/ в окне GMT (Standard Time), //| далее сравниваем время вашего терминала со временем по Гринвичу. //| Разницу между временем вашего ДЦ (брокера) и текущем временем по Гринвичу вписываем в поле ManualGMToffset. //| //| Например на ДЦ Альпари текущие серверное время 17.00, а на сайте http://wwp.greenwichmeantime.com/ 14.00, //| то есть ManualGMToffset будет равен 3. //| //| Вне тестера включите UseAutoGMToffset, разница подсчитывается автоматически (работает только в торговые дни). //+ //+--------------------------------------------------------------------------------------------------------------+ extern int ManualGMToffset = 3; //--- Ручное выставление смещения GMT. Для Альпари 3, для Интсафорекс 3. Для остальных ДЦ сравнивайте время с первыми двумя. extern bool UseDST = TRUE; //--- Переход на летнее время. C 13 марта по 6 ноября (13.03 - 06.11) необходимо выставить TRUE. extern int StartWorkTimeHour = 21; //--- Час начала торговли (Начало временного канала) extern int StartSessionMinute = 0; //--- Минута начала торговли extern int EndWorkTimeHour = 23; //--- Час окончания торговли (Конец временного канала. После этого часа новый ордер не откроется) extern int EndSessionMinute = 0; //--- Минута окончания торговли extern bool TradeMonday = TRUE; //--- Разрешение на торговлю в понедельник (При False торговля не ведется) extern bool TradeFriday = FALSE; //--- Разрешение на торговлю в пятницу extern bool TradeInStartMonth = TRUE; //--- Разрешение на торговлю с 1 по 4 число каждого месяца. Если стоит True, торговля будет вестись. extern bool TradeInEndMonth = TRUE; //--- Разрешение на торговлю с 26 по 31 число каждого месяца. Если стоит True, торговля будет вестись. //+--------------------------------------------------------------------------------------------------------------+ //| Далее расчет тейков, лосов и фильтров волатильности и шумов. //| Запись вида (3 1 15) предназначена для оптимизации, и означает стартовое занчение 3, шаг и 1 и финальное //| финальное занчение 15. То есть оптимизация будет проходить со значения 3 по значение 15 с шагом 1. //+--------------------------------------------------------------------------------------------------------------+ extern string _TP = "Основные входные параметры"; //--- Тейк-профит и стоп-лосс для каждой сделки, открываемой советником. extern int TakeProfit = 10; // (3 1 15) extern int StopLoss = 60; // (10 5 100) //+--------------------------------------------------------------------------------------------------------------+ //| Дополнительные фильтры на вход. //+--------------------------------------------------------------------------------------------------------------+ extern int Filter_a = 15; // (10 5 100) Для фильтра волатильности (преобразуется в пункты) extern double Filter_b = 0.1; // (0.1 0.1 1.0) Для трендового фильтра, должен быть меньше MathAbs_iMA //+--------------------------------------------------------------------------------------------------------------+ //| Фильтры на закрытие. //+--------------------------------------------------------------------------------------------------------------+ extern int Filter_c = 10; // (10 5 120) Для фильтра шума extern int Filter_d = 60; // (20 5 200) Для фильтра шума extern int Filter_e = 130; // (80 5 220) Для фильтра шума extern int Filter_f = 230; // (90 5 260) Для фильтра шума extern int Filter_g = 235; // (100 5 300) Для фильтра шума extern int Filter_h = 5; // (1 1 20) Для фильтра шума extern int Filter_i = 15; // (1 1 20) Для фильтра шума extern int Filter_j = 16; // (1 1 20) Для фильтра шума extern int Filter_k = 0; // (-10 1 10) Для фильтра шума extern int Filter_l = 6; // (-30 1 10) Для фильтра шума //+--------------------------------------------------------------------------------------------------------------+ //| Основные фильтры на вход. Не рекомендуются к оптимизации. //+--------------------------------------------------------------------------------------------------------------+ extern int OpenBuy_iRSI_a = 36; extern int OpenBuy_iRSI_b = 30; extern int Filter_iRSI_a_StartTrend = 20; //+--------------------------------------------------------------------------------------------------------------+ //| В расширенных настройках вы можете произвести дополнительную настройку советника, под торговые условия //| вашего брокера или ДЦ. //+--------------------------------------------------------------------------------------------------------------+ extern string _Add = "Расширенные настройки"; extern double ProfitLimit = 0.0; extern double LossLimit = 0.0; extern int RelaxHours = 0; extern bool UseCustomLevels = TRUE; //-- Фильтр шума extern bool SimpleHeightFilter = TRUE; //-- Фильтр волатильности extern bool SimpleTrendFilter = TRUE; //-- Трендовый фильтр extern bool UseFilterMA = FALSE; //-- Фильтр по Машкам extern int PeriodFilterMA = 100; extern int PriceFilterMA = 0; extern int MethodFilterMA = 0; extern bool OneOpenTrade = FALSE; extern int OneTrade = 0; extern int ReverseTrade = 0; extern string _Stuff = "Дополнительные параметры"; //--- UseStopLevels и UseFakeStopLevels нельзя включать одновременно extern bool UseStopLevels = FALSE; //--- Включение стоповых ордеров. Если выключена, то работают только виртуальные тейки и лоссы. extern bool UseFakeStopLevels = FALSE; //-- Выставление поддельных стоп уровней. extern bool IsMarketExecution = FALSE; //--- Включение рыночного исполнения открытия ордеров (сначало открывает, затем модифицирует) //--- extern bool OpenBuy = TRUE; extern bool OpenSell = TRUE; extern double MaxSpread = 2.0; //-- Макс спред. Для альпы рекомендую 1,5-3. Для инсты 3 extern int MaximumTrades = 2; //--- Максимальное кол-во ордеров. extern int Slippage = 2; //-- Проскальзывание цены. Рекомендую 1-2 extern int RequoteAttempts = 3; //--- Максимальное число повторений при открытии/закрытии ордера при реквотах и других ошибках //--- int RandomOpenTimePercent = 0; //--- extern string OpenOrderComment = "FapTurbo ver. 52.2 NF"; extern int MagicNumber = 541200; //-- Магик //--- extern bool SendEmail = FALSE; //-- Отправка сообщения об открытии/закрытии сделки extern bool SoundAlert = FALSE; //-- Звуковое оповещение об открытии/закрытии сделки extern string SoundFileAtOpen = "alert.wav"; extern string SoundFileAtClose = "alert.wav"; extern color OpenBuyColor = Blue; extern color OpenSellColor = Red; extern color CloseBuyColor = DodgerBlue; extern color CloseSellColor = DeepPink; extern bool WriteLog = TRUE; extern bool WriteDebugLog = TRUE; extern bool PrintLogOnChart = TRUE; //-- Включение комментариев на графике //+--------------------------------------------------------------------------------------------------------------+ //| Настройка фильтра новостей //+--------------------------------------------------------------------------------------------------------------+ extern string _NF = "Новостной фильтр"; extern bool AvoidNews = TRUE; //--- Включение фильтра новостей (В тестере не работает, так как новостной индикатор FFCal генерирует текстовый файл каждую неделю, в котором записаны даты и время новостей на текущую неделю). //--- То есть во время тестирования будут использоваться только даты за текущую неделю. В тестере AvoidNews отключается автоматически. //--- Параметры фильтра новостей extern bool High_Impact = TRUE; //--- Важные новости (При True советник не торгует, если были важные новости). Если вы решили не торговать при важных новостях и поставили High_Impact = TRUE, то далее настраиваем временные фильтры. //--- extern int MinsUntilNextHighNews = 120; //--- Задержка времени (в минутах) до выхода важной новости. То есть за 2 часа до выхода важной новости (в течении этих 2-х часов) советнику будет дан запрет на торговлю. extern int MinsSincePrevHighNews = 420; //--- Задержка времени (в минутах) после выхода важной новости. То есть в течении 7-ми часов после выхода важной новости, советнику будет дан запрет на торговлю. //--- extern bool Medium_Impact = FALSE; //--- Обычные новости //--- extern int MinsUntilNextMediumNews = 90; //--- Задержка времени (в минутах) до выхода обычной новости. extern int MinsSincePrevMediumNews = 240; //--- Задержка времени (в минутах) после выхода обычной новости. //--- extern bool Low_Impact = FALSE; //--- Маловажные новости //--- extern int MinsUntilNextLowNews = 60; //--- Задержка времени (в минутах) до выхода маловажной новости. extern int MinsSincePrevLowNews = 60; //--- Задержка времени (в минутах) после выхода маловажной новости. //-- Блок переменных периодов, фильтров, комментов, времени. Если каждый подписывать сума сойдешь. Исходя из названия переменных можно понять функцию переменной. int MinusEndSessionMinute = 10; extern int iMA_Period1 = 8; extern int iRSI_Period1 = 6; extern int iRSI_Period2 = 20; int iMA_TimeFrame3 = 5; extern int iMA_Price3 = PRICE_CLOSE; extern int iMA_Method3 = MODE_SMA; extern int TrendFilter = 4; extern int TrendFilterMaxBars = 3; int FakeStopLoss = 200; int PlusRandomSL = 27; int FakeTakeProfit = 90; int PlusRandomTP = 34; extern bool OpenAddOrderRule = FALSE; extern bool ScreenShot = False; extern int Width=1400; extern int Hight=750; double pozSL[21]; double pozTP[21]; double pozOP[21]; int ord,OrdTot,orr; int LanguageEA = 1; bool NoErrorEA = TRUE; bool InitRule; int LotDiggits; int pd; int PossibleOpenOrder = 2; int SP; int CloseSP; double CloseSlippage = 3; //--- Проскальзывание для закрытия ордера double pp; double MaxLot; double MinLot; double LotStep; double NeedMargin; double RiskFactor; string EASymbol; string SendMailOpenOrderEng = "New Trade Information"; string SendMailCloseOrderEng = "New Trade Information"; string SendMailOpenOrderRus = "Новая торговая информация"; string SendMailCloseOrderRus = "Новая торговая информация"; bool CheckSpreadRule; bool LongTrade = TRUE; bool ShortTrade = TRUE; int ServerTime; int VolaTime; int CheckRelaxTime_H1; int OpenSell_iRSI_b; int OpenSell_iRSI_a; int StartTrade_Filter_b; int StartTrade_Filter_a; int Gmt; //--- Зона GMT+ int DST; //--- Корректировка при UseDST = True (летнее время) int NoiseFilter_a; int NoiseFilter_b; int NoiseFilter_c; int NoiseFilter_d; int NoiseFilter_e; int StartWorkTime; int EndWorkTime; double NDTakeProfit; double NDStopLoss; double NoiseFilter_f; double NoiseFilter_g; double NoiseFilter_h; double NoiseFilter_i; double NoiseFilter_j; double NDMaxSpread; double NDStopLevel; double RelaxFilter; double HeightFilter_a; string GMTStringConcatenate; int NullValue; string GMTComment; double Profit; bool AllowTrading = true; // Обнуление разрешения на торговлю (Необходим для фильтра новостей) //+--------------------------------------------------------------------------------------------------------------+ //| INIT. Инициализация основных функций и переменных советника (в основном фильтров на вход), //| также проверка на ошибки //+--------------------------------------------------------------------------------------------------------------+ int init() { double Leverage; InitRule = TRUE; if (IsTesting() && !IsVisualMode()) PrintLogOnChart = FALSE; if (!PrintLogOnChart) Comment(""); if (!IsDllsAllowed()) { if (LanguageEA == 0) Comment("Warning: Set Parameter \"AllowDLL Imports\" ON in menu Tools -> Options -> ExpertAdvisors."); else Comment("Предупреждение: Установите параметер \"AllowDLL Imports\" ВКЛ в меню Сервис -> Настройки -> Советники."); NoErrorEA = FALSE; return (0); } NoErrorEA = TRUE; if (NoErrorEA < 0) Comment("Логическая переменная меньше нуля."); EASymbol = Symbol(); if (Digits < 4) { pp = 0.01; pd = 2; } else { pp = 0.0001; pd = 4; } if (pd == 0) Comment("Неверное значение переменной."); MaxLot = MarketInfo(EASymbol, MODE_MAXLOT); MinLot = MarketInfo(EASymbol, MODE_MINLOT); LotStep = MarketInfo(EASymbol, MODE_LOTSTEP); NeedMargin = MarketInfo(EASymbol, MODE_MARGINREQUIRED) * LotStep; if (TradeMicroLots) LotDiggits = 2; else LotDiggits = 1; NoErrorEA = TRUE; if (NoErrorEA < 0) Comment("Логическая переменная меньше нуля."); NDStopLoss = NormalizeDouble((-1 * StopLoss) * pp, pd); NDTakeProfit = NormalizeDouble(TakeProfit * pp, pd); NoiseFilter_a = 60 * Filter_c; NoiseFilter_b = 60 * Filter_d; NoiseFilter_c = 60 * Filter_e; NoiseFilter_d = 60 * Filter_f; NoiseFilter_e = 60 * Filter_g; NoiseFilter_f = Filter_h * pp; NoiseFilter_g = Filter_i * pp; NoiseFilter_h = Filter_j * pp; NoiseFilter_i = Filter_k * pp; NoiseFilter_j = Filter_l * pp; HeightFilter_a = NormalizeDouble(Filter_a * pp, pd); NDMaxSpread = NormalizeDouble(MaxSpread * pp, pd + 1); NDStopLevel = NormalizeDouble(StopLoss * pp, pd); RelaxFilter = NormalizeDouble(NDStopLevel / 2.0, Digits); OpenSell_iRSI_b = 100 - OpenBuy_iRSI_b; OpenSell_iRSI_a = 100 - OpenBuy_iRSI_a; StartTrade_Filter_b = Filter_iRSI_a_StartTrend / 2 + 50; StartTrade_Filter_a = 50 - Filter_iRSI_a_StartTrend / 2; if (PeriodFilterMA <= 0) UseFilterMA = FALSE; if (PriceFilterMA < PRICE_CLOSE || PriceFilterMA > PRICE_WEIGHTED) UseFilterMA = FALSE; if (MethodFilterMA < MODE_SMA || MethodFilterMA > MODE_LWMA) UseFilterMA = FALSE; Leverage = AccountLeverage(); RiskFactor = NormalizeDouble(LotsRiskReductor * (100 / Leverage), 2); SP = Slippage * MathPow(10, Digits - pd); CloseSP = CloseSlippage * MathPow(10, Digits - pd); //------------Screen--------------- for(int i=0;i= 24) { //--- Если время старта получилось большим или равным 24, StartWorkTime -= 24; //--- то вычитаем 24, то есть приравниваем его к нулу, или делаем чуть выше ноля. continue; //--- Например, если время старта получилось равным 26 часам, то после проверки оно будет равным 2 часам ночи. } if (StartWorkTime >= 0) break; //--- Если время старта больше или равно нуля, то прерываем цикл. StartWorkTime += 24; } //--- Цикл проверки конечного времени, Действия аналогичные проверке стартового времени while (true) { if (EndWorkTime >= 24) { EndWorkTime -= 24; continue; } if (EndWorkTime >= 0) break; EndWorkTime += 24; } //--- Проверка минут старта на ошибки if (StartSessionMinute < 0 || StartSessionMinute > 59) StartSessionMinute = 0; //--- Проверка минут окончания торговли на ошибки if (EndSessionMinute < 0 || EndSessionMinute > 59) EndSessionMinute = 0; //--- Если часы и минуты старта и окончания не равны, то if (StartWorkTime != EndWorkTime || StartSessionMinute != EndSessionMinute) { if (MinusEndSessionMinute > 0) { //--- Вычитаем из минут окончания значение MinusEndSessionMinute EndSessionMinute -= MinusEndSessionMinute; //--- При отрицательном значении EndSessionMinute прибавляем 60 минут, if (EndSessionMinute < 0) { EndSessionMinute += 60; //--- пока значение не станет положительным или равным нулю EndWorkTime--; //--- И тем самым вычитаем 1 час из EndWorkTime //--- Далее проверяем EndWorkTime на положительное значение. Если EndWorkTime прибавляем сутки. if (EndWorkTime < 0) EndWorkTime += 24; } } } Comment(""); //--- Во время проверки времени комментарии не отображаются InitRule = FALSE; //--- Обнуляем результат инициализации } //--- Закрытие if (InitRule) if (!NoErrorEA) return (0); //--- Если произошли ошибки, повторить процесс инициализации Scalper(); //--- Подключаем основную функцию //--- if(ScreenShot){Scr();}; return (0); } //+--------------------------------------------------------------------------------------------------------------+ //| SCALPER. Основная функция эксперта. В ней происходит проверка спреда и временного канала, //| отображение комментариев на графике, а также отдаются приказы на открытие. //+--------------------------------------------------------------------------------------------------------------+ void Scalper() { //+--------------------------------------------------------------------------------------------------------------+ int DayWeek; double iRSI_a; double iRSI_b; double iMA_a; int OpenSignal; int TradeCount; double iMA_CheckClose; ServerTime = TimeCurrent(); //--- Подключение дополнительных функций CloseOrders (); //--- Виртуальный тейк-профит. if (UseCustomLevels) NoiseFilter(); //--- Фильтр шума. if (PrintLogOnChart) ShowComments (); //--- Включение комментариев на графике if (StartWorkTime != EndWorkTime || StartSessionMinute != EndSessionMinute) { //--- if (ProfitLimit > 0.0) { if (Profit >= ProfitLimit) { CloseAllSymbols(); return; } } if (LossLimit > 0.0) { if (Profit <= -1.0 * LossLimit) { CloseAllSymbols(); return; } } } //--- Фильтр по дням недели + проверка дополнительных фильтров на вход DayWeek = TimeDayOfWeek(ServerTime - 3600 * Gmt); //--- Проверка дней недели if (DayWeek == 0 || DayWeek > 5) return; if (!TradeFriday) //--- Если запрещена торговля в пятницу, if (DayWeek >= 5) return; //--- и если сегодня пятница то запрещаем торговать if (!TradeMonday)//--- Если запрещена торговля в понедельник, if (DayWeek <= 1) return;//--- и если сегодня понедельник то запрещаем торговать if (!TradeInStartMonth)//--- Если запрещена торговля в начале месяца, if (Day() < 5) return;//--- и если сегодня с 1 по 4 число месяца, то запрещаем торговать if (!TradeInEndMonth)//---Если запрещена торговля в конце месяца, if (Day() > 25) return;//--- и если сегодня с 26 по 31 число месяца, то запрещаем торговать //--- if (DayWeek == 1 && TimeHour(ServerTime - 3600 * Gmt) < StartWorkTimeHour || (TimeHour(ServerTime - 3600 * Gmt) == StartWorkTimeHour && TimeMinute(ServerTime) < StartSessionMinute)) return; if (IsTradeTime(ServerTime, StartWorkTime, StartSessionMinute, EndWorkTime, EndSessionMinute)) { if (RelaxHours > 0) if (IsRelaxHours()) return; //--- Дополнительные фильтры if (SimpleHeightFilter) if (CheckVolaFilter()) return; if (SimpleTrendFilter) if (CheckTrendFilter()) return; //--- if (OneTrade != 0) { if (HaveTrade()) { if (!(WriteDebugLog)) return; if (LanguageEA == 0) { Print("Already have one trade inside this interval of time."); return; } Print("Уже есть одна сделка внутри этого интервала времени."); return; } } //--- При OneOpenTrade True будет выдаваться сообщение о том, что позиция уже открыта. if (OneOpenTrade) { if (HaveAllOrders() > 0) { if (!(WriteDebugLog)) return; if (LanguageEA == 0) { Print("Already have open order with MagicNumber = ", MagicNumber); return; } Print("Уже есть один ордер с MagicNumber = ", MagicNumber); return; } } //--- Проверка спреда. if (AllowTrading) { if (NormalizeDouble(Ask - Bid, Digits) > NDMaxSpread) { if (WriteLog && !CheckSpreadRule) { if (LanguageEA == 0) { Print("Trade signal is missed due to invalid high spread."); Print("Current spread = ", DoubleToStr(NormalizeDouble(Ask - Bid, Digits), Digits), ", MaxSpread = ", DoubleToStr(NDMaxSpread, Digits)); Print("FapTurbo will try again later when spreads come to normal."); } else { Print("Торговый сигнал пропущен из-за большого спреда."); Print("Текущий спред = ", DoubleToStr(NormalizeDouble(Ask - Bid, Digits), Digits), ", MaxSpread = ", DoubleToStr(NDMaxSpread, Digits)); Print("FapTurbo будет пробовать позже, когда спред станет допустимым."); } } CheckSpreadRule = TRUE; } else { CheckSpreadRule = FALSE; //-- Расчет основных индикаторов RSI и MA HideTestIndicators(TRUE); iRSI_a = iRSI(NULL, 0, iRSI_Period1, PRICE_CLOSE, 0); iRSI_b = iRSI(NULL, PERIOD_M1, iRSI_Period2, PRICE_CLOSE, 0); iMA_a = iMA(NULL, 0, iMA_Period1, 0, MODE_SMA, PRICE_MEDIAN, 1); HideTestIndicators(FALSE); //-- Проверка сигнала на открытие длинной позиции. //-- Если включен реверс меняем местами тип ордеров. if (ReverseTrade == 0) OpenSignal = OpenBuyRule(Ask + 0.0002, ExistPosition(), iRSI_a, iRSI_b, OpenBuy_iRSI_a, OpenBuy_iRSI_b, iMA_a); else OpenSignal = OpenSellRule(Bid - 0.0002, ExistPosition(), iRSI_a, iRSI_b, OpenSell_iRSI_a, OpenSell_iRSI_b, iMA_a); //-- Открытие ордера на Buy if (OpenSignal == 1) { if (LongTrade) { if (!UseFilterMA) TradeCount = 0; else { iMA_CheckClose = iMA(NULL, 0, PeriodFilterMA, 0, MethodFilterMA, PriceFilterMA, 0); if (Close[0] <= iMA_CheckClose) TradeCount++; } if (TradeCount == 0 && OpenBuy) { OpenPosition(OP_BUY); LongTrade = FALSE; ShortTrade = TRUE; } } } //-- Проверка сигнала на открытие короткой позиции. if (ReverseTrade == 0) OpenSignal = OpenSellRule(Bid - 0.0002, ExistPosition(), iRSI_a, iRSI_b, OpenSell_iRSI_a, OpenSell_iRSI_b, iMA_a); else OpenSignal = OpenBuyRule(Ask + 0.0002, ExistPosition(), iRSI_a, iRSI_b, OpenBuy_iRSI_a, OpenBuy_iRSI_b, iMA_a); //-- Открытие ордера на Sell if (OpenSignal == 1) { if (ShortTrade) { if (!UseFilterMA) TradeCount = 0; else { iMA_CheckClose = iMA(NULL, 0, PeriodFilterMA, 0, MethodFilterMA, PriceFilterMA, 0); if (Close[0] >= iMA_CheckClose) TradeCount++; } if (TradeCount == 0 && OpenSell) { OpenPosition(OP_SELL); ShortTrade = FALSE; LongTrade = TRUE; } } } //-- Разрешение на открытие ордеров Buy и Sell if (StartTradeRule(iRSI_a, StartTrade_Filter_b, StartTrade_Filter_a)) { ShortTrade = TRUE; LongTrade = TRUE; } } } } } //-- закрытие if (AllowTrading) { //+--------------------------------------------------------------------------------------------------------------+ //| StartTradeRule. Общее правило входа для длинной и короткой позиции. //+--------------------------------------------------------------------------------------------------------------+ bool StartTradeRule (double a, int b, int c) { //+--------------------------------------------------------------------------------------------------------------+ if (a > c && b > a) return (TRUE); else return (FALSE); } //+--------------------------------------------------------------------------------------------------------------+ //| OpenBuyRule. Сигнал на открытие длинной позиции. //+--------------------------------------------------------------------------------------------------------------+ int OpenBuyRule (double BuyPrice, int CheckOrders, double iRSI_a, double iRSI_b, int OpenBuy_iRSI_a, int OpenBuy_iRSI_b, double iMA_a) { //+--------------------------------------------------------------------------------------------------------------+ int result = 0; int result1 = 0; int result2 = 0; int New_iRSI_a = iRSI_a; int New_iRSI_b = iRSI_b; if (iMA_a >= BuyPrice && New_iRSI_a < OpenBuy_iRSI_b && CheckOrders == 0) result1 = 1; else result1 = 0; if (iMA_a >= BuyPrice && iRSI_b < OpenBuy_iRSI_a && CheckOrders == 0) result2 = 1; else result2 = 0; if (result1 == 1 || result2 == 1) result = 1; else result = 0; //--- return (result); } //+--------------------------------------------------------------------------------------------------------------+ //| OpenSellRule. Сигнал на открытие короткой позиции. //+--------------------------------------------------------------------------------------------------------------+ int OpenSellRule (double SellPrice, int CheckOrders, double iRSI_a, double iRSI_b, int OpenSell_iRSI_a, int OpenSell_iRSI_b, double iMA_a) { //+--------------------------------------------------------------------------------------------------------------+ int result = 0; int result1 = 0; int result2 = 0; if (iMA_a <= SellPrice && iRSI_b > OpenSell_iRSI_a && CheckOrders == 0) result1 = 1; else result1 = 0; if (iMA_a <= SellPrice && iRSI_a > OpenSell_iRSI_b && CheckOrders == 0) result2 = 1; else result2 = 0; if (result1 == 1 || result2 == 1) result = 1; else result = 0; //--- return (result); } //+--------------------------------------------------------------------------------------------------------------+ //| OpenPosition. Функция открытия позиции. //+--------------------------------------------------------------------------------------------------------------+ int OpenPosition(int OpType) { //+--------------------------------------------------------------------------------------------------------------+ int RandomOpenTime; //--- Задержка по времени на открытие color OpenColor; //--- Цвет открытия позиции. Если Buy то голубая, если Sell то красная int OpenOrder = 0; //--- Открытие позиции int OpenOrderError; //--- Ошибка открытия string OpTypeString; //--- Преобразования вида позиции в текстовое значение double OpenPrice; //--- Цена открытия int maxtry = RequoteAttempts; int lasterror = 0; double price = OpenPrice; //--- double TP, SL; double OrderTP = NormalizeDouble (TakeProfit * pp , pd); //--- Преобразуем тейк-профит в вид Points double OrderSL = NormalizeDouble (StopLoss * pp , pd); //--- Преобразуем стоп-лосс в вид Points double FakeOrderTP = NormalizeDouble ((FakeTakeProfit + MathRand() % PlusRandomTP)* pp , pd); //--- Преобразуем поддельный тейк-профит в вид Points double FakeOrderSL = NormalizeDouble ((FakeStopLoss + MathRand() % PlusRandomSL)* pp , pd); //--- Преобразуем поддельный стоп-лосс в вид Points //--- Задержка в секундах между открытиями if (RandomOpenTimePercent > 0) { MathSrand(TimeLocal()); RandomOpenTime = MathRand() % RandomOpenTimePercent; if (WriteLog) { if (LanguageEA == 0) Print("DelayRandomiser: delay ", RandomOpenTime, " seconds."); else Print("DelayRandomiser: задержка ", RandomOpenTime, " секунд."); } Sleep(1000 * RandomOpenTime); } //--- Закрытие if (RandomOpenTimePerc double OpenLotSize = LotsOptimized(); //--- Расчет объёма позиции //--- Если не хватет средств, возвращаем ошибку if (AccountFreeMarginCheck(EASymbol, OpType, OpenLotSize) <= 0.0 || GetLastError() == 134/* NOT_ENOUGH_MONEY */) { //--- if (WriteDebugLog) { //--- if (LanguageEA == 0) { Print("You don\'t have free margin."); Comment("You don\'t have free margin."); } else { Print("Для открытия ордера недостаточно свободной маржи."); Comment("Для открытия ордера недостаточно свободной маржи."); } //--- } return (-1); } //--- Закрытие if (AccountFreeMarginCheck RefreshRates(); //--- Если длинная позиция, то if (OpType == OP_BUY) { OpenPrice = NormalizeDouble(Ask,Digits); OpenColor = OpenBuyColor; //--- if (UseStopLevels && !UseFakeStopLevels) { //--- Если включены стоп-уровни (стоп-лосс и тейк-профит) TP = OpenPrice + OrderTP; //--- То расчитывает тейк-профит SL = OpenPrice - OrderSL; //--- и стоп-лосс } //--- if (UseFakeStopLevels && !UseStopLevels) { //--- Если включены поддельные стоп-уровни TP = OpenPrice + FakeOrderTP; //--- То расчитывает поддельный тейк-профит SL = OpenPrice - FakeOrderSL; //--- и поддельный стоп-лосс } //--- Если UseStopLevels и UseFakeStopLevels оба равны True или False, то используем только вируальное закрытие if (!UseFakeStopLevels && !UseStopLevels || UseFakeStopLevels && UseStopLevels) {TP = 0; SL = 0;} //--- Если короткая позиция, то } else { OpenPrice = NormalizeDouble(Bid,Digits); OpenColor = OpenSellColor; //--- if (UseStopLevels && !UseFakeStopLevels) { TP = OpenPrice - OrderTP; SL = OpenPrice + OrderSL; } //--- if (UseFakeStopLevels && !UseStopLevels) { TP = OpenPrice - FakeOrderTP; SL = OpenPrice + FakeOrderSL; } //--- if (!UseFakeStopLevels && !UseStopLevels || UseFakeStopLevels && UseStopLevels) {TP = 0; SL = 0;} } //--- Если тип исполнения Market Execution (рыночное исполнение), то сначало открываем ордер без sl и tp, а после модифицируем его if (IsMarketExecution && UseStopLevels) { OpenOrder = OrderSend(EASymbol, OpType, OpenLotSize, OpenPrice, SP, 0, 0, OpenOrderComment, MagicNumber, 0, OpenColor); if (OpenOrder > 0) { OrderModify(OpenOrder,OrderOpenPrice(),SL,TP,0); return(OpenOrder); } } //--- Если же нет, то сразу открываем с sl и tp else { OpenOrder = OrderSend(EASymbol, OpType, OpenLotSize, OpenPrice, SP, SL, TP, OpenOrderComment, MagicNumber, 0, OpenColor); if (OpenOrder > 0) return(OpenOrder); } //--- Если тип ордера не верен, то повторяем операцию. if ((OpType != OP_BUY) && (OpType != OP_SELL)) return(OpenOrder); //--- Если ордер открылся успешно, то отправляем сообщение на e-mail (если включена отправка) if (OpenOrder > 0) { if (SendEmail) { if (LanguageEA == 0) { //--- На Англиском SendMail(SendMailOpenOrderEng, StringConcatenate("FapTurbo ver. 52.2 News Filter Mod Trade Information\nCurrency Pair: ", StringSubstr(EASymbol, 0, 6), "\nTime: ", TimeToStr(TimeCurrent(), TIME_DATE|TIME_MINUTES|TIME_SECONDS), "\nOrder Type: ", OrderTypeToStr(OpType), "\nPrice: ", DoubleToStr(OpenPrice, Digits), "\nLot size: ", DoubleToStr(OpenLotSize, LotDiggits), "\nEvent: Trade Opened", "\n\nCurrent Balance: ", DoubleToStr(AccountBalance(), 2), " ", AccountCurrency(), "\nCurrent Equity: ", DoubleToStr(AccountEquity(), 2), " ", AccountCurrency())); } else { //--- Или на Русском SendMail(SendMailOpenOrderRus, StringConcatenate("FapTurbo ver. 52.2 News Filter Mod торговая информация\nВалютная пара: ", StringSubstr(EASymbol, 0, 6), "\nВремя: ", TimeToStr(TimeCurrent(), TIME_DATE|TIME_MINUTES|TIME_SECONDS), "\nТип ордера: ", OrderTypeToStr(OpType), "\nЦена: ", DoubleToStr(OpenPrice, Digits), "\nРазмер лота: ", DoubleToStr(OpenLotSize, LotDiggits), "\nСобытие: открытие ордера", "\n\nТекущий баланс: ", DoubleToStr(AccountBalance(), 2), " ", AccountCurrency(), "\nТекущие средства: ", DoubleToStr(AccountEquity(), 2), " ", AccountCurrency())); } } //--- Закрытие if (SendEmail) if (SoundAlert) PlaySound(SoundFileAtOpen); //--- Проигрываение звука, если он включен } if (OpenOrder < 0) { OpenOrderError = GetLastError(); //--- Возвращаем ошибку //--- if (WriteDebugLog) { if (OpType == OP_BUY) OpTypeString = "OP_BUY"; else OpTypeString = "OP_SELL"; if (LanguageEA == 0) Print("Open: OrderSend(", OpTypeString, ") error = ", ErrorDescription(OpenOrderError)); //--- Код ошибки на Английском else Print("Открытие: OrderSend(", OpTypeString, ") ошибка = ", ErrorDescription(OpenOrderError)); //--- Код ошибки на Русском } //--- Закрытие if (WriteDebugLog) } //--- При реквотах повторяем операцию. lasterror = GetLastError(); if ((OpenOrder < 0) && ((lasterror == 135) || (lasterror == 138) || (lasterror == 146))) { Print("Requote. Error" + lasterror + ". Ticket: " + OpenOrder); } else { return(OpenOrder); } //--- Цикл открытия ордера при возникновении ошибок (Максимальное число попыток открытия при возникновении ошибок равно значению RequoteAttempts) for (int attempt = 1; attempt <= maxtry; attempt++) { RefreshRates(); if (OpType == OP_BUY) { if (Ask <= price) { if (IsMarketExecution && UseStopLevels) { OpenOrder = OrderSend(EASymbol, OpType, OpenLotSize, NormalizeDouble(Ask,Digits), SP, 0, 0, OpenOrderComment, MagicNumber, 0, OpenColor); if (OpenOrder > 0) { OrderModify(OpenOrder,OrderOpenPrice(),SL,TP,0); return(OpenOrder); } } else { OpenOrder = OrderSend(EASymbol, OpType, OpenLotSize, NormalizeDouble(Ask,Digits), SP, SL, TP, OpenOrderComment, MagicNumber, 0, OpenColor); if (OpenOrder > 0) return(OpenOrder); } if ((GetLastError() != 135) && (GetLastError() != 138) && (GetLastError() != 146)) return(OpenOrder); Print("Requote. " + "Attempt " + (attempt + 1)); continue; } } if (OpType == OP_SELL) { if (Bid >= price) { if (IsMarketExecution && UseStopLevels) { OpenOrder = OrderSend(EASymbol, OpType, OpenLotSize, NormalizeDouble(Bid,Digits), SP, 0, 0, OpenOrderComment, MagicNumber, 0, OpenColor); if (OpenOrder > 0) { OrderModify(OpenOrder,OrderOpenPrice(),SL,TP,0); return(OpenOrder); } } else { OpenOrder = OrderSend(EASymbol, OpType, OpenLotSize, NormalizeDouble(Bid,Digits), SP, SL, TP, OpenOrderComment, MagicNumber, 0, OpenColor); if (OpenOrder > 0) return(OpenOrder); } if ((GetLastError() != 135) && (GetLastError() != 138) && (GetLastError() != 146)) return(OpenOrder); Print("Requote. " + "Attempt " + (OpenOrder + 1)); } } } //--- return(-1); } //+--------------------------------------------------------------------------------------------------------------+ //| CloseTrades. Виртуальный тейк-профит и стоп-лосс. //| Если включена функция UseStopLevels, то используется как функция резервного закрытия. //+--------------------------------------------------------------------------------------------------------------+ void CloseOrders() { //+--------------------------------------------------------------------------------------------------------------+ bool TicketClose; //--- Закрытие ордера int total = OrdersTotal() - 1; int OpenLongOrdersCount = 0; int OpenShortOrdersCount = 0; int MaxCount = 3; int CloseError = GetLastError(); int CloseTicketID = OrderTicket(); string CloseOrderType = OrderType(); //--- for (int i = total; i >= 0; i--) { //--- Счетчик открытых ордеров if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (WriteDebugLog) Print("Произошла ошибка во время выборки ордера. Причина: ", ErrorDescription(CloseError)); } else { //--- Закрытие по профиту или лоссу ордеров на покупку if (OrderType() == OP_BUY) { OpenLongOrdersCount++; if (OrderMagicNumber() == MagicNumber && OrderSymbol() == EASymbol) { if (Bid >= OrderOpenPrice() + TakeProfit * pp || Bid <= OrderOpenPrice() - StopLoss * pp) { //--- for (int MinCount = 1; MinCount <= MathMax(1, MaxCount); MinCount++) { RefreshRates(); if (OrderClose(OrderTicket(), OrderLots(), NormalizeDouble(Bid, Digits), CloseSP, CloseBuyColor)) { OpenLongOrdersCount--; //--- Обнуляем счетчик break; //--- } else { if (WriteDebugLog) Print("Произошла ошибка во время закрытия ордера (",CloseOrderType, ",", CloseTicketID, "). Причина: ", ErrorDescription(CloseError)); } //--- } } } } //--- Закрытие if (OrderType() == OP_BUY) //--- Закрытие по профиту или лоссу ордеров на продажу if (OrderType() == OP_SELL) { OpenShortOrdersCount++; if (OrderMagicNumber() == MagicNumber && OrderSymbol() == EASymbol) { if (Ask <= OrderOpenPrice() - TakeProfit * pp || Ask >= OrderOpenPrice() + StopLoss * pp) { //--- for (int MinCount = 1; MinCount <= MathMax(1, MaxCount); MinCount++) { RefreshRates(); if (OrderClose(OrderTicket(), OrderLots(), NormalizeDouble(Ask, Digits), CloseSP, CloseSellColor)) { OpenShortOrdersCount--; //--- Обнуляем счетчик break; //--- } else { if (WriteDebugLog) Print("Произошла ошибка во время закрытия ордера (",CloseOrderType, ",", CloseTicketID, "). Причина: ", ErrorDescription(CloseError)); } //--- } } } } //--- Закрытие if (OrderType() == OP_SELL) } } //--- Закрытие for (int i = total - 1; i >= 0; i--) { } //+--------------------------------------------------------------------------------------------------------------+ //| CloseOrder. Закрытие предварительно выбранного ордера. //+--------------------------------------------------------------------------------------------------------------+ int CloseOrder(int CloseTicketID, double CloseTicketLots, int CloseTypeColor, int CloseOrderSlippage) { //+--------------------------------------------------------------------------------------------------------------+ color CloseColor; double CloseOrderPrice; bool CloseOrder; int CloseError; string CloseOrderType; bool CheckOrderClose; if (CloseTypeColor == 0) CloseColor = CloseBuyColor; else CloseColor = CloseSellColor; int ErrorPriceCount = 0; int ErrorStopsCount = 0; int ErrorBrokerCount = 0; int ErrorRequoteCount = 0; while (true) { while (!IsTradeAllowed()) Sleep(1000); RefreshRates(); if (CloseTypeColor == 0) CloseOrderPrice = NormalizeDouble(Bid, Digits); else CloseOrderPrice = NormalizeDouble(Ask, Digits); CloseOrder = OrderClose(CloseTicketID, CloseTicketLots, CloseOrderPrice, CloseOrderSlippage, CloseColor); if (!CloseOrder) { CloseError = GetLastError(); if (WriteDebugLog) { if (CloseTypeColor == 0) CloseOrderType = "BUY"; else CloseOrderType = "SELL"; Print("OrderClose(", CloseOrderType, ",", CloseTicketID, ") error = ", ErrorDescription(CloseError)); } CheckOrderClose = FALSE; switch (CloseError) { case 0/* NO_ERROR */: Sleep(10000); if (OrderSelect(CloseTicketID, SELECT_BY_TICKET)) if (OrderCloseTime() == 0) CheckOrderClose = TRUE; break; case 1/* NO_RESULT */: break; case 2/* COMMON_ERROR */: break; case 3/* INVALID_TRADE_PARAMETERS */: break; case 4/* SERVER_BUSY */: break; case 5/* OLD_VERSION */: break; case 6/* NO_CONNECTION */: Sleep(10000); if (IsConnected()) CheckOrderClose = TRUE; break; case 7/* NOT_ENOUGH_RIGHTS */: break; case 8/* TOO_FREQUENT_REQUESTS */: break; case 9/* MALFUNCTIONAL_TRADE */: break; case 64/* ACCOUNT_DISABLED */: break; case 65/* INVALID_ACCOUNT */: break; case 128/* TRADE_TIMEOUT */: Sleep(70000); if (OrderSelect(CloseTicketID, SELECT_BY_TICKET)) if (OrderCloseTime() == 0) CheckOrderClose = TRUE; break; case 129/* INVALID_PRICE */: Sleep(6000); ErrorPriceCount++; if (ErrorPriceCount <= 3) CheckOrderClose = TRUE; break; case 130/* INVALID_STOPS */: Sleep(6000); ErrorStopsCount++; if (ErrorStopsCount <= 3) CheckOrderClose = TRUE; break; case 131/* INVALID_TRADE_VOLUME */: break; case 132/* MARKET_CLOSED */: break; case 133/* TRADE_DISABLED */: break; case 134/* NOT_ENOUGH_MONEY */: break; case 135/* PRICE_CHANGED */: CheckOrderClose = TRUE; break; case 136/* OFF_QUOTES */: Sleep(6000); CheckOrderClose = TRUE; break; case 137/* BROKER_BUSY */: Sleep(20000); ErrorBrokerCount++; if (ErrorBrokerCount <= 3) CheckOrderClose = TRUE; break; case 138/* REQUOTE */: ErrorRequoteCount++; if (ErrorRequoteCount <= 3) CheckOrderClose = TRUE; break; case 139/* ORDER_LOCKED */: break; case 140/* LONG_POSITIONS_ONLY_ALLOWED */: break; case 141/* TOO_MANY_REQUESTS */: break; case 142: Sleep(70000); if (OrderSelect(CloseTicketID, SELECT_BY_TICKET)) if (OrderCloseTime() == 0) CheckOrderClose = TRUE; break; case 143: Sleep(70000); if (OrderSelect(CloseTicketID, SELECT_BY_TICKET)) if (OrderCloseTime() == 0) CheckOrderClose = TRUE; break; case 144: break; case 145/* TRADE_MODIFY_DENIED */: Sleep(20000); CheckOrderClose = TRUE; break; case 146/* TRADE_CONTEXT_BUSY */: while (IsTradeContextBusy()) Sleep(1000); CheckOrderClose = TRUE; break; case 147/* ERR_TRADE_EXPIRATION_DENIED */: break; case 148/* ERR_TRADE_TOO_MANY_ORDERS */: break; case 4000/* NO_MQLERROR */: Sleep(10000); if (OrderSelect(CloseTicketID, SELECT_BY_TICKET)) if (OrderCloseTime() == 0) CheckOrderClose = TRUE; case 4051/* INVALID_FUNCTION_PARAMETER_VALUE */: break; case 4062/* STRING_PARAMETER_EXPECTED */: break; case 4063/* INTEGER_PARAMETER_EXPECTED */: break; case 4064/* DOUBLE_PARAMETER_EXPECTED */: break; case 4105/* NO_ORDER_SELECTED */: break; case 4106/* UNKNOWN_SYMBOL */: break; case 4107/* INVALID_PRICE_PARAM */: break; case 4108/* INVALID_TICKET */: break; case 4109/* TRADE_NOT_ALLOWED */: break; case 4110/* LONGS__NOT_ALLOWED */: break; case 4111/* SHORTS_NOT_ALLOWED */: break; } if (!(CheckOrderClose)) break; continue; } if (OrderSelect(CloseTicketID, SELECT_BY_TICKET)) CloseOrderPrice = OrderClosePrice(); if (SendEmail) { if (LanguageEA == 0) { SendMail(SendMailCloseOrderEng, StringConcatenate("FapTurbo ver. 52.2 News Filter Mod trade Information\nCurrency Pair: ", StringSubstr(EASymbol, 0, 6), "\nTime: ", TimeToStr(TimeCurrent(), TIME_DATE|TIME_MINUTES|TIME_SECONDS), "\nOrder Type: ", OrderTypeToStr(CloseTypeColor), "\nPrice: ", DoubleToStr(CloseOrderPrice, Digits), "\nLot size: ", DoubleToStr(CloseTicketLots, LotDiggits), "\nEvent: Trade Closed", "\n\nCurrent Balance: ", DoubleToStr(AccountBalance(), 2), " ", AccountCurrency(), "\nCurrent Equity: ", DoubleToStr(AccountEquity(), 2), " ", AccountCurrency())); } else { SendMail(SendMailCloseOrderRus, StringConcatenate("FapTurbo ver. 52.2 News Filter Mod торговая информация\nВалютная пара: ", StringSubstr(EASymbol, 0, 6), "\nВремя: ", TimeToStr(TimeCurrent(), TIME_DATE|TIME_MINUTES|TIME_SECONDS), "\nТип ордера: ", OrderTypeToStr(CloseTypeColor), "\nЦена: ", DoubleToStr(CloseOrderPrice, Digits), "\nРазмер лота: ", DoubleToStr(CloseTicketLots, LotDiggits), "\nСобытие: закрытие ордера", "\n\nТекущий баланс: ", DoubleToStr(AccountBalance(), 2), " ", AccountCurrency(), "\nТекущие средства: ", DoubleToStr(AccountEquity(), 2), " ", AccountCurrency())); } } if (!(SoundAlert)) break; PlaySound(SoundFileAtClose); break; } return (CloseOrder); } //+--------------------------------------------------------------------------------------------------------------+ //| CloseAllSymbols. Закрытие ордеров. Испльзуется если ProfitLimit и LossLimit > 0, при условии, //| если ордера остались открыты по истечении временного канала. //+--------------------------------------------------------------------------------------------------------------+ int CloseAllSymbols() { //+--------------------------------------------------------------------------------------------------------------+ int OType; bool DeleteOrder; int DeleteError = 0; int trade = OrdersTotal() - 1; for (int i = trade; i >= 0; i--) { if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (WriteDebugLog) Print("CloseAllSymbols: OrderSelect() error = ", GetLastError()); } else { if (OrderMagicNumber() == MagicNumber) { OType = OrderType(); RefreshRates(); while (!IsTradeAllowed()) Sleep(1000); if (OType <= OP_SELL) DeleteOrder = CloseOrder(OrderTicket(), OrderLots(), OType, CloseSP); else { DeleteOrder = OrderDelete(OrderTicket()); if (!DeleteOrder) if (WriteDebugLog) Print("CloseAllSymbols: OrderDelete() error = ", GetLastError()); } if (!DeleteOrder) DeleteError = -1; } } } return (DeleteError); } //+--------------------------------------------------------------------------------------------------------------+ //| IsTradeTime. Функция проверки торгового канала. //| Если время подходит для торговли, дает разрешение на открытие. //+--------------------------------------------------------------------------------------------------------------+ bool IsTradeTime(int fServerTime, int fStartWorkTimeHour, int fStartSessionMinute, int fEndWorkTimeHour, int fEndSessionMinute) { //+--------------------------------------------------------------------------------------------------------------+ int NewEndWorkTimeHour; //--- Час окончания торговли int NewStartWorkTimeMinute; //---Минута начала торговли //--- int ScalperTimeHour = TimeHour(fServerTime); //--- Возвращает час для ServerTime = TimeCurrent() int ScalperTimeMinute = TimeMinute(fServerTime); //--- Возвращает минуты для ServerTime = TimeCurrent() //--- if (fStartWorkTimeHour == fEndWorkTimeHour && fStartSessionMinute == fEndSessionMinute) return (TRUE); //--- Если правило выполняется отправляем разрешение на открытие //--- Инициализация NewEndWorkTimeHour и NewStartWorkTimeMinute if (fEndSessionMinute == 0) { if (fEndWorkTimeHour == 0) NewEndWorkTimeHour = 23; else NewEndWorkTimeHour = fEndWorkTimeHour - 1; NewStartWorkTimeMinute = 59; } else { NewEndWorkTimeHour = fEndWorkTimeHour; NewStartWorkTimeMinute = fEndSessionMinute - 1; } //--- Проверка NewEndWorkTimeHour и NewStartWorkTimeMinute if (fStartWorkTimeHour == NewEndWorkTimeHour) { if (fStartSessionMinute == NewStartWorkTimeMinute) return (TRUE); //--- Если же условие не выполняется, то возвращаем FALSE if (fStartSessionMinute < NewStartWorkTimeMinute) { if (ScalperTimeHour != fStartWorkTimeHour) return (FALSE); if (ScalperTimeMinute < fStartSessionMinute || ScalperTimeMinute > NewStartWorkTimeMinute) return (FALSE); return (TRUE); } //--- Проверка минут старта торгови if (fStartSessionMinute > NewStartWorkTimeMinute) { if (ScalperTimeHour == fStartWorkTimeHour) //--- Если же условие не выполняется, то возвращаем FALSE if (ScalperTimeMinute < fStartSessionMinute && ScalperTimeMinute > NewStartWorkTimeMinute) return (FALSE); return (TRUE); } } //--- Если час старта меньше часа окончания, то if (fStartWorkTimeHour < NewEndWorkTimeHour) { //--- Сравниваем часы if (ScalperTimeHour < fStartWorkTimeHour || ScalperTimeHour > NewEndWorkTimeHour) return (FALSE); //--- Сравниваем минуты старта if (ScalperTimeHour == fStartWorkTimeHour && ScalperTimeMinute < fStartSessionMinute) return (FALSE); //--- Дополнительная проверка if (ScalperTimeHour == NewEndWorkTimeHour && ScalperTimeMinute > NewStartWorkTimeMinute) return (FALSE); return (TRUE); } //--- Если час старта больше часа окончания, то if (fStartWorkTimeHour > NewEndWorkTimeHour) { //--- Сравниваем часы if (ScalperTimeHour < fStartWorkTimeHour && ScalperTimeHour > NewEndWorkTimeHour) return (FALSE); //--- Сравниваем минуты старта if (ScalperTimeHour == fStartWorkTimeHour && ScalperTimeMinute < fStartSessionMinute) return (FALSE); //--- Дополнительная проверка if (ScalperTimeHour == NewEndWorkTimeHour && ScalperTimeMinute > NewStartWorkTimeMinute) return (FALSE); return (TRUE); } //--- return (TRUE); } //+--------------------------------------------------------------------------------------------------------------+ //| ExistPosition. Функция проверки открытых ордеров. //| Если открыт ордер возвращает True, если нет, дает разрешение (False, 0) на открытие //+--------------------------------------------------------------------------------------------------------------+ int ExistPosition() { //+--------------------------------------------------------------------------------------------------------------+ int trade = OrdersTotal() - 1; for (int i = trade; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderMagicNumber() == MagicNumber) { if (OrderSymbol() == EASymbol) if (OrderType() <= OP_SELL) return (1); } } } return (0); } //+--------------------------------------------------------------------------------------------------------------+ //| CheckTrendFilter. Трендовый фильтр. //+--------------------------------------------------------------------------------------------------------------+ bool CheckTrendFilter() { //+--------------------------------------------------------------------------------------------------------------+ double iMA_b; double iMA_c; double MathAbs_iMA; int iMA_Shift3; if (TrendFilter <= 0) return (FALSE); for (iMA_Shift3 = 0; iMA_Shift3 <= TrendFilterMaxBars; iMA_Shift3++) { iMA_b = NormalizeDouble(iMA(NULL, 0, iMA_TimeFrame3, 0, iMA_Method3, iMA_Price3, iMA_Shift3), pd); iMA_c = NormalizeDouble(iMA(NULL, 0, iMA_TimeFrame3, 0, iMA_Method3, iMA_Price3, iMA_Shift3 + TrendFilter), pd); MathAbs_iMA = 100.0 * MathAbs(iMA_b - iMA_c) / iMA_c; if (MathAbs_iMA > Filter_b) break; } if (iMA_Shift3 > TrendFilterMaxBars) return (FALSE); if (WriteDebugLog) { if (LanguageEA == 0) Print("Today market is in risky conditions. Trading is forbidden by the filter TrendFilter."); else Print("Сегодня рынок в опасном состоянии. Торговля запрещена фильтром TrendFilter."); if (iMA_Shift3 != 0) { if (LanguageEA == 0) Print("Relax Bars Left = " + DoubleToStr(TrendFilterMaxBars - iMA_Shift3, 0) + " (after MaxPercentMove)."); else Print("Осталось Relax баров = " + DoubleToStr(TrendFilterMaxBars - iMA_Shift3, 0) + " (после MaxPercentMove)."); } } return (TRUE); } //+--------------------------------------------------------------------------------------------------------------+ //| CheckVolaFilter. Фильтр волатильности. //+--------------------------------------------------------------------------------------------------------------+ bool CheckVolaFilter() { //+--------------------------------------------------------------------------------------------------------------+ int time; bool VolRule = FALSE; if (NormalizeDouble(iHigh(NULL, PERIOD_M15, 1) - iLow(NULL, PERIOD_M15, 1), pd) > HeightFilter_a) VolRule = TRUE; if (NormalizeDouble(iHigh(NULL, PERIOD_M15, 2) - iLow(NULL, PERIOD_M15, 2), pd) > HeightFilter_a) VolRule = TRUE; if (VolRule) { time = iTime(NULL, PERIOD_M15, 0); if (VolaTime != time) { if (WriteLog) { if (LanguageEA == 0) Print("Today market is in risky conditions. Trade is forbidden by the filter SimpleHeightFilter."); else Print("Сегодня рынок в опасном состоянии. Торговля запрещена фильтром SimpleHeightFilter."); } VolaTime = time; } return (TRUE); } return (FALSE); } //+--------------------------------------------------------------------------------------------------------------+ //| NoiseFilter. Фильтр шума. Если на рынке наблюдается высокая волатильность и открыт ордер, то //| произойдет закрытие ордера. //+--------------------------------------------------------------------------------------------------------------+ void NoiseFilter() { //+--------------------------------------------------------------------------------------------------------------+ int NoiseTime; double NoiseClosePrice; double NoiseOpenPrice; int CloseBecauseNoise; double NoiseNewPrice; int trade = OrdersTotal() - 1; for (int i = trade; i >= 0; i--) { if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (WriteDebugLog) Print("NoiseFilter: OrderSelect() error = ", GetLastError()); } else { if (OrderMagicNumber() == MagicNumber) { if (OrderType() <= OP_SELL) { if (OrderSymbol() == EASymbol) { NoiseTime = ServerTime - OrderOpenTime(); if (NoiseTime > NoiseFilter_a) { NoiseClosePrice = NormalizeDouble(OrderClosePrice(), Digits); NoiseOpenPrice = NormalizeDouble(OrderOpenPrice(), Digits); CloseBecauseNoise = 0; if (OrderType() == OP_BUY) NoiseNewPrice = NoiseClosePrice - NoiseOpenPrice; else NoiseNewPrice = NoiseOpenPrice - NoiseClosePrice; if (NoiseTime < NoiseFilter_b && NoiseNewPrice >= NoiseFilter_f) CloseBecauseNoise = 1; else { if (NoiseTime > NoiseFilter_b && NoiseTime < NoiseFilter_c && NoiseNewPrice >= NoiseFilter_g) CloseBecauseNoise = 2; else { if (NoiseTime > NoiseFilter_c && NoiseTime < NoiseFilter_d && NoiseNewPrice >= NoiseFilter_h) CloseBecauseNoise = 3; else { if (NoiseTime > NoiseFilter_d && NoiseTime < NoiseFilter_e && NoiseNewPrice >= NoiseFilter_i) CloseBecauseNoise = 4; else if (NoiseTime > NoiseFilter_e && NoiseNewPrice >= NoiseFilter_j) CloseBecauseNoise = 5; } } } if (CloseBecauseNoise != 0) CloseOrder(OrderTicket(), OrderLots(), OrderType(), CloseSP); } } } } } } } //+--------------------------------------------------------------------------------------------------------------+ //| LotsOptimized. Функция расчета обьема лота. //| При включенной UseMM расчитывает объём лота относительно свободных средств. //+--------------------------------------------------------------------------------------------------------------+ double LotsOptimized() { //+--------------------------------------------------------------------------------------------------------------+ if (!UseMM) return (Lots); //--- Если ММ выключена, то возвращает значение Lots //--- double FreeMargin = AccountFreeMargin() * RiskFactor / 100.0; //--- Расчет маржи относительно риска double OpLot = NormalizeDouble(MathFloor(FreeMargin / NeedMargin) * LotStep, LotDiggits); //--- Расчет нового объёма //--- Сравнение нового объёма с MinLot, MaxLot и MaxLots if (OpLot < MinLot) OpLot = MinLot; if (OpLot > MaxLot) OpLot = MaxLot; if (OpLot > MaxLots) OpLot = MaxLots; //--- return (OpLot); } //+--------------------------------------------------------------------------------------------------------------+ //| HaveTrade. Проверка сделок внутри временного канала. //+--------------------------------------------------------------------------------------------------------------+ bool HaveTrade() { //+--------------------------------------------------------------------------------------------------------------+ int TimeOpenOrder; if (StartWorkTime == EndWorkTime && StartSessionMinute == EndSessionMinute) return (FALSE); int CurrentTime = TimeCurrent(); int TimeD1 = iTime(NULL, PERIOD_D1, 0); int TimeCurrentHour = TimeHour(CurrentTime); if (StartWorkTime > EndWorkTime) if (TimeCurrentHour < StartWorkTime) TimeD1 -= 86400; TimeD1 += 3600 * StartWorkTime + 60 * StartSessionMinute; int trade = OrdersTotal() - 1; int CheckTime = -2147483648; for (int i = trade; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (OrderMagicNumber() == MagicNumber) { if (OrderSymbol() == EASymbol) { TimeOpenOrder = OrderOpenTime(); if (CheckTime < TimeOpenOrder) CheckTime = TimeOpenOrder; } } } } if (CheckTime >= TimeD1) return (TRUE); trade = OrdersHistoryTotal() - 1; CheckTime = -2147483648; for (int i = trade; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { if (OrderMagicNumber() == MagicNumber) { if (OrderSymbol() == EASymbol) { TimeOpenOrder = OrderOpenTime(); if (CheckTime < TimeOpenOrder) CheckTime = TimeOpenOrder; } } } } if (CheckTime >= TimeD1) return (TRUE); return (FALSE); } //+--------------------------------------------------------------------------------------------------------------+ //| IsRelaxHours. Включение паузы равной RelaxHours (часы), от времени закрытия последней позиции. //| Во время паузы сделки не открываются. //| //| Например если RelaxHours = 1, и 20 минут назад сделка была закрыта, то новая сможет открытся только //| спустя 40 минут, при условии, если будет сигнал на вход. //+--------------------------------------------------------------------------------------------------------------+ bool IsRelaxHours() { //+--------------------------------------------------------------------------------------------------------------+ int RelaxCloseTime; bool RelaxRule; double RelaxOpenPrice; double RelaxClosePrice; double RelaxStopLoss; int Time_H1; int ticket = -1; int history = OrdersHistoryTotal() - 1; int RelaxTime = -2147483648; for (int i = history; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { if (OrderMagicNumber() == MagicNumber) { if (OrderSymbol() == EASymbol) { RelaxCloseTime = OrderCloseTime(); if (RelaxTime < RelaxCloseTime) { RelaxTime = RelaxCloseTime; ticket = OrderTicket(); } } } } } if (ticket < 0) return (FALSE); if (OrderSelect(ticket, SELECT_BY_TICKET)) { RelaxRule = FALSE; RelaxOpenPrice = NormalizeDouble(OrderOpenPrice(), Digits); RelaxClosePrice = NormalizeDouble(OrderClosePrice(), Digits); RelaxStopLoss = NormalizeDouble(OrderStopLoss(), Digits); if (OrderType() == OP_BUY) { if (RelaxClosePrice <= RelaxStopLoss && RelaxStopLoss != 0.0) RelaxRule = TRUE; else if (NormalizeDouble(RelaxOpenPrice - RelaxClosePrice, Digits) >= RelaxFilter) RelaxRule = TRUE; } else { if (RelaxClosePrice >= RelaxStopLoss && RelaxStopLoss != 0.0) RelaxRule = TRUE; else if (NormalizeDouble(RelaxClosePrice - RelaxOpenPrice, Digits) >= RelaxFilter) RelaxRule = TRUE; } } else return (FALSE); if (!RelaxRule) return (FALSE); int RelaxBarShift = iBarShift(NULL, PERIOD_H1, RelaxTime, FALSE); if (RelaxBarShift < RelaxHours) { Time_H1 = iTime(NULL, PERIOD_H1, 0); if (CheckRelaxTime_H1 != Time_H1) { if (WriteLog) { if (LanguageEA == 0) Print("Relax Hours Left = " + DoubleToStr(RelaxBarShift - RelaxHours, 0) + " (after StopLoss)."); else Print("Осталось Relax часов = " + DoubleToStr(RelaxBarShift - RelaxHours, 0) + " (после StopLoss)."); } CheckRelaxTime_H1 = Time_H1; } return (TRUE); } return (FALSE); } //+--------------------------------------------------------------------------------------------------------------+ //| HaveAllOrders. Счетчик открытых ордеров по всем валютным парам. //+--------------------------------------------------------------------------------------------------------------+ int HaveAllOrders() { //+--------------------------------------------------------------------------------------------------------------+ int count = 0; int trade = OrdersTotal() - 1; for (int i = trade; i >= 0; i--) { if (OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) if (OrderMagicNumber() == MagicNumber) count++; } return (count); } //+--------------------------------------------------------------------------------------------------------------+ //| ShowComments. Функция для отображения комментариев на графике. //+--------------------------------------------------------------------------------------------------------------+ void ShowComments() { //+--------------------------------------------------------------------------------------------------------------+ string TextOnGraf = ""; datetime MyOpDate = TIME_DATE; //--- Вывод в комментарий даты оптимизации (формат) double NextLotSize = LotsOptimized(); string EngTypeGMT; string RusTypeGMT; int ShowGmt; //--- Отображение на графике способа расчета смещения GMT if (UseAutoGMToffset) { //--- ShowGmt = GetGmtOffset(); EngTypeGMT = " (automatic)"; RusTypeGMT = " (автоматический)"; //--- } else { ShowGmt = ManualGMToffset; EngTypeGMT = " (manual)"; RusTypeGMT = " (ручной)"; //--- } if (ProfitLimit > 0.0 || LossLimit > 0.0) { if (StartWorkTime != EndWorkTime || StartSessionMinute != EndSessionMinute) { Profit = CalculateProfitSession(); if (LanguageEA == 0) { TextOnGraf = StringConcatenate("Current Profit: ", DoubleToStr(Profit, 2), " ", AccountCurrency(), "\n"); } else { TextOnGraf = StringConcatenate("Текущая прибыль: ", DoubleToStr(Profit, 2), " ", AccountCurrency(), "\n"); } if (ProfitLimit > 0.0) { if (LanguageEA == 0) { TextOnGraf = StringConcatenate(TextOnGraf, "Profit Limit: ", DoubleToStr(ProfitLimit, 2), " ", AccountCurrency(), "\n"); } else { TextOnGraf = StringConcatenate(TextOnGraf, "Ограничение прибыли: ", DoubleToStr(ProfitLimit, 2), " ", AccountCurrency(), "\n"); } } if (LossLimit > 0.0) { if (LanguageEA == 0) { TextOnGraf = StringConcatenate(TextOnGraf, "Loss Limit: ", DoubleToStr(-1.0 * LossLimit, 2), " ", AccountCurrency(), "\n"); } else { TextOnGraf = StringConcatenate(TextOnGraf, "Ограничение убытка: ", DoubleToStr(-1.0 * LossLimit, 2), " ", AccountCurrency(), "\n"); } } } } if (PrintLogOnChart) { if (DST == 0) { GMTStringConcatenate = StringConcatenate("GmtOffset: ", DoubleToStr(Gmt, 1), GMTComment, "\n"); } else { GMTStringConcatenate = StringConcatenate("GmtOffset: ", DoubleToStr(Gmt + 1, 1), GMTComment, "\n"); } //-- Комменты на графике if (LanguageEA == 0) { Comment("" + "------------------------------------------------" + "\n" + Name + "\n" + "\n" + Cop + "\n" + "Optimization date: " + TimeToStr (Date, MyOpDate) + "\n" + "Optimisation for symbol: " + Symbol_Op + "\n" + "------------------------------------------------" + "\n" + "EA INFORMATION" + "\n" + "GMT Offset: " + ShowGmt + EngTypeGMT + "\n" + "Current Spread: " + DoubleToStr(MarketInfo(EASymbol, MODE_SPREAD) / MathPow(10, Digits - pd), Digits - pd) + "\n" + "MaxSpread: " + DoubleToStr(MaxSpread, Digits - pd) + "\n" + IIFs(UseMM, "Next Lot size: " + DoubleToStr(NextLotSize, 2) + "\n","") + IIFs(UseMM == False, "Lot size: " + DoubleToStr(NextLotSize, 2) + "\n","") + "\n" + IIFs(UseStopLevels, "Use stop levels" + "\n","") + IIFs(UseFakeStopLevels, "Use fake stop levels" + "\n","") + IIFs(UseDST, "Use DST" + "\n","") + TextOnGraf + "------------------------------------------------" + "\n" + "BROKER INFORMATION:" + "\n" + "Broker Company: " + AccountCompany() + "\n" + "------------------------------------------------" + "\n" + "ACCOUNT INFORMATION:" + "\n" + "Account Name: " + AccountName() + "\n" + "Account Number: " + AccountNumber() + "\n" + "Account Leverage: " + DoubleToStr(AccountLeverage(), 0) + "\n" + "Account Balance: " + DoubleToStr(AccountBalance(), 2) + "\n" + "Account Currency: " + AccountCurrency() + "\n" + "Account Equity: " + DoubleToStr(AccountEquity(), 2) + "\n" + "------------------------------------------------" + "\n" + "MARGIN INFORMATION:" + "\n" + "Free Margin: " + DoubleToStr(AccountFreeMargin(), 2) + "\n" + "Used Margin: " + DoubleToStr(AccountMargin(), 2) + "\n" + "------------------------------------------------" + "\n" + "Actual Server Time: " + TimeToStr(TimeCurrent(), TIME_SECONDS) + "\n" + "------------------------------------------------"); } else { Comment("" + "------------------------------------------------" + "\n" + Name + "\n" + "\n" + Cop + "\n" + Op + ": " + TimeToStr (Date, MyOpDate) + "\n" + Op2 + ": " + Symbol_Op + "\n" + "------------------------------------------------" + "\n" + "Информация об эксперте" + "\n" + "Смещение по GMT: " + ShowGmt + RusTypeGMT + "\n" + "Текущий спред: " + DoubleToStr(MarketInfo(EASymbol, MODE_SPREAD) / MathPow(10, Digits - pd), Digits - pd) + "\n" + "Максимальный спред: " + DoubleToStr(MaxSpread, Digits - pd) + "\n" + "Максимум сделок: " + MaximumTrades + "\n" + IIFs(UseMM, "Следующий объём лота: " + DoubleToStr(NextLotSize, 2) + "\n","") + IIFs(UseMM == False, "Лот: " + DoubleToStr(NextLotSize, 2) + "\n","") + "\n" + IIFs(UseStopLevels, "Используются стоп-уровни" + "\n","") + IIFs(UseFakeStopLevels, "Используются поддельные стоп-уровни" + "\n","") + IIFs(UseDST, "Используется летнее время" + "\n","") + TextOnGraf + "------------------------------------------------" + "\n" + "Информация о брокере:" + "\n" + "Брокерская компания: " + AccountCompany() + "\n" + "------------------------------------------------" + "\n" + "Информация о счёте:" + "\n" + "Название счёта: " + AccountName() + "\n" + "Номер счёта: " + AccountNumber() + "\n" + "Плечо счёта: " + DoubleToStr(AccountLeverage(), 0) + "\n" + "Баланс: " + DoubleToStr(AccountBalance(), 2) + "\n" + "Валюта счёта: " + AccountCurrency() + "\n" + "Средства: " + DoubleToStr(AccountEquity(), 2) + "\n" + "------------------------------------------------" + "\n" + "Информация о марже:" + "\n" + "Свободная маржа: " + DoubleToStr(AccountFreeMargin(), 2) + "\n" + "Используемая маржа: " + DoubleToStr(AccountMargin(), 2) + "\n" + "------------------------------------------------" + "\n" + "Текущее время сервера: " + TimeToStr(TimeCurrent(), TIME_SECONDS) + "\n" + "------------------------------------------------"); } } } //+--------------------------------------------------------------------------------------------------------------+ //| IIFs. Возвращает одно из двух значений взависимости от условия. Используется при выводе комментариев. //+--------------------------------------------------------------------------------------------------------------+ string IIFs(bool condition, string ifTrue, string ifFalse) { //+--------------------------------------------------------------------------------------------------------------+ if (condition) return(ifTrue); else return(ifFalse); } //+--------------------------------------------------------------------------------------------------------------+ //| OrderTypeToStr. Возвращает тип ордера в string. //+--------------------------------------------------------------------------------------------------------------+ string OrderTypeToStr(int a) { //+--------------------------------------------------------------------------------------------------------------+ string OType; // Order Type switch (a) { case 0: OType = "Buy"; break; case 1: OType = "Sell"; break; case 2: OType = "BuyLimit"; break; case 3: OType = "SellLimit"; break; case 4: OType = "BuyStop"; break; case 5: OType = "SellStop"; break; default: OType = "Unknown"; } return (OType); } //+--------------------------------------------------------------------------------------------------------------+ //| CalculateProfitSession. Подсчет профита. Используется в комментариях на графике. //+--------------------------------------------------------------------------------------------------------------+ double CalculateProfitSession() { //+--------------------------------------------------------------------------------------------------------------+ int time; int date; int hour; double pr = 0; // обнуление профита int trade = OrdersTotal() - 1; for (int i = trade; i >= 0; i--) { if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES)) { if (WriteDebugLog) Print("CalculateProfitSession: OrderSelect() error = ", GetLastError()); } else if (OrderMagicNumber() == MagicNumber) pr += OrderProfit() + OrderSwap() + OrderCommission(); } if (StartWorkTime == EndWorkTime && StartSessionMinute == EndSessionMinute) time = 0; else { date = TimeCurrent(); time = iTime(NULL, PERIOD_D1, 0); hour = TimeHour(date); if (StartWorkTime > EndWorkTime) if (hour < StartWorkTime) time -= 86400; time += 3600 * StartWorkTime + 60 * StartSessionMinute; } trade = OrdersHistoryTotal() - 1; for (int i = trade; i >= 0; i--) { if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) { if (WriteDebugLog) Print("CalculateProfitSession: OrderSelect() error = ", GetLastError()); } else { if (OrderMagicNumber() == MagicNumber) if (OrderCloseTime() >= time) pr += OrderProfit() + OrderSwap() + OrderCommission(); // Общий профит } } return (pr); } //+--------------------------------------------------------------------------------------------------------------+ //| ErrorDescription. Возвращает описание ошибки по её номеру. //+--------------------------------------------------------------------------------------------------------------+ string ErrorDescription(int error) { //+--------------------------------------------------------------------------------------------------------------+ string ErrorNumber; //--- if (LanguageEA == 0) { //--- На Английском switch (error) { case 0: case 1: ErrorNumber = "No error"; break; case 2: ErrorNumber = "Common error"; break; case 3: ErrorNumber = "Invalid trade parameters"; break; case 4: ErrorNumber = "Trade server is busy"; break; case 5: ErrorNumber = "Old version of the client terminal"; break; case 6: ErrorNumber = "No connection with trade server"; break; case 7: ErrorNumber = "Not enough rights"; break; case 8: ErrorNumber = "Too frequent requests"; break; case 9: ErrorNumber = "Malfunctional trade operation (never returned error)"; break; case 64: ErrorNumber = "Account disabled"; break; case 65: ErrorNumber = "Invalid account"; break; case 128: ErrorNumber = "Trade timeout"; break; case 129: ErrorNumber = "Invalid price"; break; case 130: ErrorNumber = "Invalid stops"; break; case 131: ErrorNumber = "Invalid trade volume"; break; case 132: ErrorNumber = "Market is closed"; break; case 133: ErrorNumber = "Trade is disabled"; break; case 134: ErrorNumber = "Not enough money"; break; case 135: ErrorNumber = "Price changed"; break; case 136: ErrorNumber = "Off quotes"; break; case 137: ErrorNumber = "Broker is busy (never returned error)"; break; case 138: ErrorNumber = "Requote"; break; case 139: ErrorNumber = "Order is locked"; break; case 140: ErrorNumber = "Long positions only allowed"; break; case 141: ErrorNumber = "Too many requests"; break; case 145: ErrorNumber = "Modification denied because order too close to market"; break; case 146: ErrorNumber = "Trade context is busy"; break; case 147: ErrorNumber = "Expirations are denied by broker"; break; case 148: ErrorNumber = "Amount of open and pending orders has reached the limit"; break; //---- case 4000: ErrorNumber = "No error (never generated code)"; break; case 4001: ErrorNumber = "Wrong function pointer"; break; case 4002: ErrorNumber = "Array index is out of range"; break; case 4003: ErrorNumber = "No memory for function call stack"; break; case 4004: ErrorNumber = "Recursive stack overflow"; break; case 4005: ErrorNumber = "Not enough stack for parameter"; break; case 4006: ErrorNumber = "No memory for parameter string"; break; case 4007: ErrorNumber = "No memory for temp string"; break; case 4008: ErrorNumber = "Not initialized string"; break; case 4009: ErrorNumber = "Not initialized string in array"; break; case 4010: ErrorNumber = "No memory for array\' string"; break; case 4011: ErrorNumber = "Too long string"; break; case 4012: ErrorNumber = "Remainder from zero divide"; break; case 4013: ErrorNumber = "Zero divide"; break; case 4014: ErrorNumber = "Unknown command"; break; case 4015: ErrorNumber = "Wrong jump (never generated error)"; break; case 4016: ErrorNumber = "Not initialized array"; break; case 4017: ErrorNumber = "Dll calls are not allowed"; break; case 4018: ErrorNumber = "Cannot load library"; break; case 4019: ErrorNumber = "Cannot call function"; break; case 4020: ErrorNumber = "Expert function calls are not allowed"; break; case 4021: ErrorNumber = "Not enough memory for temp string returned from function"; break; case 4022: ErrorNumber = "System is busy (never generated error)"; break; case 4050: ErrorNumber = "Invalid function parameters count"; break; case 4051: ErrorNumber = "Invalid function parameter value"; break; case 4052: ErrorNumber = "String function internal error"; break; case 4053: ErrorNumber = "Some array error"; break; case 4054: ErrorNumber = "Incorrect series array using"; break; case 4055: ErrorNumber = "Custom indicator error"; break; case 4056: ErrorNumber = "Arrays are incompatible"; break; case 4057: ErrorNumber = "Global variables processing error"; break; case 4058: ErrorNumber = "Global variable not found"; break; case 4059: ErrorNumber = "Function is not allowed in testing mode"; break; case 4060: ErrorNumber = "Function is not confirmed"; break; case 4061: ErrorNumber = "Send mail error"; break; case 4062: ErrorNumber = "String parameter expected"; break; case 4063: ErrorNumber = "Integer parameter expected"; break; case 4064: ErrorNumber = "Double parameter expected"; break; case 4065: ErrorNumber = "Array as parameter expected"; break; case 4066: ErrorNumber = "Requested history data in update state"; break; case 4099: ErrorNumber = "End of file"; break; case 4100: ErrorNumber = "Some file error"; break; case 4101: ErrorNumber = "Wrong file name"; break; case 4102: ErrorNumber = "Too many opened files"; break; case 4103: ErrorNumber = "Cannot open file"; break; case 4104: ErrorNumber = "Incompatible access to a file"; break; case 4105: ErrorNumber = "No order selected"; break; case 4106: ErrorNumber = "Unknown symbol"; break; case 4107: ErrorNumber = "Invalid price parameter for trade function"; break; case 4108: ErrorNumber = "Invalid ticket"; break; case 4109: ErrorNumber = "Trade is not allowed in the expert properties"; break; case 4110: ErrorNumber = "Longs are not allowed in the expert properties"; break; case 4111: ErrorNumber = "Shorts are not allowed in the expert properties"; break; case 4200: ErrorNumber = "Object is already exist"; break; case 4201: ErrorNumber = "Unknown object property"; break; case 4202: ErrorNumber = "Object is not exist"; break; case 4203: ErrorNumber = "Unknown object type"; break; case 4204: ErrorNumber = "No object name"; break; case 4205: ErrorNumber = "Object coordinates error"; break; case 4206: ErrorNumber = "No specified subwindow"; break; default: ErrorNumber = "Unknown error"; } } else { //--- На Русском switch (error) { case 0: case 1: ErrorNumber = "Нет ошибки, но результат неизвестен"; break; case 2: ErrorNumber = "Общая ошибка"; break; case 3: ErrorNumber = "Неправильные параметры"; break; case 4: ErrorNumber = "Торговый сервер занят"; break; case 5: ErrorNumber = "Старая версия клиентского терминала"; break; case 6: ErrorNumber = "Нет связи с торговым сервером"; break; case 7: ErrorNumber = "Недостаточно прав"; break; case 8: ErrorNumber = "Слишком частые запросы"; break; case 9: ErrorNumber = "Недопустимая операция нарушающая функционирование сервера"; break; case 64: ErrorNumber = "Счет заблокирован"; break; case 65: ErrorNumber = "Неправильный номер счета"; break; case 128: ErrorNumber = "Истек срок ожидания совершения сделки"; break; case 129: ErrorNumber = "Неправильная цена"; break; case 130: ErrorNumber = "Неправильные стопы"; break; case 131: ErrorNumber = "Неправильный объем"; break; case 132: ErrorNumber = "Рынок закрыт"; break; case 133: ErrorNumber = "Торговля запрещена"; break; case 134: ErrorNumber = "Недостаточно денег для совершения операции"; break; case 135: ErrorNumber = "Цена изменилась"; break; case 136: ErrorNumber = "Нет цен"; break; case 137: ErrorNumber = "Брокер занят"; break; case 138: ErrorNumber = "Новые цены - Реквот"; break; case 139: ErrorNumber = "Ордер заблокирован и уже обрабатывается"; break; case 140: ErrorNumber = "Разрешена только покупка"; break; case 141: ErrorNumber = "Слишком много запросов"; break; case 145: ErrorNumber = "Модификация запрещена, так как ордер слишком близок к рынку";break; case 146: ErrorNumber = "Подсистема торговли занята"; break; case 147: ErrorNumber = "Использование даты истечения ордера запрещено брокером"; break; case 148: ErrorNumber = "Количество открытых и отложенных ордеров достигло предела "; break; //---- case 4000: ErrorNumber = "Нет ошибки"; break; case 4001: ErrorNumber = "Неправильный указатель функции"; break; case 4002: ErrorNumber = "Индекс массива - вне диапазона"; break; case 4003: ErrorNumber = "Нет памяти для стека функций"; break; case 4004: ErrorNumber = "Переполнение стека после рекурсивного вызова"; break; case 4005: ErrorNumber = "На стеке нет памяти для передачи параметров"; break; case 4006: ErrorNumber = "Нет памяти для строкового параметра"; break; case 4007: ErrorNumber = "Нет памяти для временной строки"; break; case 4008: ErrorNumber = "Неинициализированная строка"; break; case 4009: ErrorNumber = "Неинициализированная строка в массиве"; break; case 4010: ErrorNumber = "Нет памяти для строкового массива"; break; case 4011: ErrorNumber = "Слишком длинная строка"; break; case 4012: ErrorNumber = "Остаток от деления на ноль"; break; case 4013: ErrorNumber = "Деление на ноль"; break; case 4014: ErrorNumber = "Неизвестная команда"; break; case 4015: ErrorNumber = "Неправильный переход"; break; case 4016: ErrorNumber = "Неинициализированный массив"; break; case 4017: ErrorNumber = "Вызовы DLL не разрешены"; break; case 4018: ErrorNumber = "Невозможно загрузить библиотеку"; break; case 4019: ErrorNumber = "Невозможно вызвать функцию"; break; case 4020: ErrorNumber = "eВызовы внешних библиотечных функций не разрешены"; break; case 4021: ErrorNumber = "Недостаточно памяти для строки, возвращаемой из функции"; break; case 4022: ErrorNumber = "Система занята"; break; case 4050: ErrorNumber = "Неправильное количество параметров функции"; break; case 4051: ErrorNumber = "Недопустимое значение параметра функции"; break; case 4052: ErrorNumber = "Внутренняя ошибка строковой функции"; break; case 4053: ErrorNumber = "Ошибка массива"; break; case 4054: ErrorNumber = "Неправильное использование массива-таймсерии"; break; case 4055: ErrorNumber = "Ошибка пользовательского индикатора"; break; case 4056: ErrorNumber = "Массивы несовместимы"; break; case 4057: ErrorNumber = "Ошибка обработки глобальныех переменных"; break; case 4058: ErrorNumber = "Глобальная переменная не обнаружена"; break; case 4059: ErrorNumber = "Функция не разрешена в тестовом режиме"; break; case 4060: ErrorNumber = "Функция не подтверждена"; break; case 4061: ErrorNumber = "Ошибка отправки почты"; break; case 4062: ErrorNumber = "Ожидается параметр типа string"; break; case 4063: ErrorNumber = "Ожидается параметр типа integer"; break; case 4064: ErrorNumber = "Ожидается параметр типа double"; break; case 4065: ErrorNumber = "В качестве параметра ожидается массив"; break; case 4066: ErrorNumber = "Запрошенные исторические данные в состоянии обновления"; break; case 4067: ErrorNumber = "Ошибка при выполнении торговой операции"; break; case 4099: ErrorNumber = "Конец файла"; break; case 4100: ErrorNumber = "Ошибка при работе с файлом"; break; case 4101: ErrorNumber = "Неправильное имя файла"; break; case 4102: ErrorNumber = "Слишком много открытых файлов"; break; case 4103: ErrorNumber = "Невозможно открыть файл"; break; case 4104: ErrorNumber = "Несовместимый режим доступа к файлу"; break; case 4105: ErrorNumber = "Ни один ордер не выбран"; break; case 4106: ErrorNumber = "Неизвестный символ"; break; case 4107: ErrorNumber = "Неправильный параметр цены для торговой функции"; break; case 4108: ErrorNumber = "Неверный номер тикета"; break; case 4109: ErrorNumber = "Торговля не разрешена"; break; case 4110: ErrorNumber = "Длинные позиции не разрешены"; break; case 4111: ErrorNumber = "Короткие позиции не разрешены"; break; case 4200: ErrorNumber = "Объект уже существует"; break; case 4201: ErrorNumber = "Запрошено неизвестное свойство объекта"; break; case 4202: ErrorNumber = "Объект не существует"; break; case 4203: ErrorNumber = "Неизвестный тип объекта"; break; case 4204: ErrorNumber = "Нет имени объекта"; break; case 4205: ErrorNumber = "Ошибка координат объекта"; break; case 4206: ErrorNumber = "Не найдено указанное подокно"; break; case 4207: ErrorNumber = "Ошибка при работе с объектом"; break; default: ErrorNumber = "Неизвестная ошибка"; }} //--- return (ErrorNumber); } //+--------------------------------------------------------------------------------------------------------------+ //| GetGmtOffset. Функция возвращает значение временной зоны по GMT //+--------------------------------------------------------------------------------------------------------------+ double GetGmtOffset() { //+--------------------------------------------------------------------------------------------------------------+ return (TimeZoneServer()); } //+--------------------------------------------------------------------------------------------------------------+ //| TimeZoneServer. Функция возвращает значение временной зоны по серверному времени //+--------------------------------------------------------------------------------------------------------------+ double TimeZoneServer() { //+--------------------------------------------------------------------------------------------------------------+ int ServerToLocalDiffMinutes = (TimeCurrent() - TimeLocal()) / 60; int nHalfHourDiff = MathRound(ServerToLocalDiffMinutes / 30.0); ServerToLocalDiffMinutes = 30 * nHalfHourDiff; double TimeZoneServerValue = TimeZoneLocal() + ServerToLocalDiffMinutes / 60.0; //--- return (TimeZoneServerValue); } //+--------------------------------------------------------------------------------------------------------------+ //| TimeZoneLocal. Функция возвращает значение временной зоны по локальному времени. //| При расчете используется kernel32.dll. //+--------------------------------------------------------------------------------------------------------------+ double TimeZoneLocal() { //+--------------------------------------------------------------------------------------------------------------+ int TZInfoArray[43]; switch (GetTimeZoneInformation(TZInfoArray)) { case 0: return (TZInfoArray[0] / (-60.0)); case 1: return (TZInfoArray[0] / (-60.0)); case 2: return ((TZInfoArray[0] + TZInfoArray[42]) / (-60.0)); } //--- return (0); } //================= void Scr(){ OrdTot=OrdersTotal(); if(OrdTot>ord) { orr = OrderSelect(OrdTot-1,SELECT_BY_POS); if(OrderSymbol()==Symbol()){Screen();init();return;}else {init();return;} } //+------------------------------------------------------------------+ if(OrdTot