//IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| e-PSI@SAR.mq4 | //| Copyright © 2012, Igor Stepovoi aka TarasBY | //| taras_bulba@tut.by | //| | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Данный продукт предназначен для некоммерческого использования. Публикация раз- | //|решена только при указании имени автора (TarasBY). Редактирование исходного кода | //|допустима только при условии сохранения данного текста, ссылок и имени автора. | //| Продажа советника или отдельных её частей ЗАПРЕЩЕНА. | //| Автор не несёт ответственности за возможные убытки, полученные в результате ис- | //|пользования советника. | //| По всем вопросам, связанным с работой советника, замечаниями или предложениями | //|по его доработке обращаться на Skype: TarasBY или e-mail. | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ #property copyright "Copyright © 2008-12, TarasBY WM R418875277808; Z670270286972" #property link "taras_bulba@tut.by" //IIIIIIIIIIIIIIIIIII==================CONSTANS=================IIIIIIIIIIIIIIIIIIIIII+ #define BULL 0 #define BEAR 1 #define STOP -1 //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| ***** Параметры советника ***** | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ extern string SETUP_Expert = "========== Общие настройки советника =========="; extern int MagicNumber = 2012; extern int NewBarInPeriod = 1; // >= 0 - работаем на начале периода нового бара, -1 - работаем на каждом тике extern int TF_Indicators = PERIOD_H1; // Период, на котором работают индикаторы //IIIIIIIIIIIIIIIIIII==========Подключенные библиотеки==========IIIIIIIIIIIIIIIIIIIIII+ #include // Библиотека базовых функций #include // Библиотека создания и контроля СТОПов #include // Библиотека получения сигналов #include // Библиотека управления капиталом #include // Библиотека торговли сетью ордеров #include // Библиотека трейлинга ордеров (стандартная) #include // Библиотека по управлению общим профитом советника #include // Библиотека сервисных переменных #include // Библиотека функций торговых операций //IIIIIIIIIIIIIIIIIII======Глобальные переменные советника======IIIIIIIIIIIIIIIIIIIIII+ double gda_Lots[2]; int gia_MyOrders[2], gia_HistoryOrders[3]; string gs_Info; bool gb_VirtSTOPs; // флаг наличия у ордеров виртуальных СТОПов //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Custom expert initialization function | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ int init() { int err = GetLastError(); //---- //---- Проверяем переданные в советник внешние параметры if (!fCheck_ExternParameters()) {bb_OptimContinue = true; return (0);} //---- Инициализируем библиотеку базовых функций fInit_Base (Symbol(), MagicNumber, TF_Indicators, ShowCommentInChart, PrintCom, SoundAlert, CreatVStopsInChart); //---- Инициализируем библиотеку управления общим профитом if (!fInit_ManagerPA()) return (0); //---- Инициализируем библиотеку СТОПов if (!fInit_STOPs()) return (0); //---- Инициализируем библиотеку трейлинга if (!fInit_Trail()) return (0); //---- Собираем первоначальную статистику fGet_Statistic (-1); //---- Инициализируем библиотеку MM bd_LotsMM = fInit_MM (Order_Lots, MagicNumber); //---- Инициализируем библиотеку построения сети if (!fInit_NET()) return (0); //---- Получаем даты начала и последнего трейдинга bdt_BeginTrade = fGet_TermsTrade (bs_Symbol, MagicNumber, bdt_LastTrade); //---- Контролируем возможные ошибки fGet_LastErrorInArray (bsa_Comment, "init()", bi_indERR); //---- return (0); } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Custor expert deinitialization function | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ int deinit() { //---- fMineDeInit(); //---- return (0); } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Custom expert iteration function | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ int start() { //---- Для оптимизации убираем "пустые" варианты if (fSet_Continue()) return (0); //---- Фиксируем начало текущего контрольного бара bdt_BeginNewBar = iTime (bs_Symbol, TF_Indicators, 0); //---- int err = GetLastError(); //---- //---- Считаем "свои" ордера bi_MyOrders = fMyPositions (bd_ProfitCUR, gia_MyOrders, MagicNumber); //---- Управляем линией БезУбытка fControl_BreakEven (gda_Lots); //---- Собираем статистику fGet_Statistic (PERIOD_D1); //---- Выводим информацию на график (если разрешено) if (ShowCommentInChart) {fCommentInChart (bsa_Comment, fGet_StringManagerPA());} //---- Входим в начале указанного бара (если NewBarInPeriod >= 0) if (!fCheck_NewBarInPeriod (NewBarInPeriod)) return (0); //---- Запускаем в работу библиотеку управления общим профитом советника if (fManagerPA (bd_ProfitCUR, bd_Balance, bi_MyOrders > 0)) { bi_MyOrders = 0; //---- Обнуляем счётчик серии bi_curOrdersInSeries = 0; //---- На этом баре больше не входим bdt_NewBar = bdt_BeginNewBar; return (0); } //---- Организовываем управление открытыми ордерами if (bi_MyOrders > 0) { //---- Организуем закрытие ордеров по показаниям индикаторов if (!bb_TSProfit) { //---- Организуем закрытие ордеров по показаниям индикаторов if (fClose_Control()) return (0); //---- Организуем работу виртуальных СТОПов и трейлинга ордеров else fControl_Positions(); } } else bi_cntTrades = 0; //---- Следим за рынком на начале открытия бара TF_Indicators if (bdt_NewBar != bdt_BeginNewBar) { //---- Заносим в массив текущие цены RefreshRates(); for (int li_IND = 0; li_IND < 2; li_IND++) {bda_Price[li_IND] = fGet_TradePrice (li_IND, bb_RealTrade, bs_Symbol);} //---- Получаем сигналы от индикаторов int li_Send = fSend_Control (bi_TREND); //----Строим сеть ордеров fControl_NET (MagicNumber, gia_HistoryOrders[2], bd_BaseBalance, bd_ProfitCUR, Order_Lots, bd_LotsMM, EXP_Comment, li_Send, bb_IsOpenOrders, SendOnlyOrders, Slippage); bdt_NewBar = bdt_BeginNewBar; } //---- Контролируем возможные ошибки fGet_LastErrorInArray (bsa_Comment, "start()", bi_indERR); //---- return (0); } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Автор : TarasBY, taras_bulba@tut.by | //+-----------------------------------------------------------------------------------+ //| Закрываемся по показаниям индикаторов | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ bool fClose_Control() { //---- int li_SignalClose; if (fGet_SignalClose (bs_Symbol, TF_Indicators, Use_close_IND, li_SignalClose, SignalCloseOnBar, VerificationCloseBars)) { if (gia_MyOrders[li_SignalClose] > 0) { double ld_Pribul; if (fClose_AllOrders (bs_Symbol, MagicNumber, ld_Pribul, li_SignalClose, NBars_LifeMIN, TF_Indicators) > 0) {fWrite_Log (StringConcatenate ("Закрылись по сигналу индикатора. Результат = ", bs_sign, DSDig (ld_Pribul)), 4); return (true);} } } //---- return (false); } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Автор : TarasBY, taras_bulba@tut.by | //+-----------------------------------------------------------------------------------+ //| Деинициализируем советник | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ void fMineDeInit() { //---- if (!bb_RealTrade) GlobalVariablesDeleteAll (bs_NameGV); //---- В тестере (при оптимизации) дальнейшие действия не нужны if (bb_VirtualTrade) return (0); //---- Подчищаем после себя график if (ClearALLAfterTrade) { Comment (""); //---- Удаляем графические объекты с чарта fObjectsDeleteAll (bs_NameGV, -1, -1); //---- Удаляем GV-переменные GlobalVariablesDeleteAll (bs_NameGV); } else { if (ShowCommentInChart) { //---- Подсчитываем итоги работы fGet_Statistic (-1); //---- Рисуем на графике комменты fCommentInChart (bsa_Comment, fGet_StringManagerPA()); } } //---- Удаляем предупредительные надписи for (int li_IND = 0; li_IND < 3; li_IND++) {if (ObjectFind ("STOP" + li_IND) == 0) ObjectDelete ("STOP" + li_IND);} //---- "Передышка" Sleep (500); //---- } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Автор : TarasBY, taras_bulba@tut.by | //+-----------------------------------------------------------------------------------+ // Проверяем переданные в советник внешние параметры. | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ bool fCheck_ExternParameters() { //---- bs_ERROR = ""; //---- Проверяем разрешение советнику на торговлю if (!IsTesting() && !IsOptimization()) {if (!IsExpertEnabled()) {return (false);}} //---- Проверяем корректность введённых данных if (!fCheck_ExternParametersSAR()) {return (false);} //---- Создаём префикс GV-переменных советника bs_NameGV = StringConcatenate ("SAR[", MagicNumber, "]"); if (NewBarInPeriod == 0) {NewBarInPeriod = Period();} if (TF_Indicators == 0) {TF_Indicators = Period();} if (IsOptimization()) {if (DeleteBallastOrders == 1) USE_Dinamic_TP = True;} else {if (DeleteBallastOrders == 1) if (!USE_Dinamic_TP) {bs_ERROR = "Поставьте USE_Dinamic_TP = True или DeleteBallastOrders != 1!!!"; return (false);}} //---- Принудительно заполняем имя советника для комментариев ордеров if (EXP_Comment == "") EXP_Comment = StringSubstr (WindowExpertName(), StringFind (WindowExpertName(), "@") + 1); gb_VirtSTOPs = USE_VirtualSTOPs || VirtualTrail_ON; //---- Сразу после инициализации не открываемся bdt_NewBar = iTime (Symbol(), TF_Indicators, 0); //---- return (true); } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //+===================================================================================+ //|***********************************************************************************| //| РАЗДЕЛ: Работы с ордерами | //|***********************************************************************************| //+===================================================================================+ //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Автор : TarasBY, taras_bulba@tut.by | //+-----------------------------------------------------------------------------------+ //| Проверяем наличие "своих" открытых позиций | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ int fMyPositions (double& fd_Profit, // возвращаемые текущие результаты трейдинга int& ar_MyOrders[], // возвращаемый счётчик "своих" ордеров int fi_Magic = -1) // Magic { int li_total = OrdersTotal(), li_ord = 0; //---- //---- Обнуляем рабочие переменные fd_Profit = 0.0; ArrayInitialize (ar_MyOrders, 0); ArrayInitialize (gda_Lots, 0); if (li_total == 0) {return (0);} for (int li_pos = li_total - 1; li_pos >= 0; li_pos--) { if (!OrderSelect (li_pos, SELECT_BY_POS, MODE_TRADES)) continue; if (OrderSymbol() != bs_Symbol) continue; if (OrderMagicNumber() != fi_Magic) {if (fi_Magic >= 0) continue;} if (OrderType() > 1) continue; //---- Подсчитываем суммарный Profit открытых позиций fd_Profit += (OrderProfit() + OrderSwap() + OrderCommission()); //---- Подсчитываем ордера по их типу (BUY/SELL) ar_MyOrders[OrderType()]++; //---- Подсчитываем суммарное количество открытых позиций li_ord++; //---- Подсчитываем суммарный лот открытых позиций gda_Lots[OrderType()] += OrderLots(); } //---- return (li_ord); } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Автор : TarasBY, taras_bulba@tut.by | //+-----------------------------------------------------------------------------------+ //| Управляем "своими" открытыми позициями | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ void fControl_Positions() { int li_Ticket, li_LifeBar, err = GetLastError(); double ld_Profit; bool lb_NewBar = false; static datetime ldt_NewBar = 0; datetime ldt_BeginBar = iTime (NULL, TF_STOPs, 0); //---- if (ldt_NewBar != ldt_BeginBar) lb_NewBar = true; for (int i = OrdersTotal() - 1; i >= 0; i--) { if (!OrderSelect (i, SELECT_BY_POS, MODE_TRADES)) continue; if (OrderSymbol() != bs_Symbol) continue; if (OrderMagicNumber() != MagicNumber) if (MagicNumber >= 0) continue; if (OrderType() > 1) continue; li_Ticket = OrderTicket(); //---- Определяем "жизнь" ордера в TF_Indicators барах li_LifeBar = iBarShift (Symbol(), TF_Indicators, OrderOpenTime()); //---- Получаем актуальные данные по символу fGet_MarketInfo (bs_Symbol); //---- Организуем закрытие по МАКС жизни ордера if (fControl_MAXLife (li_LifeBar, NBars_LifeMAX)) continue; //---- Модифицируем 1-ый ордер и самый последний в серии, или все, если удаляем балластные ордера if (!DeleteBallastOrders) if (bi_curOrdersInSeries != 1) {if (bi_curOrdersInSeries != Max_trades + bi_cntTrades) continue;} //---- Организуем работу виртуальных стопов if (Virtual_Order_SL != 0 || Virtual_Order_TP != 0 || USE_VirtualSTOPs) { //---- Контролируем "жизнь" ордера if ((NBars_LifeMIN > 0 && NBars_LifeMIN < li_LifeBar) || NBars_LifeMIN == 0) {if (fVirtualSTOPs (li_Ticket, Virtual_Order_SL, Virtual_Order_TP, Slippage)) continue;} } //---- Производим установку СТОПов if (lb_NewBar || !GlobalVariableCheck (StringConcatenate (li_Ticket, "_#STOP"))) {if (fCreat_STOPs (N_STOPs, li_Ticket, bda_Price[OrderType()], TF_STOPs, USE_VirtualSTOPs, (bi_curOrdersInSeries != Max_trades + bi_cntTrades))) continue;} //---- Удаляем балластные ордера if (DeleteBallastOrders == 1) if (fDelete_BallastOrders (li_Ticket, Slippage, gb_VirtSTOPs, bi_MyOrders > 1)) {bi_MyOrders--; continue;} //---- Тралим выбранную позицию fTrail_Position (li_Ticket, Slippage); } if (lb_NewBar) ldt_NewBar = ldt_BeginBar; //---- Контролируем возможные ошибки fGet_LastErrorInArray (bsa_Comment, "fControl_Positions()", bi_indERR); //---- return; } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //+===================================================================================+ //|***********************************************************************************| //| РАЗДЕЛ: Сервисных функций | //|***********************************************************************************| //+===================================================================================+ //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Автор : TarasBY, taras_bulba@tut.by | //+-----------------------------------------------------------------------------------+ //| Выводим информацию на чарт | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ void fCommentInChart (string& ar_Comment[], // массив с комментариями string fs_ManagerPA = "") // строка со статистикой от библиотеки управления общим профитом { static string lsa_Time[], lsa_Comment[], ls_BeginTrade, ls_Conditions, ls_SendOrders = "BUY&SELL", ls_row = "—————————————————————————————————\n", ls_PSI = "————————————• PSI©TarasBY •————————————\n"; static bool lb_first = true; static int li_size, li_size_CommTime, li_Period = 60; string ls_CTRL = "", ls_BLOCK_Comment, ls_Comment = "", ls_TermsTrade, ls_Error = "", ls_time = "", ls_sign; //---- //---- При первом запуске формируем рабочие массивы if (lb_first) { li_Period *= NewBarInPeriod; li_size = ArraySize (ar_Comment); ArrayResize (lsa_Time, li_size); ArrayResize (lsa_Comment, li_size); InitializeArray_STR (lsa_Comment, ""); InitializeArray_STR (lsa_Time, ""); if (SendOnlyOrders == 0) ls_SendOrders = "BUY"; else if (SendOnlyOrders == 1) ls_SendOrders = "SELL"; ls_BeginTrade = StringConcatenate ("Terms Trade :: Begin - ", TimeToStr (bdt_BeginTrade)); ls_Conditions = StringConcatenate ("NewBarInPeriod - ", fGet_NameTF (NewBarInPeriod), " | TF Indicators - ", fGet_NameTF (TF_Indicators), " | TF STOPs - ", fGet_NameTF (TF_STOPs), "\niMax trades - ", Max_trades, " | SendOnlyOrders - ", ls_SendOrders, "\n"); bdt_NewBar = iTime (Symbol(), TF_Indicators, 1); bdt_NewBarInPeriod = iTime (Symbol(), NewBarInPeriod, 0); lb_first = false; } //---- БЛОК КОММЕНТАРИЕВ for (int li_MSG = 0; li_MSG < li_size; li_MSG++) { //---- Запоминаем время последнего сообщения if (StringLen (ar_Comment[li_MSG]) > 0) { if (ar_Comment[li_MSG] != lsa_Comment[li_MSG]) {lsa_Comment[li_MSG] = ar_Comment[li_MSG];} if (li_MSG == li_size - 1) {ls_sign = "";} else {ls_sign = " : ";} lsa_Time[li_MSG] = StringConcatenate (TimeToStr (bdt_curTime), ls_sign); ar_Comment[li_MSG] = ""; } //---- Формируем блок комментариев if (li_MSG < li_size - 1) {if (StringLen (lsa_Comment[li_MSG]) > 0) {ls_Comment = StringConcatenate (ls_Comment, lsa_Time[li_MSG], lsa_Comment[li_MSG], "\n");}} //---- Формируем блок ошибок else if (li_MSG == li_size - 1) { //---- Спустя 2 часа упоминание об ошибке убираем if (bdt_curTime > StrToTime (lsa_Time[li_MSG]) + 7200) {lsa_Comment[li_MSG] = "";} if (StringLen (lsa_Comment[li_MSG]) > 0) {ls_Error = StringConcatenate (ls_row, "ERROR: ", lsa_Time[li_MSG], "\n", lsa_Comment[li_MSG]);} } } //---- Строка контроля за временем работы советника ls_time = StringConcatenate ("\nTime :: cur ", TimeToStr (bdt_curTime, TIME_DATE|TIME_SECONDS), " | local ", TimeToStr (TimeLocal(), TIME_MINUTES|TIME_SECONDS)); if (NewBarInPeriod > 0) {ls_time = StringConcatenate (TimeToStr (bdt_NewBarInPeriod + li_Period), " | ", TimeToStr (bdt_NewBar + TF_Indicators * 60), ls_time);} ls_TermsTrade = StringConcatenate (ls_BeginTrade, " | Last - ", TimeToStr (bdt_LastTrade), "\n"); //---- Формируем ВСЕ блоки комментариев ls_BLOCK_Comment = StringConcatenate (bs_ExpertName, "\n", ls_row, gs_Info, ls_time, "\n", ls_TermsTrade, ls_Conditions, ls_row, //---- Блок результатов работы " PROFIT = ", bs_sign, " ", fSplitField (DoubleToStr (bd_ProfitCUR, 1)), " | ", DoubleToStr (bd_ProfitPercent - 100.0, 1), " % [ ", bi_MyOrders, " | ", gia_MyOrders[0], " / ", gia_MyOrders[1], " ]\n", //---- Блок работы с общим профитом fs_ManagerPA, " RESULT = ", bs_sign, " ", fSplitField (DoubleToStr (bd_Pribul, 1)), " [ ", fSplitField (gia_HistoryOrders[2]), " | ", fSplitField (gia_HistoryOrders[0]), " / ", fSplitField (gia_HistoryOrders[1]), " ]\n", ls_PSI, //---- Блок комментариев ls_Comment, //---- Отображаем ошибки ls_Error);//, //---- Выводим на чарт сформированный блок комментариев Comment (ls_BLOCK_Comment); //---- } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Автор : TarasBY, taras_bulba@tut.by | //+-----------------------------------------------------------------------------------+ //| Собираем статистику | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ void fGet_Statistic (int fi_Period = 0, // Минимальный период (TF) на котором собираем статистику bool fb_IsTimeGMT = false) // Какое время учитываем { static datetime ldt_NewBar = 0; static int li_PreHistOrders = 0; int li_ORD, err = GetLastError(), li_Period = MathMax (0, fi_Period); datetime ldt_NewPeriod = iTime (bs_Symbol, li_Period, 0); //---- //---- Фиксируем время в "настоящий момент" bdt_curTime = TimeCurrent(); bd_Balance = AccountBalance(); bd_Equity = AccountEquity(); bd_FreeMargin = AccountFreeMargin(); bd_Margin = AccountMargin(); if (li_PreHistOrders != OrdersHistoryTotal() || ldt_NewBar != ldt_NewPeriod || fi_Period < 0) { li_PreHistOrders = OrdersHistoryTotal(); ldt_NewBar = ldt_NewPeriod; //---- Подсчитываем итоги работы bd_Pribul = fCalculate_Pribul (gia_HistoryOrders, bs_Symbol, MagicNumber); } //---- Получаем текущие значения переменных для отображения на графике fCheckInfo(); //---- Контролируем возможные ошибки fGet_LastErrorInArray (bsa_Comment, "fGet_Statistic()", bi_indERR); //---- } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Автор : TarasBY, taras_bulba@tut.by | //+-----------------------------------------------------------------------------------+ //| Создаём информацию для отображения настроек на графике | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ void fCheckInfo() { static double ld_preLot = 0.0; //---- if (ShowCommentInChart) { if (ld_preLot != bd_LotsMM) { string ls_Trail = "", ls_MM, ls_addConditions; ls_MM = IIFs (UseMM, StringConcatenate ("MM (", DSDig (bd_LotsMM), ")", fGet_MeansType (MeansType, LotsPercent)), "L: " + DSDig (bd_LotsMM)); ls_addConditions = StringConcatenate (IIFs ((StringLen (ls_Trail) > 0), ls_Trail, ""), IIFs ((StringLen (ls_MM) > 0), " - ", ""), IIFs ((StringLen (ls_MM) > 0), ls_MM, "")); //---- Убираем " - " из начала строки (если есть) ls_addConditions = IIFs ((StringFind (ls_addConditions, " - ") == 0), StringSubstr (ls_addConditions, 3), ls_addConditions); //---- Формируем информационную строку gs_Info = StringConcatenate (bs_NameGV, ": STOP`s", " [ ", StopLoss, "/", TakeProfit, " | ", Virtual_Order_SL, "/", Virtual_Order_TP, " ]", "\n", IIFs ((StringLen (ls_addConditions) > 0), StringConcatenate (ls_addConditions, "\n"), ""), "Lots: MIN = ", DSDig (bd_MINLOT), " | MAX = ", DSDig (bd_MAXLOT), " | STEP = ", bd_LOTSTEP, "\n", IIFs ((NewBarInPeriod < 0), "Работаем на каждом тике", "ПАУЗА до: ")); ld_preLot = bd_LotsMM; } } //---- } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //+===================================================================================+ //|***********************************************************************************| //| РАЗДЕЛ: TESTER | //|***********************************************************************************| //+===================================================================================+ //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Автор : TarasBY, taras_bulba@tut.by | //+-----------------------------------------------------------------------------------+ //| Для ускорения оптимизации убираем "пустые" варианты | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ bool fSet_Continue() { static bool lb_Continue = true; //---- if (!bb_RealTrade) { //---- Следим за наличием истории (котировок) if (NewBarInPeriod >= 0) if (iTime (bs_Symbol, NewBarInPeriod, 0) == 0) {fPrintAlert (bs_Symbol, NewBarInPeriod, 0); return (true);} if (iTime (bs_Symbol, TF_Indicators, 0) == 0) {fPrintAlert (bs_Symbol, TF_Indicators, 1); return (true);} } //---- Проверку параметров производим один раз if (!lb_Continue) return (false); if (IsOptimization()) { if (bb_OptimContinue) return (true); if (fGet_NumPeriods (TF_Indicators) < 0) {bb_OptimContinue = true; return (true);} if (fGet_NumPeriods (NewBarInPeriod) < 0) {bb_OptimContinue = true; return (true);} //---- Переменные трейлинга if (TrailStairs_ON) { if (Virtual_Order_TP > 0.0) {if (TrailingStop >= Virtual_Order_TP) {bb_OptimContinue = true; return (true);}} else { if (!USE_VirtualSTOPs) if (N_STOPs == 0) {if (TrailingStop >= TakeProfit) {bb_OptimContinue = true; return (true);}} } } if (BreakEven > 0.0) { if (Virtual_Order_TP > 0.0) {if (BreakEven >= Virtual_Order_TP) {bb_OptimContinue = true; return (true);}} else { if (!USE_VirtualSTOPs) if (N_STOPs == 0) {if (BreakEven >= TakeProfit) {bb_OptimContinue = true; return (true);}} } } //---- Переменные NET if (fSet_ContinueNET()) {bb_OptimContinue = true; return (true);} //---- Переменные индикаторов if (fSet_ContinueSARComplete()) {bb_OptimContinue = true; return (true);} //---- Спорное утверждение //if (TF_STOPs < TF_Indicators) {bb_OptimContinue = true; return (true);} } else {if (fSTOPTRADE()) return (true);} lb_Continue = false; //---- return (false); } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+