//+-----------------------------------------------------------------------------------+ //| TREND_alexcud.mq4 | //| Copyright © 2007-2011, Aleksander Kudimov & TarasBY | //| alexcud@rambler.ru | //+-----------------------------------------------------------------------------------+ #property copyright "Copyright © 2007-2011, Aleksander Kudimov & TarasBY" #property link "alexcud@rambler.ru" //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ #property indicator_separate_window #property indicator_minimum 0 #property indicator_maximum 3 #property indicator_buffers 8 #property indicator_color1 DeepSkyBlue #property indicator_width1 3 #property indicator_color2 Red #property indicator_width2 3 #property indicator_color3 DarkBlue #property indicator_width3 3 #property indicator_color4 FireBrick #property indicator_width4 3 #property indicator_color5 Yellow #property indicator_width5 3 #property indicator_color6 Gold #property indicator_width6 1 #property indicator_color7 Green #property indicator_width7 1 #property indicator_level1 0.0 #property indicator_level2 0.5 #property indicator_level3 0.75 #property indicator_level4 1.0 #property indicator_levelcolor RoyalBlue //IIIIIIIIIIIIIIIIIII==================CONSTANS=================IIIIIIIIIIIIIIIIIIIIII+ #define Send_BUY 0 #define Send_SELL 1 #define Send_BUY_PLUS 2 #define Send_SELL_PLUS 3 #define STOP 4 //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| ***** Параметры индикатора ***** | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ extern string MA_TrendPeriod = "5,12,25,50,75";//"5,8,13,21,34"; extern string List_TF = "15,60,240"; extern bool Use_AveragingOUT = True; // Усреднение показаний индикаторов по всем периодам extern bool CreatArrowOnChart = True; extern bool RedrawArrow = False; // Перерисовывание стрелок на одном баре при изменении сигнала extern bool SoundAlert = False; extern bool VisualAlert = False; //IIIIIIIIIIIIIIIIIII=============Буферы индикатора=============IIIIIIIIIIIIIIIIIIIIII+ double UP_Buffer[], DW_Buffer[], FL_Buffer[], SUP_Buffer[], SDW_Buffer[], SUM0_Buffer[], SUM1_Buffer[], SIG_Buffer[]; //IIIIIIIIIIIIIIIIIII======Глобальные переменные индикатора=====IIIIIIIIIIIIIIIIIIIIII+ double gd_Itog_U[3], gd_Itog_D[3], gd_Price; string short_name = "TREND_alexcud", IND_Name, gs_Signal[5] = {"BY","SELL","BY+","SELL+","STOP"}, gs_Lable[7] = {"MA","AC","rez","TF","TF1_","TF2_","TF3_"}, gs_Font_0[3] = {"Arial Black","Arial","Arial"}, gs_Font_1[3] = {"Arial","Arial Black","Arial"}; color gc_color[3][5], gc_col_st[3] = {Red,Blue,Green}; int gi_AC_U[3], gi_AC_D[3], gi_MA_TrendPeriod[5], gi_TF[3], gi_Window, cnt_TF, N_Bars, Last_arrow, Last_Signal = -1, General_Signal, cnt_PRD, gi_Vol_U[3] = {0,1,0}, gi_Vol_D[] = {1,0,0}, gi_Arrow[3] = {218,217,91}; bool lb_first = true; datetime gi_newBar_M1, gi_newBar, NOT_Connect, gi_Time, Time_lastSignal, Time_lastArrow = 0; //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Custom indicator initialization function | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ int init() { int li_minTF; cnt_PRD = MathMin (5, StringToArrayINT (MA_TrendPeriod, gi_MA_TrendPeriod, ",")); cnt_TF = MathMin (3, fCreatArray_TF (List_TF, gi_TF)); //---- name for indicator window IND_Name = short_name + " ("; for (int li_int = 0; li_int < cnt_PRD; li_int++) {IND_Name = StringConcatenate (IND_Name, gi_MA_TrendPeriod[li_int], IIFs ((li_int == cnt_PRD - 1), ")", ","));} IndicatorShortName (IND_Name); gi_Window = WindowFind (IND_Name); IndicatorBuffers (8); SetIndexBuffer (0, UP_Buffer); SetIndexStyle (0, DRAW_HISTOGRAM); SetIndexLabel (0, "UP"); SetIndexBuffer (1, DW_Buffer); SetIndexStyle (1, DRAW_HISTOGRAM); SetIndexLabel (1, "DW"); SetIndexBuffer (2, SUP_Buffer); SetIndexStyle (2, DRAW_HISTOGRAM); SetIndexLabel (2, "SUP"); SetIndexBuffer (3, SDW_Buffer); SetIndexStyle (3, DRAW_HISTOGRAM); SetIndexLabel (3, "SDW"); SetIndexBuffer (4, FL_Buffer); SetIndexStyle (4, DRAW_HISTOGRAM); SetIndexLabel (4, "FL"); SetIndexBuffer (5, SUM0_Buffer); SetIndexStyle (5, DRAW_LINE); SetIndexLabel (5, "SUM 0"); SetIndexBuffer (6, SUM1_Buffer); SetIndexStyle (6, DRAW_LINE); SetIndexLabel (6, "SUM 1"); SetIndexBuffer (7, SIG_Buffer); SetIndexStyle (7, DRAW_NONE); SetIndexLabel (7, "SIGNAL"); SetIndexEmptyValue (0, 0.0); SetIndexEmptyValue (1, 0.0); SetIndexEmptyValue (2, 0.0); SetIndexEmptyValue (3, 0.0); SetIndexEmptyValue (4, 0.0); SetIndexEmptyValue (5, 0.0); SetIndexEmptyValue (6, 0.0); SetIndexEmptyValue (7, -1.0); IndicatorDigits (2); fCreatTable(); li_minTF = MathMin (Period(), gi_TF[0]); N_Bars = iBars (Symbol(), li_minTF); gi_Time = iTime (Symbol(), li_minTF, N_Bars); N_Bars = iBarShift (Symbol(), 0, gi_Time); NOT_Connect = TimeCurrent(); lb_first = true; //---- return (0); } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Custor indicator deinitialization function | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ int deinit() { //---- ObjectsDeleteAll (gi_Window); ObjectsDeleteAll (0, OBJ_ARROW); lb_first = true; //---- return (0); } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Custom indicator iteration function | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ int start() { int li_Bar, li_MA, li_PRD, li_result, li_pos, li_arrow, li_Total; int li_SIG, nLimit, li_int, nCountedBars; static int cnt_TimeOnBar = 0; string ls_txt, ls_Name; double ld_MA[2], ld_AC[4], ld_Price, ld_Itog_U, ld_Itog_D; color lc_ColorArrow; bool s_Alert, v_Alert, lb_ITOG[4], HaveSell = false, HaveBuy = false; //---- //---- Просчёт индикатора производим один раз в начале M1 периода if (gi_newBar_M1 == iTime (Symbol(), PERIOD_M1, 0)) {return (0);} gi_newBar_M1 = iTime (Symbol(), PERIOD_M1, 0); //---- Определяем количество просчитываемых баров if (lb_first) {nLimit = N_Bars;} else {nLimit = fRecalculateHistoryBars();} if (nLimit < 0) {return (0);} if (nLimit == 0) { if (cnt_TimeOnBar == Period()) { nLimit = 1; cnt_TimeOnBar = 0; } } //---- main loop for (li_Bar = nLimit; li_Bar >= 0; li_Bar--) { //---- Обнуляем буфера на просчитываемом баре UP_Buffer[li_Bar] = 0.0; SUP_Buffer[li_Bar] = 0.0; DW_Buffer[li_Bar] = 0.0; SDW_Buffer[li_Bar] = 0.0; FL_Buffer[li_Bar] = 0.0; SUM0_Buffer[li_Bar] = 0.0; SUM1_Buffer[li_Bar] = 0.0; SIG_Buffer[li_Bar] = -1.0; ld_Itog_U = 0.0; ld_Itog_D = 0.0; //---- Обнуляем массивы ArrayInitialize (gd_Itog_U, 0); ArrayInitialize (gd_Itog_D, 0); //---- Определяем время открытия просчитываемого бара gi_Time = iTime (Symbol(), 0, li_Bar); for (li_PRD = 0; li_PRD < 3; li_PRD++) { //---- Определяем номер бара на соответствующем периоде в заданное время N_Bars = iBarShift (Symbol(), gi_TF[li_PRD], gi_Time); //---- Расчитываем показания MA на заданных периодах for (li_MA = 0; li_MA < cnt_PRD; li_MA++) { ld_MA[0] = iMA (NULL, gi_TF[li_PRD], gi_MA_TrendPeriod[li_MA], 0, MODE_SMA, PRICE_CLOSE, N_Bars); ld_MA[1] = iMA (NULL, gi_TF[li_PRD], gi_MA_TrendPeriod[li_MA], 0, MODE_SMA, PRICE_CLOSE, N_Bars + 1); li_result = IIFi ((ld_MA[0] < ld_MA[1]), 0, IIFi ((ld_MA[0] > ld_MA[1]), 1, 0)); if (li_Bar == 0) {ObjectSetText (gs_Lable[li_PRD+4] + (li_MA + 1), CharToStr (gi_Arrow[li_result]) , 13, "Wingdings", gc_col_st[li_result]);} //---- Подсчитываем суммарный итог gd_Itog_U[li_PRD] += gi_Vol_U[li_result]; gd_Itog_D[li_PRD] += gi_Vol_D[li_result]; } } //---- Расчитываем показания AC по 4-рём последним барам for (li_PRD = 0; li_PRD < 3; li_PRD++) { for (li_pos = 0; li_pos < 4; li_pos++) {ld_AC[li_pos] = iAC (NULL, gi_TF[li_PRD], N_Bars + li_pos);} if ((ld_AC[1] < ld_AC[2] && ld_AC[2] < ld_AC[3] && ld_AC[0] > 0 && ld_AC[0] < ld_AC[1]) || (ld_AC[0] < ld_AC[1] && ld_AC[1] < ld_AC[2] && ld_AC[0] < 0)) {li_result = 0;} if ((ld_AC[1] > ld_AC[2] && ld_AC[2] > ld_AC[3] && ld_AC[0] < 0 && ld_AC[0] > ld_AC[1]) || (ld_AC[0] > ld_AC[1] && ld_AC[1] > ld_AC[2] && ld_AC[0] > 0)) {li_result = 1;} if ((((ld_AC[1] < ld_AC[2] || ld_AC[2] < ld_AC[3]) && ld_AC[0] < 0 && ld_AC[0] > ld_AC[1]) || (ld_AC[0] > ld_AC[1] && ld_AC[1] < ld_AC[2] && ld_AC[0] > 0)) || (((ld_AC[1] > ld_AC[2] || ld_AC[2] > ld_AC[3]) && ld_AC[0] > 0 && ld_AC[0] < ld_AC[1]) || (ld_AC[0] < ld_AC[1] && ld_AC[1] > ld_AC[2] && ld_AC[0] < 0))) {li_result = 2;} gi_AC_U[li_PRD] = IIFi ((gi_Vol_U[li_result] == 1), 3, 0); gi_AC_D[li_PRD] = IIFi ((gi_Vol_D[li_result] == 1), 3, 0); //---- На текщем баре выводим актуальную информацию на график if (li_Bar == 0) { ls_Name = "AC1" + (li_PRD + 1); SetLabel (ls_Name, CharToStr (gi_Arrow[li_result]), 210, 32 + (20 * li_PRD), 13, "Wingdings", 0, gi_Window, gc_col_st[li_result]); } //---- Подсчитываем суммарный итог gd_Itog_U[li_PRD] += gi_AC_U[li_PRD]; gd_Itog_D[li_PRD] += gi_AC_D[li_PRD]; gd_Itog_U[li_PRD] *= 12.5; gd_Itog_D[li_PRD] *= 12.5; ld_Itog_U += gd_Itog_U[li_PRD]; ld_Itog_D += gd_Itog_D[li_PRD]; } ld_Itog_U /= 3; ld_Itog_D /= 3; SUM0_Buffer[li_Bar] = ld_Itog_U / 100; SUM1_Buffer[li_Bar] = ld_Itog_D / 100; //---- На текщем баре выводим актуальную информацию на график if (li_Bar == 0) { for (li_PRD = 0; li_PRD < 3; li_PRD++) { li_result = IIFi ((gd_Itog_U[li_PRD] > gd_Itog_D[li_PRD]), 0, IIFi ((gd_Itog_U[li_PRD] < gd_Itog_D[li_PRD]), 1, 2)); ls_Name = "uitog" + (li_PRD + 1); SetLabel (ls_Name + "_A", CharToStr (225), 245, 30 + (20 * li_PRD), 13, "Wingdings", 0, gi_Window, Blue); SetLabel (ls_Name, StringConcatenate (" ", gd_Itog_U[li_PRD], "%"), 245, 30 + (20 * li_PRD), 11, gs_Font_0[li_result], 0, gi_Window, Blue); ls_Name = "ditog" + (li_PRD + 1); SetLabel (ls_Name + "_A", CharToStr (226), 320, 30 + (20 * li_PRD), 13, "Wingdings", 0, gi_Window, Red); SetLabel (ls_Name, StringConcatenate (" ", gd_Itog_D[li_PRD], "%"), 320, 30 + (20 * li_PRD), 11, gs_Font_1[li_result], 0, gi_Window, Red); } //---- li_Total = OrdersTotal(); //---- Обрабатываем открытые ордера for (li_int = li_Total - 1; li_int >= 0; li_int--) { if (!OrderSelect (li_int, SELECT_BY_POS, MODE_TRADES)) {continue;} //---- только "активные" if (Symbol() != OrderSymbol()) {continue;} //---- только "активные" if (OrderType() == OP_BUY) {HaveBuy = True;} if (OrderType() == OP_SELL) {HaveSell = True;} } } //---- Логика сообщений звук и видео такая: открываем по Удачному, закрываем по первому подходящему сигналу, а далее решайте сами ;) li_arrow = 0; lc_ColorArrow = Black; li_SIG = -1; //---- Подводим итоги наших расчётов ArrayInitialize (lb_ITOG, False); if (Use_AveragingOUT) { lb_ITOG[0] = ld_Itog_U > 50; lb_ITOG[1] = ld_Itog_U > 75; lb_ITOG[2] = ld_Itog_D > 50; lb_ITOG[3] = ld_Itog_D > 75; } else { lb_ITOG[0] = gd_Itog_U[0] > 50 && gd_Itog_U[1] > 50 && gd_Itog_U[2] > 50; lb_ITOG[1] = gd_Itog_U[0] >= 75 && gd_Itog_U[1] >= 75 && gd_Itog_U[2] >= 75; lb_ITOG[2] = gd_Itog_D[0] > 50 && gd_Itog_D[1] > 50 && gd_Itog_D[2] > 50; lb_ITOG[3] = gd_Itog_D[0] >= 75 && gd_Itog_D[1] >= 75 && gd_Itog_D[2] >= 75; } if (lb_ITOG[0]) { ls_txt = "Не плохой момент для открытия позиции BUY"; if (HaveSell) {s_Alert = true; v_Alert = true;} li_SIG = 0; if (lb_ITOG[1]) { ls_txt = "УДАЧНЫЙ момент для открытия позиции BUY"; s_Alert = true; if (HaveSell) {v_Alert = true;} li_SIG = 2; } } else { ls_txt = "Не рекомендуется открывать позиции. ЖДИТЕ."; li_SIG = 4; } if (lb_ITOG[2]) { ls_txt = "Не плохой момент для открытия позиции SELL"; if (HaveBuy) {s_Alert = true; v_Alert = true;} li_SIG = 1; if (lb_ITOG[3]) { ls_txt = "УДАЧНЫЙ момент для открытия позиции SELL"; s_Alert = true; if (HaveBuy) {v_Alert = true;} li_SIG = 3; } } /*else { ls_txt = "Не рекомендуется открывать позиции. ЖДИТЕ."; li_SIG = 4; }*/ //---- if (li_SIG == -1) {li_SIG = 5;} if (li_Bar == 0) {li_SIG = fCurrentSignal (li_SIG);} //---- В конце текущего бара запоминаем его итог if (cnt_TimeOnBar == Period()) { General_Signal = li_SIG; Print (Symbol(), ": Текущий сигнал (", TS_DS (TimeCurrent()), ") ", li_SIG, " на отметке ", Bid); } //---- В начале 0-го бара подводим итог прошедшему бару if (gi_newBar != iTime (Symbol(), Period(), 0) && li_Bar == 1) {li_SIG = General_Signal;} switch (li_SIG) { case 0: UP_Buffer[li_Bar] = 1; lc_ColorArrow = indicator_color1; li_arrow = IIFi (HaveSell, 236, 228); break; case 1: DW_Buffer[li_Bar] = 1; lc_ColorArrow = indicator_color2; li_arrow = IIFi (HaveBuy, 238, 230); break; case 2: SUP_Buffer[li_Bar] = 1; lc_ColorArrow = indicator_color3; li_arrow = IIFi (HaveSell, 233, 225); break; case 3: SDW_Buffer[li_Bar] = 1; lc_ColorArrow = indicator_color4; li_arrow = IIFi (HaveBuy, 234, 226); break; case 4: FL_Buffer[li_Bar] = 1; lc_ColorArrow = indicator_color5; li_arrow = 251; break; } //---- Вносим значение для сигнального буфера SIG_Buffer[] SIG_Buffer[li_Bar] = li_SIG; //---- На текщем баре выводим актуальную информацию if (li_Bar == 0) { SetLabel ("txt", ls_txt, 420, 50, 14, "Verdana", 0, gi_Window, Lime); //---- Если разрешены сигналы - выводим их на "свет" один раз втечение бара if (gi_newBar != iTime (Symbol(), Period(), 0)) { if (SoundAlert && s_Alert) {PlaySound ("alert.wav");} if (VisualAlert && v_Alert) {Alert (Symbol(), ": Не пора бы зафиксировать прибыль по открытым позициям?");} gi_newBar = iTime (Symbol(), Period(), 0); } } //---- Обновляем актуальную информацию и рисуем на графике стрелочки (если разрешено) fUpdateActualInformation (li_SIG, li_arrow, li_Bar, lc_ColorArrow); } //---- lb_first = false; cnt_TimeOnBar++; NOT_Connect = 0; //---- return (0); } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Расчитываем значение сигнала на последнем баре | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ int fCurrentSignal (int iSignal) { int li_int, сnt = -1, li_result = -1; static int cnt_Time[6]; //---- for (li_int = 0; li_int < 6; li_int++) { if (iSignal == li_int) {cnt_Time[li_int]++;} if (сnt <= cnt_Time[li_int] || (сnt == cnt_Time[li_int] && iSignal == li_int)) { li_result = li_int; сnt = cnt_Time[li_int]; } } //---- return (li_result); } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Следим за наличием связи с сервером и количеством не просчитанных баров | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ int fRecalculateHistoryBars() { int li_result = 0; static int li_CountedBars = 0; //---- if (NOT_Connect != TimeCurrent()) { if (NOT_Connect - TimeCurrent() > Period() * 60) { NOT_Connect = TimeCurrent(); li_result = iBarShift (Symbol(), 0, NOT_Connect) - iBarShift (Symbol(), 0, TimeCurrent()); } if (li_CountedBars != IndicatorCounted()) { li_result = MathMax (li_result, IndicatorCounted() - li_CountedBars); li_CountedBars = IndicatorCounted(); } } //---- return (li_result); } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Рисуем на графике стрелочки | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ void fUpdateActualInformation (int cur_Signal, int arrow, int iBar, color ArColor) { int li_K; string ls_price, ls_Name; static int cnt_Arrow = 0; bool lb_ChangeSignal = false; //---- //---- Проверяем изменение сигнала с момента последнего расчёта if (Last_Signal != cur_Signal) {lb_ChangeSignal = true;} if (iBarShift (Symbol(), 0, Time_lastArrow) - iBar >= 3 //---- Одинаковые стрелки выставляем не чаще раз за три бара || lb_ChangeSignal) //---- Сигнал изменился { ls_Name = "Arrow" + cnt_Arrow; //---- Просчитываем текущие данные if (iBar == 0) { if (CreatArrowOnChart) { if (RedrawArrow && lb_ChangeSignal && iBarShift (Symbol(), 0, TimeCurrent()) == iBarShift (Symbol(), 0, Time_lastSignal)) { ls_Name = "Arrow" + (cnt_Arrow - 1); ObjectDelete (ls_Name); cnt_Arrow--; Print ("Изменился сигнал (", gs_Signal[Last_Signal], " -> ", gs_Signal[cur_Signal], ") - удалили стрелочку № ", cnt_Arrow, " (", TS_DS (TimeCurrent()), ")!!!"); } } gd_Price = IIFd ((cur_Signal == 0 || cur_Signal == 2), MarketInfo (Symbol(), MODE_ASK), MarketInfo (Symbol(), MODE_BID)); //Print (Symbol(), ": Предыдущий сигнал ", gs_Signal[Last_Signal], " был в ", TS_DS (Time_lastSignal), ".", //"\nТекущий сигнал - ", gs_Signal[cur_Signal], " по цене ", DoubleToStr (gd_Price, Digits), " от ", TS_DS (TimeCurrent()), "."); if (lb_ChangeSignal) { Last_Signal = cur_Signal; //---- Запоминаем последнее время изменения сигнала Time_lastSignal = TimeCurrent(); } } //---- Просчитываем данные на истории else { //---- За цену берём середину м\у Open и Close бара gd_Price = IIFd ((iOpen (Symbol(), 0, iBar) <= iClose (Symbol(), 0, iBar)), iOpen (Symbol(), 0, iBar), iClose (Symbol(), 0, iBar)) + MathAbs (((iOpen (Symbol(), 0, iBar) - iClose (Symbol(), 0, iBar)) / 2)); if (lb_ChangeSignal) { Time_lastSignal = Time[iBar] + Period() * 30; Last_Signal = cur_Signal; } } //---- Рисуем на графике стрелочку (если разрешено) if (CreatArrowOnChart && (lb_ChangeSignal || iBarShift (Symbol(), 0, Time_lastArrow) - iBar >= 3)) { Time_lastArrow = IIFi ((iBar == 0), TimeCurrent(), Time[iBar] + Period() * 30); ObjectCreate (ls_Name, OBJ_ARROW, 0, Time_lastArrow, gd_Price); ObjectSet (ls_Name, OBJPROP_COLOR, ArColor); ObjectSet (ls_Name, OBJPROP_ARROWCODE, arrow); ObjectSetText (ls_Name, TS_MS (Time_lastArrow)); //if (iBar == 0) //{Print ("Бар-Last[", iBarShift (Symbol(), 0, Time_lastSignal), "], бар-cur[", iBar, "], бар-lastArrow[", iBarShift (Symbol(), 0, Time_lastArrow), "]. Arrow[", arrow, "] № ", cnt_Arrow);} //---- Увеличиваем счётчик стрелочек cnt_Arrow++; //---- Запоминаем время последней выставленной стрелочки } } //---- Выводим на график строку о последнем сигнале if (iBar == 0) { //---- Если бар текущий if (TimeCurrent() < Time_lastSignal + Period() * 60) {gd_Price = IIFd ((Last_Signal == Send_BUY || Last_Signal == Send_BUY_PLUS), MarketInfo (Symbol(), MODE_ASK), MarketInfo (Symbol(), MODE_BID));} else //---- Если бар не текущий //{gd_Price = iClose (Symbol(), PERIOD_M1, iBarShift (Symbol(), PERIOD_M1, Time_lastSignal));} {gd_Price = IIFd ((iOpen (Symbol(), 0, iBar) <= iClose (Symbol(), 0, iBar)), iOpen (Symbol(), 0, iBar), iClose (Symbol(), 0, iBar)) + MathAbs (((iOpen (Symbol(), 0, iBar) - iClose (Symbol(), 0, iBar)) / 2)); ls_price = IIFs ((Last_Signal == STOP), "", " по цене " + DoubleToStr (gd_Price, Digits));} SetLabel ("sinal", StringConcatenate ("Сигнал ", gs_Signal[Last_Signal], " от " + TS_DS (Time_lastSignal), ls_price), 420, 70, 12, "Verdana", 0, gi_Window, Lime); } //---- return; } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Автор : TarasBY, taras_bulba@tut.by | //+-----------------------------------------------------------------------------------+ //| Версия : 23.07.2010 | //| Описание : Установка объекта OBJ_LABEL | //+-----------------------------------------------------------------------------------+ //| Параметры: | //| name - наименование объекта | //| text - сам объект | //| X - координата X | //| Y - координата Y | //| size - размер объекта | //| Font - шрифт объекта | //| Angle - угол (0 - по умолчанию) | //| iWindow - окно в котором расположен объект (0 - по умолчанию) | //| CL1 - цвет (CLR_NONE - по умолчанию) | //| CL2 - цвет (CLR_NONE - по умолчанию) | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ void SetLabel (string name, string text, int X, int Y, int size, string Font, int Angle = 0, int iWindow = 0, color CL1 = CLR_NONE, color CL2 = CLR_NONE) { if (ObjectFind (name) == -1) {ObjectCreate (name, OBJ_LABEL, iWindow, 0, 0);} ObjectSet (name, OBJPROP_COLOR, CL1); ObjectSet (name, OBJPROP_XDISTANCE, X); ObjectSet (name, OBJPROP_YDISTANCE, Y); if (Angle > 0) {ObjectSet (name, OBJPROP_ANGLE, Angle);} if (text != "") { if (CL2 == CLR_NONE) {CL2 = CL1;} ObjectSetText (name, text, size, Font, CL2); } //---- return; } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Рисуем на графике таблицу | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ void fCreatTable() { int li_OBJ, li_LBL, li_int, li_result, X_Dist = 0, Y_Dist = 0, li_Lable[7] = {1,1,1,4,6,6,6}; string ls_txt, ls_Name, ls_font = "Verdana", ls_TXT[3]; //---- for (li_int = 0; li_int < 3; li_int++) {ls_TXT[li_int] = GetNameTF (gi_TF[li_int]);} for (li_LBL = 0; li_LBL < 7; li_LBL++) { for (li_OBJ = IIFi ((li_LBL <= 2), 0, 1); li_OBJ < li_Lable[li_LBL]; li_OBJ++) { if (li_LBL <= 2) { X_Dist = IIFi ((li_LBL == 0), 60, IIFi ((li_LBL == 1), 210, 260)); Y_Dist = 15; ls_txt = IIFs ((li_LBL == 0), "Moving Average", IIFs ((li_LBL == 1), "AC", "РЕЗУЛЬТАТЫ")); ls_Name = gs_Lable[li_LBL]; } else { if (li_LBL == 3) { X_Dist = 11; Y_Dist = 30 + (20 * (li_OBJ - 1)); ls_txt = ls_TXT[li_OBJ-1]; } else { X_Dist = 50 + (30 * (li_OBJ - 1)); Y_Dist = 32 + (20 * (li_LBL - 4)); } ls_Name = gs_Lable[li_LBL] + li_OBJ; } ObjectCreate (ls_Name, OBJ_LABEL, gi_Window, 0, 0); if (li_LBL <= 3) {ObjectSetText (ls_Name, ls_txt, IIFi ((li_LBL <= 2), 9, 11), ls_font, Lime);} ObjectSet (ls_Name, OBJPROP_XDISTANCE, X_Dist); ObjectSet (ls_Name, OBJPROP_YDISTANCE, Y_Dist); } } SetLabel ("txt2", "Мультитаймфреймный индикатор \"iPSI-@TREND_alexcud\"", 11, 95, 9, "Verdana", 0, gi_Window, Silver); SetLabel ("txt3", "Copyright © 2007-2011 ALEXCUD&TarasBY", 420, 95, 9, "Verdana", 0, gi_Window, Silver); } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Создаём массив INT из строки, разделённой sDelimiter | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ int StringToArrayINT (string List, int& iArray[], string sDelimiter = ",") { int i = 0, num; string ls_tmp; //---- ArrayResize (iArray, 0); while (StringLen (List) > 0) { num = StringFind (List, sDelimiter); if (num < 0) { ls_tmp = List; List = ""; } else { ls_tmp = StringSubstr (List, 0, num); List = StringSubstr (List, num + 1); } i++; ArrayResize (iArray, i); iArray[i-1] = StrToDouble (ls_tmp); } //---- return (ArraySize (iArray)); } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Функция, перевода времени в сек. в строку формата "yyyy.mm.dd hh:mi:ss" | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ string TS_DS (datetime v) {return (TimeToStr (v, TIME_DATE|TIME_SECONDS));} //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Функция, перевода времени в сек. в строку формата "hh:mi:ss" | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ string TS_MS (datetime v) {return (TimeToStr (v, TIME_MINUTES|TIME_SECONDS));} //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Возвращает наименование таймфрейма | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ string GetNameTF (int TimeFrame) { switch (TimeFrame) { case PERIOD_M1: return ("M1"); case PERIOD_M5: return ("M5"); case PERIOD_M15: return ("M15"); case PERIOD_M30: return ("M30"); case PERIOD_H1: return ("H1"); case PERIOD_H4: return ("H4"); case PERIOD_D1: return ("D1"); case PERIOD_W1: return ("W1"); case PERIOD_MN1: return ("MN1"); default: return (""); } } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Автор : TarasBY, taras_bulba@tut.by | //+-----------------------------------------------------------------------------------+ //| Версия : 15.06.2010 | //| Описание : Возвращает значение таймрейма в соответствие со стандартными периода- | //| ми графиков. | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ int fTFNormalize (int Timeframe) { int li_TF = 0, li_UP = 50000, li_DOWN, cnt_TM = 9; int ar_TM[] = {1,5,15,30,60,240,1440,10080,43200}; //---- if (Timeframe == 0) {return (Period());} for (int li_int = 0; li_int < cnt_TM; li_int++) { if (Timeframe <= ar_TM[li_int]) {li_UP = MathMin (li_UP, ar_TM[li_int]);} if (Timeframe > ar_TM[li_int]) {li_DOWN = MathMax (li_DOWN, ar_TM[li_int]);} } li_TF = IIFi ((MathAbs (Timeframe - li_UP) <= MathAbs (Timeframe - li_DOWN)), li_UP, li_DOWN); //---- return (li_TF); } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Автор : TarasBY, taras_bulba@tut.by | //+-----------------------------------------------------------------------------------+ //| Версия : 12.01.2011 | //| Описание : Возвращает массив TF из строки, контролируя правильность задания TF. | //+-----------------------------------------------------------------------------------+ //| Параметры: | //| s_List - строка | //| iAr_TF - массив элементов типа int (TF) | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ int fCreatArray_TF (string s_List, int& iAr_TF[]) { int li_cnt_TF, li_cnt = 0; //---- li_cnt_TF = StringToArrayINT (s_List, iAr_TF); for (int li_TF = 0; li_TF < li_cnt_TF; li_TF++) { iAr_TF[li_TF] = fTFNormalize (iAr_TF[li_TF]); if (li_TF > 0) { if (iAr_TF[li_TF] != iAr_TF[li_cnt]) { li_cnt++; iAr_TF[li_cnt] = iAr_TF[li_TF]; } else {Print ("Не верно задан TF. При нормализации получили дубликат: TF[", li_cnt, "/", iAr_TF[li_cnt], "] = TF[", li_TF, "/", iAr_TF[li_TF], "]- удаляем дубликат!!!");} } } li_cnt++; if (li_cnt_TF != li_cnt) {ArrayResize (iAr_TF, li_cnt);} //---- return (li_cnt); } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ //| Автор : Ким Игорь В. aka KimIV, http://www.kimiv.ru | //+-----------------------------------------------------------------------------------+ //| Версия : 01.02.2008 | //| Описание : Возвращает одно из двух значений взависимости от условия. | //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+ int IIFi (bool condition, int ifTrue, int ifFalse) { if (condition) {return (ifTrue);} else {return (ifFalse);} } //+-----------------------------------------------------------------------------------+ string IIFs (bool condition, string ifTrue, string ifFalse) { if (condition) {return (ifTrue);} else {return (ifFalse);} } //+-----------------------------------------------------------------------------------+ double IIFd (bool condition, double ifTrue, double ifFalse) { if (condition) {return (ifTrue);} else {return (ifFalse);} } //IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII+