0
Views
0
Downloads
0
Favorites
SHI_Channel_true
//+------------------------------------------------------------------+
//| SHI_Channel_true.mq5 |
//| Copyright © 2004, Shurka & Kevin |
//+------------------------------------------------------------------+
//---- author of the indicator
#property copyright "Copyright © 2004, Shurka & Kevin"
//---- link to the website of the author
#property link ""
//---- indicator version
#property version "1.00"
//---- drawing the indicator in the main window
#property indicator_chart_window
//---- one buffer is used for calculation and drawing the indicator
#property indicator_buffers 1
//---- only one plot is used
#property indicator_plots 1
//---- drawing the indicator as a line
#property indicator_type1 DRAW_ARROW
//---- blue color is used as the color of the indicator line
#property indicator_color1 Blue
//---- the indicator line is a continuous curve
#property indicator_style1 STYLE_SOLID
//---- indicator line width is equal to 2
#property indicator_width1 2
//---- displaying the indicator label
#property indicator_label1 "SHI Channel true"
//---- indicator input parameters
input int AllBars=240;
input int BarsForFract=0;
input color UpChannelColor=Lime;
input color MdChannelColor=Blue;
input color DnChannelColor=Red;
//---- declaration of a dynamic array that further
//---- will be used as an indicator buffer
double ExtBuffer[];
int count,BFF;
//---- declaration of the integer variables for the start of data calculation
int StartBars;
//+------------------------------------------------------------------+
//| Creating a trend line |
//+------------------------------------------------------------------+
void CreateTline
(long chart_id, // chart ID
string name, // object name
int nwin, // window index
datetime time1, // time 1 of the price level
double price1, // price level 1
datetime time2, // time 2 of the price level
double price2, // price level 2
color Color, // line color
int style, // line style
int width, // line width
string text) // text
{
//----
ObjectCreate(chart_id,name,OBJ_TREND,nwin,time1,price1,time2,price2);
ObjectSetInteger(chart_id,name,OBJPROP_COLOR,Color);
ObjectSetInteger(chart_id,name,OBJPROP_STYLE,style);
ObjectSetInteger(chart_id,name,OBJPROP_WIDTH,width);
ObjectSetString(chart_id,name,OBJPROP_TEXT,text);
ObjectSetInteger(chart_id,name,OBJPROP_BACK,true);
//----
}
//+------------------------------------------------------------------+
//| Trend line reinstallation |
//+------------------------------------------------------------------+
void SetTline
(long chart_id, // chart ID
string name, // object name
int nwin, // window index
datetime time1, // time 1 of the price level
double price1, // price level 1
datetime time2, // time 2 of the price level
double price2, // price level 2
color Color, // line color
int style, // line style
int width, // line width
string text) // text
{
//----
if(ObjectFind(chart_id,name)==-1) CreateTline(chart_id,name,nwin,time1,price1,time2,price2,Color,style,width,text);
else
{
ObjectSetString(chart_id,name,OBJPROP_TEXT,text);
ObjectMove(chart_id,name,0,time1,price1);
ObjectMove(chart_id,name,1,time2,price2);
}
//----
}
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
void OnInit()
{
//---- initialization of variables
if(BarsForFract>0) BFF=BarsForFract;
else switch(Period())
{
case PERIOD_M1: BFF=12; break;
case PERIOD_M2: BFF=24; break;
case PERIOD_M3: BFF=36; break;
case PERIOD_M4: BFF=40; break;
case PERIOD_M5: BFF=48; break;
case PERIOD_M6: BFF=12; break;
case PERIOD_M10: BFF=15; break;
case PERIOD_M12: BFF=20; break;
case PERIOD_M15: BFF=24; break;
case PERIOD_M20: BFF=24; break;
case PERIOD_M30: BFF=24; break;
case PERIOD_H1: BFF=12; break;
case PERIOD_H2: BFF=12; break;
case PERIOD_H3: BFF=12; break;
case PERIOD_H4: BFF=15; break;
case PERIOD_H6: BFF=12; break;
case PERIOD_H8: BFF=12; break;
case PERIOD_H12: BFF=12; break;
case PERIOD_D1: BFF=10; break;
case PERIOD_W1: BFF=6; break;
case PERIOD_MN1: BFF=6; break;
}
count=BFF*2+1;
StartBars=MathMax(BFF-1,AllBars);
//---- set ExteBuffer dynamic array as an indicator buffer
SetIndexBuffer(0,ExtBuffer,INDICATOR_DATA);
//---- set the position, from which the indicator drawing starts
PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,StartBars);
//---- indexing the elements in buffers as timeseries
ArraySetAsSeries(ExtBuffer,true);
//---- initializations of a variable for the indicator short name
string shortname="SHI Channel true";
//--- create label to display in Data Window
PlotIndexSetString(0,PLOT_LABEL,shortname);
//---- creating a name for displaying in a separate sub-window and in a tooltip
IndicatorSetString(INDICATOR_SHORTNAME,shortname);
//---- determination of accuracy of displaying the indicator values
IndicatorSetInteger(INDICATOR_DIGITS,_Digits+1);
//---- restriction to draw empty values for the indicator
PlotIndexSetDouble(0,PLOT_EMPTY_VALUE,0.0);
//----
}
//+------------------------------------------------------------------+
//| Deleting objects from a chart |
//+------------------------------------------------------------------+
void DelObj()
{
//----
ObjectDelete(0,"Upper SHI");
ObjectDelete(0,"Lower SHI");
ObjectDelete(0,"Middle SHI");
Comment("");
//----
}
//+------------------------------------------------------------------+
//| Custom indicator deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//----
DelObj();
//----
}
//+------------------------------------------------------------------+
//| Custom indicator iteration function |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total, // number of bars in history at the current tick
const int prev_calculated,// number of bars calculated at previous call
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 the number of bars to be enough for the calculation
if(rates_total<StartBars) return(0);
double Step,iprice,P1=0,P2=0,PP;
int nbar,bar,B1,B2,UpDown,ishift,i,AB;
datetime T1,T2;
//---- indexing elements in arrays as timeseries
ArraySetAsSeries(time,true);
ArraySetAsSeries(close,true);
ArraySetAsSeries(high,true);
ArraySetAsSeries(low,true);
ArrayInitialize(ExtBuffer,0.0);
if(AllBars==0 || rates_total<AllBars)
AB=rates_total;
else AB=AllBars; //AB-quantity of calculated bars
bar=2; //calculating from the third bar to let the fractal "fix"
B1 = -1;
B2 = -1;
UpDown=0;
while((B1==-1 || B2==-1) && bar<AB)
{
ExtBuffer[bar]=0.0;
nbar=bar-BFF;
if(nbar<0)nbar=0;
//---- UpDown = 1, that means the first fractal is found above, UpDown = -1 means that the first fractal
//---- is found below, UpDown = 0 means that the fractal is not found yet.
//---- Â1 and Â2 are the indexes of bars with fractals. The reference line is built through them.
//---- Ð1 and Ð2 are prices, through which the line is drawn
if(UpDown<1 && bar==ArrayMinimum(low,nbar,count))
{
if(UpDown==0)
{
UpDown=-1;
B1 = bar;
P1 = low[B1];
}
else
{
B2 = bar;
P2 = low[B2];
}
}
if(UpDown>-1 && bar==ArrayMaximum(high,nbar,count))
{
if(UpDown==0)
{
UpDown=1;
B1 = bar;
P1 = high[B1];
}
else
{
B2 = bar;
P2 = high[B2];
}
}
bar++;
}
if(B1==-1 || B2==-1)
{
DelObj();
return(0);
} // It means thaere are no fractals among 300 bars
Step=(P2-P1)/(B2-B1); //The step is calculated. If it is positive, the channel is descending
P1=P1-B1*Step;
B1=0; //relocate the price and the first bar to zero
//And now it is the turn for the reference point of the channel's opposite line.
ishift = 0;
iprice = 0;
if(UpDown==1)
{
PP=low[2]-2*Step;
for(i=3; i<=B2; i++) if(low[i]<PP+Step*i) PP=low[i]-i*Step;
if(low[0]<PP)
{
ishift = 0;
iprice = PP;
}
if(low[1]<PP+Step)
{
ishift = 1;
iprice = PP + Step;
}
if(high[0]>P1)
{
ishift = 0;
iprice = P1;
}
if(low[1]>P1+Step)
{
ishift = 1;
iprice = P1 + Step;
}
}
else
{
PP=high[2]-2*Step;
for(i=3; i<=B2; i++) if(high[i]>PP+Step*i) PP=high[i]-i*Step;
if(low[0]<P1)
{
ishift = 0;
iprice = P1;
}
if(low[1]<P1+Step)
{
ishift = 1;
iprice = P1 + Step;
}
if(high[0]>PP)
{
ishift = 0;
iprice = PP;
}
if(high[1]>PP+Step)
{
ishift = 1;
iprice = PP + Step;
}
}
//---- now, let's relocate the final price and bar to AB for the channel lines to be drawn longer
P2 = P1 + AB*Step;
T1 = time[B1];
T2 = time[AB];
//---- if there has been no channel crossing. then 0, otherwise, set the reference point price.
if(iprice!=0) ExtBuffer[ishift]=iprice;
else ExtBuffer[ishift]=0.0;
SetTline(0,"Upper SHI",0,T2,PP+Step*AB,T1,PP,UpChannelColor,STYLE_SOLID,2,"Upper SHI");
SetTline(0,"Lower SHI",0,T2,P2,T1,P1,DnChannelColor,STYLE_SOLID,2,"Lower SHI");
SetTline(0,"Middle SHI",0,T2,(P2+PP+Step*AB)/2,T1,(P1+PP)/2,MdChannelColor,STYLE_DOT,1,"Middle SHI");
Comment(" Channel size = ",DoubleToString(MathAbs(PP-P1)/_Point,0)," Slope = ",DoubleToString(-Step/_Point,2));
//----
return(rates_total);
}
//+------------------------------------------------------------------+
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

`code`
```
code block
```
> blockquote
- Item 1
- Item 2
1. First item
2. Second item
---