//+------------------------------------------------------------------+ //| iSignalByCrossAD.mq4 | //| Copyright 2016, Artem A. Trishkin, Skype artmedia70 | //| https://login.mql5.com/ru/users/artmedia70 | //+------------------------------------------------------------------+ #property copyright "Copyright 2016, Artem A. Trishkin, Skype artmedia70" #property link "https://login.mql5.com/ru/users/artmedia70" #property version "1.00" #property strict //#property indicator_chart_window #property indicator_separate_window #property indicator_buffers 3 #property indicator_plots 3 //--- plot AD #property indicator_label1 "AD" #property indicator_type1 DRAW_LINE #property indicator_color1 clrRed #property indicator_style1 STYLE_SOLID #property indicator_width1 1 //--- plot ArrowUP #property indicator_label2 "Arrow to Up" #property indicator_type2 DRAW_ARROW #property indicator_color2 clrBlue #property indicator_style2 STYLE_SOLID #property indicator_width2 1 //--- plot ArrowDN #property indicator_label3 "Arrow to Down" #property indicator_type3 DRAW_ARROW #property indicator_color3 clrRed #property indicator_style3 STYLE_SOLID #property indicator_width3 1 //--- enums enum enumYN { enYes=1, // Yes enNo=0, // No }; //--- enum enumStyle { enStFill=1, // Fill enStFrame=0, // Frame }; //--- enum enumWidth { enWidth1=1, // 1 enWidth2=2, // 2 enWidth3=3, // 3 enWidth4=4, // 4 }; //--- enum enumFilterBy { enFilterNot=0, // Without filtration enFilterCCI=1, // Filter by CCI }; enum enumLineStoch { enLineSto0=MODE_MAIN, // Main Line enLineSto1=MODE_SIGNAL, // Signal Line }; //--- input parameters input int PeriodFind=60; // Number bars for calculate int periodFind=(PeriodFind<6)?6:PeriodFind; // Number bars for calculate input int UnheckedBars=3; // Unchecked bars int unheckedBars=(UnheckedBars<2)?2:UnheckedBars; // Unchecked bars //--- extern string _P_Filters = "-- Filtration --"; //====================================== input enumFilterBy FilterBy=enFilterCCI; // Filtering indicator input enumYN UseDefaultSetting=enYes; // Use settings by default CCI parameters //--- input int PeriodIND=14; // Period for CCI int periodIND=(PeriodIND<1)?1:PeriodIND; input ENUM_APPLIED_PRICE AppledPriceIND=PRICE_TYPICAL; // Appled Price for CCI ENUM_APPLIED_PRICE appledPriceIND=AppledPriceIND; extern string _P_Levels = "-- Parameters of CCI levels --"; //====================================== input double UpperLevelIND=100.0; // The upper level of the filter indicator double upperLevelIND=UpperLevelIND; input double LowerLevelIND=-100.0; // The lower level of the filter indicator double lowerLevelIND=LowerLevelIND; //--- extern string _P_Graphs = "-- Graphics Options --"; //====================================== sinput enumYN DrawArea=enNo; // Draw the search area sinput enumStyle StyleFrame=enStFrame; // Style the search area (Frame or Fill) sinput enumWidth WidthLineArea=enWidth1; // Line width the search area (if Frame) sinput ENUM_LINE_STYLE StyleLineFrame=STYLE_SOLID; // Line style the search area (if Frame) sinput color ColorArea=clrLightSteelBlue; // Line color the search area //--- sinput enumYN DrawTrendLine=enNo; // Draw a trend line sinput enumWidth WidthTrendLine=enWidth1; // The thickness of the trend line sinput ENUM_LINE_STYLE StyleTrendLine=STYLE_DOT; // Line style of the trend line sinput color ColorTrendDN=clrRed; // Color downtrend line sinput color ColorTrendUP=clrBlue; // Color uptrend line //--- sinput enumYN DrawChartsArrow=enNo; // Draws arrows on chart sinput enumWidth ArrowSize=enWidth2; // The size of the arrows on the chart sinput color ColorBullishArrow=clrBlue; // Color bullish arrows sinput color ColorBearishArrow=clrRed; // Color bearish arrows //--- indicator buffers double BufferAD[]; double BufferUpperArrow[]; double BufferLowerArrow[]; //--- double BufferPeakUP[][2]; // array of peak up [i][0] - time, [i][1] - value double BufferPeakDN[][2]; // array of peak down [i][0] - time, [i][1] - value //--- Global variables double point; bool checkFilter; string symbol, Prefix; int digits, wnd; //+------------------------------------------------------------------+ //| Custom indicator initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- symbol=Symbol(); point=SymbolInfoDouble(symbol,SYMBOL_POINT); digits=int(SymbolInfoInteger(symbol,SYMBOL_DIGITS)); Prefix="SCAD("+IntegerToString(periodFind)+")"+symbol; wnd=ChartWindowFind(); checkFilter=true; //--- correct input variables if(UseDefaultSetting) CorrectInputValue(FilterBy); //--- indicator buffers mapping SetIndexBuffer(0,BufferAD); SetIndexBuffer(1,BufferUpperArrow); SetIndexBuffer(2,BufferLowerArrow); //--- setting a code from the Wingdings charset as the property of PLOT_ARROW PlotIndexSetInteger(1,PLOT_ARROW,241); PlotIndexSetInteger(2,PLOT_ARROW,242); SetIndexArrow(1,241); SetIndexArrow(2,242); //--- IndicatorSetInteger(INDICATOR_DIGITS,digits); IndicatorSetString(INDICATOR_SHORTNAME,Prefix); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Custom indicator deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { //--- delete graphics RemoveAllObjectsFromChart(0,Prefix); //--- } //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- //--- Checking for number bars of calculated if(rates_total1) { limit=rates_total-periodFind-unheckedBars-1; ArrayInitialize(BufferAD,EMPTY_VALUE); ArrayInitialize(BufferUpperArrow,EMPTY_VALUE); ArrayInitialize(BufferLowerArrow,EMPTY_VALUE); } //--- double value_left_dn=DBL_MAX, value_left_up=-DBL_MAX; double value_right_dn=DBL_MAX, value_right_up=-DBL_MAX; datetime time_right_dn=0, time_right_up=0; int bar_max=0, bar_min=0; ArrayResize(BufferPeakUP,0); ArrayResize(BufferPeakDN,0); //--- Main cicle for(int i=limit; i>=0; i--) { BufferAD[i]=GetDataAD(symbol,Period(),i); BufferUpperArrow[i]=EMPTY_VALUE; BufferLowerArrow[i]=EMPTY_VALUE; //--- Finding all the extremes within the period Find. Найдём все экстремумы в пределах periodFind int jup=0, jdn=0; for(int j=i; j<=i+periodFind+unheckedBars-1; j++) { BufferAD[j]=GetDataAD(symbol,Period(),j); if(j>i+unheckedBars) { //--- Up peacks. вершины if(DirectionExtremum(BufferAD[j+1],BufferAD[j],BufferAD[j-1])==OP_SELL) { jup++; ArrayResize(BufferPeakUP,jup,periodFind); BufferPeakUP[jup-1][0]=int(time[j]); BufferPeakUP[jup-1][1]=BufferAD[j]; } //--- Down peacks. донышки if(DirectionExtremum(BufferAD[j+1],BufferAD[j],BufferAD[j-1])==OP_BUY) { jdn++; ArrayResize(BufferPeakDN,jdn,periodFind); BufferPeakDN[jdn-1][0]=int(time[j]); BufferPeakDN[jdn-1][1]=BufferAD[j]; } } } //--- Tops within the period Find. Вершины в пределах periodFind int size_mass_up=ArrayRange(BufferPeakUP,0); if(size_mass_up>0) { time_right_up=int(BufferPeakUP[0][0]); int bar_right_up=iBarShift(symbol,Period(),time_right_up); value_right_up=BufferPeakUP[0][1]; int index_max=ArrayMaximumInXDimm(BufferPeakUP,1); // наибольшее значение в массиве datetime time_max=int(BufferPeakUP[index_max][0]); bar_max=iBarShift(symbol,Period(),time_max); value_left_up=BufferPeakUP[index_max][1]; if(time_right_up>time_max && BufferAD[bar_max]>value_right_up) { for(int k=index_max-0; k>0; k--) { int bar_k=iBarShift(symbol,Period(),datetime(BufferPeakUP[k][0])); double virtual_price=EquationDirect(bar_max,value_left_up,bar_right_up,value_right_up,bar_k); //--- if the top of crosses the line. если вершина пересекает линию if(BufferAD[bar_k]>virtual_price) { bar_max=iBarShift(symbol,Period(),int(BufferPeakUP[k][0])); value_left_up=BufferPeakUP[k][1]; } } //--- check the intersection to down. проверка пересечения вниз if(EquationDirect(bar_max,value_left_up,bar_right_up,value_right_up,i+1)=BufferAD[i+2] || EquationDirect(bar_max,value_left_up,bar_right_up,value_right_up,i+3)>=BufferAD[i+3])) { if(FilterBy!=enFilterNot) { double filter_1=GetDataIND(symbol,Period(),FilterBy,i+1); double filter_2=GetDataIND(symbol,Period(),FilterBy,i+2); double filter_3=GetDataIND(symbol,Period(),FilterBy,i+3); checkFilter=(filter_1<=lowerLevelIND && filter_20) { time_right_dn=int(BufferPeakDN[0][0]); int bar_right_dn=iBarShift(symbol,Period(),time_right_dn); value_right_dn=BufferPeakDN[0][1]; int index_min=ArrayMinimumInXDimm(BufferPeakDN,1); // наименьшее значение в массиве datetime time_min=int(BufferPeakDN[index_min][0]); bar_min=iBarShift(symbol,Period(),time_min); value_left_dn=BufferPeakDN[index_min][1]; if(time_right_dn>time_min && BufferAD[bar_min]0; k--) { int bar_k=iBarShift(symbol,Period(),datetime(BufferPeakDN[k][0])); double virtual_price=EquationDirect(bar_min,value_left_dn,bar_right_dn,value_right_dn,bar_k); //--- if the bottom of line crosses. если дно пересекает линию if(BufferAD[bar_k]BufferAD[i+1] && (EquationDirect(bar_min,value_left_dn,bar_right_dn,value_right_dn,i+2)<=BufferAD[i+2] || EquationDirect(bar_min,value_left_dn,bar_right_dn,value_right_dn,i+3)<=BufferAD[i+3])) { if(FilterBy!=enFilterNot) { double filter_1=GetDataIND(symbol,Period(),FilterBy,i+1); double filter_2=GetDataIND(symbol,Period(),FilterBy,i+2); double filter_3=GetDataIND(symbol,Period(),FilterBy,i+3); checkFilter=(filter_1>=upperLevelIND && filter_2>upperLevelIND)?true:false; } else checkFilter=true; if(checkFilter) { BufferLowerArrow[i]=BufferAD[i+1]; if(DrawChartsArrow) SetArrow(0,242,ColorBearishArrow,0,Prefix+"ChartArrowDN_"+TimeToString(time[i]),ANCHOR_BOTTOM,time[i],open[i],ArrowSize); } } } } } if(DrawArea) SetRectangle(0,ColorArea,Prefix+"_range",wnd,time[periodFind+unheckedBars],BufferAD[ArrayMaximum(BufferAD,periodFind,unheckedBars)],time[unheckedBars],BufferAD[ArrayMinimum(BufferAD,periodFind,unheckedBars)],WidthLineArea,StyleLineFrame,StyleFrame); if(DrawTrendLine) { SetTLine(0,Prefix+"_TLineDN",ColorTrendDN,wnd,time[bar_max],BufferAD[bar_max],time_right_up,BufferPeakUP[0][1],WidthTrendLine,StyleTrendLine,true); SetTLine(0,Prefix+"_TLineUP",ColorTrendUP,wnd,time[bar_min],BufferAD[bar_min],time_right_dn,BufferPeakDN[0][1],WidthTrendLine,StyleTrendLine,true); } //--- return value of prev_calculated for next call return(rates_total); } //+----------------------------------------------------------------------------+ //--- Author KimIV (http://www.kimiv.ru/), edited by Artmedia70 (https://www.mql5.com/ru/users/artmedia70) double EquationDirect(int left_bar, double left_price, int right_bar, double right_price, double bar_to_search) { return((right_bar==left_bar)?left_price:(right_price-left_price)/(right_bar-left_bar)*(bar_to_search-left_bar)+left_price); } //+------------------------------------------------------------------+ int DirectionExtremum(double a, double b, double c) { if((a-b)*(b-c)<0) { if(c>b) return(OP_BUY); if(cvalue) { value=massive[i][rank_index]; res=i; } } return(res); } //+------------------------------------------------------------------+ int ArrayMinimumInXDimm(double &massive[][], int rank_index=1, int count=0, int start_find=0) { if(ArrayRange(massive,0)<=0) return(EMPTY); int res=0, num=(count==0)?ArrayRange(massive,0):count; double value=massive[start_find][rank_index]; for(int i=start_find+1; i