MTF_Price_Bar

Author: Copyright 2018, MetaQuotes Software Corp.
Price Data Components
Series array that contains open time of each bar
0 Views
0 Downloads
0 Favorites
MTF_Price_Bar
ÿþ//+------------------------------------------------------------------+

//|                                                MTF_Price_Bar.mq5 |

//|                        Copyright 2018, MetaQuotes Software Corp. |

//|                                                 https://mql5.com |

//+------------------------------------------------------------------+

#property copyright "Copyright 2018, MetaQuotes Software Corp."

#property link      "https://mql5.com"

#property version   "1.00"

#property description "Multi Time Frame Price Bar indicator\n"

#property description "Indicator showing the last N candles of the\ndifferent time frames of the current currency pair."

#property indicator_separate_window

#property indicator_buffers 105

#property indicator_plots   105

#include <Arrays\ArrayInt.mqh>

//--- structures

struct SBuffer

  {

   ENUM_TIMEFRAMES   timeframe;

   MqlRates          array_rates[];

   double            Open[];

   double            High[];

   double            Low[];

   double            Close[];

   double            Colors[];

   int               index_base;

   int               shift;

  };

//--- enums

enum ENUM_INPUT_YES_NO

  {

   INPUT_YES   =  1,          // Yes

   INPUT_NO    =  0           // No

  };

//--- input parameters

input uint              InpNumBars  =  20;            // The number of bars of each timeframe

input uchar             InpDelta    =  4;             // The gap between datas

input color             InpColorU   =  clrLimeGreen;  // Bullish candle color

input color             InpColorD   =  clrOrangeRed;  // Bearish candle color

input color             InpColorN   =  clrGray;       // Neutral candle color

input color             InpColorT   =  clrLightGray;  // Description color

input ENUM_INPUT_YES_NO InpUseM1    =  INPUT_YES;     // Use 1 minute timeframe

input ENUM_INPUT_YES_NO InpUseM2    =  INPUT_NO;      // Use 2 minute timeframe

input ENUM_INPUT_YES_NO InpUseM3    =  INPUT_NO;      // Use 3 minute timeframe

input ENUM_INPUT_YES_NO InpUseM4    =  INPUT_NO;      // Use 4 minute timeframe

input ENUM_INPUT_YES_NO InpUseM5    =  INPUT_YES;     // Use 5 minute timeframe

input ENUM_INPUT_YES_NO InpUseM6    =  INPUT_NO;      // Use 6 minute timeframe

input ENUM_INPUT_YES_NO InpUseM10   =  INPUT_NO;      // Use 10 minute timeframe

input ENUM_INPUT_YES_NO InpUseM12   =  INPUT_NO;      // Use 12 minute timeframe

input ENUM_INPUT_YES_NO InpUseM15   =  INPUT_YES;     // Use 15 minute timeframe

input ENUM_INPUT_YES_NO InpUseM20   =  INPUT_NO;      // Use 20 minute timeframe

input ENUM_INPUT_YES_NO InpUseM30   =  INPUT_YES;     // Use 30 minute timeframe

input ENUM_INPUT_YES_NO InpUseH1    =  INPUT_YES;     // Use 1 hour timeframe

input ENUM_INPUT_YES_NO InpUseH2    =  INPUT_NO;      // Use 2 hour timeframe

input ENUM_INPUT_YES_NO InpUseH3    =  INPUT_NO;      // Use 3 hour timeframe

input ENUM_INPUT_YES_NO InpUseH4    =  INPUT_YES;     // Use 4 hour timeframe

input ENUM_INPUT_YES_NO InpUseH6    =  INPUT_NO;      // Use 6 hour timeframe

input ENUM_INPUT_YES_NO InpUseH8    =  INPUT_NO;      // Use 8 hour timeframe

input ENUM_INPUT_YES_NO InpUseH12   =  INPUT_NO;      // Use 12 hour timeframe

input ENUM_INPUT_YES_NO InpUseD1    =  INPUT_YES;     // Use 1 Day timeframe

input ENUM_INPUT_YES_NO InpUseW1    =  INPUT_YES;     // Use 1 Week timeframe

input ENUM_INPUT_YES_NO InpUseMN1   =  INPUT_YES;     // Use 1 Month timeframe

//--- global variables

SBuffer        rates[];

CArrayInt      list_timeframes;

CArrayInt      list_colors;

string         prefix;

int            bars_count;

int            gap;

int            wnd;

//+------------------------------------------------------------------+

//| Custom indicator initialization function                         |

