//+---------------------------------------------------------------------------+ //| mv-i-Chuvashov_1_3.mq4 | //| Максим Василенко В. MaxV42 | //| http:// | //| Индикатор работает по стратегии "Вилка Чувашова". | //| Версия 1.3: | //| 03.12.2009 Исправлено: | //| - не срабатывали ордера и алерты, если кол-во "вилок" больше 1. | //| Добавлено: | //| - Функция проверки внешних параметров индикатора. | //| | //| Версия 1.2: | //| 01.12.2009 Добавлено: | //| - Вкл/выкл отображения ордеров; | //| - повторный "вход" после срабатывания "виртуального" стоплосса; | //| - отправка торговых сигналов на E-mail. | //| | //| Версия 1.1: | //| 29.11.2009 Добавлена отрисовка ордеров с алертами. | //+---------------------------------------------------------------------------+ #property copyright "Максим Василенко В. MaxV42" #property link "http://" //+---------------------------------------------------------------------------+ #property indicator_chart_window #property indicator_buffers 2 #property indicator_color1 Blue #property indicator_color2 Red #property indicator_width1 1 #property indicator_width2 1 //+---------------------------------------------------------------------------+ extern string Ind_Coment1= "--- Внешние параметры индикатора ---"; extern bool ShowFractals = true; // Вкл/выкл значков фракталов extern bool OnAlert = false; // Вкл/выкл сигнала extern bool OnPrint = false; // Вкл/выкл вывод сигнала в журнале эксперта extern int nVilka.Upper = 1; // Количество выводимых восходящих "вилок" extern int nVilka.Lower = 1; // Количество выводимых нисходящих "вилок" extern color Color.LineUpper = Red; // Цвет восходящих "вилок" extern color Color.LineLower = Blue; // Цвет нисходящих "вилок" extern int Width.LineUpper = 2; // Ширина восходящих "вилок" extern int Width.LineLower = 2; // Ширина нисходящих "вилок" extern string Ind_Coment2= "--- Параметры отображения ордеров ---"; extern bool ShowOrders = true; // Вкл/выкл отображения ордеров extern bool OnAlert.Orders = true; // Вкл/выкл сигнала extern color Color.OrderBuy = Blue; // Цвет ордеров на покупку extern color Color.OrderSell = Green; // Цвет ордеров на продажу extern int Width.OrderBuy = 2; // Ширина ордеров на покупку extern int Width.OrderSell = 2; // Ширина ордеров на продажу extern color Color.SLBuy = Red; // Цвет стоплосса на покупку extern color Color.SLSell = Red; // Цвет стоплосса на продажу extern int Orders.FontSize = 12; // Размер шрифта ордеров extern string Ind_Coment3= "--- Параметры E-mail сообщений ---"; extern bool SendEnter = false; // сигналы Buy, Sell extern bool SendLoss = false; // сигналы StopLoss //+---------------------------------------------------------------------------+ // глобальные переменные int nLine.Upper = 0, // Количество трендовых линий, направленных вверх nLine.Lower = 0, // Количество трендовых линий, направленных вниз nBars = 0; // datetime mLineUpper.DateTime[][2]; // массив с параметрами восходящих "вилок" // mLineUpper.DateTime[i][0] // Время первой координаты // mLineUpper.DateTime[i][1] // Время второй координаты double mLineUpper.Price[][2]; // массив с параметрами восходящих "вилок" // mLineUpper.Price[i][0] // Цена первой координаты // mLineUpper.Price[i][1] // Цена второй координаты datetime mLineLower.DateTime[][2]; // массив с параметрами нисходящих "вилок" // mLineLower.DateTime[i][0] // Время первой координаты // mLineLower.DateTime[i][1] // Время второй координаты double mLineLower.Price[][2]; // массив с параметрами нисходящих "вилок" // mLineLower.Price[i][0] // Цена первой координаты // mLineLower.Price[i][1] // Цена второй координаты string mOrders[2][5]; // массив с параметрами "открытых" позиций // mOrders[0][0] // Buy - 0-нет ордера, 10-есть ордер // mOrders[1][0] // Sell- 0-нет ордера, 20-есть ордер // mOrders[i][1] // Дата и время "открытия" ордера // mOrders[i][2] // Цена ордера ордера // mOrders[i][3] // Стоплосс ордера ордера // mOrders[i][4] // 0-стоплосс НЕ сработал, 1-стоплосс сработал string NameLine.Buy=""; // имя сигнальной трендовой линии для покупки string NameLine.Sell=""; // имя сигнальной трендовой линии для продажи //----- buffers double ExtMapBuffer1[]; double ExtMapBuffer2[]; //+---------------------------------------------------------------------------+ void init() { // Custom indicator initialization function int Qnt=ObjectsTotal(); // ----- Indicators Properties SetIndexStyle(0,DRAW_ARROW); SetIndexArrow(0,217); SetIndexBuffer(0,ExtMapBuffer1); SetIndexEmptyValue(0,0.0); SetIndexStyle(1,DRAW_ARROW); SetIndexArrow(1,218); SetIndexBuffer(1,ExtMapBuffer2); SetIndexEmptyValue(1,0.0); // ----- Name for DataWindow and indicator subwindow label IndicatorShortName("Fractals"); SetIndexLabel(0,"FractalsUp"); SetIndexLabel(1,"FractalsDown"); // ----- устанавливаем количество элементов в массивах трендовых линий ArrayResize(mLineUpper.DateTime,nVilka.Upper*2); ArrayResize(mLineUpper.Price,nVilka.Upper*2); ArrayResize(mLineLower.DateTime,nVilka.Lower*2); ArrayResize(mLineLower.Price,nVilka.Lower*2); // ----- определяемся с именами сигнальных трендовых линий if (nVilka.Lower==1) NameLine.Buy ="Line.Lower1"; if (nVilka.Lower>1) NameLine.Buy ="Line.Lower"+DoubleToStr(nVilka.Lower*2-1,0); if (nVilka.Upper==1) NameLine.Sell="Line.Upper1"; if (nVilka.Upper>1) NameLine.Sell="Line.Upper"+DoubleToStr(nVilka.Upper*2-1,0); return; } //+---------------------------------------------------------------------------+ void deinit() { // Custom indicator deinitialization function int Qnt=ObjectsTotal(); // ----- Удаляем трендовые линии for (int i=0; i=0) { ObjectDelete(ObjectName(i)); // направленные вверх i--; continue; } if(StringFind(ObjectName(i),"Line.Lower",0)>=0) { ObjectDelete(ObjectName(i)); // направленные вниз i--; continue; } if(i>=ObjectsTotal()) break; } DeleteOrders(10); DeleteOrders(20); return; } //+---------------------------------------------------------------------------+ void start() { // Custom indicator iteration function int counted_bars=IndicatorCounted(); int limit; int Spred=MarketInfo(Symbol(),MODE_SPREAD); // ----- Проверка внешних параметров индикатора if(!CheckParameters()) return; // ----- новый бар не появился if(!isNewBar()) return; // ----- Последний посчитанный бар будет пересчитан if (counted_bars>0) counted_bars--; limit=Bars-counted_bars; // ----- Основной цикл //for (int i=limit; i>2; i--) { for (int i=limit; i>=0; i--) { if(ShowFractals) { // отображаем вракталы на графике ExtMapBuffer1[i]=iFractals(NULL,0,MODE_UPPER,i)+Spred*Point; ExtMapBuffer2[i]=iFractals(NULL,0,MODE_LOWER,i)-Spred*Point; } //---- Блок Upper-фракталов (нисходящие "вилки") if (iFractals(NULL,0,MODE_UPPER,i)!=0) { if(LowerVilka(i)) { if(i==0) { if(OnAlert) Alert(Symbol(),Period()," Нисходящая вилка! ",TimeToStr(Time[i],TIME_DATE|TIME_SECONDS)); if(OnPrint) Print(Symbol(),Period()," Нисходящая вилка! ",TimeToStr(Time[i],TIME_DATE|TIME_SECONDS)); } } } //---- Блок Lower-фракталов (восходящие "вилки") if (iFractals(NULL,0,MODE_LOWER,i)!=0) { if(UpperVilka(i)) { if(i==0) { if(OnAlert) Alert(Symbol(),Period()," Восходящая вилка! ",TimeToStr(Time[i],TIME_DATE|TIME_SECONDS)); if(OnPrint) Print(Symbol(),Period()," Восходящая вилка! ",TimeToStr(Time[i],TIME_DATE|TIME_SECONDS)); } } } //----- пересечение нисходящей "вилки" - сигнал на покупку if((StrToDouble(mOrders[0][0])==0 || (StrToDouble(mOrders[0][0])==10 && StrToDouble(mOrders[0][4])==1)) && (Close[i+1]>ObjectGetValueByShift(NameLine.Buy,i+1) || Open[i]>ObjectGetValueByShift(NameLine.Buy,i))) { if(DrawOrdersBuy(i)) { if(OnAlert.Orders) { if(i==0) { Alert(Symbol(),Period(),": Сигнал на покупку! ",TimeToStr(Time[i],TIME_DATE|TIME_SECONDS)); } } if(SendEnter) { if(i==0) { SendMailSignals(i, 10); } } } } //----- пересечение стоплосса ордера на покупку if(StrToDouble(mOrders[0][0])==10 && StrToDouble(mOrders[0][4])==0 && (StrToDouble(mOrders[0][3])>=Low[i+1] || StrToDouble(mOrders[0][3])>=Open[i])) { // ----- устанавливаем флаг срабатывания стоплосса mOrders[0][4]=1; // ----- if(OnAlert.Orders) { if(i==0) { Alert(Symbol(),Period(),": Сработал стоплосс для оредра Buy! ",TimeToStr(Time[i],TIME_DATE|TIME_SECONDS)); } } if(SendLoss) { if(i==0) { SendMailSignals(i, 11); } } } //----- пересечение восходящей "вилки" - сигнал на продажу if((StrToDouble(mOrders[1][0])==0 || (StrToDouble(mOrders[1][0])==20 && StrToDouble(mOrders[1][4])==1)) && (Close[i+1]2) break; } // ----- рисуем восходящую "вилку" if(mFractals.Price[2]2) break; } // ----- рисуем нисходящие "вилку" if(mFractals.Price[2]>mFractals.Price[1] && mFractals.Price[1]>mFractals.Price[0]) { string Name1="Line.Lower"+DoubleToStr(nLine.Lower,0); nLine.Lower++; string Name2="Line.Lower"+DoubleToStr(nLine.Lower,0); nLine.Lower++; ObjectCreate(Name1,OBJ_TREND,0,mFractals.DateTime[2],mFractals.Price[2],mFractals.DateTime[1],mFractals.Price[1]); ObjectCreate(Name2,OBJ_TREND,0,mFractals.DateTime[1],mFractals.Price[1],mFractals.DateTime[0],mFractals.Price[0]); if (ObjectGetValueByShift(Name1,nBar)>ObjectGetValueByShift(Name2,nBar)) { ObjectDelete(Name1); ObjectDelete(Name2); nLine.Lower--; nLine.Lower--; return(false); } ObjectSet(Name1,OBJPROP_COLOR,Color.LineLower); ObjectSet(Name2,OBJPROP_COLOR,Color.LineLower); ObjectSet(Name1,OBJPROP_WIDTH,Width.LineLower); ObjectSet(Name2,OBJPROP_WIDTH,Width.LineLower); ObjectSet(Name1,OBJPROP_RAY,True); ObjectSet(Name2,OBJPROP_RAY,True); CheckNumVilka(20); // ----- удаляем предыдущий ордер на покупку DeleteOrders(10); return(true); } return(false); } //+---------------------------------------------------------------------------+ bool isNewBar() { // Функция возвращает true, если появиться новый бар, иначе false if(nBars!=Bars) { nBars=Bars; return(true); } return(false); } //+---------------------------------------------------------------------------+ void CheckNumVilka(int Type) { // Функция проверяет допустимое количество вилок указанного типа int i; switch(Type) { case 10: //--------------------------------------------------------- 1 -- if(nLine.Upper<=nVilka.Upper*2) { mLineUpper.DateTime[nLine.Upper-2][0]=ObjectGet("Line.Upper"+(nLine.Upper-2),OBJPROP_TIME1); mLineUpper.DateTime[nLine.Upper-2][1]=ObjectGet("Line.Upper"+(nLine.Upper-2),OBJPROP_TIME2); mLineUpper.Price[nLine.Upper-2][0]=ObjectGet("Line.Upper"+(nLine.Upper-2),OBJPROP_PRICE1); mLineUpper.Price[nLine.Upper-2][1]=ObjectGet("Line.Upper"+(nLine.Upper-2),OBJPROP_PRICE2); //+------------------------------------------------------------------+ mLineUpper.DateTime[nLine.Upper-1][0]=ObjectGet("Line.Upper"+(nLine.Upper-1),OBJPROP_TIME1); mLineUpper.DateTime[nLine.Upper-1][1]=ObjectGet("Line.Upper"+(nLine.Upper-1),OBJPROP_TIME2); mLineUpper.Price[nLine.Upper-1][0]=ObjectGet("Line.Upper"+(nLine.Upper-1),OBJPROP_PRICE1); mLineUpper.Price[nLine.Upper-1][1]=ObjectGet("Line.Upper"+(nLine.Upper-1),OBJPROP_PRICE2); } //--------------------------------------------------------- 2 -- if(nLine.Upper >nVilka.Upper*2) { for (i=0; inVilka.Lower*2) { for (i=0; i=ObjectGetValueByShift(NameLine.Buy,i) || StopLoss.Buy>=Price.Buy) { return(false); } // ----- удаляем предыдущий ордер на покупку DeleteOrders(10); // ----- определяемся с параметрами ордера mOrders[0][0]=10; // устанавливаем флаг "открытого" ордера на покупку mOrders[0][1]=TimeToStr(Time[nBar],TIME_DATE|TIME_MINUTES); // Дата и время "открытия" ордера mOrders[0][2]=Price.Buy; // Цена ордера ордера mOrders[0][3]=StopLoss.Buy; // Стоплосс ордера ордера mOrders[0][4]=0; // флаг срабатывания стоплосса: 0-стоплосс НЕ сработал, 1-стоплосс сработал // ----- рисуем, если разрешено if(ShowOrders) { // ----- рисуем ордер на покупку ObjectCreate("Order.Buy",OBJ_TREND,0,Time[nBar+25],Price.Buy,Time[nBar],Price.Buy); ObjectCreate("OrderArrow.Buy",OBJ_ARROW,0,Time[nBar+23],Price.Buy); ObjectSet("Order.Buy",OBJPROP_COLOR,Color.OrderBuy); ObjectSet("OrderArrow.Buy",OBJPROP_COLOR,Color.OrderBuy); ObjectSet("Order.Buy",OBJPROP_WIDTH,Width.OrderBuy); ObjectSet("OrderArrow.Buy",OBJPROP_WIDTH,Width.OrderBuy); ObjectSet("Order.Buy",OBJPROP_RAY,false); ObjectSet("OrderArrow.Buy",OBJPROP_ARROWCODE,225); ObjectCreate("LabelPrice.Buy",OBJ_TEXT,0,Time[nBar+10],Price.Buy); ObjectSetText("LabelPrice.Buy","Buy: "+DoubleToStr(Price.Buy,Digits),Orders.FontSize, "Times New Roman", Color.OrderBuy); // ----- рисуем стоплос на покупку ObjectCreate("StopLoss.Buy",OBJ_TREND,0,Time[nBar+25],StopLoss.Buy,Time[nBar],StopLoss.Buy); ObjectCreate("StopLossArrow.Buy",OBJ_ARROW,0,Time[nBar+23],StopLoss.Buy); ObjectSet("StopLoss.Buy",OBJPROP_COLOR,Color.SLBuy); ObjectSet("StopLossArrow.Buy",OBJPROP_COLOR,Color.SLBuy); ObjectSet("StopLoss.Buy",OBJPROP_WIDTH,Width.OrderBuy); ObjectSet("StopLossArrow.Buy",OBJPROP_WIDTH,Width.OrderBuy); ObjectSet("StopLoss.Buy",OBJPROP_RAY,false); ObjectSet("StopLossArrow.Buy",OBJPROP_ARROWCODE,251); ObjectCreate("LabelStopLoss.Buy",OBJ_TEXT,0,Time[nBar+10],StopLoss.Buy); ObjectSetText("LabelStopLoss.Buy","SL Buy: "+DoubleToStr(StopLoss.Buy,Digits),Orders.FontSize, "Times New Roman", Color.SLBuy); } return(true); } //+---------------------------------------------------------------------------+ bool DrawOrdersSell(int nBar) { // Функция рисут ордера Sell double Price.Sell=Open[nBar]; double StopLoss.Sell; // ----- определяем стоплосс for (int i=nBar; i