last ...
This commit is contained in:
Binary file not shown.
@@ -0,0 +1,250 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Camarilla Channel.mq5 |
|
||||
//| Copyright 2009-2024, MetaQuotes Ltd |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2024, MetaQuotes Ltd"
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "Camarilla Channels"
|
||||
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 10
|
||||
#property indicator_plots 10
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrGreen
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrGreen
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrGreen
|
||||
#property indicator_width3 2
|
||||
#property indicator_type4 DRAW_LINE
|
||||
#property indicator_color4 clrGreen
|
||||
#property indicator_type5 DRAW_LINE
|
||||
#property indicator_color5 clrGreen
|
||||
#property indicator_type6 DRAW_LINE
|
||||
#property indicator_color6 clrRed
|
||||
#property indicator_type7 DRAW_LINE
|
||||
#property indicator_color7 clrRed
|
||||
#property indicator_type8 DRAW_LINE
|
||||
#property indicator_color8 clrRed
|
||||
#property indicator_width8 2
|
||||
#property indicator_type9 DRAW_LINE
|
||||
#property indicator_color9 clrRed
|
||||
#property indicator_type10 DRAW_LINE
|
||||
#property indicator_color10 clrRed
|
||||
//--- labels
|
||||
#property indicator_label1 "H5"
|
||||
#property indicator_label2 "H4"
|
||||
#property indicator_label3 "H3"
|
||||
#property indicator_label4 "H2"
|
||||
#property indicator_label5 "H1"
|
||||
#property indicator_label6 "L1"
|
||||
#property indicator_label7 "L2"
|
||||
#property indicator_label8 "L3"
|
||||
#property indicator_label9 "L4"
|
||||
#property indicator_label10 "L5"
|
||||
|
||||
//--- input parameter
|
||||
input bool InpShowLabel=true; // show price of level
|
||||
|
||||
//--- indicator buffers
|
||||
double ExtH5Buffer[];
|
||||
double ExtH4Buffer[];
|
||||
double ExtH3Buffer[];
|
||||
double ExtH2Buffer[];
|
||||
double ExtH1Buffer[];
|
||||
double ExtL1Buffer[];
|
||||
double ExtL2Buffer[];
|
||||
double ExtL3Buffer[];
|
||||
double ExtL4Buffer[];
|
||||
double ExtL5Buffer[];
|
||||
|
||||
//--- unique prefix to identify indicator objects
|
||||
string ExtPrefixUniq;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- check current timeframe
|
||||
if(PeriodSeconds()>PeriodSeconds(PERIOD_D1))
|
||||
{
|
||||
Alert("Timeframe of chart must be D1 or lower. Exit");
|
||||
return(INIT_FAILED);
|
||||
}
|
||||
|
||||
//--- define buffers
|
||||
SetIndexBuffer(0, ExtH5Buffer);
|
||||
SetIndexBuffer(1, ExtH4Buffer);
|
||||
SetIndexBuffer(2, ExtH3Buffer);
|
||||
SetIndexBuffer(3, ExtH2Buffer);
|
||||
SetIndexBuffer(4, ExtH1Buffer);
|
||||
SetIndexBuffer(5, ExtL1Buffer);
|
||||
SetIndexBuffer(6, ExtL2Buffer);
|
||||
SetIndexBuffer(7, ExtL3Buffer);
|
||||
SetIndexBuffer(8, ExtL4Buffer);
|
||||
SetIndexBuffer(9, ExtL5Buffer);
|
||||
|
||||
//--- indicator name
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, "Camarilla Channels");
|
||||
//--- number of digits of indicator value
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||
|
||||
//--- prepare prefix for objects
|
||||
string number=StringFormat("%I64d", GetTickCount64());
|
||||
ExtPrefixUniq=StringSubstr(number, StringLen(number)-4);
|
||||
ExtPrefixUniq=ExtPrefixUniq+"_CH";
|
||||
Print("Indicator \"Camarilla Channels\" started, prefix=", ExtPrefixUniq);
|
||||
|
||||
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[])
|
||||
{
|
||||
static MqlRates LAST_DAY[]; // previous day
|
||||
static datetime last_time=0; // reference time
|
||||
static datetime error_time=0; // error output time
|
||||
|
||||
//--- if the indicator has previously been calculated, start from the bar preceding the last one
|
||||
int start=prev_calculated-1;
|
||||
|
||||
//--- if this is the first calculation of the indicator, start from the first bar on the chart
|
||||
if(prev_calculated==0)
|
||||
start=0;
|
||||
|
||||
//--- calculate levels for all bars in a loop
|
||||
for(int i=start; i<rates_total; i++)
|
||||
{
|
||||
//--- get day opening time for the current bar
|
||||
datetime rem_seconds=time[i]%PeriodSeconds(PERIOD_D1);
|
||||
datetime open_time=time[i]-rem_seconds;
|
||||
|
||||
//--- if the opening time is different from the reference time, update LAST_DAY - level calculations will be based on this value
|
||||
if(open_time!=last_time)
|
||||
{
|
||||
//--- If you're running the indicator on this symbol for the first time,
|
||||
//--- first open the D1 chart for the symbol to initiate immediate downloading of daily bars
|
||||
//--- if getting the current timeframe bars for the specified day fails
|
||||
if(CopyRates(Symbol(), PERIOD_D1, open_time-1, 1, LAST_DAY)!=-1)
|
||||
{
|
||||
//--- remember the reference time
|
||||
last_time=open_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- generate error messages no more than once a minute
|
||||
if(TimeCurrent()>=error_time)
|
||||
{
|
||||
error_time=TimeCurrent()+60;
|
||||
Print("Failed to get previous day by CopyRates(Symbol(), PERIOD_D1, error ", GetLastError());
|
||||
}
|
||||
return(prev_calculated);
|
||||
}
|
||||
}
|
||||
|
||||
//--- calculate levels
|
||||
double range=LAST_DAY[0].high - LAST_DAY[0].low;
|
||||
double h5=(LAST_DAY[0].high/LAST_DAY[0].low) * LAST_DAY[0].close;
|
||||
double h4=LAST_DAY[0].close + range*1.1/2.0;
|
||||
double h3=LAST_DAY[0].close + range*1.1/4.0;
|
||||
double h2=LAST_DAY[0].close + range*1.1/6.0;
|
||||
double h1=LAST_DAY[0].close + range*1.1/12.0;
|
||||
double l1=LAST_DAY[0].close - range*1.1/12.0;
|
||||
double l2=LAST_DAY[0].close - range*1.1/6.0;
|
||||
double l3=LAST_DAY[0].close - range*1.1/4.0;
|
||||
double l4=LAST_DAY[0].close - range*1.1/2.0;
|
||||
double l5=LAST_DAY[0].close - (h5 -LAST_DAY[0].close);
|
||||
|
||||
//--- write values into buffers
|
||||
ExtH5Buffer[i]=h5;
|
||||
ExtH4Buffer[i]=h4;
|
||||
ExtH3Buffer[i]=h3;
|
||||
ExtH2Buffer[i]=h2;
|
||||
ExtH1Buffer[i]=h1;
|
||||
ExtL1Buffer[i]=l1;
|
||||
ExtL2Buffer[i]=l2;
|
||||
ExtL3Buffer[i]=l3;
|
||||
ExtL4Buffer[i]=l4;
|
||||
ExtL5Buffer[i]=l5;
|
||||
}
|
||||
|
||||
//--- draw labels on levels
|
||||
if(InpShowLabel)
|
||||
{
|
||||
ShowPriceLevels(time[rates_total-1], rates_total-1);
|
||||
ChartRedraw();
|
||||
}
|
||||
|
||||
//--- succesfully calculated
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//--- delete all our graphical objects after use
|
||||
Print("Indicator \"Camarilla Channels\" stopped, delete all objects with prefix=", ExtPrefixUniq);
|
||||
ObjectsDeleteAll(0, ExtPrefixUniq, 0, OBJ_ARROW_RIGHT_PRICE);
|
||||
ChartRedraw(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Show prices' levels |
|
||||
//+------------------------------------------------------------------+
|
||||
void ShowPriceLevels(datetime time, int last_index)
|
||||
{
|
||||
ShowRightPrice(ExtPrefixUniq+"_H5", time, ExtH5Buffer[last_index], clrGreen);
|
||||
ShowRightPrice(ExtPrefixUniq+"_H4", time, ExtH4Buffer[last_index], clrGreen);
|
||||
ShowRightPrice(ExtPrefixUniq+"_H3", time, ExtH3Buffer[last_index], clrGreen);
|
||||
ShowRightPrice(ExtPrefixUniq+"_H2", time, ExtH2Buffer[last_index], clrGreen);
|
||||
ShowRightPrice(ExtPrefixUniq+"_H1", time, ExtH1Buffer[last_index], clrGreen);
|
||||
ShowRightPrice(ExtPrefixUniq+"_L1", time, ExtL1Buffer[last_index], clrRed);
|
||||
ShowRightPrice(ExtPrefixUniq+"_L2", time, ExtL2Buffer[last_index], clrRed);
|
||||
ShowRightPrice(ExtPrefixUniq+"_L3", time, ExtL3Buffer[last_index], clrRed);
|
||||
ShowRightPrice(ExtPrefixUniq+"_L4", time, ExtL4Buffer[last_index], clrRed);
|
||||
ShowRightPrice(ExtPrefixUniq+"_L5", time, ExtL5Buffer[last_index], clrRed);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create or Update "Right Price Label" object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool ShowRightPrice(const string name, datetime time, double price, color clr)
|
||||
{
|
||||
if(!ObjectCreate(0, name, OBJ_ARROW_RIGHT_PRICE, 0, time, price))
|
||||
{
|
||||
ObjectMove(0, name, 0, time, price);
|
||||
return(false);
|
||||
}
|
||||
|
||||
//--- make the label size adaptive
|
||||
long scale=2;
|
||||
if(!ChartGetInteger(0, CHART_SCALE, 0, scale))
|
||||
{
|
||||
//--- output an error message to the Experts journal
|
||||
Print(__FUNCTION__+", ChartGetInteger(CHART_SCALE) failed, error = ", GetLastError());
|
||||
}
|
||||
int width=scale>1 ? 2:1; // if chart scale > 1, then label size = 2
|
||||
|
||||
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
|
||||
ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
|
||||
ObjectSetInteger(0, name, OBJPROP_WIDTH, width);
|
||||
ObjectSetInteger(0, name, OBJPROP_BACK, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTED, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
|
||||
ObjectSetInteger(0, name, OBJPROP_ZORDER, 0);
|
||||
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,204 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| DeMark Channel.mq5 |
|
||||
//| Copyright 2009-2024, MetaQuotes Ltd |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2024, MetaQuotes Ltd"
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "DeMark Channel"
|
||||
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 3
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrGreen
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrBlue
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrRed
|
||||
//--- labels
|
||||
#property indicator_label1 "PP"
|
||||
#property indicator_label2 "R1"
|
||||
#property indicator_label3 "S1"
|
||||
|
||||
//--- input parameter
|
||||
input bool InpShowLabel=true; // show price of level
|
||||
|
||||
//--- indicator buffers
|
||||
double ExtPPBuffer[];
|
||||
double ExtR1Buffer[];
|
||||
double ExtS1Buffer[];
|
||||
|
||||
//--- unique prefix to identify indicator objects
|
||||
string ExtPrefixUniq;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- check current timeframe
|
||||
if(PeriodSeconds()>PeriodSeconds(PERIOD_D1))
|
||||
{
|
||||
Alert("Timeframe of chart must be D1 or lower. Exit");
|
||||
return(INIT_FAILED);
|
||||
}
|
||||
|
||||
//--- define buffers
|
||||
SetIndexBuffer(0, ExtPPBuffer);
|
||||
SetIndexBuffer(1, ExtR1Buffer);
|
||||
SetIndexBuffer(2, ExtS1Buffer);
|
||||
|
||||
//--- indicator name
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, "DeMark Channel");
|
||||
//--- number of digits of indicator value
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||
|
||||
//--- prepare prefix for objects
|
||||
string number=StringFormat("%I64d", GetTickCount64());
|
||||
ExtPrefixUniq=StringSubstr(number, StringLen(number)-4);
|
||||
ExtPrefixUniq=ExtPrefixUniq+"_DM";
|
||||
Print("Indicator \"DeMark Channels\" started, prefix=", ExtPrefixUniq);
|
||||
|
||||
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[])
|
||||
{
|
||||
static MqlRates LAST_DAY[]; // previous day
|
||||
static datetime last_time=0; // reference time
|
||||
static datetime error_time=0; // error output time
|
||||
|
||||
//--- if the indicator has previously been calculated, start from the bar preceding the last one
|
||||
int start=prev_calculated-1;
|
||||
|
||||
//--- if this is the first calculation of the indicator, start from the first bar on the chart
|
||||
if(prev_calculated==0)
|
||||
start=0;
|
||||
|
||||
//--- calculate levels for all bars in a loop
|
||||
for(int i=start; i<rates_total; i++)
|
||||
{
|
||||
//--- get day opening time for the current bar
|
||||
datetime rem_seconds=time[i]%PeriodSeconds(PERIOD_D1);
|
||||
datetime open_time=time[i]-rem_seconds;
|
||||
|
||||
//--- if the opening time is different from the reference time, update LAST_DAY - level calculations will be based on this value
|
||||
if(open_time!=last_time)
|
||||
{
|
||||
//--- If you're running the indicator on this symbol for the first time,
|
||||
//--- first open the D1 chart for the symbol to initiate immediate downloading of daily bars
|
||||
//--- if getting the current timeframe bars for the specified day fails
|
||||
if(CopyRates(Symbol(), PERIOD_D1, open_time-1, 1, LAST_DAY)!=-1)
|
||||
{
|
||||
//--- remember the reference time
|
||||
last_time=open_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- generate error messages no more than once a minute
|
||||
if(TimeCurrent()>=error_time)
|
||||
{
|
||||
error_time=TimeCurrent()+60;
|
||||
Print("Failed to get previous day by CopyRates(Symbol(), PERIOD_D1, error ", GetLastError());
|
||||
}
|
||||
return(prev_calculated);
|
||||
}
|
||||
}
|
||||
|
||||
//--- preparations
|
||||
double day_close=LAST_DAY[0].close;
|
||||
double day_open=LAST_DAY[0].open;
|
||||
double day_high=LAST_DAY[0].high;
|
||||
double day_low=LAST_DAY[0].low;
|
||||
|
||||
//--- initial calculation
|
||||
double x=day_high+day_low+2*day_close;
|
||||
if(day_close<day_open)
|
||||
x=day_high+2*day_low+day_close;
|
||||
if(day_close>day_open)
|
||||
x=2*day_high+day_low+day_close;
|
||||
|
||||
//--- calculate levels
|
||||
double pivot_point=x/4;
|
||||
double s1=x/2-day_high;
|
||||
double r1=x/2-day_low;
|
||||
|
||||
//--- write values into buffers
|
||||
ExtPPBuffer[i]=pivot_point;
|
||||
ExtR1Buffer[i]=r1;
|
||||
ExtS1Buffer[i]=s1;
|
||||
}
|
||||
|
||||
//--- draw labels on levels
|
||||
if(InpShowLabel)
|
||||
{
|
||||
ShowPriceLevels(time[rates_total-1], rates_total-1);
|
||||
ChartRedraw();
|
||||
}
|
||||
|
||||
//--- succesfully calculated
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//--- delete all our graphical objects after use
|
||||
Print("Indicator \"DeMark Channels\" stopped, delete all objects with prefix=", ExtPrefixUniq);
|
||||
ObjectsDeleteAll(0, ExtPrefixUniq, 0, OBJ_ARROW_RIGHT_PRICE);
|
||||
ChartRedraw(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Show prices' levels |
|
||||
//+------------------------------------------------------------------+
|
||||
void ShowPriceLevels(datetime time, int last_index)
|
||||
{
|
||||
ShowRightPrice(ExtPrefixUniq+"_PP", time, ExtPPBuffer[last_index], clrGreen);
|
||||
ShowRightPrice(ExtPrefixUniq+"_R1", time, ExtR1Buffer[last_index], clrBlue);
|
||||
ShowRightPrice(ExtPrefixUniq+"_S1", time, ExtS1Buffer[last_index], clrRed);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create or Update "Right Price Label" object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool ShowRightPrice(const string name, datetime time, double price, color clr)
|
||||
{
|
||||
if(!ObjectCreate(0, name, OBJ_ARROW_RIGHT_PRICE, 0, time, price))
|
||||
{
|
||||
ObjectMove(0, name, 0, time, price);
|
||||
return(false);
|
||||
}
|
||||
|
||||
//--- make the label size adaptive
|
||||
long scale=2;
|
||||
if(!ChartGetInteger(0, CHART_SCALE, 0, scale))
|
||||
{
|
||||
//--- output an error message to the Experts journal
|
||||
Print(__FUNCTION__+", ChartGetInteger(CHART_SCALE) failed, error = ", GetLastError());
|
||||
}
|
||||
int width=scale>1 ? 2:1; // if chart scale > 1, then label size = 2
|
||||
|
||||
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
|
||||
ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
|
||||
ObjectSetInteger(0, name, OBJPROP_WIDTH, width);
|
||||
ObjectSetInteger(0, name, OBJPROP_BACK, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTED, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
|
||||
ObjectSetInteger(0, name, OBJPROP_ZORDER, 0);
|
||||
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,160 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Donchian Channel.mq5 |
|
||||
//| Copyright 2009-2024, MetaQuotes Ltd |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2024, MetaQuotes Ltd"
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "Donchian Channel"
|
||||
//---
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 3
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrBlue
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrGray
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrRed
|
||||
//--- labels
|
||||
#property indicator_label1 "Upper Donchian"
|
||||
#property indicator_label2 "Middle Donchian"
|
||||
#property indicator_label3 "Lower Donchian"
|
||||
|
||||
//--- input parameter
|
||||
input int InpDonchianPeriod=20; // period of the channel
|
||||
input bool InpShowLabel =true; // show price of the level
|
||||
|
||||
//--- indicator buffers
|
||||
double ExtUpBuffer[];
|
||||
double ExtMdBuffer[];
|
||||
double ExtDnBuffer[];
|
||||
|
||||
//--- unique prefix to identify indicator objects
|
||||
string ExtPrefixUniq;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- define buffers
|
||||
SetIndexBuffer(0, ExtUpBuffer);
|
||||
SetIndexBuffer(1, ExtMdBuffer);
|
||||
SetIndexBuffer(2, ExtDnBuffer);
|
||||
|
||||
//--- set a 1-bar offset for each line
|
||||
PlotIndexSetInteger(0, PLOT_SHIFT, 1);
|
||||
PlotIndexSetInteger(1, PLOT_SHIFT, 1);
|
||||
PlotIndexSetInteger(2, PLOT_SHIFT, 1);
|
||||
|
||||
//--- indicator name
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, "Donchian Channel");
|
||||
//--- number of digits of indicator value
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||
|
||||
//--- prepare prefix for objects
|
||||
string number=StringFormat("%I64d", GetTickCount64());
|
||||
ExtPrefixUniq=StringSubstr(number, StringLen(number)-4);
|
||||
ExtPrefixUniq=ExtPrefixUniq+"_DN";
|
||||
Print("Indicator \"Donchian Channels\" started, prefix=", ExtPrefixUniq);
|
||||
|
||||
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[])
|
||||
{
|
||||
//--- if the indicator has previously been calculated, start from the bar preceding the last one
|
||||
int start=prev_calculated-1;
|
||||
|
||||
//--- if this is the first calculation of the indicator, then move by InpDonchianPeriod bars form the beginning
|
||||
if(prev_calculated==0)
|
||||
start=InpDonchianPeriod+1;
|
||||
|
||||
//--- calculate levels for all bars in a loop
|
||||
for(int i=start; i<rates_total; i++)
|
||||
{
|
||||
//--- get max/min values for the last InpDonchianPeriod bars
|
||||
int highest_bar_index=ArrayMaximum(high, i-InpDonchianPeriod+1, InpDonchianPeriod);
|
||||
int lowest_bar_index=ArrayMinimum(low, i-InpDonchianPeriod+1, InpDonchianPeriod);;
|
||||
double highest=high[highest_bar_index];
|
||||
double lowest=low[lowest_bar_index];
|
||||
|
||||
//--- write values into buffers
|
||||
ExtUpBuffer[i]=highest;
|
||||
ExtDnBuffer[i]=lowest;
|
||||
ExtMdBuffer[i]=(highest+lowest)/2;
|
||||
}
|
||||
|
||||
//--- draw labels on levels
|
||||
if(InpShowLabel)
|
||||
{
|
||||
ShowPriceLevels(time[rates_total-1], rates_total-1);
|
||||
ChartRedraw();
|
||||
}
|
||||
|
||||
//--- succesfully calculated
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//--- delete all our graphical objects after use
|
||||
Print("Indicator \"Donchian Channels\" stopped, delete all objects with prefix=", ExtPrefixUniq);
|
||||
ObjectsDeleteAll(0, ExtPrefixUniq, 0, OBJ_ARROW_RIGHT_PRICE);
|
||||
ChartRedraw(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Show prices' levels |
|
||||
//+------------------------------------------------------------------+
|
||||
void ShowPriceLevels(datetime time, int last_index)
|
||||
{
|
||||
ShowRightPrice(ExtPrefixUniq+"_UP", time, ExtUpBuffer[last_index], clrBlue);
|
||||
ShowRightPrice(ExtPrefixUniq+"_MD", time, ExtMdBuffer[last_index], clrGray);
|
||||
ShowRightPrice(ExtPrefixUniq+"_Dn", time, ExtDnBuffer[last_index], clrRed);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create or Update "Right Price Label" object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool ShowRightPrice(const string name, datetime time, double price, color clr)
|
||||
{
|
||||
if(!ObjectCreate(0, name, OBJ_ARROW_RIGHT_PRICE, 0, time, price))
|
||||
{
|
||||
ObjectMove(0, name, 0, time, price);
|
||||
return(false);
|
||||
}
|
||||
|
||||
//--- make the label size adaptive
|
||||
long scale=2;
|
||||
if(!ChartGetInteger(0, CHART_SCALE, 0, scale))
|
||||
{
|
||||
//--- output an error message to the Experts journal
|
||||
Print(__FUNCTION__+", ChartGetInteger(CHART_SCALE) failed, error = ", GetLastError());
|
||||
}
|
||||
int width=scale>1 ? 2:1; // if chart scale > 1, then label size = 2
|
||||
|
||||
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
|
||||
ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
|
||||
ObjectSetInteger(0, name, OBJPROP_WIDTH, width);
|
||||
ObjectSetInteger(0, name, OBJPROP_BACK, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTED, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
|
||||
ObjectSetInteger(0, name, OBJPROP_ZORDER, 0);
|
||||
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,264 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Fibonacci Channel.mq5 |
|
||||
//| Copyright 2009-2024, MetaQuotes Ltd |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2024, MetaQuotes Ltd"
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "Fibonacci Daily Channels"
|
||||
//---
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 9
|
||||
#property indicator_plots 9
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrBlue
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrOrange
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrRed
|
||||
#property indicator_type4 DRAW_LINE
|
||||
#property indicator_color4 clrTeal
|
||||
#property indicator_type5 DRAW_LINE
|
||||
#property indicator_color5 clrGreen
|
||||
//--- labels
|
||||
#property indicator_label1 "PP"
|
||||
#property indicator_label2 "R1"
|
||||
#property indicator_label3 "R2"
|
||||
#property indicator_label4 "S1"
|
||||
#property indicator_label5 "S2"
|
||||
#property indicator_label6 "R3"
|
||||
#property indicator_label7 "R4"
|
||||
#property indicator_label8 "S3"
|
||||
#property indicator_label9 "S4"
|
||||
|
||||
//--- input parameter
|
||||
input bool InpShowAllLevels=false; // show all levels
|
||||
input bool InpShowLabel =true; // show price of level
|
||||
|
||||
//--- indicator buffers
|
||||
double ExtPPBuffer[];
|
||||
double ExtR1Buffer[];
|
||||
double ExtR2Buffer[];
|
||||
double ExtR3Buffer[];
|
||||
double ExtR4Buffer[];
|
||||
double ExtS1Buffer[];
|
||||
double ExtS2Buffer[];
|
||||
double ExtS3Buffer[];
|
||||
double ExtS4Buffer[];
|
||||
|
||||
//--- unique prefix to identify indicator objects
|
||||
string ExtPrefixUniq;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- check current timeframe
|
||||
if(PeriodSeconds()>PeriodSeconds(PERIOD_D1))
|
||||
{
|
||||
Alert("Timeframe of chart must be D1 or lower. Exit");
|
||||
return(INIT_FAILED);
|
||||
}
|
||||
|
||||
//--- define buffers
|
||||
SetIndexBuffer(0, ExtPPBuffer);
|
||||
SetIndexBuffer(1, ExtR1Buffer);
|
||||
SetIndexBuffer(2, ExtR2Buffer);
|
||||
SetIndexBuffer(3, ExtS1Buffer);
|
||||
SetIndexBuffer(4, ExtS2Buffer);
|
||||
if(InpShowAllLevels)
|
||||
{
|
||||
SetIndexBuffer(5, ExtR3Buffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(6, ExtR4Buffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(7, ExtS3Buffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(8, ExtS4Buffer, INDICATOR_DATA);
|
||||
//--- set plot type
|
||||
PlotIndexSetInteger(5, PLOT_DRAW_TYPE, DRAW_LINE);
|
||||
PlotIndexSetInteger(6, PLOT_DRAW_TYPE, DRAW_LINE);
|
||||
PlotIndexSetInteger(7, PLOT_DRAW_TYPE, DRAW_LINE);
|
||||
PlotIndexSetInteger(8, PLOT_DRAW_TYPE, DRAW_LINE);
|
||||
//--- set line style
|
||||
PlotIndexSetInteger(5, PLOT_LINE_STYLE, STYLE_DASH);
|
||||
PlotIndexSetInteger(6, PLOT_LINE_STYLE, STYLE_SOLID);
|
||||
PlotIndexSetInteger(7, PLOT_LINE_STYLE, STYLE_DASH);
|
||||
PlotIndexSetInteger(8, PLOT_LINE_STYLE, STYLE_SOLID);
|
||||
//--- set line color
|
||||
PlotIndexSetInteger(5, PLOT_LINE_COLOR, clrGold);
|
||||
PlotIndexSetInteger(6, PLOT_LINE_COLOR, clrGold);
|
||||
PlotIndexSetInteger(7, PLOT_LINE_COLOR, clrGold);
|
||||
PlotIndexSetInteger(8, PLOT_LINE_COLOR, clrGold);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetIndexBuffer(5, ExtR3Buffer, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(6, ExtR4Buffer, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(7, ExtS3Buffer, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(8, ExtS4Buffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//--- indicator name
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, "Fibonacci Daily Channels");
|
||||
//--- number of digits of indicator value
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||
|
||||
//--- prepare prefix for objects
|
||||
string number=StringFormat("%I64d", GetTickCount64());
|
||||
ExtPrefixUniq=StringSubstr(number, StringLen(number)-4);
|
||||
ExtPrefixUniq=ExtPrefixUniq+"_FB";
|
||||
Print("Indicator \"Fibonacci Channels\" started, prefix=", ExtPrefixUniq);
|
||||
|
||||
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[])
|
||||
{
|
||||
static MqlRates LAST_DAY[]; // previous day
|
||||
static datetime last_time=0; // reference time
|
||||
static datetime error_time=0; // error output time
|
||||
|
||||
//--- if the indicator has previously been calculated, start from the bar preceding the last one
|
||||
int start=prev_calculated-1;
|
||||
|
||||
//--- if this is the first calculation of the indicator, start from the first bar on the chart
|
||||
if(prev_calculated==0)
|
||||
start=0;
|
||||
|
||||
//--- calculate levels for all bars in a loop
|
||||
for(int i=start; i<rates_total; i++)
|
||||
{
|
||||
//--- get day opening time for the current bar
|
||||
datetime rem_seconds=time[i]%PeriodSeconds(PERIOD_D1);
|
||||
datetime open_time=time[i]-rem_seconds;
|
||||
|
||||
//--- if the opening time is different from the reference time, update LAST_DAY - level calculations will be based on this value
|
||||
if(open_time!=last_time)
|
||||
{
|
||||
//--- If you're running the indicator on this symbol for the first time,
|
||||
//--- first open the D1 chart for the symbol to initiate immediate downloading of daily bars
|
||||
//--- if getting the current timeframe bars for the specified day fails
|
||||
if(CopyRates(Symbol(), PERIOD_D1, open_time-1, 1, LAST_DAY)!=-1)
|
||||
{
|
||||
//--- remember the reference time
|
||||
last_time=open_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- generate error messages no more than once a minute
|
||||
if(TimeCurrent()>=error_time)
|
||||
{
|
||||
error_time=TimeCurrent()+60;
|
||||
Print("Failed to get previous day by CopyRates(Symbol(), PERIOD_D1, error ", GetLastError());
|
||||
}
|
||||
return(prev_calculated);
|
||||
}
|
||||
}
|
||||
|
||||
//--- calculate Pivot levels
|
||||
double range=LAST_DAY[0].high-LAST_DAY[0].low;
|
||||
double pivot_point=(LAST_DAY[0].high+LAST_DAY[0].low+LAST_DAY[0].close)/3;
|
||||
double r1=pivot_point+0.382*range;
|
||||
double r2=pivot_point+0.618*range;
|
||||
double s1=pivot_point-0.382*range;
|
||||
double s2=pivot_point-0.618*range;
|
||||
|
||||
//--- write values into buffers
|
||||
ExtPPBuffer[i]=pivot_point;
|
||||
ExtR1Buffer[i]=r1;
|
||||
ExtR2Buffer[i]=r2;
|
||||
ExtS1Buffer[i]=s1;
|
||||
ExtS2Buffer[i]=s2;
|
||||
|
||||
//--- additional levels
|
||||
double r3=pivot_point+range;
|
||||
double r4=pivot_point+1.618*range;
|
||||
double s3=pivot_point-range;
|
||||
double s4=pivot_point-1.618*range;
|
||||
ExtR3Buffer[i]=r3;
|
||||
ExtR4Buffer[i]=r4;
|
||||
ExtS3Buffer[i]=s3;
|
||||
ExtS4Buffer[i]=s4;
|
||||
}
|
||||
|
||||
//--- draw labels on levels
|
||||
if(InpShowLabel)
|
||||
{
|
||||
ShowPriceLevels(time[rates_total-1], rates_total-1);
|
||||
ChartRedraw();
|
||||
}
|
||||
|
||||
//--- succesfully calculated
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//--- delete all our graphical objects after use
|
||||
Print("Indicator \"Fibonacci Channels\" stopped, delete all objects with prefix=", ExtPrefixUniq);
|
||||
ObjectsDeleteAll(0, ExtPrefixUniq, 0, OBJ_ARROW_RIGHT_PRICE);
|
||||
ChartRedraw(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Show prices' levels |
|
||||
//+------------------------------------------------------------------+
|
||||
void ShowPriceLevels(datetime time, int last_index)
|
||||
{
|
||||
ShowRightPrice(ExtPrefixUniq+"_PP", time, ExtPPBuffer[last_index], clrBlue);
|
||||
ShowRightPrice(ExtPrefixUniq+"_R1", time, ExtR1Buffer[last_index], clrOrange);
|
||||
ShowRightPrice(ExtPrefixUniq+"_R2", time, ExtR2Buffer[last_index], clrRed);
|
||||
ShowRightPrice(ExtPrefixUniq+"_S1", time, ExtS1Buffer[last_index], clrTeal);
|
||||
ShowRightPrice(ExtPrefixUniq+"_S2", time, ExtS2Buffer[last_index], clrGreen);
|
||||
|
||||
if(InpShowAllLevels)
|
||||
{
|
||||
ShowRightPrice(ExtPrefixUniq+"_R3", time, ExtR3Buffer[last_index], clrGold);
|
||||
ShowRightPrice(ExtPrefixUniq+"_R4", time, ExtR4Buffer[last_index], clrGold);
|
||||
ShowRightPrice(ExtPrefixUniq+"_S3", time, ExtS3Buffer[last_index], clrGold);
|
||||
ShowRightPrice(ExtPrefixUniq+"_S4", time, ExtS4Buffer[last_index], clrGold);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create or Update "Right Price Label" object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool ShowRightPrice(const string name, datetime time, double price, color clr)
|
||||
{
|
||||
if(!ObjectCreate(0, name, OBJ_ARROW_RIGHT_PRICE, 0, time, price))
|
||||
{
|
||||
ObjectMove(0, name, 0, time, price);
|
||||
return(false);
|
||||
}
|
||||
|
||||
//--- make the label size adaptive
|
||||
long scale=2;
|
||||
if(!ChartGetInteger(0, CHART_SCALE, 0, scale))
|
||||
{
|
||||
//--- output an error message to the Experts journal
|
||||
Print(__FUNCTION__+", ChartGetInteger(CHART_SCALE) failed, error = ", GetLastError());
|
||||
}
|
||||
int width=scale>1 ? 2:1; // if chart scale > 1, then label size = 2
|
||||
|
||||
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
|
||||
ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
|
||||
ObjectSetInteger(0, name, OBJPROP_WIDTH, width);
|
||||
ObjectSetInteger(0, name, OBJPROP_BACK, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTED, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
|
||||
ObjectSetInteger(0, name, OBJPROP_ZORDER, 0);
|
||||
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,246 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Keltner Channel.mq5 |
|
||||
//| Copyright 2009-2024, MetaQuotes Ltd |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2024, MetaQuotes Ltd"
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "Keltner Channel"
|
||||
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 3
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrBlue
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrGray
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrRed
|
||||
//--- labels
|
||||
#property indicator_label1 "Upper Keltner"
|
||||
#property indicator_label2 "Middle Keltner"
|
||||
#property indicator_label3 "Lower Keltner"
|
||||
|
||||
//--- input parameters
|
||||
input int InpEMAPeriod=20; // Period of EMA
|
||||
input int InpATRPeriod=10; // Period of ATR
|
||||
input double InpATRFactor=2.0; // ATR multiplier
|
||||
input bool InpShowLabel=true; // Show price of level
|
||||
|
||||
|
||||
//--- global variables for parameters
|
||||
int ExtEMAPeriod;
|
||||
int ExtATRPeriod;
|
||||
double ExtATRFactor;
|
||||
|
||||
//--- indicator buffers
|
||||
double ExtUppBuffer[];
|
||||
double ExtEMABuffer[];
|
||||
double ExtDwnBuffer[];
|
||||
|
||||
//--- indicator handles
|
||||
int ExtEMAHandle;
|
||||
int ExtATRHandle;
|
||||
|
||||
//--- unique prefix to identify indicator objects
|
||||
string ExtPrefixUniq;
|
||||
int ExtPeriod;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- check for input values
|
||||
if(InpEMAPeriod<10)
|
||||
{
|
||||
ExtEMAPeriod=20;
|
||||
PrintFormat("Incorrect value for input variable InpEMAPeriod=%d. Indicator will use value=%d for calculations.",
|
||||
InpEMAPeriod, ExtEMAPeriod);
|
||||
}
|
||||
else
|
||||
ExtEMAPeriod=InpEMAPeriod;
|
||||
|
||||
if(InpATRPeriod<3)
|
||||
{
|
||||
ExtATRPeriod=10;
|
||||
PrintFormat("Incorrect value for input variable InpATRPeriod=%d. Indicator will use value=%d for calculations.",
|
||||
InpATRPeriod, ExtATRPeriod);
|
||||
}
|
||||
else
|
||||
ExtATRPeriod=InpATRPeriod;
|
||||
|
||||
if(InpATRFactor<1.0)
|
||||
{
|
||||
ExtATRFactor=2.0;
|
||||
PrintFormat("Incorrect value for input variable InpBandsDeviations=%f. Indicator will use value=%f for calculations.",
|
||||
InpATRFactor, ExtATRFactor);
|
||||
}
|
||||
else
|
||||
ExtATRFactor=InpATRFactor;
|
||||
|
||||
//--- define buffers
|
||||
SetIndexBuffer(0, ExtUppBuffer);
|
||||
SetIndexBuffer(1, ExtEMABuffer);
|
||||
SetIndexBuffer(2, ExtDwnBuffer);
|
||||
|
||||
//--- indexes draw begin settings
|
||||
PlotIndexSetInteger(0, PLOT_DRAW_BEGIN, InpEMAPeriod+1);
|
||||
PlotIndexSetInteger(1, PLOT_DRAW_BEGIN, InpEMAPeriod+1);
|
||||
PlotIndexSetInteger(2, PLOT_DRAW_BEGIN, InpEMAPeriod+1);
|
||||
|
||||
//--- set a 1-bar offset for each line
|
||||
PlotIndexSetInteger(0, PLOT_SHIFT, 1);
|
||||
PlotIndexSetInteger(1, PLOT_SHIFT, 1);
|
||||
PlotIndexSetInteger(2, PLOT_SHIFT, 1);
|
||||
|
||||
//--- set drawing line empty value
|
||||
PlotIndexSetDouble(0, PLOT_EMPTY_VALUE, 0.0);
|
||||
PlotIndexSetDouble(1, PLOT_EMPTY_VALUE, 0.0);
|
||||
PlotIndexSetDouble(2, PLOT_EMPTY_VALUE, 0.0);
|
||||
|
||||
//--- indicator name
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, "Keltner Channel");
|
||||
//--- number of digits of indicator value
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||
|
||||
//--- create indicators
|
||||
ExtEMAHandle=iMA(NULL, 0, InpEMAPeriod, 0, MODE_EMA, PRICE_CLOSE);
|
||||
ExtATRHandle=iATR(NULL, 0, InpATRPeriod);
|
||||
|
||||
ExtPeriod=PeriodSeconds(_Period);
|
||||
|
||||
//--- prepare prefix for objects
|
||||
string number=StringFormat("%I64d", GetTickCount64());
|
||||
ExtPrefixUniq=StringSubstr(number, StringLen(number)-4);
|
||||
ExtPrefixUniq=ExtPrefixUniq+"_KLT";
|
||||
Print("Indicator \"Keltner Channels\" started, prefix=", ExtPrefixUniq);
|
||||
|
||||
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[])
|
||||
{
|
||||
//--- if this is the first calculation of the indicator
|
||||
if(prev_calculated==0)
|
||||
{
|
||||
//--- populate the beginning values, for which the indicator cannot be calculated, with empty values
|
||||
ArrayFill(ExtUppBuffer, 0, rates_total, 0);
|
||||
ArrayFill(ExtEMABuffer, 0, rates_total, 0);
|
||||
ArrayFill(ExtDwnBuffer, 0, rates_total, 0);
|
||||
|
||||
//--- get EMA values into the indicator buffer
|
||||
if(CopyBuffer(ExtEMAHandle, 0, 0, rates_total, ExtEMABuffer)<0)
|
||||
return(0);
|
||||
|
||||
//--- get ATR indicator values into a dynamic array
|
||||
double atr[];
|
||||
if(CopyBuffer(ExtATRHandle, 0, 0, rates_total, atr)<0)
|
||||
return(0);
|
||||
|
||||
//--- shift from the beginning by the required number of bars
|
||||
int start=MathMax(InpEMAPeriod, InpATRPeriod)+1;
|
||||
|
||||
//--- fill in the values of the upper and lower channel borders
|
||||
for(int i=start; i<rates_total; i++)
|
||||
{
|
||||
ExtUppBuffer[i]=ExtEMABuffer[i]+InpATRFactor*atr[i];
|
||||
ExtDwnBuffer[i]=ExtEMABuffer[i]-InpATRFactor*atr[i];
|
||||
}
|
||||
|
||||
//--- succesfully calculated
|
||||
return(rates_total);
|
||||
}
|
||||
|
||||
//--- if the indicator has previously been calculated, calculate values for the last 2 bars
|
||||
int start=prev_calculated-2;
|
||||
for(int i=start; i<rates_total; i++)
|
||||
{
|
||||
//--- for element-by-element copying from the indicator, use the reverse index
|
||||
int reverse_index=rates_total-i;
|
||||
|
||||
//--- get indicator values
|
||||
double ema[];
|
||||
if(CopyBuffer(ExtEMAHandle, 0, reverse_index, 1, ema)<0)
|
||||
return(prev_calculated);
|
||||
double atr[];
|
||||
if(CopyBuffer(ExtATRHandle, 0, reverse_index, 1, atr)<0)
|
||||
return(prev_calculated);
|
||||
|
||||
//--- write values into buffers
|
||||
ExtEMABuffer[i]=ema[0];
|
||||
ExtUppBuffer[i]=ema[0]+InpATRFactor*atr[0];
|
||||
ExtDwnBuffer[i]=ema[0]-InpATRFactor*atr[0];
|
||||
}
|
||||
|
||||
//--- draw labels on levels
|
||||
if(InpShowLabel)
|
||||
{
|
||||
ShowPriceLevels(time[rates_total-1]+ExtPeriod, rates_total-1);
|
||||
ChartRedraw();
|
||||
}
|
||||
|
||||
//--- succesfully calculated
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//--- delete all our graphical objects after use
|
||||
Print("Indicator \"Keltner Channels\" stopped, delete all objects with prefix=", ExtPrefixUniq);
|
||||
ObjectsDeleteAll(0, ExtPrefixUniq, 0, OBJ_ARROW_RIGHT_PRICE);
|
||||
ChartRedraw(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Show prices' levels |
|
||||
//+------------------------------------------------------------------+
|
||||
void ShowPriceLevels(datetime time, int last_index)
|
||||
{
|
||||
ShowRightPrice(ExtPrefixUniq+"_Upp", time, ExtUppBuffer[last_index], clrBlue);
|
||||
ShowRightPrice(ExtPrefixUniq+"_EMA", time, ExtEMABuffer[last_index], clrGray);
|
||||
ShowRightPrice(ExtPrefixUniq+"_DWN", time, ExtDwnBuffer[last_index], clrRed);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create or Update "Right Price Label" object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool ShowRightPrice(const string name, datetime time, double price, color clr)
|
||||
{
|
||||
if(!ObjectCreate(0, name, OBJ_ARROW_RIGHT_PRICE, 0, time, price))
|
||||
{
|
||||
ObjectMove(0, name, 0, time, price);
|
||||
return(false);
|
||||
}
|
||||
|
||||
//--- make the label size adaptive
|
||||
long scale=2;
|
||||
if(!ChartGetInteger(0, CHART_SCALE, 0, scale))
|
||||
{
|
||||
//--- output an error message to the Experts journal
|
||||
Print(__FUNCTION__+", ChartGetInteger(CHART_SCALE) failed, error = ", GetLastError());
|
||||
}
|
||||
int width=scale>1 ? 2:1; // if chart scale > 1, then label size = 2
|
||||
|
||||
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
|
||||
ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
|
||||
ObjectSetInteger(0, name, OBJPROP_WIDTH, width);
|
||||
ObjectSetInteger(0, name, OBJPROP_BACK, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTED, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
|
||||
ObjectSetInteger(0, name, OBJPROP_ZORDER, 0);
|
||||
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,448 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| MarketProfile Canvas.mq5 |
|
||||
//| Copyright 2009-2024, MetaQuotes Ltd |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright 2022, MetaQuotes Ltd."
|
||||
#property link "https://www.mql5.com"
|
||||
#property version "1.00"
|
||||
#property indicator_chart_window
|
||||
#property indicator_plots 0
|
||||
|
||||
#include<Canvas\Canvas.mqh>
|
||||
#include <Generic\ArrayList.mqh>
|
||||
|
||||
//--- input parameters
|
||||
input uint InpStartDate =0; // day number to start calculation
|
||||
input uint InpShowDays =7; // number of days to show
|
||||
input int InpMultiplier =1; // histogram length multiplier
|
||||
input color InpAsiaSession =clrGold; // Asian session
|
||||
input color InpEuropeSession =clrBlue; // European session
|
||||
input color InpAmericaSession =clrViolet; // American session
|
||||
input uchar InpTransparency =150; // transparency, 0 = invisible
|
||||
input uint InpEuropeStartHour =8; // European session opening hour
|
||||
input uint InpAmericaStartHour=14; // American session opening hour
|
||||
|
||||
//--- unique prefix to identify indicator objects
|
||||
string ExtPrefixUniq;
|
||||
|
||||
//--- forward class declaration
|
||||
class CMarketProfile;
|
||||
//--- collection of pointers of CMarketProfile type
|
||||
CArrayList<CMarketProfile*> mp_list;
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- prepare prefix for objects
|
||||
string number=StringFormat("%I64d", GetTickCount64());
|
||||
ExtPrefixUniq=StringSubstr(number, StringLen(number)-4);
|
||||
Print("Indicator \"Market Profile Canvas\" started, prefix=", ExtPrefixUniq);
|
||||
|
||||
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[])
|
||||
{
|
||||
//--- opening time of the current daily bar
|
||||
datetime static open_time=0;
|
||||
|
||||
//--- number of the last day for calculations
|
||||
uint lastday=InpStartDate+InpShowDays;
|
||||
|
||||
//--- if the calculation has already been done
|
||||
if(prev_calculated!=0)
|
||||
{
|
||||
datetime current_open=iTime(Symbol(), PERIOD_D1, 0);
|
||||
//--- and we don't need to calculate Market Profile for the first day
|
||||
if(InpStartDate!=0)
|
||||
{
|
||||
//--- if the opening time has not been updated
|
||||
if(open_time==current_open)
|
||||
return(rates_total); // no calculation needed, exit
|
||||
}
|
||||
//--- otherwise, updated the opening time
|
||||
open_time=current_open;
|
||||
//--- further in the code, we will calculate Market Profile for only one day
|
||||
lastday=InpStartDate+1;
|
||||
}
|
||||
|
||||
//--- make calculations for the specified days range
|
||||
for(uint day=InpStartDate; day<lastday; day++)
|
||||
{
|
||||
//--- get the day with the 'day' index
|
||||
MqlRates day_rate[];
|
||||
//--- if getting the current day failed
|
||||
//--- if you're running the indicator on weekend or holiday when there are no ticks
|
||||
//--- first open D1 chart for the symbol
|
||||
if(CopyRates(Symbol(), PERIOD_D1, day, 1, day_rate)==-1)
|
||||
return(prev_calculated); // exit and try the next call
|
||||
|
||||
//--- get the beginning and end of the day
|
||||
datetime start_time=day_rate[0].time;
|
||||
datetime stop_time=start_time+PeriodSeconds(PERIOD_D1)-1;
|
||||
|
||||
//--- get current day bars
|
||||
MqlRates bars_in_day[];
|
||||
if(CopyRates(Symbol(), PERIOD_CURRENT, start_time, stop_time, bars_in_day)==-1)
|
||||
return(prev_calculated); // exit and try the next call
|
||||
|
||||
CMarketProfile *market_profile;
|
||||
//--- if Market Profile calculations and drawing have already been done earlier
|
||||
if(prev_calculated>0) // then update the profile of the current day having the index of 0
|
||||
{
|
||||
//--- search for the required CMarketProfile profile in the mp_list collection: it must be there
|
||||
market_profile=GetMarketProfileByDate(ExtPrefixUniq, start_time);
|
||||
//--- check
|
||||
if(market_profile==NULL)
|
||||
{
|
||||
PrintFormat("Market Profile not found for %s. Indicator will be recalculated for all specified days",
|
||||
TimeToString(start_time, TIME_DATE));
|
||||
return(0); // exit with zero value to ensure all calculations are done again
|
||||
}
|
||||
//--- the CMarketProfile object not found; pass valid High/Low values and a set of current-timeframe bars to it
|
||||
market_profile.SetHiLoBars(day_rate[0].high, day_rate[0].low, bars_in_day);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- create a new object to store the profile
|
||||
market_profile = new CMarketProfile(ExtPrefixUniq, start_time, stop_time, day_rate[0].high, day_rate[0].low, bars_in_day);
|
||||
//--- add the created CMarketProfile to the collection
|
||||
mp_list.Add(market_profile);
|
||||
}
|
||||
//--- set drawing parameters
|
||||
market_profile.UpdateSizes();
|
||||
//--- calculate profiles for each session
|
||||
market_profile.CalculateSessions();
|
||||
//--- draw the profile
|
||||
market_profile.Draw(InpMultiplier);
|
||||
}
|
||||
//--- redraw all objects
|
||||
ChartRedraw(0);
|
||||
|
||||
//--- return value of prev_calculated for the next call
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//--- delete all our Market Profile graphical objects after use
|
||||
Print("Indicator \"Market Profile Canvas\" stopped, delete all objects CMarketProfile with prefix=", ExtPrefixUniq);
|
||||
int size=mp_list.Count();
|
||||
for(int i=0; i<size; i++)
|
||||
{
|
||||
CMarketProfile *market_profile;
|
||||
mp_list.TryGetValue(i, market_profile);
|
||||
if(market_profile!=NULL)
|
||||
if(CheckPointer(market_profile)!=POINTER_INVALID)
|
||||
delete market_profile;
|
||||
}
|
||||
ChartRedraw(0);
|
||||
//---
|
||||
}
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator chart's event handler |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnChartEvent(const int id, const long& lparam, const double& dparam, const string& sparam)
|
||||
{
|
||||
//--- do not handle user events
|
||||
if(id>=CHARTEVENT_CUSTOM)
|
||||
return;
|
||||
|
||||
//--- there have been changes on the chart
|
||||
if(CHARTEVENT_CHART_CHANGE==id)
|
||||
{
|
||||
int size=mp_list.Count();
|
||||
for(int i=0; i<size; i++)
|
||||
{
|
||||
CMarketProfile *market_profile;
|
||||
mp_list.TryGetValue(i, market_profile);
|
||||
if(market_profile)
|
||||
if(market_profile.isVisibleOnChart())
|
||||
{
|
||||
market_profile.UpdateSizes();
|
||||
market_profile.Draw(InpMultiplier);
|
||||
}
|
||||
}
|
||||
//--- update the chart after calculating all Market Profiles
|
||||
ChartRedraw();
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Returns CMarketProfile or NULL by the date |
|
||||
//+------------------------------------------------------------------+
|
||||
CMarketProfile* GetMarketProfileByDate(string prefix, datetime time)
|
||||
{
|
||||
int size=mp_list.Count();
|
||||
for(int i=0; i<size; i++)
|
||||
{
|
||||
CMarketProfile *market_profile;
|
||||
mp_list.TryGetValue(i, market_profile);
|
||||
if(market_profile!=NULL)
|
||||
if(CheckPointer(market_profile)!=POINTER_INVALID)
|
||||
{
|
||||
//--- check that the received market_profile pointer was created for the specified 'time' date
|
||||
if(market_profile.Check(prefix, time))
|
||||
return(market_profile); // CMarketProfile object found by date
|
||||
}
|
||||
}
|
||||
//--- not found
|
||||
return(NULL);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class to store and draw Market Profile for the daily bar |
|
||||
//+------------------------------------------------------------------+
|
||||
class CMarketProfile
|
||||
{
|
||||
public:
|
||||
CMarketProfile() {};
|
||||
CMarketProfile(string prefix, datetime time1, datetime time2, double high, double low, MqlRates &bars[]);
|
||||
~CMarketProfile(void);
|
||||
|
||||
//--- checks if the object is created for the specified 'time' date
|
||||
bool Check(string prefix, datetime time);
|
||||
//--- sets High/Low and a set of current-timeframe bars
|
||||
void SetHiLoBars(double high, double low, MqlRates &bars[]);
|
||||
//--- sets drawing parameters
|
||||
void UpdateSizes(void);
|
||||
//--- is the profile in the visible part of the chart?
|
||||
bool isVisibleOnChart(void);
|
||||
//--- has the chart scale changed?
|
||||
bool isChartScaleChanged(void);
|
||||
//--- calculate the profile by sessions
|
||||
bool CalculateSessions(void);
|
||||
//--- draw the profile
|
||||
void Draw(double multiplier=1.0);
|
||||
//---
|
||||
protected:
|
||||
CCanvas m_canvas; // canvas object to draw the profile
|
||||
uchar m_alpha; // alpha channel value that sets transparency
|
||||
string m_prefix; // unique prefix of OBJ_BITMAP object
|
||||
string m_name; // name of the OBJ_BITMAP object used in m_canvas
|
||||
double m_high; // day High
|
||||
double m_low; // day Low
|
||||
datetime m_time1; // day beginning
|
||||
datetime m_time2; // day end
|
||||
int m_day_size_pt; // daily bar height in points
|
||||
int m_height; // daily bar height in pixels on the chart
|
||||
int m_width; // daily bar width in pixels on the chart
|
||||
MqlRates m_bars[]; // current-timeframe bars between m_time1 and m_time2
|
||||
vector m_asia; // Asian session counters
|
||||
vector m_europe; // European session counters
|
||||
vector m_america; // American session counters
|
||||
double m_vert_scale; // factor conversion box -> y
|
||||
double m_hor_scale; // factor conversion count -> x
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
void CMarketProfile::CMarketProfile(string prefix, datetime time1, datetime time2, double high, double low, MqlRates &bars[]):
|
||||
m_prefix(prefix),
|
||||
m_time1(time1),
|
||||
m_time2(time2),
|
||||
m_high(high),
|
||||
m_low(low),
|
||||
m_vert_scale(NULL),
|
||||
m_hor_scale(NULL)
|
||||
{
|
||||
ArrayCopy(m_bars, bars);
|
||||
m_name=ExtPrefixUniq+"_MP_"+TimeToString(time1, TIME_DATE);
|
||||
m_day_size_pt=(int)((m_high-m_low)/SymbolInfoDouble(Symbol(), SYMBOL_POINT));
|
||||
//--- set the sizes of vectors for trading sessions
|
||||
m_asia=vector::Zeros(m_day_size_pt);
|
||||
m_europe=vector::Zeros(m_day_size_pt);
|
||||
m_america=vector::Zeros(m_day_size_pt);
|
||||
//--- create an object
|
||||
UpdateSizes();
|
||||
//--- if it is the first tick at the day opening, the canvas sizes will be equal to zero - set 1 px for both coordinates
|
||||
m_height=m_height?m_height:1;
|
||||
m_width=m_width?m_width:1;
|
||||
if(m_canvas.CreateBitmap(m_name, m_time1, m_high, m_width, m_height, COLOR_FORMAT_ARGB_NORMALIZE))
|
||||
ObjectSetInteger(0, m_name, OBJPROP_BACK, true);
|
||||
else
|
||||
{
|
||||
Print("Error creating canvas: ", GetLastError());
|
||||
Print("time1=", m_time1, " high=", m_high, " width=", m_width, " height=", m_height);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Checks if CMarketProfile object is for the specified 'time' date |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CMarketProfile::Check(string prefix, datetime time)
|
||||
{
|
||||
string calculated= prefix+"_MP_"+TimeToString(time, TIME_DATE);
|
||||
return (m_name==(calculated));
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Sets High/Low and a set of current-timeframe bars |
|
||||
//+------------------------------------------------------------------+
|
||||
void CMarketProfile::SetHiLoBars(double high, double low, MqlRates &bars[])
|
||||
{
|
||||
//--- if the day's High changed, move the OBJ_BITMAP object linked by m_name
|
||||
if(high>m_high)
|
||||
{
|
||||
m_high=high;
|
||||
if(!ObjectSetDouble(0, m_name, OBJPROP_PRICE, m_high))
|
||||
PrintFormat("Failed to update canvas for %s, error %d", TimeToString(m_time1, TIME_DATE), GetLastError());
|
||||
}
|
||||
ArrayCopy(m_bars, bars);
|
||||
m_high=high;
|
||||
m_low=low;
|
||||
//--- day range in points
|
||||
m_day_size_pt=(int)((m_high-m_low)/SymbolInfoDouble(Symbol(), SYMBOL_POINT));
|
||||
//--- re-set the sizes of vectors for trading sessions
|
||||
m_asia=vector::Zeros(m_day_size_pt);
|
||||
m_europe=vector::Zeros(m_day_size_pt);
|
||||
m_america=vector::Zeros(m_day_size_pt);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Sets drawing parameters |
|
||||
//+------------------------------------------------------------------+
|
||||
void CMarketProfile::UpdateSizes(void)
|
||||
{
|
||||
//--- convert time/price to x/y coordinates
|
||||
int x1, y1, x2, y2;
|
||||
ChartTimePriceToXY(0, 0, m_time1, m_high, x1, y1);
|
||||
ChartTimePriceToXY(0, 0, m_time2, m_low, x2, y2);
|
||||
//--- calculate window size
|
||||
m_height=y2-y1;
|
||||
m_width =x2-x1;
|
||||
//--- calculate coefficients for converting boxes and counters into chart pixels
|
||||
m_vert_scale=double(m_height)/(m_day_size_pt);
|
||||
m_hor_scale =double(m_width*PeriodSeconds(PERIOD_CURRENT))/PeriodSeconds(PERIOD_D1);
|
||||
|
||||
m_canvas.Resize(m_width, m_height);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
void CMarketProfile::~CMarketProfile(void)
|
||||
{
|
||||
//--- delete all our graphical objects after use
|
||||
ObjectsDeleteAll(0, m_prefix, 0, OBJ_BITMAP);
|
||||
ChartRedraw();
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Checks that the profile is in the visible part of the chart |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CMarketProfile::isVisibleOnChart(void)
|
||||
{
|
||||
long last_bar=ChartGetInteger(0, CHART_FIRST_VISIBLE_BAR);
|
||||
long first_bar=last_bar+-ChartGetInteger(0, CHART_VISIBLE_BARS);
|
||||
first_bar=first_bar>0?first_bar:0;
|
||||
datetime left =iTime(Symbol(), Period(), (int)last_bar);
|
||||
datetime right=iTime(Symbol(), Period(), (int)first_bar);
|
||||
//--- return check result
|
||||
return((m_time1>= left && m_time1 <=right) || (m_time2>= left && m_time2 <=right));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Prepares profile arrays by sessions |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CMarketProfile::CalculateSessions(void)
|
||||
{
|
||||
double point=SymbolInfoDouble(Symbol(), SYMBOL_POINT);
|
||||
if(ArraySize(m_bars)==0)
|
||||
return(false);
|
||||
//---- iterate through all bars of the current day and mark the boxes they fall into
|
||||
int size=ArraySize(m_bars);
|
||||
for(int i=0; i<size; i++)
|
||||
{
|
||||
MqlDateTime bar_time;
|
||||
TimeToStruct(m_bars[i].time, bar_time);
|
||||
uint hour =bar_time.hour;
|
||||
int start_box=(int)((m_bars[i].low-m_low)/point);
|
||||
int stop_box =(int)((m_bars[i].high-m_low)/point);
|
||||
|
||||
//--- American session
|
||||
if(hour>=InpAmericaStartHour)
|
||||
{
|
||||
for(int ind=start_box; ind<stop_box; ind++)
|
||||
m_america[ind]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- European session
|
||||
if(hour>=InpEuropeStartHour && hour<InpAmericaStartHour)
|
||||
for(int ind=start_box; ind<stop_box; ind++)
|
||||
m_europe[ind]++;
|
||||
else
|
||||
//--- Asian session
|
||||
for(int ind=start_box; ind<stop_box; ind++)
|
||||
m_asia[ind]++;
|
||||
}
|
||||
}
|
||||
//--- session vectors are ready
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Draw Market Profile on the canvas |
|
||||
//+------------------------------------------------------------------+
|
||||
void CMarketProfile::Draw(double multiplier=1.0)
|
||||
{
|
||||
//--- sum the sessions for drawing
|
||||
vector total_profile=m_asia+m_europe+m_america; // profile including all sessions
|
||||
vector europe_asia=m_asia+m_europe; // profile as the sum of the European and Asian sessions
|
||||
|
||||
//--- set a transparent background, any color
|
||||
m_canvas.Erase(ColorToARGB(clrBlack, 0));
|
||||
|
||||
//--- draw the American session with rectangles
|
||||
int x1=0; // to draw a rectangle, the left corner always starts at zero
|
||||
int y1, x2, y2;
|
||||
int size=(int)total_profile.Size();
|
||||
for(int i=0; i<size; i++)
|
||||
{
|
||||
//--- skip zero values, do not draw
|
||||
if(total_profile[i]==0)
|
||||
continue;
|
||||
//--- calculate the bottom point to draw the rectangle
|
||||
y1=m_height-int(i*m_vert_scale); // x1=0 always
|
||||
y2=(int)(y1+m_vert_scale); // top point of the rectangle
|
||||
x2=(int)(total_profile[i]*m_hor_scale*multiplier); // right corner of the rectangle
|
||||
m_canvas.FillRectangle(x1, y1, x2, y2, ColorToARGB(InpAmericaSession, InpTransparency));
|
||||
}
|
||||
|
||||
//--- draw the European session with rectangles
|
||||
for(int i=0; i<size; i++)
|
||||
{
|
||||
//--- skip zero values, do not draw
|
||||
if(total_profile[i]==0)
|
||||
continue;
|
||||
//--- calculate 2 points to draw the rectangle
|
||||
y1=m_height-int(i*m_vert_scale);
|
||||
y2=(int)(y1+m_vert_scale);
|
||||
x2=(int)(europe_asia[i]*m_hor_scale*multiplier);
|
||||
m_canvas.FillRectangle(x1, y1, x2, y2, ColorToARGB(InpEuropeSession, InpTransparency));
|
||||
}
|
||||
|
||||
//--- draw the Asian session with rectangles
|
||||
for(int i=0; i<size; i++)
|
||||
{
|
||||
//--- skip zero values, do not draw
|
||||
if(total_profile[i]==0)
|
||||
continue;
|
||||
//--- calculate 2 points to draw the rectangle
|
||||
y1=m_height-int(i*m_vert_scale);
|
||||
y2=(int)(y1+m_vert_scale);
|
||||
x2=(int)(m_asia[i]*m_hor_scale*multiplier);
|
||||
m_canvas.FillRectangle(x1, y1, x2, y2, ColorToARGB(InpAsiaSession, InpTransparency));
|
||||
}
|
||||
//--- update the OBJ_BITMAP object without refreshing the chart
|
||||
m_canvas.Update(false);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,410 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| MurreyMath Channel.mq5 |
|
||||
//| Copyright 2009-2024, MetaQuotes Ltd |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2024, MetaQuotes Ltd"
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "Murrey Math Channels based on https://www.mql5.com/ru/code/8157"
|
||||
#property description "Author of calculations is Vladyslav Goshkov (https://www.mql5.com/en/users/vladislavvg)"
|
||||
|
||||
//--- input parameters
|
||||
input int InpCalculationPeriod=64; // calculation period
|
||||
input bool InpShowExtraLevels =false; // show all levels
|
||||
input bool InpShowLabel =true; // show price of level
|
||||
|
||||
//--- properties
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 13
|
||||
#property indicator_plots 13
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrDarkBlue
|
||||
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrDarkViolet
|
||||
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrMediumSlateBlue
|
||||
#property indicator_width3 2
|
||||
|
||||
#property indicator_type4 DRAW_LINE
|
||||
#property indicator_color4 clrFireBrick
|
||||
|
||||
#property indicator_type5 DRAW_LINE
|
||||
#property indicator_color5 clrRed
|
||||
#property indicator_width5 2
|
||||
|
||||
#property indicator_type6 DRAW_LINE
|
||||
#property indicator_color6 clrGreen
|
||||
|
||||
#property indicator_type7 DRAW_LINE
|
||||
#property indicator_color7 clrDarkGray
|
||||
#property indicator_width7 2
|
||||
|
||||
#property indicator_type8 DRAW_LINE
|
||||
#property indicator_color8 clrGreen
|
||||
|
||||
#property indicator_type9 DRAW_LINE
|
||||
#property indicator_color9 clrRed
|
||||
#property indicator_width9 2
|
||||
|
||||
#property indicator_type10 DRAW_LINE
|
||||
#property indicator_color10 clrFireBrick
|
||||
|
||||
#property indicator_type11 DRAW_LINE
|
||||
#property indicator_color11 clrMediumSlateBlue
|
||||
#property indicator_width11 2
|
||||
|
||||
#property indicator_type12 DRAW_LINE
|
||||
#property indicator_color12 clrDarkViolet
|
||||
|
||||
#property indicator_type13 DRAW_LINE
|
||||
#property indicator_color13 clrDarkBlue
|
||||
|
||||
//---labels
|
||||
#property indicator_label1 "[+2/8]"
|
||||
#property indicator_label2 "[+1/8]"
|
||||
#property indicator_label3 "[8/8]"
|
||||
#property indicator_label4 "[7/8]"
|
||||
#property indicator_label5 "[6/8]"
|
||||
#property indicator_label6 "[5/8]"
|
||||
#property indicator_label7 "[4/8]"
|
||||
#property indicator_label8 "[3/8]"
|
||||
#property indicator_label9 "[2/8]"
|
||||
#property indicator_label10 "[1/8]"
|
||||
#property indicator_label11 "[0/8]"
|
||||
#property indicator_label12 "[-1/8]"
|
||||
#property indicator_label13 "[-2/8]"
|
||||
|
||||
//--- indicator buffers
|
||||
double Ext1Buffer[];
|
||||
double Ext2Buffer[];
|
||||
double Ext3Buffer[];
|
||||
double Ext4Buffer[];
|
||||
double Ext5Buffer[];
|
||||
double Ext6Buffer[];
|
||||
double Ext7Buffer[];
|
||||
double Ext8Buffer[];
|
||||
double Ext9Buffer[];
|
||||
double Ext10Buffer[];
|
||||
double Ext11Buffer[];
|
||||
double Ext12Buffer[];
|
||||
double Ext13Buffer[];
|
||||
|
||||
//--- unique prefix to identify indicator objects
|
||||
string ExtPrefixUniq;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- check current timeframe
|
||||
if(PeriodSeconds()>PeriodSeconds(PERIOD_D1))
|
||||
{
|
||||
Alert("Timeframe of chart must be D1 or lower. Exit");
|
||||
return(INIT_FAILED);
|
||||
}
|
||||
|
||||
//--- define buffers
|
||||
if(InpShowExtraLevels)
|
||||
{
|
||||
SetIndexBuffer(0, Ext1Buffer);
|
||||
SetIndexBuffer(1, Ext2Buffer);
|
||||
SetIndexBuffer(2, Ext3Buffer);
|
||||
SetIndexBuffer(3, Ext4Buffer);
|
||||
SetIndexBuffer(4, Ext5Buffer);
|
||||
SetIndexBuffer(5, Ext6Buffer);
|
||||
SetIndexBuffer(6, Ext7Buffer);
|
||||
SetIndexBuffer(7, Ext8Buffer);
|
||||
SetIndexBuffer(8, Ext9Buffer);
|
||||
SetIndexBuffer(9, Ext10Buffer);
|
||||
SetIndexBuffer(10, Ext11Buffer);
|
||||
SetIndexBuffer(11, Ext12Buffer);
|
||||
SetIndexBuffer(12, Ext13Buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetIndexBuffer(0, Ext1Buffer, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(1, Ext2Buffer, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(2, Ext3Buffer);
|
||||
SetIndexBuffer(3, Ext4Buffer);
|
||||
SetIndexBuffer(4, Ext5Buffer);
|
||||
SetIndexBuffer(5, Ext6Buffer);
|
||||
SetIndexBuffer(6, Ext7Buffer);
|
||||
SetIndexBuffer(7, Ext8Buffer);
|
||||
SetIndexBuffer(8, Ext9Buffer);
|
||||
SetIndexBuffer(9, Ext10Buffer);
|
||||
SetIndexBuffer(10, Ext11Buffer);
|
||||
SetIndexBuffer(11, Ext12Buffer, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(12, Ext13Buffer, INDICATOR_CALCULATIONS);
|
||||
}
|
||||
|
||||
//--- indicator name
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, "Murrey Math Channels");
|
||||
//--- number of digits of indicator value
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||
|
||||
//--- prepare prefix for objects
|
||||
string number=StringFormat("%I64d", GetTickCount64());
|
||||
ExtPrefixUniq=StringSubstr(number, StringLen(number)-4);
|
||||
ExtPrefixUniq=ExtPrefixUniq+"_MM";
|
||||
Print("Indicator \"Murrey Math Channels\" started, prefix=", ExtPrefixUniq);
|
||||
|
||||
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[])
|
||||
{
|
||||
int start;
|
||||
//--- if this is the first calculation of the indicator, fill buffers with empty initial values
|
||||
if(prev_calculated==0)
|
||||
{
|
||||
FillBuffers(EMPTY_VALUE);
|
||||
//--- shift from the beginning by the required number of bars
|
||||
start=InpCalculationPeriod+1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- if the indicator has previously been calculated, calculate values for the last 2 bars
|
||||
start=prev_calculated-2;
|
||||
}
|
||||
|
||||
//--- calculate levels for all bars in a loop
|
||||
int i=start;
|
||||
for(; i<rates_total; i++)
|
||||
{
|
||||
//--- calculate parameters
|
||||
double min=low[ArrayMinimum(low, i-InpCalculationPeriod, InpCalculationPeriod)];
|
||||
double max=high[ArrayMaximum(high, i-InpCalculationPeriod, InpCalculationPeriod)];
|
||||
double fractal=DetermineFractal(max);
|
||||
double range=max-min;
|
||||
double sum=MathFloor(MathLog(fractal/range)/MathLog(2));
|
||||
double octave=fractal*(MathPow(0.5, sum));
|
||||
double mn=MathFloor(min/octave)*octave;
|
||||
double mx=mn+(2*octave);
|
||||
if((mn+octave)>=max)
|
||||
mx=mn+octave;
|
||||
|
||||
//--- calculation of Resistance level
|
||||
double x1=0, x2=0, x3=0, x4=0, x5=0, x6=0;
|
||||
if((min>=(3*(mx-mn)/16+mn)) && (max<=(9*(mx-mn)/16+mn)))
|
||||
x2=mn+(mx-mn)/2;
|
||||
if((min>=(mn-(mx-mn)/8)) && (max<=(5*(mx-mn)/8+mn)) && (x2==0))
|
||||
x1=mn+(mx-mn)/2;
|
||||
if((min>=(mn+7*(mx-mn)/16)) && (max<=(13*(mx-mn)/16+mn)))
|
||||
x4=mn+3*(mx-mn)/4;
|
||||
if((min>=(mn+3*(mx-mn)/8)) && (max<=(9*(mx-mn)/8+mn)) && (x4==0))
|
||||
x5=mx;
|
||||
if((min>=(mn+(mx-mn)/8)) && (max<=(7*(mx-mn)/8+mn)) && (x1==0) && (x2==0) && (x4==0) && (x5==0))
|
||||
x3=mn+3*(mx-mn)/4;
|
||||
if((x1+x2+x3+x4+x5)==0)
|
||||
x6=mx;
|
||||
double resistance_level=x1+x2+x3+x4+x5+x6;
|
||||
|
||||
//--- calculation of Support level
|
||||
double y1=0, y2=0, y3=0, y4=0, y5=0, y6=0;
|
||||
if(x1>0)
|
||||
y1=mn;
|
||||
if(x2>0)
|
||||
y2=mn+(mx-mn)/4;
|
||||
if(x3>0)
|
||||
y3=mn+(mx-mn)/4;
|
||||
if(x4>0)
|
||||
y4=mn+(mx-mn)/2;
|
||||
if(x5>0)
|
||||
y5=mn+(mx-mn)/2;
|
||||
if((resistance_level>0) && ((y1+y2+y3+y4+y5)==0))
|
||||
y6=mn;
|
||||
double support_level=y1+y2+y3+y4+y5+y6;
|
||||
|
||||
//--- divider of MM levels
|
||||
double divide_mml=(resistance_level-support_level)/8;
|
||||
|
||||
//--- write values into buffers
|
||||
Ext13Buffer[i]=support_level-2*divide_mml;
|
||||
Ext12Buffer[i]=Ext13Buffer[i]+divide_mml;
|
||||
Ext11Buffer[i]=Ext12Buffer[i]+divide_mml;
|
||||
Ext10Buffer[i]=Ext11Buffer[i]+divide_mml;
|
||||
Ext9Buffer[i]=Ext10Buffer[i]+divide_mml;
|
||||
Ext8Buffer[i]=Ext9Buffer[i]+divide_mml;
|
||||
Ext7Buffer[i]=Ext8Buffer[i]+divide_mml;
|
||||
Ext6Buffer[i]=Ext7Buffer[i]+divide_mml;
|
||||
Ext5Buffer[i]=Ext6Buffer[i]+divide_mml;
|
||||
Ext4Buffer[i]=Ext5Buffer[i]+divide_mml;
|
||||
Ext3Buffer[i]=Ext4Buffer[i]+divide_mml;
|
||||
Ext2Buffer[i]=Ext3Buffer[i]+divide_mml;
|
||||
Ext1Buffer[i]=Ext2Buffer[i]+divide_mml;
|
||||
|
||||
//--- remove line clutter
|
||||
if(Ext1Buffer[i]!=Ext1Buffer[i-1])
|
||||
Ext1Buffer[i-1]=EMPTY_VALUE;
|
||||
if(Ext2Buffer[i]!=Ext2Buffer[i-1])
|
||||
Ext2Buffer[i-1]=EMPTY_VALUE;
|
||||
if(Ext3Buffer[i]!=Ext3Buffer[i-1])
|
||||
Ext3Buffer[i-1]=EMPTY_VALUE;
|
||||
if(Ext4Buffer[i]!=Ext4Buffer[i-1])
|
||||
Ext4Buffer[i-1]=EMPTY_VALUE;
|
||||
if(Ext5Buffer[i]!=Ext5Buffer[i-1])
|
||||
Ext5Buffer[i-1]=EMPTY_VALUE;
|
||||
if(Ext6Buffer[i]!=Ext6Buffer[i-1])
|
||||
Ext6Buffer[i-1]=EMPTY_VALUE;
|
||||
if(Ext7Buffer[i]!=Ext7Buffer[i-1])
|
||||
Ext7Buffer[i-1]=EMPTY_VALUE;
|
||||
if(Ext8Buffer[i]!=Ext8Buffer[i-1])
|
||||
Ext8Buffer[i-1]=EMPTY_VALUE;
|
||||
if(Ext9Buffer[i]!=Ext9Buffer[i-1])
|
||||
Ext9Buffer[i-1]=EMPTY_VALUE;
|
||||
if(Ext10Buffer[i]!=Ext10Buffer[i-1])
|
||||
Ext10Buffer[i-1]=EMPTY_VALUE;
|
||||
if(Ext11Buffer[i]!=Ext11Buffer[i-1])
|
||||
Ext11Buffer[i-1]=EMPTY_VALUE;
|
||||
if(Ext12Buffer[i]!=Ext12Buffer[i-1])
|
||||
Ext12Buffer[i-1]=EMPTY_VALUE;
|
||||
if(Ext13Buffer[i]!=Ext13Buffer[i-1])
|
||||
Ext13Buffer[i-1]=EMPTY_VALUE;
|
||||
}
|
||||
|
||||
//--- draw labels on levels
|
||||
if(InpShowLabel)
|
||||
{
|
||||
ShowPriceLevels(time[rates_total-1], rates_total-1);
|
||||
ChartRedraw();
|
||||
}
|
||||
|
||||
//--- succesfully calculated
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize buffers with initial values |
|
||||
//+------------------------------------------------------------------+
|
||||
void FillBuffers(double value=0)
|
||||
{
|
||||
int count=ArraySize(Ext1Buffer);
|
||||
ArrayFill(Ext1Buffer, 0, count, value);
|
||||
ArrayFill(Ext2Buffer, 0, count, value);
|
||||
ArrayFill(Ext3Buffer, 0, count, value);
|
||||
ArrayFill(Ext4Buffer, 0, count, value);
|
||||
ArrayFill(Ext5Buffer, 0, count, value);
|
||||
ArrayFill(Ext6Buffer, 0, count, value);
|
||||
ArrayFill(Ext7Buffer, 0, count, value);
|
||||
ArrayFill(Ext8Buffer, 0, count, value);
|
||||
ArrayFill(Ext9Buffer, 0, count, value);
|
||||
ArrayFill(Ext10Buffer, 0, count, value);
|
||||
ArrayFill(Ext11Buffer, 0, count, value);
|
||||
ArrayFill(Ext12Buffer, 0, count, value);
|
||||
ArrayFill(Ext13Buffer, 0, count, value);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Determine the fractal |
|
||||
//+------------------------------------------------------------------+
|
||||
double DetermineFractal(double value)
|
||||
{
|
||||
if(value<=250000 && value>25000)
|
||||
return(100000);
|
||||
|
||||
if(value<=25000 && value>2500)
|
||||
return(10000);
|
||||
|
||||
if(value<=2500 && value>250)
|
||||
return(1000);
|
||||
|
||||
if(value<=250 && value>25)
|
||||
return(100);
|
||||
|
||||
if(value<=25 && value>12.5)
|
||||
return(12.5);
|
||||
|
||||
if(value<=12.5 && value>6.25)
|
||||
return(12.5);
|
||||
|
||||
if(value<=6.25 && value>3.125)
|
||||
return(6.25);
|
||||
|
||||
if(value<=3.125 && value>1.5625)
|
||||
return(3.125);
|
||||
|
||||
if(value<=1.5625 && value>0.390625)
|
||||
return(1.5625);
|
||||
|
||||
if(value<=0.390625 && value>0)
|
||||
return(0.1953125);
|
||||
|
||||
return(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//--- delete all our graphical objects after use
|
||||
Print("Indicator \"Murrey Math Channels\" stopped, delete all objects with prefix=", ExtPrefixUniq);
|
||||
ObjectsDeleteAll(0, ExtPrefixUniq, 0, OBJ_ARROW_RIGHT_PRICE);
|
||||
ChartRedraw(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Show prices' levels |
|
||||
//+------------------------------------------------------------------+
|
||||
void ShowPriceLevels(datetime time, int last_index)
|
||||
{
|
||||
ShowRightPrice(ExtPrefixUniq+" [8/8]", time, Ext3Buffer[last_index], clrMediumSlateBlue);
|
||||
ShowRightPrice(ExtPrefixUniq+" [7/8]", time, Ext4Buffer[last_index], clrFireBrick);
|
||||
ShowRightPrice(ExtPrefixUniq+" [6/8]", time, Ext5Buffer[last_index], clrRed);
|
||||
ShowRightPrice(ExtPrefixUniq+" [5/8]", time, Ext6Buffer[last_index], clrGreen);
|
||||
ShowRightPrice(ExtPrefixUniq+" [4/8]", time, Ext7Buffer[last_index], clrDarkGray);
|
||||
ShowRightPrice(ExtPrefixUniq+" [3/8]", time, Ext8Buffer[last_index], clrGreen);
|
||||
ShowRightPrice(ExtPrefixUniq+" [2/8]", time, Ext9Buffer[last_index], clrRed);
|
||||
ShowRightPrice(ExtPrefixUniq+" [1/8]", time, Ext10Buffer[last_index], clrFireBrick);
|
||||
ShowRightPrice(ExtPrefixUniq+" [0/8]", time, Ext11Buffer[last_index], clrMediumSlateBlue);
|
||||
|
||||
if(InpShowLabel)
|
||||
{
|
||||
ShowRightPrice(ExtPrefixUniq+" [+2/8]", time, Ext1Buffer[last_index], clrDarkBlue);
|
||||
ShowRightPrice(ExtPrefixUniq+" [+1/8]", time, Ext2Buffer[last_index], clrDarkViolet);
|
||||
ShowRightPrice(ExtPrefixUniq+" [-1/8]", time, Ext12Buffer[last_index], clrDarkViolet);
|
||||
ShowRightPrice(ExtPrefixUniq+" [-2/8]", time, Ext13Buffer[last_index], clrDarkBlue);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create or Update "Right Price Label" object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool ShowRightPrice(const string name, datetime time, double price, color clr)
|
||||
{
|
||||
if(!ObjectCreate(0, name, OBJ_ARROW_RIGHT_PRICE, 0, time, price))
|
||||
{
|
||||
ObjectMove(0, name, 0, time, price);
|
||||
return(false);
|
||||
}
|
||||
|
||||
//--- make the label size adaptive
|
||||
long scale=2;
|
||||
if(!ChartGetInteger(0, CHART_SCALE, 0, scale))
|
||||
{
|
||||
//--- output an error message to the Experts journal
|
||||
Print(__FUNCTION__+", ChartGetInteger(CHART_SCALE) failed, error = ", GetLastError());
|
||||
}
|
||||
int width=scale>1 ? 2:1; // if chart scale > 1, then label size = 2
|
||||
|
||||
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
|
||||
ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
|
||||
ObjectSetInteger(0, name, OBJPROP_WIDTH, width);
|
||||
ObjectSetInteger(0, name, OBJPROP_BACK, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTED, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
|
||||
ObjectSetInteger(0, name, OBJPROP_ZORDER, 0);
|
||||
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,281 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| NRTR Channel.mq5 |
|
||||
//| Copyright 2009-2024, MetaQuotes Ltd |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2024, MetaQuotes Ltd"
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "NRTR Channel"
|
||||
//---
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 6
|
||||
#property indicator_plots 4
|
||||
#property indicator_type1 DRAW_ARROW
|
||||
#property indicator_color1 clrDeepSkyBlue
|
||||
#property indicator_type2 DRAW_ARROW
|
||||
#property indicator_color2 clrDeepSkyBlue
|
||||
#property indicator_type3 DRAW_ARROW
|
||||
#property indicator_color3 clrLightSalmon
|
||||
#property indicator_type4 DRAW_ARROW
|
||||
#property indicator_color4 clrLightSalmon
|
||||
//--- labels
|
||||
#property indicator_label1 "Long Resistance"
|
||||
#property indicator_label2 "Long Support"
|
||||
#property indicator_label3 "Short Support"
|
||||
#property indicator_label4 "Short Resistance"
|
||||
|
||||
//--- inputs
|
||||
input int InpATRPeriod=40; // ATR period
|
||||
input double InpkATR =2.0; // ATR multiplier
|
||||
input bool InpShowLabel=true; // show price of level
|
||||
|
||||
//--- uptrend buffers
|
||||
double ExtCeilingBuffer[];
|
||||
double ExtBuyBuffer[];
|
||||
//--- downtrend buffers
|
||||
double ExtSellBuffer[];
|
||||
double ExtFloorBuffer[];
|
||||
//--- auxiliary buffers
|
||||
double ExtTrendBuffer[];
|
||||
double ExtATRBuffer[];
|
||||
|
||||
//--- indicator handle
|
||||
int ExtATRHandle;
|
||||
|
||||
#define UP_TREND 1
|
||||
#define DOWN_TREND -1
|
||||
|
||||
//--- unique prefix to identify indicator objects
|
||||
string ExtPrefixUniq;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- define buffers and plots
|
||||
SetIndexBuffer(0, ExtCeilingBuffer);
|
||||
PlotIndexSetInteger(0, PLOT_ARROW, 159);
|
||||
|
||||
SetIndexBuffer(1, ExtBuyBuffer);
|
||||
PlotIndexSetInteger(1, PLOT_ARROW, 251);
|
||||
|
||||
SetIndexBuffer(2, ExtSellBuffer);
|
||||
PlotIndexSetInteger(2, PLOT_ARROW, 251);
|
||||
|
||||
SetIndexBuffer(3, ExtFloorBuffer);
|
||||
PlotIndexSetInteger(3, PLOT_ARROW, 159);
|
||||
|
||||
SetIndexBuffer(4, ExtTrendBuffer, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(5, ExtATRBuffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
//--- indicator name
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, "NRTR Channel");
|
||||
//--- number of digits of indicator value
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||
|
||||
//---- Get the indicator handle
|
||||
ExtATRHandle=iATR(NULL, 0, InpATRPeriod);
|
||||
|
||||
//--- prepare prefix for objects
|
||||
string number=StringFormat("%I64d", GetTickCount64());
|
||||
ExtPrefixUniq=StringSubstr(number, StringLen(number)-4);
|
||||
ExtPrefixUniq=ExtPrefixUniq+"_NRTR";
|
||||
Print("Indicator \"_NRTR Channel\" started, prefix=", ExtPrefixUniq);
|
||||
|
||||
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[])
|
||||
{
|
||||
//--- if the indicator has previously been calculated, start from the bar preceding the last one
|
||||
int start=prev_calculated-2;
|
||||
|
||||
//--- if this is the first calculation of the indicator, set the calculation start and the trend direction
|
||||
if(prev_calculated==0)
|
||||
{
|
||||
start=InpATRPeriod;
|
||||
ArrayFill(ExtSellBuffer, 0, rates_total, EMPTY_VALUE);
|
||||
ArrayFill(ExtBuyBuffer, 0, rates_total, EMPTY_VALUE);
|
||||
ArrayFill(ExtCeilingBuffer, 0, rates_total, EMPTY_VALUE);
|
||||
ArrayFill(ExtFloorBuffer, 0, rates_total, EMPTY_VALUE);
|
||||
ArrayFill(ExtTrendBuffer, 0, rates_total, EMPTY_VALUE);
|
||||
|
||||
//--- trend direction
|
||||
if(close[start-1]>low[start-1])
|
||||
{
|
||||
ExtTrendBuffer[start-1]=UP_TREND;
|
||||
ExtCeilingBuffer[start-1]=close[start-1];
|
||||
ExtBuyBuffer [start-1]=close[start-1]-InpkATR*ExtATRBuffer[start-1];
|
||||
}
|
||||
else
|
||||
{
|
||||
ExtTrendBuffer[start-1]=DOWN_TREND;
|
||||
ExtFloorBuffer[start-1]=close[start-1];
|
||||
ExtSellBuffer[start-1]=close[start-1]+InpkATR*ExtATRBuffer[start-1];
|
||||
}
|
||||
}
|
||||
|
||||
//--- indicator values in the buffer
|
||||
if(CopyBuffer(ExtATRHandle, 0, 0, rates_total, ExtATRBuffer)<0)
|
||||
return(0);
|
||||
|
||||
//--- calculate levels for all bars in a loop
|
||||
for(int i=start; i<rates_total; i++)
|
||||
{
|
||||
//--- if there was an uptrend on the previous bar
|
||||
if(ExtTrendBuffer[i-1]>0)
|
||||
{
|
||||
//--- if Low of the current bar is higher than the resistance level on the previous bar
|
||||
if(low[i]>ExtCeilingBuffer[i-1])
|
||||
{
|
||||
//--- update resistance levels
|
||||
ExtCeilingBuffer[i]=close[i]; // uptrend resistance level
|
||||
ExtFloorBuffer[i]=EMPTY_VALUE; // empty downtrend resistance level
|
||||
//--- update support levels
|
||||
ExtBuyBuffer[i]=close[i]-InpkATR*ExtATRBuffer[i];
|
||||
ExtSellBuffer[i]=EMPTY_VALUE;
|
||||
//--- set the sign of an uptrend on the current bar
|
||||
ExtTrendBuffer[i]=UP_TREND;
|
||||
continue;
|
||||
}
|
||||
|
||||
//--- if closed lower than the previous-bar support level
|
||||
if(close[i]<ExtBuyBuffer[i-1])
|
||||
{
|
||||
ExtTrendBuffer[i]=DOWN_TREND; // downtrend
|
||||
//--- set levels for the downtrend
|
||||
ExtFloorBuffer[i]=close[i]; // resistance level
|
||||
ExtSellBuffer[i]=close[i]+InpkATR * ExtATRBuffer[i]; // support
|
||||
//--- delete uptrend levels
|
||||
ExtCeilingBuffer[i]=EMPTY_VALUE;
|
||||
ExtBuyBuffer[i]=EMPTY_VALUE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else // if there was a downtrend on the previous bar
|
||||
{
|
||||
//--- if High of the current bar is lower than the resistance level on the previous bar
|
||||
if(high[i]<ExtFloorBuffer[i-1])
|
||||
{
|
||||
//--- update resistance levels
|
||||
ExtFloorBuffer[i]=close[i]; // downtrend resistance level
|
||||
ExtCeilingBuffer[i]=EMPTY_VALUE; // empty uptrend resistance level
|
||||
//--- update support levels
|
||||
ExtSellBuffer[i]=close[i]+InpkATR*ExtATRBuffer[i];
|
||||
ExtBuyBuffer[i]=EMPTY_VALUE;
|
||||
//--- set the sign of a downtrend on the current bar
|
||||
ExtTrendBuffer[i]=DOWN_TREND;
|
||||
continue;
|
||||
}
|
||||
|
||||
//--- if closed higher than the previous-bar support level
|
||||
if(close[i]>ExtSellBuffer[i-1])
|
||||
{
|
||||
ExtTrendBuffer[i]=UP_TREND; // uptrend
|
||||
//--- set levels for the uptrend
|
||||
ExtCeilingBuffer[i]=close[i]; // resistance level
|
||||
ExtBuyBuffer[i]=close[i]-InpkATR*ExtATRBuffer[i]; // support
|
||||
//--- delete downtrend levels
|
||||
ExtFloorBuffer[i]=EMPTY_VALUE;
|
||||
ExtSellBuffer[i]=EMPTY_VALUE;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
//--- if we reached this code line, the trend has not changed
|
||||
//--- so, copy the previous buffer values
|
||||
ExtSellBuffer[i] = ExtSellBuffer[i-1];
|
||||
ExtBuyBuffer[i] = ExtBuyBuffer[i-1];
|
||||
ExtCeilingBuffer[i]= ExtCeilingBuffer[i-1];
|
||||
ExtFloorBuffer[i] = ExtFloorBuffer[i-1];
|
||||
ExtTrendBuffer[i] = ExtTrendBuffer[i-1];
|
||||
}
|
||||
|
||||
//--- draw labels on levels
|
||||
if(InpShowLabel)
|
||||
{
|
||||
ShowPriceLevels(time[rates_total-1], rates_total-1);
|
||||
ChartRedraw();
|
||||
}
|
||||
|
||||
//--- succesfully calculated
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//--- delete all our graphical objects after use
|
||||
Print("Indicator \"NRTR Channel\" stopped, delete all objects with prefix=", ExtPrefixUniq);
|
||||
ObjectsDeleteAll(0, ExtPrefixUniq, 0, OBJ_ARROW_RIGHT_PRICE);
|
||||
ChartRedraw(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Show prices' levels |
|
||||
//+------------------------------------------------------------------+
|
||||
void ShowPriceLevels(datetime time, int last_index)
|
||||
{
|
||||
color clr;
|
||||
double up, dn;
|
||||
//--- define color and levels
|
||||
if(ExtTrendBuffer[last_index]==UP_TREND)
|
||||
{
|
||||
clr=clrDeepSkyBlue;
|
||||
up=ExtCeilingBuffer[last_index];
|
||||
dn=ExtBuyBuffer[last_index];
|
||||
}
|
||||
else
|
||||
{
|
||||
clr=clrLightSalmon;
|
||||
up=ExtSellBuffer[last_index];
|
||||
dn=ExtFloorBuffer[last_index];
|
||||
}
|
||||
|
||||
ShowRightPrice(ExtPrefixUniq+"_Res", time, up, clr);
|
||||
ShowRightPrice(ExtPrefixUniq+"_Sup", time, dn, clr);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create or Update "Right Price Label" object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool ShowRightPrice(const string name, datetime time, double price, color clr)
|
||||
{
|
||||
if(!ObjectCreate(0, name, OBJ_ARROW_RIGHT_PRICE, 0, time, price))
|
||||
{
|
||||
ObjectMove(0, name, 0, time, price);
|
||||
return(false);
|
||||
}
|
||||
|
||||
//--- make the label size adaptive
|
||||
long scale=2;
|
||||
if(!ChartGetInteger(0, CHART_SCALE, 0, scale))
|
||||
{
|
||||
//--- output an error message to the Experts journal
|
||||
Print(__FUNCTION__+", ChartGetInteger(CHART_SCALE) failed, error = ", GetLastError());
|
||||
}
|
||||
int width=scale>2 ? 2:1; // if chart scale > 1, then label size = 2
|
||||
|
||||
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
|
||||
ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
|
||||
ObjectSetInteger(0, name, OBJPROP_WIDTH, width);
|
||||
ObjectSetInteger(0, name, OBJPROP_BACK, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTED, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
|
||||
ObjectSetInteger(0, name, OBJPROP_ZORDER, 0);
|
||||
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,176 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Parabolic Channel.mq5 |
|
||||
//| Copyright 2009-2024, MetaQuotes Ltd |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2024, MetaQuotes Ltd"
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "Parabolic Channel"
|
||||
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 3
|
||||
#property indicator_plots 3
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrRoyalBlue
|
||||
#property indicator_style1 STYLE_SOLID
|
||||
#property indicator_width1 1
|
||||
#property indicator_type2 DRAW_ARROW
|
||||
#property indicator_width2 2
|
||||
#property indicator_color2 clrDeepSkyBlue
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrDarkOrange
|
||||
#property indicator_style3 STYLE_SOLID
|
||||
#property indicator_width3 1
|
||||
//--- labels
|
||||
#property indicator_label1 "Upper"
|
||||
#property indicator_label2 "Parabolic"
|
||||
#property indicator_label3 "Lower "
|
||||
|
||||
//--- input parameters
|
||||
input double InpSARStep =0.02; // Step
|
||||
input double InpSARMaximum=0.2; // Maximum
|
||||
input bool InpShowLabel =true; // Show price of level
|
||||
|
||||
//--- indicator buffers
|
||||
double ExtUpperBuffer[];
|
||||
double ExtParabolicBuffer[];
|
||||
double ExtLowerBuffer[];
|
||||
|
||||
//--- indicator handle
|
||||
int ExtParabolicHandle;
|
||||
//--- unique prefix to identify indicator objects
|
||||
string ExtPrefixUniq;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- define buffers
|
||||
SetIndexBuffer(0, ExtUpperBuffer);
|
||||
SetIndexBuffer(1, ExtParabolicBuffer);
|
||||
SetIndexBuffer(2, ExtLowerBuffer);
|
||||
PlotIndexSetInteger(1,PLOT_ARROW,159);
|
||||
|
||||
//--- indicator name
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, "Parabolic Channel");
|
||||
//--- number of digits of indicator value
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||
|
||||
//--- create indicators
|
||||
ExtParabolicHandle=iSAR(NULL,0,InpSARStep,InpSARMaximum);
|
||||
|
||||
//--- prepare prefix for objects
|
||||
string number=StringFormat("%I64d", GetTickCount64());
|
||||
ExtPrefixUniq=StringSubstr(number, StringLen(number)-4);
|
||||
ExtPrefixUniq=ExtPrefixUniq+"_PS";
|
||||
Print("Indicator \"Parabolic Channels\" started, prefix=", ExtPrefixUniq);
|
||||
|
||||
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[])
|
||||
{
|
||||
//--- write Parabolic SAR indicator values to the buffer
|
||||
if(CopyBuffer(ExtParabolicHandle, 0, 0, rates_total, ExtParabolicBuffer)<0)
|
||||
return(0);
|
||||
|
||||
//--- start calculations from the bar preceding the last one
|
||||
int start=prev_calculated-2;
|
||||
|
||||
//--- if this is the first calculation of the indicator
|
||||
if(prev_calculated==0)
|
||||
{
|
||||
start=1;
|
||||
ArrayFill(ExtUpperBuffer,0,rates_total,0);
|
||||
ArrayFill(ExtLowerBuffer,0,rates_total,0);
|
||||
ExtUpperBuffer[start-1]=close[start-1];
|
||||
ExtLowerBuffer[start-1]=open[start-1];
|
||||
}
|
||||
|
||||
for(int i=start; i<rates_total; i++)
|
||||
{
|
||||
ExtUpperBuffer[i]=ExtUpperBuffer[i-1];
|
||||
ExtLowerBuffer[i]=ExtLowerBuffer[i-1];
|
||||
|
||||
//--- check if the parabolic has jumped down
|
||||
if(close[i]>ExtParabolicBuffer[i] && close[i-1]<ExtParabolicBuffer[i-1])
|
||||
ExtLowerBuffer[i]=ExtParabolicBuffer[i];
|
||||
|
||||
//--- check if the parabolic has jumped up
|
||||
if(close[i]<ExtParabolicBuffer[i] && close[i-1]>ExtParabolicBuffer[i-1])
|
||||
ExtUpperBuffer[i]=ExtParabolicBuffer[i];
|
||||
}
|
||||
|
||||
//--- draw labels on levels
|
||||
if(InpShowLabel)
|
||||
{
|
||||
ShowPriceLevels(time[rates_total-1], rates_total-1);
|
||||
ChartRedraw();
|
||||
}
|
||||
|
||||
//--- succesfully calculated
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//--- delete all our graphical objects after use
|
||||
Print("Indicator \"Parabolic Channel\" stopped, delete all objects with prefix=", ExtPrefixUniq);
|
||||
ObjectsDeleteAll(0, ExtPrefixUniq, 0, OBJ_ARROW_RIGHT_PRICE);
|
||||
ChartRedraw(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Show prices' levels |
|
||||
//+------------------------------------------------------------------+
|
||||
void ShowPriceLevels(datetime time, int last_index)
|
||||
{
|
||||
ShowRightPrice(ExtPrefixUniq+"_Upper", time, ExtUpperBuffer[last_index], clrRoyalBlue);
|
||||
ShowRightPrice(ExtPrefixUniq+"_Parabolic", time, ExtParabolicBuffer[last_index], clrDeepSkyBlue);
|
||||
ShowRightPrice(ExtPrefixUniq+"_Lower", time, ExtLowerBuffer[last_index], clrDarkOrange);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create or Update "Right Price Label" object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool ShowRightPrice(const string name, datetime time, double price, color clr)
|
||||
{
|
||||
if(!ObjectCreate(0, name, OBJ_ARROW_RIGHT_PRICE, 0, time, price))
|
||||
{
|
||||
ObjectMove(0, name, 0, time, price);
|
||||
return(false);
|
||||
}
|
||||
|
||||
//--- make the label size adaptive
|
||||
long scale=2;
|
||||
if(!ChartGetInteger(0, CHART_SCALE, 0, scale))
|
||||
{
|
||||
//--- output an error message to the Experts journal
|
||||
Print(__FUNCTION__+", ChartGetInteger(CHART_SCALE) failed, error = ", GetLastError());
|
||||
}
|
||||
int width=scale>1 ? 2:1; // if chart scale > 1, then label size = 2
|
||||
|
||||
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
|
||||
ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
|
||||
ObjectSetInteger(0, name, OBJPROP_WIDTH, width);
|
||||
ObjectSetInteger(0, name, OBJPROP_BACK, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTED, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
|
||||
ObjectSetInteger(0, name, OBJPROP_ZORDER, 0);
|
||||
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,264 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Pivot Channel.mq5 |
|
||||
//| Copyright 2009-2024, MetaQuotes Ltd |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2024, MetaQuotes Ltd"
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "Pivot Daily Channels"
|
||||
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 9
|
||||
#property indicator_plots 9
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrBlue
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrOrange
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrRed
|
||||
#property indicator_type4 DRAW_LINE
|
||||
#property indicator_color4 clrTeal
|
||||
#property indicator_type5 DRAW_LINE
|
||||
#property indicator_color5 clrGreen
|
||||
//--- labels
|
||||
#property indicator_label1 "PP"
|
||||
#property indicator_label2 "R1"
|
||||
#property indicator_label3 "R2"
|
||||
#property indicator_label4 "S1"
|
||||
#property indicator_label5 "S2"
|
||||
#property indicator_label6 "M1"
|
||||
#property indicator_label7 "M2"
|
||||
#property indicator_label8 "M3"
|
||||
#property indicator_label9 "M4"
|
||||
|
||||
//--- input parameters
|
||||
input bool InpShowLevelsM=false; // show M levels
|
||||
input bool InpShowLabel =true; // show price of level
|
||||
|
||||
//--- indicator buffers
|
||||
double ExtPPBuffer[];
|
||||
double ExtR1Buffer[];
|
||||
double ExtR2Buffer[];
|
||||
double ExtS1Buffer[];
|
||||
double ExtS2Buffer[];
|
||||
//--- additional indicator buffers
|
||||
double ExtM1Buffer[];
|
||||
double ExtM2Buffer[];
|
||||
double ExtM3Buffer[];
|
||||
double ExtM4Buffer[];
|
||||
|
||||
//--- unique prefix to identify indicator objects
|
||||
string ExtPrefixUniq;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- check current timeframe
|
||||
if(PeriodSeconds()>PeriodSeconds(PERIOD_D1))
|
||||
{
|
||||
Alert("Timeframe of chart must be D1 or lower. Exit");
|
||||
return(INIT_FAILED);
|
||||
}
|
||||
|
||||
//--- define buffers
|
||||
SetIndexBuffer(0, ExtPPBuffer);
|
||||
SetIndexBuffer(1, ExtR1Buffer);
|
||||
SetIndexBuffer(2, ExtR2Buffer);
|
||||
SetIndexBuffer(3, ExtS1Buffer);
|
||||
SetIndexBuffer(4, ExtS2Buffer);
|
||||
if(InpShowLevelsM)
|
||||
{
|
||||
SetIndexBuffer(5, ExtM1Buffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(6, ExtM2Buffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(7, ExtM3Buffer, INDICATOR_DATA);
|
||||
SetIndexBuffer(8, ExtM4Buffer, INDICATOR_DATA);
|
||||
//--- set plot type
|
||||
PlotIndexSetInteger(5, PLOT_DRAW_TYPE, DRAW_LINE);
|
||||
PlotIndexSetInteger(6, PLOT_DRAW_TYPE, DRAW_LINE);
|
||||
PlotIndexSetInteger(7, PLOT_DRAW_TYPE, DRAW_LINE);
|
||||
PlotIndexSetInteger(8, PLOT_DRAW_TYPE, DRAW_LINE);
|
||||
//--- set line style
|
||||
PlotIndexSetInteger(5, PLOT_LINE_STYLE, STYLE_DASH);
|
||||
PlotIndexSetInteger(6, PLOT_LINE_STYLE, STYLE_DASH);
|
||||
PlotIndexSetInteger(7, PLOT_LINE_STYLE, STYLE_DASH);
|
||||
PlotIndexSetInteger(8, PLOT_LINE_STYLE, STYLE_DASH);
|
||||
//--- set line color
|
||||
PlotIndexSetInteger(5, PLOT_LINE_COLOR, clrGold);
|
||||
PlotIndexSetInteger(6, PLOT_LINE_COLOR, clrGold);
|
||||
PlotIndexSetInteger(7, PLOT_LINE_COLOR, clrGold);
|
||||
PlotIndexSetInteger(8, PLOT_LINE_COLOR, clrGold);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetIndexBuffer(5, ExtM1Buffer, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(6, ExtM2Buffer, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(7, ExtM3Buffer, INDICATOR_CALCULATIONS);
|
||||
SetIndexBuffer(8, ExtM4Buffer, INDICATOR_CALCULATIONS);
|
||||
|
||||
}
|
||||
|
||||
//--- indicator name
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, "Pivot Daily Channels");
|
||||
//--- number of digits of indicator value
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||
|
||||
//--- prepare prefix for objects
|
||||
string number=StringFormat("%I64d", GetTickCount64());
|
||||
ExtPrefixUniq=StringSubstr(number, StringLen(number)-4);
|
||||
ExtPrefixUniq=ExtPrefixUniq+"_PP";
|
||||
Print("Indicator \"Pivot Channels\" started, prefix=", ExtPrefixUniq);
|
||||
|
||||
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[])
|
||||
{
|
||||
static MqlRates LAST_DAY[]; // previous day
|
||||
static datetime last_time=0; // reference time
|
||||
static datetime error_time=0; // error output time
|
||||
|
||||
//--- if the indicator has previously been calculated, start from the bar preceding the last one
|
||||
int start=prev_calculated-1;
|
||||
|
||||
//--- if this is the first calculation of the indicator, start from the first bar on the chart
|
||||
if(prev_calculated==0)
|
||||
start=0;
|
||||
|
||||
//--- calculate levels for all bars in a loop
|
||||
for(int i=start; i<rates_total; i++)
|
||||
{
|
||||
//--- get day opening time for the current bar
|
||||
datetime rem_seconds=time[i]%PeriodSeconds(PERIOD_D1);
|
||||
datetime open_time=time[i]-rem_seconds;
|
||||
|
||||
//--- if the opening time is different from the reference time, update LAST_DAY - level calculations will be based on this value
|
||||
if(open_time!=last_time)
|
||||
{
|
||||
//--- If you're running the indicator on this symbol for the first time,
|
||||
//--- first open the D1 chart for the symbol to initiate immediate downloading of daily bars
|
||||
//--- if getting the current timeframe bars for the specified day fails
|
||||
if(CopyRates(Symbol(), PERIOD_D1, open_time-1, 1, LAST_DAY)!=-1)
|
||||
{
|
||||
//--- remember the reference time
|
||||
last_time=open_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- generate error messages no more than once a minute
|
||||
if(TimeCurrent()>=error_time)
|
||||
{
|
||||
error_time=TimeCurrent()+60;
|
||||
Print("Failed to get previous day by CopyRates(Symbol(), PERIOD_D1, error ", GetLastError());
|
||||
}
|
||||
return(prev_calculated);
|
||||
}
|
||||
}
|
||||
|
||||
//--- calculate Pivot levels
|
||||
double pivot_point=(LAST_DAY[0].high+LAST_DAY[0].low+LAST_DAY[0].close)/3;
|
||||
double r1=2*pivot_point-LAST_DAY[0].low;
|
||||
double r2=pivot_point+(LAST_DAY[0].high-LAST_DAY[0].low);
|
||||
double s1=2*pivot_point-LAST_DAY[0].high;
|
||||
double s2=pivot_point-(LAST_DAY[0].high-LAST_DAY[0].low);
|
||||
|
||||
//--- write values into buffers
|
||||
ExtPPBuffer[i]=pivot_point;
|
||||
ExtR1Buffer[i]=r1;
|
||||
ExtR2Buffer[i]=r2;
|
||||
ExtS1Buffer[i]=s1;
|
||||
ExtS2Buffer[i]=s2;
|
||||
|
||||
//--- additional levels
|
||||
double m1=(s1+s2)/2;
|
||||
double m2=(s1+pivot_point)/2;
|
||||
double m3=(r1+pivot_point)/2;
|
||||
double m4=(r1+r2)/2;
|
||||
ExtM1Buffer[i]=m1;
|
||||
ExtM2Buffer[i]=m2;
|
||||
ExtM3Buffer[i]=m3;
|
||||
ExtM4Buffer[i]=m4;
|
||||
}
|
||||
|
||||
//--- draw labels on levels
|
||||
if(InpShowLabel)
|
||||
{
|
||||
ShowPriceLevels(time[rates_total-1], rates_total-1);
|
||||
ChartRedraw();
|
||||
}
|
||||
|
||||
//--- succesfully calculated
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//--- delete all our graphical objects after use
|
||||
Print("Indicator \"Pivot Channel\" stopped, delete all objects with prefix=", ExtPrefixUniq);
|
||||
ObjectsDeleteAll(0, ExtPrefixUniq, 0, OBJ_ARROW_RIGHT_PRICE);
|
||||
ChartRedraw(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Show prices' levels |
|
||||
//+------------------------------------------------------------------+
|
||||
void ShowPriceLevels(datetime time, int last_index)
|
||||
{
|
||||
ShowRightPrice(ExtPrefixUniq+"_PP", time, ExtPPBuffer[last_index], clrBlue);
|
||||
ShowRightPrice(ExtPrefixUniq+"_R1", time, ExtR1Buffer[last_index], clrOrange);
|
||||
ShowRightPrice(ExtPrefixUniq+"_R2", time, ExtR2Buffer[last_index], clrRed);
|
||||
ShowRightPrice(ExtPrefixUniq+"_S1", time, ExtS1Buffer[last_index], clrTeal);
|
||||
ShowRightPrice(ExtPrefixUniq+"_S2", time, ExtS2Buffer[last_index], clrGreen);
|
||||
if(InpShowLevelsM)
|
||||
{
|
||||
ShowRightPrice(ExtPrefixUniq+"_M1", time, ExtM1Buffer[last_index], clrGold);
|
||||
ShowRightPrice(ExtPrefixUniq+"_M2", time, ExtM2Buffer[last_index], clrGold);
|
||||
ShowRightPrice(ExtPrefixUniq+"_M3", time, ExtM3Buffer[last_index], clrGold);
|
||||
ShowRightPrice(ExtPrefixUniq+"_M4", time, ExtM4Buffer[last_index], clrGold);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create or Update "Right Price Label" object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool ShowRightPrice(const string name, datetime time, double price, color clr)
|
||||
{
|
||||
if(!ObjectCreate(0, name, OBJ_ARROW_RIGHT_PRICE, 0, time, price))
|
||||
{
|
||||
ObjectMove(0, name, 0, time, price);
|
||||
return(false);
|
||||
}
|
||||
|
||||
//--- make the label size adaptive
|
||||
long scale=2;
|
||||
if(!ChartGetInteger(0, CHART_SCALE, 0, scale))
|
||||
{
|
||||
//--- output an error message to the Experts journal
|
||||
Print(__FUNCTION__+", ChartGetInteger(CHART_SCALE) failed, error = ", GetLastError());
|
||||
}
|
||||
int width=scale>1 ? 2:1; // if chart scale > 1, then label size = 2
|
||||
|
||||
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
|
||||
ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
|
||||
ObjectSetInteger(0, name, OBJPROP_WIDTH, width);
|
||||
ObjectSetInteger(0, name, OBJPROP_BACK, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTED, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
|
||||
ObjectSetInteger(0, name, OBJPROP_ZORDER, 0);
|
||||
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Binary file not shown.
@@ -0,0 +1,240 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| Woodie Channel.mq5.mq5 |
|
||||
//| Copyright 2009-2024, MetaQuotes Ltd |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "2009-2024, MetaQuotes Ltd"
|
||||
#property link "http://www.mql5.com"
|
||||
#property description "Woodie Channels"
|
||||
|
||||
#property indicator_chart_window
|
||||
#property indicator_buffers 9
|
||||
#property indicator_plots 9
|
||||
#property indicator_type1 DRAW_LINE
|
||||
#property indicator_color1 clrGreen
|
||||
#property indicator_type2 DRAW_LINE
|
||||
#property indicator_color2 clrGreen
|
||||
#property indicator_type3 DRAW_LINE
|
||||
#property indicator_color3 clrGreen
|
||||
#property indicator_type4 DRAW_LINE
|
||||
#property indicator_color4 clrGreen
|
||||
#property indicator_type5 DRAW_LINE
|
||||
#property indicator_color5 clrBlue
|
||||
#property indicator_type6 DRAW_LINE
|
||||
#property indicator_color6 clrRed
|
||||
#property indicator_type7 DRAW_LINE
|
||||
#property indicator_color7 clrRed
|
||||
#property indicator_type8 DRAW_LINE
|
||||
#property indicator_color8 clrRed
|
||||
#property indicator_type9 DRAW_LINE
|
||||
#property indicator_color9 clrRed
|
||||
|
||||
//--- labels
|
||||
#property indicator_label1 "R4"
|
||||
#property indicator_label2 "R3"
|
||||
#property indicator_label3 "R2"
|
||||
#property indicator_label4 "R1"
|
||||
#property indicator_label5 "PP"
|
||||
#property indicator_label6 "S1"
|
||||
#property indicator_label7 "S2"
|
||||
#property indicator_label8 "S3"
|
||||
#property indicator_label9 "S4"
|
||||
|
||||
//--- input parameter
|
||||
input bool InpShowLabel=true; // show price of level
|
||||
|
||||
//--- indicator buffers
|
||||
double ExtR4Buffer[];
|
||||
double ExtR3Buffer[];
|
||||
double ExtR2Buffer[];
|
||||
double ExtR1Buffer[];
|
||||
double ExtPPBuffer[];
|
||||
double ExtS1Buffer[];
|
||||
double ExtS2Buffer[];
|
||||
double ExtS3Buffer[];
|
||||
double ExtS4Buffer[];
|
||||
|
||||
//--- unique prefix to identify indicator objects
|
||||
string ExtPrefixUniq;
|
||||
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator initialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
int OnInit()
|
||||
{
|
||||
//--- check current timeframe
|
||||
if(PeriodSeconds()>PeriodSeconds(PERIOD_D1))
|
||||
{
|
||||
Alert("Timeframe of chart must be D1 or lower. Exit");
|
||||
return(INIT_FAILED);
|
||||
}
|
||||
|
||||
//--- define buffers
|
||||
SetIndexBuffer(0, ExtR4Buffer);
|
||||
SetIndexBuffer(1, ExtR3Buffer);
|
||||
SetIndexBuffer(2, ExtR2Buffer);
|
||||
SetIndexBuffer(3, ExtR1Buffer);
|
||||
SetIndexBuffer(4, ExtPPBuffer);
|
||||
SetIndexBuffer(5, ExtS1Buffer);
|
||||
SetIndexBuffer(6, ExtS2Buffer);
|
||||
SetIndexBuffer(7, ExtS3Buffer);
|
||||
SetIndexBuffer(8, ExtS4Buffer);
|
||||
|
||||
//--- indicator name
|
||||
IndicatorSetString(INDICATOR_SHORTNAME, "Woodie Channels");
|
||||
//--- number of digits of indicator value
|
||||
IndicatorSetInteger(INDICATOR_DIGITS, _Digits);
|
||||
|
||||
//--- prepare prefix for objects
|
||||
string number=StringFormat("%I64d", GetTickCount64());
|
||||
ExtPrefixUniq=StringSubstr(number, StringLen(number)-4);
|
||||
ExtPrefixUniq=ExtPrefixUniq+"_WD";
|
||||
Print("Indicator \"Woodie Channels\" started, prefix=", ExtPrefixUniq);
|
||||
|
||||
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[])
|
||||
{
|
||||
static MqlRates LAST_DAY[]; // previous day
|
||||
static datetime last_time=0; // reference time
|
||||
static datetime error_time=0; // error output time
|
||||
|
||||
//--- if the indicator has previously been calculated, start from the bar preceding the last one
|
||||
int start=prev_calculated-1;
|
||||
|
||||
//--- if this is the first calculation of the indicator, start from the first bar on the chart
|
||||
if(prev_calculated==0)
|
||||
start=0;
|
||||
|
||||
//--- calculate levels for all bars in a loop
|
||||
for(int i=start; i<rates_total; i++)
|
||||
{
|
||||
//--- get day opening time for the current bar
|
||||
datetime rem_seconds=time[i]%PeriodSeconds(PERIOD_D1);
|
||||
datetime open_time=time[i]-rem_seconds;
|
||||
|
||||
//--- if the opening time is different from the reference time, update LAST_DAY - level calculations will be based on this value
|
||||
if(open_time!=last_time)
|
||||
{
|
||||
//--- If you're running the indicator on this symbol for the first time,
|
||||
//--- first open the D1 chart for the symbol to initiate immediate downloading of daily bars
|
||||
//--- if getting the current timeframe bars for the specified day fails
|
||||
if(CopyRates(Symbol(), PERIOD_D1, open_time-1, 1, LAST_DAY)!=-1)
|
||||
{
|
||||
//--- remember the reference time
|
||||
last_time=open_time;
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- generate error messages no more than once a minute
|
||||
if(TimeCurrent()>=error_time)
|
||||
{
|
||||
error_time=TimeCurrent()+60;
|
||||
Print("Failed to get previous day by CopyRates(Symbol(), PERIOD_D1, error ", GetLastError());
|
||||
}
|
||||
return(prev_calculated);
|
||||
}
|
||||
}
|
||||
|
||||
//--- calculate levels
|
||||
double pp=(LAST_DAY[0].high+LAST_DAY[0].low+2* LAST_DAY[0].close)/4;
|
||||
double r1=2*pp-LAST_DAY[0].low;
|
||||
double r2=pp+(LAST_DAY[0].high-LAST_DAY[0].low);
|
||||
double r3=r2+(r1-pp);
|
||||
double r4=r3+(r2-pp);
|
||||
double s1=2*pp -LAST_DAY[0].high;
|
||||
double s2=pp-(LAST_DAY[0].high-LAST_DAY[0].low);
|
||||
double s3=s2-(pp-s1);
|
||||
double s4=s3-(pp-s2);
|
||||
|
||||
//--- write values into buffers
|
||||
ExtR4Buffer[i]=r4;
|
||||
ExtR3Buffer[i]=r3;
|
||||
ExtR2Buffer[i]=r2;
|
||||
ExtR1Buffer[i]=r1;
|
||||
ExtPPBuffer[i]=pp;
|
||||
ExtS1Buffer[i]=s1;
|
||||
ExtS2Buffer[i]=s2;
|
||||
ExtS3Buffer[i]=s3;
|
||||
ExtS4Buffer[i]=s4;
|
||||
}
|
||||
|
||||
//--- draw labels on levels
|
||||
if(InpShowLabel)
|
||||
{
|
||||
ShowPriceLevels(time[rates_total-1], rates_total-1);
|
||||
ChartRedraw();
|
||||
}
|
||||
|
||||
//--- succesfully calculated
|
||||
return(rates_total);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Custom indicator deinitialization function |
|
||||
//+------------------------------------------------------------------+
|
||||
void OnDeinit(const int reason)
|
||||
{
|
||||
//--- delete all our graphical objects after use
|
||||
Print("Indicator \"Woodie Channel\" stopped, delete all objects with prefix=", ExtPrefixUniq);
|
||||
ObjectsDeleteAll(0, ExtPrefixUniq, 0, OBJ_ARROW_RIGHT_PRICE);
|
||||
ChartRedraw(0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Show prices' levels |
|
||||
//+------------------------------------------------------------------+
|
||||
void ShowPriceLevels(datetime time, int last_index)
|
||||
{
|
||||
ShowRightPrice(ExtPrefixUniq+"_R4", time, ExtR4Buffer[last_index], clrGreen);
|
||||
ShowRightPrice(ExtPrefixUniq+"_R3", time, ExtR3Buffer[last_index], clrGreen);
|
||||
ShowRightPrice(ExtPrefixUniq+"_R2", time, ExtR2Buffer[last_index], clrGreen);
|
||||
ShowRightPrice(ExtPrefixUniq+"_R1", time, ExtR1Buffer[last_index], clrGreen);
|
||||
ShowRightPrice(ExtPrefixUniq+"_PP", time, ExtPPBuffer[last_index], clrBlue);
|
||||
ShowRightPrice(ExtPrefixUniq+"_S1", time, ExtS1Buffer[last_index], clrRed);
|
||||
ShowRightPrice(ExtPrefixUniq+"_S2", time, ExtS2Buffer[last_index], clrRed);
|
||||
ShowRightPrice(ExtPrefixUniq+"_S3", time, ExtS3Buffer[last_index], clrRed);
|
||||
ShowRightPrice(ExtPrefixUniq+"_S4", time, ExtS4Buffer[last_index], clrRed);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create or Update "Right Price Label" object |
|
||||
//+------------------------------------------------------------------+
|
||||
bool ShowRightPrice(const string name, datetime time, double price, color clr)
|
||||
{
|
||||
if(!ObjectCreate(0, name, OBJ_ARROW_RIGHT_PRICE, 0, time, price))
|
||||
{
|
||||
ObjectMove(0, name, 0, time, price);
|
||||
return(false);
|
||||
}
|
||||
|
||||
//--- make the label size adaptive
|
||||
long scale=2;
|
||||
if(!ChartGetInteger(0, CHART_SCALE, 0, scale))
|
||||
{
|
||||
//--- output an error message to the Experts journal
|
||||
Print(__FUNCTION__+", ChartGetInteger(CHART_SCALE) failed, error = ", GetLastError());
|
||||
}
|
||||
int width=scale>1 ? 2:1; // if chart scale > 1, then label size = 2
|
||||
|
||||
ObjectSetInteger(0, name, OBJPROP_COLOR, clr);
|
||||
ObjectSetInteger(0, name, OBJPROP_STYLE, STYLE_SOLID);
|
||||
ObjectSetInteger(0, name, OBJPROP_WIDTH, width);
|
||||
ObjectSetInteger(0, name, OBJPROP_BACK, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTABLE, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_SELECTED, false);
|
||||
ObjectSetInteger(0, name, OBJPROP_HIDDEN, true);
|
||||
ObjectSetInteger(0, name, OBJPROP_ZORDER, 0);
|
||||
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Reference in New Issue
Block a user