//+------------------------------------------------------------------+

int OnInit()

  {

//--- timer

   EventSetTimer(90);

//--- setting indicator parameters

   prefix=MQLInfoString(MQL_PROGRAM_NAME)+"_";

   bars_count=int(InpNumBars);

   gap=(InpDelta<1 ? 1 : InpDelta);

   wnd=ChartWindowFind();

//--- colors

   list_colors.Clear();

   list_colors.Add(InpColorU);

   list_colors.Add(InpColorD);

   list_colors.Add(InpColorN);

//--- timeframes

   list_timeframes.Clear();

   for(int i=0;i<21;i++)

     {

      int tf=GetInputTimeframe(i);

      if(tf==WRONG_VALUE)

         continue;

      list_timeframes.Add((int)tf);

     }   

//--- indicator buffers mapping

   int total=list_timeframes.Total();

   ArrayResize(rates,total);

   for(int i=0;i<total;i++)

     {

      rates[i].index_base=i*5;

      rates[i].timeframe=(ENUM_TIMEFRAMES)list_timeframes.At(i);

      SetIndexBuffer(0+i*5,rates[i].Open,INDICATOR_DATA);

      SetIndexBuffer(1+i*5,rates[i].High,INDICATOR_DATA);

      SetIndexBuffer(2+i*5,rates[i].Low,INDICATOR_DATA);

      SetIndexBuffer(3+i*5,rates[i].Close,INDICATOR_DATA);

      SetIndexBuffer(4+i*5,rates[i].Colors,INDICATOR_COLOR_INDEX);

      //---

      ArraySetAsSeries(rates[i].Open,true);

      ArraySetAsSeries(rates[i].High,true);

      ArraySetAsSeries(rates[i].Low,true);

      ArraySetAsSeries(rates[i].Close,true);

      ArraySetAsSeries(rates[i].Colors,true);

      ArraySetAsSeries(rates[i].array_rates,true);

      //---

      Time(NULL,rates[i].timeframe,1);

     }

//---

   for(int i=0;i<ArraySize(rates);i++)

     {

      int shift=i*(bars_count+gap);

      rates[i].shift=shift;

      string tf=TimeframeToString((ENUM_TIMEFRAMES)rates[i].timeframe);

      PlotIndexSetInteger(i,PLOT_DRAW_TYPE,DRAW_COLOR_CANDLES);

      PlotIndexSetInteger(i,PLOT_LINE_WIDTH,8);

      PlotIndexSetInteger(i,PLOT_COLOR_INDEXES,list_colors.Total());

      for(int j=0;j<list_colors.Total();j++)

         PlotIndexSetInteger(i,PLOT_LINE_COLOR,j,list_colors.At(j));

      PlotIndexSetString(i,PLOT_LABEL,tf+" Open;"+tf+" High;"+tf+" Low;"+tf+" Close");

      PlotIndexSetInteger(i,PLOT_SHIFT,-shift);

      //---

     }

//--- setting indicator parameters

   IndicatorSetString(INDICATOR_SHORTNAME,"MTF Price Candle");

   IndicatorSetInteger(INDICATOR_DIGITS,Digits());

//---

   return(INIT_SUCCEEDED);

  }

//+------------------------------------------------------------------+

//| Custom indicator deinitialization function                       |

//+------------------------------------------------------------------+

void OnDeinit(const int reason)

  {

//--- timer

   EventKillTimer();

   ObjectsDeleteAll(0,prefix);

   ChartRedraw();

//---

  }

//+------------------------------------------------------------------+

