Period_Donchian_Channel

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

//|                                      Period_Donchian_Channel.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 "Period Donchian Channel indicator"

#property indicator_chart_window

#property indicator_buffers 3

#property indicator_plots   3

//--- plot UP

#property indicator_label1  "Top"

#property indicator_type1   DRAW_LINE

#property indicator_color1  clrRed

#property indicator_style1  STYLE_SOLID

#property indicator_width1  1

//--- plot MD

#property indicator_label2  "Middle"

#property indicator_type2   DRAW_LINE

#property indicator_color2  clrGreen

#property indicator_style2  STYLE_SOLID

#property indicator_width2  1

//--- plot DN

#property indicator_label3  "Bottom"

#property indicator_type3   DRAW_LINE

#property indicator_color3  clrBlue

#property indicator_style3  STYLE_SOLID

#property indicator_width3  1

//--- enums

enum ENUM_INPUT_YES_NO

  {

   INPUT_YES   =  1,    // Yes

   INPUT_NO    =  0     // No

  };

//--- input parameters

input uint              InpPeriod      =  20;         // Channel period

input ENUM_TIMEFRAMES   InpTimeframe   =  PERIOD_H1;  // Timeframe

input ENUM_INPUT_YES_NO InpShowMiddle  =  INPUT_YES;  // Show middle line

//--- indicator buffers

double         BufferUP[];

double         BufferMD[];

double         BufferDN[];

//--- global variables

int            period;

int            range;

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

//| Custom indicator initialization function                         |

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

int OnInit()

  {

//--- timer

   EventSetTimer(90);

//--- set global variables

   period=int(InpPeriod<1 ? 1 : InpPeriod);

   range=period*MinutesInPeriod(InpTimeframe)*60;

//--- indicator buffers mapping

   SetIndexBuffer(0,BufferUP,INDICATOR_DATA);

   SetIndexBuffer(1,BufferMD,INDICATOR_DATA);

   SetIndexBuffer(2,BufferDN,INDICATOR_DATA);

//--- setting indicator parameters

   IndicatorSetString(INDICATOR_SHORTNAME,"Period Donchian Channel ("+(string)period+", "+TimeframeToString(InpTimeframe)+")");

   IndicatorSetInteger(INDICATOR_DIGITS,Digits());

//--- setting plot buffer parameters

   PlotIndexSetInteger(1,PLOT_DRAW_TYPE,InpShowMiddle);

//--- setting buffer arrays as timeseries

   ArraySetAsSeries(BufferUP,true);

   ArraySetAsSeries(BufferMD,true);

   ArraySetAsSeries(BufferDN,true);

//--- get timeframe

   Time(NULL,InpTimeframe,1);

//---

   return(INIT_SUCCEEDED);

  }

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

//| 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(high,true);

   ArraySetAsSeries(low,true);

   ArraySetAsSeries(time,true);

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

   int bars=(InpTimeframe==PERIOD_CURRENT || InpTimeframe==Period() ? rates_total : Bars(NULL,InpTimeframe));

   if(bars==0)

      return 0;

   if(rates_total<4 || Time(NULL,InpTimeframe,1)==0) return 0;

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

   int limit=rates_total-prev_calculated;

   if(limit>1)

     {

      limit=rates_total-2;

      ArrayInitialize(BufferUP,EMPTY_VALUE);

      ArrayInitialize(BufferMD,EMPTY_VALUE);

      ArrayInitialize(BufferDN,EMPTY_VALUE);

     }



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

   for(int i=limit; i>=0 && !IsStopped(); i--)

     {

      datetime time_start=time[i]-range;

      if(time_start<=0)

         continue;

      int bar_start=BarShift(NULL,PERIOD_CURRENT,time_start,false);

      if(bar_start==WRONG_VALUE || bar_start>rates_total-2)

         continue;

      double max=0;

      double min=DBL_MAX;

      for(int j=bar_start; j>=i; j--)

        {

         max=fmax(max,high[j]);

         min=fmin(min,low[j]);

        }

      if(min==DBL_MAX || max==0)

         continue;

      BufferUP[i]=max;

      BufferDN[i]=min;

      BufferMD[i]=(min+max)/2.0;

     }



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

   return(rates_total);

  }

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

//| Custom indicator timer function                                  |

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

void OnTimer()

  {

   Time(NULL,InpTimeframe,1);

  }  

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

//| >72@0I05B Time                                                  |

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

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

  {

   datetime array[];

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

  }  

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

//| >72@0I05B :>;8G5AB2> <8=CB 2 ?5@8>45                            |

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

int MinutesInPeriod(const ENUM_TIMEFRAMES timeframe)

  {

   return PeriodSeconds(timeframe!=PERIOD_CURRENT ? timeframe : Period())/60;

  }

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

//| >72@0I05B :>;8G5AB2> 10@>2 2 ?5@8>45                            |

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

int BarsCurrentInTimeframe(const ENUM_TIMEFRAMES timeframe)

  {

   return MinutesInPeriod(timeframe)/MinutesInPeriod(PERIOD_CURRENT);

  }

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

//| Timeframe to string                                              |

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

string TimeframeToString(const ENUM_TIMEFRAMES timeframe)

  {

   return StringSubstr(EnumToString(timeframe),7);

  }

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

//| >72@0I05B A<5I5=85 10@0 ?> 2@5<5=8                              |

//| https://www.mql5.com/ru/forum/743/page11#comment_7010041         |

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

int BarShift(const string symbol_name,const ENUM_TIMEFRAMES timeframe,const datetime time,bool exact=false)

  {

   int res=Bars(symbol_name,timeframe,time+1,UINT_MAX);

   if(exact) if((timeframe!=PERIOD_MN1 || time>TimeCurrent()) && res==Bars(symbol_name,timeframe,time-PeriodSeconds(timeframe)+1,UINT_MAX)) return(WRONG_VALUE);

   return res;

  }

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

Comments

Markdown supported. Formatting help

Markdown Formatting Guide

Element Markdown Syntax
Heading # H1
## H2
### H3
Bold **bold text**
Italic *italicized text*
Link [title](https://www.example.com)
Image ![alt text](image.jpg)
Code `code`
Code Block ```
code block
```
Quote > blockquote
Unordered List - Item 1
- Item 2
Ordered List 1. First item
2. Second item
Horizontal Rule ---