//| 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[])

  {

//--- #AB0=>2:0 <0AA82>2 1CD5@>2 :0: B09<A5@89

   ArraySetAsSeries(open,true);

   ArraySetAsSeries(high,true);

   ArraySetAsSeries(low,true);

   ArraySetAsSeries(close,true);

   ArraySetAsSeries(time,true);

//--- @>25@:0 :>;8G5AB20 4>ABC?=KE 10@>2

   if(rates_total<list_timeframes.Total()) return 0;

//---  0AGQB @07<5@>2

   wnd=ChartWindowFind();

   double max=ChartGetDouble(0,CHART_PRICE_MAX,wnd);

   double min=ChartGetDouble(0,CHART_PRICE_MIN,wnd);

   double pp2=(max-min)/20;

   double p1=max-pp2;

   double p2=min+pp2;

//--- @>25@:0 8 @0AGQB :>;8G5AB20 ?@>AG8BK205<KE 10@>2

   int limit=rates_total-prev_calculated;

   if(limit>0)

     {

      limit=rates_total-1;

      int total=ArraySize(rates);

      for(int i=0;i<total;i++)

        {

         ArrayInitialize(rates[i].Open,EMPTY_VALUE);

         ArrayInitialize(rates[i].High,EMPTY_VALUE);

         ArrayInitialize(rates[i].Low,EMPTY_VALUE);

         ArrayInitialize(rates[i].Close,EMPTY_VALUE);

         ArrayInitialize(rates[i].Colors,2);

         

         datetime t1=time[rates[i].shift+bars_count];

         datetime t2=time[rates[i].shift]+PeriodSeconds();

         string name=prefix+TimeframeToString(rates[i].timeframe);

         DrawRectangle(name,wnd,t1,p1,t2,p2,InpColorT,1,0);

        }

     }

//---  0AGQB 8=48:0B>@0

   int total=ArraySize(rates);

   for(int i=0;i<total;i++)

     {

      if(GetDataCandle(rates[i].timeframe,rates[i].array_rates))

        {

         for(int j=0;j<bars_count;j++)

           {

            rates[i].Open[j]=rates[i].array_rates[j].open;

            rates[i].High[j]=rates[i].array_rates[j].high;

            rates[i].Low[j]=rates[i].array_rates[j].low;

            rates[i].Close[j]=rates[i].array_rates[j].close;

            rates[i].Colors[j]=(rates[i].Close[j]>rates[i].Open[j] ? 0 : rates[i].Close[j]<rates[i].Open[j] ? 1 : 2);

           }

         datetime t1=time[rates[i].shift+bars_count];

         datetime t2=time[rates[i].shift]+PeriodSeconds();

         string tf=TimeframeToString(rates[i].timeframe);

         string name=prefix+tf;

         DrawRectangle(name,wnd,t1,p1,t2,p2,InpColorT,1,0);

         DrawText(name+"_T",wnd,p2,t1,InpColorT,8,ANCHOR_LEFT_LOWER,"  "+tf);

        }

     }

     

//--- return value of prev_calculated for next call

   return(rates_total);

  }

//+------------------------------------------------------------------+

//| Custom indicator timer function                                  |

//+------------------------------------------------------------------+

void OnTimer()

  {

   int total=list_timeframes.Total();

   for(int i=0;i<total;i++)

     {

      if(list_timeframes.At(i)==Period())

         return;

      Time(NULL,ENUM_TIMEFRAMES(list_timeframes.At(i)),1);

     }

  }  

//+------------------------------------------------------------------+

//| >72@0I05B 40==K5 A25G8                                          |

//+------------------------------------------------------------------+

bool GetDataCandle(const ENUM_TIMEFRAMES timeframe,MqlRates &data[])

  {

   return(CopyRates(NULL,timeframe,0,bars_count,data)==bars_count);

  }

//+------------------------------------------------------------------+

//| >72@0I05B Time                                                  |

//+------------------------------------------------------------------+

datetime Time(const string symbol_name,const ENUM_TIMEFRAMES timeframe,const int shift)

  {

   datetime array[];

   return(CopyTime(symbol_name,timeframe,shift,1,array)==1 ? array[0] : 0);

  }

//+------------------------------------------------------------------+

//|  8AC5B ?@O<>C3>;L=8:                                             |

//+------------------------------------------------------------------+

void DrawRectangle(const string name,

                   const int sub_win,

                   const datetime time1,

                   const double price1,

                   const datetime time2,

                   const double price2,

                   const color rect_color,

                   const int border_width,

                   const ENUM_LINE_STYLE border_style,

                   const bool background=true,

                   const bool fill=false,

                   const string text="\n",

                   const string tooltip="\n")

  {

   if(ObjectFind(0,name)<0)

     {

      ObjectCreate(0,name,OBJ_RECTANGLE,sub_win,time1,price1,time2,price2);

      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);

      ObjectSetInteger(0,name,OBJPROP_SELECTED,false);

      ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);

     }

   ObjectSetInteger(0,name,OBJPROP_TIME,0,time1);

   ObjectSetInteger(0,name,OBJPROP_TIME,1,time2);

   ObjectSetDouble(0,name,OBJPROP_PRICE,0,price1);

   ObjectSetDouble(0,name,OBJPROP_PRICE,1,price2);

//---

   ObjectSetInteger(0,name,OBJPROP_FILL,fill);

   ObjectSetInteger(0,name,OBJPROP_BACK,background);

   ObjectSetInteger(0,name,OBJPROP_WIDTH,border_width);

   ObjectSetInteger(0,name,OBJPROP_COLOR,rect_color);

   ObjectSetInteger(0,name,OBJPROP_STYLE,border_style);

   ObjectSetString(0,name,OBJPROP_TEXT,text);

   ObjectSetString(0,name,OBJPROP_TOOLTIP,tooltip);

  }

//+------------------------------------------------------------------+

//| K2>48B B5:AB                                                    |

//+------------------------------------------------------------------+

void DrawText(const string name,

              const int sub_win,

              const double price,

              const datetime time,

              const color text_color,

              const int font_size,

              const ENUM_ANCHOR_POINT anchor,

              const string text,

              const string font_name="Calibri",

              const string tooltip="\n")

  {

   if(ObjectFind(0,name)<0)

     {

      ObjectCreate(0,name,OBJ_TEXT,sub_win,time,price);

      ObjectSetInteger(0,name,OBJPROP_SELECTABLE,false);

      ObjectSetInteger(0,name,OBJPROP_SELECTED,false);

      ObjectSetInteger(0,name,OBJPROP_HIDDEN,true);

      ObjectSetString(0,name,OBJPROP_FONT,font_name);

     }

   ObjectSetInteger(0,name,OBJPROP_ANCHOR,anchor);

   ObjectSetInteger(0,name,OBJPROP_TIME,0,time);

   ObjectSetDouble(0,name,OBJPROP_PRICE,0,price);

//---

   ObjectSetInteger(0,name,OBJPROP_FONTSIZE,font_size);

   ObjectSetInteger(0,name,OBJPROP_COLOR,text_color);

   ObjectSetString(0,name,OBJPROP_TEXT,text);

   ObjectSetString(0,name,OBJPROP_TOOLTIP,tooltip);

  }

//+------------------------------------------------------------------+

//| >72@0I05B 2E>4=>9 ?0@0<5B@ B09<D@59<0 ?> 8=45:AC                |

//+------------------------------------------------------------------+

int GetInputTimeframe(const int index)

  {

   switch(index)

     {

      case 0   : return (InpUseM1   ? PERIOD_M1    : WRONG_VALUE);

      case 1   : return (InpUseM2   ? PERIOD_M2    : WRONG_VALUE);

      case 2   : return (InpUseM3   ? PERIOD_M3    : WRONG_VALUE);

      case 3   : return (InpUseM4   ? PERIOD_M4    : WRONG_VALUE);

      case 4   : return (InpUseM5   ? PERIOD_M5    : WRONG_VALUE);

      case 5   : return (InpUseM6   ? PERIOD_M6    : WRONG_VALUE);

      case 6   : return (InpUseM10  ? PERIOD_M10   : WRONG_VALUE);

      case 7   : return (InpUseM12  ? PERIOD_M12   : WRONG_VALUE);

      case 8   : return (InpUseM15  ? PERIOD_M15   : WRONG_VALUE);

      case 9   : return (InpUseM20  ? PERIOD_M20   : WRONG_VALUE);

      case 10  : return (InpUseM30  ? PERIOD_M30   : WRONG_VALUE);

      case 11  : return (InpUseH1   ? PERIOD_H1    : WRONG_VALUE);

      case 12  : return (InpUseH2   ? PERIOD_H2    : WRONG_VALUE);

      case 13  : return (InpUseH3   ? PERIOD_H3    : WRONG_VALUE);

      case 14  : return (InpUseH4   ? PERIOD_H4    : WRONG_VALUE);

      case 15  : return (InpUseH6   ? PERIOD_H6    : WRONG_VALUE);

      case 16  : return (InpUseH8   ? PERIOD_H8    : WRONG_VALUE);

      case 17  : return (InpUseH12  ? PERIOD_H12   : WRONG_VALUE);

      case 18  : return (InpUseD1   ? PERIOD_D1    : WRONG_VALUE);

      case 19  : return (InpUseW1   ? PERIOD_W1    : WRONG_VALUE);

      case 20  : return (InpUseMN1  ? PERIOD_MN1   : WRONG_VALUE);

      default  : return WRONG_VALUE;

     }

  }

//+------------------------------------------------------------------+

//| Timeframe to string                                              |

//+------------------------------------------------------------------+

string TimeframeToString(const ENUM_TIMEFRAMES timeframe)

  {

   return StringSubstr(EnumToString(timeframe),7);

  }

//+------------------------------------------------------------------+

Comments