Price Data Components
Miscellaneous
0
Views
0
Downloads
0
Favorites
MTF_MCP_Scanner
ÿþ//+------------------------------------------------------------------+
//| MTF_MCP_Scanner.mq5 |
//| Copyright 2018, MetaQuotes Software Corp. |
//| https://mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2018, MetaQuotes Software Corp."
#property link "https://mql5.com"
//--- includes
#include <Canvas\Canvas.mqh>
//+------------------------------------------------------------------+
//| ;0AA->:=> |
//+------------------------------------------------------------------+
enum ENUM_MOUSE_STATE
{
MOUSE_STATE_NOT_PRESSED,
MOUSE_STATE_PRESSED_OUTSIDE_WINDOW,
MOUSE_STATE_PRESSED_INSIDE_WINDOW,
MOUSE_STATE_PRESSED_INSIDE_HEADER,
MOUSE_STATE_OUTSIDE_WINDOW,
MOUSE_STATE_INSIDE_WINDOW,
MOUSE_STATE_INSIDE_HEADER
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
class CWnd
{
protected:
CCanvas m_canvas;
CCanvas m_field;
long m_chart_id;
int m_chart_w;
int m_chart_h;
int m_sub_wnd;
string m_name;
string m_caption;
string m_caption_font;
string m_name_gv_x;
string m_name_gv_y;
color m_color_bg;
color m_color_border;
color m_color_bg_header;
color m_color_caption;
color m_color_texts;
uchar m_alpha_bg;
uchar m_alpha_head;
int m_x;
int m_y;
int m_w;
int m_h;
int m_y_act;
int m_caption_font_size;
uint m_caption_alignment;
uint m_x_caption;
bool m_is_visible;
bool m_header_on;
bool m_movable;
bool m_wider_wnd;
bool m_higher_wnd;
ENUM_PROGRAM_TYPE m_program_type;
ENUM_MOUSE_STATE m_mouse_state;
ENUM_MOUSE_STATE MouseButtonState(const int x,const int y,bool pressed);
void Move(int x,int y);
bool CreateCanvas(CCanvas &canvas,const int wnd_id,const int x,const int y,const int w,const int h);
void DrawHeaderArea(const string caption);
void RedrawHeaderArea(const color clr_area,const color clr_caption);
string TimeframeToString(const ENUM_TIMEFRAMES timeframe);
int CoordX1(void) const { return this.m_x; }
int CoordX2(void) const { return this.m_x+this.m_w; }
int CoordY1(void) const { return this.m_y; }
int CoordY2(void) const { return this.m_y+this.m_h; }
int CoordYAct(void) const { return this.m_y+this.m_y_act; }
color RGBToColor(const double r,const double g,const double b);
void ColorToRGB(const color clr,double &r,double &g,double &b);
double GetR(const color clr) { return clr&0xff; }
double GetG(const color clr) { return(clr>>8)&0xff; }
double GetB(const color clr) { return(clr>>16)&0xff; }
int ChartWidth(void) const { return this.m_chart_w; }
int ChartHeight(void) const { return this.m_chart_h; }
bool HigherWnd(void) const { return(this.m_h+2>this.m_chart_h); }
bool WiderWnd(void) const { return(this.m_w+2>this.m_chart_w); }
public:
bool CreateWindow(const string caption_text,const int x,const int y,const int w,const int h,const bool header,bool movable);
void Resize(const int w,const int h);
void SetColors(const color clr_bg,const color clr_bd,const color clr_hd,const color clr_capt,const color clr_text,uchar alpha_bg=128,uchar alpha_hd=200);
CCanvas *GetFieldCanvas(void) { return &this.m_field; }
void DrawSeparateVLine(const int x,const int y1,const int y2,const color clr1,const color clr2,const uchar w=1);
void DrawSeparateHLine(const int x,const int y1,const int y2,const color clr1,const color clr2,const uchar w=1);
color NewColor(color base_color,int shift_red,int shift_green,int shift_blue);
string Caption(void) const { return this.m_caption; }
string NameCaptionFont(void) const { return this.m_caption_font; }
color ColorCaption(void) const { return this.m_color_caption; }
color ColorBackground(void) const { return this.m_color_bg; }
color ColorHeaderBackground(void) const { return this.m_color_bg_header; }
color ColorTexts(void) const { return this.m_color_texts; }
void OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
CWnd(void);
~CWnd(void);
};
//+------------------------------------------------------------------+
//| CWnd :>=AB@C:B>@ |
//+------------------------------------------------------------------+
CWnd::CWnd(void) : m_chart_id(::ChartID()),
m_program_type((ENUM_PROGRAM_TYPE)::MQLInfoInteger(MQL_PROGRAM_TYPE)),
m_name(::MQLInfoString(MQL_PROGRAM_NAME)),
m_name_gv_x(m_name+"_GVX"),
m_name_gv_y(m_name+"_GVY"),
m_sub_wnd(m_program_type==PROGRAM_EXPERT || m_program_type==PROGRAM_SCRIPT ? 0 : ::ChartWindowFind()),
m_chart_w((int)::ChartGetInteger(m_chart_id,CHART_WIDTH_IN_PIXELS,m_sub_wnd)),
m_chart_h((int)::ChartGetInteger(m_chart_id,CHART_HEIGHT_IN_PIXELS,m_sub_wnd)),
m_caption(""),
m_caption_font("Calibri"),
m_caption_font_size(-100),
m_alpha_bg(128),
m_alpha_head(200),
m_color_bg(C'200,200,200'),
m_color_bg_header(clrDarkGray),
m_color_border(clrDarkGray),
m_color_caption(clrYellow),
m_color_texts(clrSlateGray),
m_h(100),
m_w(160),
m_x(3),
m_y(::ChartGetInteger(m_chart_id,CHART_SHOW_ONE_CLICK) ? 79 : 20),
m_y_act(10),
m_is_visible(false),
m_movable(true),
m_header_on(true),
m_x_caption(4),
m_caption_alignment(TA_LEFT|TA_VCENTER),
m_mouse_state(MOUSE_STATE_NOT_PRESSED)
{
::ChartSetInteger(0,CHART_EVENT_MOUSE_MOVE,true);
if(!::GlobalVariableCheck(this.m_name_gv_x))
::GlobalVariableSet(this.m_name_gv_x,this.m_x);
else
this.m_x=(int)::GlobalVariableGet(this.m_name_gv_x);
if(!::GlobalVariableCheck(this.m_name_gv_y))
::GlobalVariableSet(this.m_name_gv_y,this.m_y);
else
this.m_y=(int)::GlobalVariableGet(this.m_name_gv_y);
this.m_higher_wnd=this.HigherWnd();
this.m_wider_wnd=this.WiderWnd();
}
//+------------------------------------------------------------------+
//| CWnd 45AB@C:B>@ |
//+------------------------------------------------------------------+
CWnd::~CWnd(void)
{
::ObjectsDeleteAll(this.m_chart_id,m_name);
::GlobalVariableSet(this.m_name_gv_x,this.m_x);
::GlobalVariableSet(this.m_name_gv_y,this.m_y);
}
//+------------------------------------------------------------------+
//| CWnd Chart event function |
//+------------------------------------------------------------------+
void CWnd::OnChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
if(id==CHARTEVENT_CHART_CHANGE)
{
this.m_sub_wnd=(this.m_program_type==PROGRAM_EXPERT || this.m_program_type==PROGRAM_SCRIPT ? 0 : ::ChartWindowFind());
int w=(int)::ChartGetInteger(this.m_chart_id,CHART_WIDTH_IN_PIXELS,this.m_sub_wnd);
int h=(int)::ChartGetInteger(this.m_chart_id,CHART_HEIGHT_IN_PIXELS,this.m_sub_wnd);
this.m_higher_wnd=this.HigherWnd();
this.m_wider_wnd=this.WiderWnd();
if(this.m_chart_h!=h)
{
this.m_chart_h=h;
int y=this.CoordY1();
if(this.CoordY1()+this.m_h>h-1) y=h-this.m_h-1;
if(y<1) y=1;
this.Move(this.CoordX1(),y);
}
if(this.m_chart_w!=w)
{
this.m_chart_w=w;
int x=this.CoordX1();
if(this.CoordX1()+this.m_w>w-1) x=w-this.m_w-1;
if(x<1) x=1;
this.Move(x,this.CoordY1());
}
}
if(!this.m_movable)
return;
static int diff_x=0;
static int diff_y=0;
bool pressed=(sparam=="1" || sparam=="" ? true : false);
int mouse_x=(int)lparam;
int mouse_y=(int)dparam-(int)::ChartGetInteger(this.m_chart_id,CHART_WINDOW_YDISTANCE,this.m_sub_wnd);
ENUM_MOUSE_STATE state=this.MouseButtonState(mouse_x,mouse_y,pressed);
if(id==CHARTEVENT_MOUSE_MOVE)
{
if(state==MOUSE_STATE_PRESSED_INSIDE_WINDOW)
{
::ChartSetInteger(0,CHART_MOUSE_SCROLL,false);
::ChartRedraw(this.m_chart_id);
return;
}
else if(state==MOUSE_STATE_PRESSED_INSIDE_HEADER)
{
::ChartSetInteger(0,CHART_MOUSE_SCROLL,false);
this.Move(mouse_x-diff_x,mouse_y-diff_y);
return;
}
else
{
::ChartSetInteger(0,CHART_MOUSE_SCROLL,true);
diff_x=mouse_x-this.CoordX1();
diff_y=mouse_y-this.CoordY1();
}
}
}
//+------------------------------------------------------------------+
//| >72@0I05B A>AB>O=85 :=>?:8 <KH8 |
//+------------------------------------------------------------------+
ENUM_MOUSE_STATE CWnd::MouseButtonState(const int x,const int y,bool pressed)
{
//--- A;8 :=>?:0 =060B0
if(pressed)
{
//--- A;8 C65 70D8:A8@>20=> A>AB>O=85 - 2KE>4
if(this.m_mouse_state!=MOUSE_STATE_NOT_PRESSED)
return this.m_mouse_state;
//--- A;8 =060B0 :=>?:0 2=CB@8 >:=0
if(x>this.CoordX1() && x<this.CoordX2() && y>this.CoordY1() && y<this.CoordY2())
{
//--- A;8 =060B0 :=>?:0 2=CB@8 703>;>2:0
if(y>this.CoordY1() && y<this.CoordYAct())
{
this.RedrawHeaderArea(this.NewColor(this.m_color_bg_header,30,30,30),this.m_color_caption);
this.m_mouse_state=MOUSE_STATE_PRESSED_INSIDE_HEADER;
return this.m_mouse_state;
}
//--- A;8 =060B0 :=>?:0 2=CB@8 >:=0
else if(y>this.CoordY1() && y<this.CoordY2())
{
this.m_mouse_state=(this.m_header_on ? MOUSE_STATE_PRESSED_INSIDE_WINDOW : MOUSE_STATE_PRESSED_INSIDE_HEADER);
return this.m_mouse_state;
}
}
//--- =>?:0 =060B0 2=5 ?@545;>2 >:=0
else
{
this.m_mouse_state=MOUSE_STATE_PRESSED_OUTSIDE_WINDOW;
return this.m_mouse_state;
}
}
//--- =>?:0 =5 =060B0
else
{
this.m_mouse_state=MOUSE_STATE_NOT_PRESSED;
//--- C@A>@ 2=CB@8 >:=0
if(x>this.CoordX1() && x<this.CoordX2() && y>this.CoordY1() && y<this.CoordY2())
{
//--- C@A>@ 2=CB@8 703>;>2:0
if(y>this.CoordY1() && y<this.CoordYAct())
{
this.RedrawHeaderArea(this.NewColor(this.m_color_bg_header,20,20,20),this.m_color_caption);
return MOUSE_STATE_INSIDE_HEADER;
}
//--- C@A>@ 2=CB@8 >:=0
else
{
this.RedrawHeaderArea(this.m_color_bg_header,this.m_color_caption);
return MOUSE_STATE_INSIDE_WINDOW;
}
}
}
this.RedrawHeaderArea(this.m_color_bg_header,this.m_color_caption);
return MOUSE_STATE_NOT_PRESSED;
}
//+------------------------------------------------------------------+
//| CWnd ?5@5<5I5=85 >:=0 |
//+------------------------------------------------------------------+
void CWnd::Move(int x,int y)
{
if(!this.m_wider_wnd)
{
if(x+this.m_w>this.m_chart_w-1) x=this.m_chart_w-this.m_w-1;
if(x<1) x=1;
}
else
{
if(x>1) x=1;
if(x<this.m_chart_w-this.m_w-1) x=this.m_chart_w-this.m_w-1;
}
if(!this.m_higher_wnd)
{
if(y+this.m_h>this.m_chart_h-2) y=this.m_chart_h-this.m_h-2;
if(y<1) y=1;
}
else
{
if(y>1) y=1;
if(y<this.m_chart_h-this.m_h-2) y=this.m_chart_h-this.m_h-2;
}
this.m_x=x;
this.m_y=y;
::ObjectSetInteger(this.m_chart_id,this.m_name+"0",OBJPROP_XDISTANCE,this.m_x);
::ObjectSetInteger(this.m_chart_id,this.m_name+"0",OBJPROP_YDISTANCE,this.m_y);
::ObjectSetInteger(this.m_chart_id,this.m_name+"1",OBJPROP_XDISTANCE,this.m_x+1);
::ObjectSetInteger(this.m_chart_id,this.m_name+"1",OBJPROP_YDISTANCE,this.m_y+this.m_y_act+1);
this.m_canvas.Update(true);
}
//+------------------------------------------------------------------+
//| CWnd !>740QB E>;AB |
//+------------------------------------------------------------------+
bool CWnd::CreateCanvas(CCanvas &canvas,const int wnd_id,const int x,const int y,const int w,const int h)
{
if(!canvas.CreateBitmapLabel(this.m_chart_id,this.m_sub_wnd,this.m_name+(string)wnd_id,x,y,w,h,COLOR_FORMAT_ARGB_NORMALIZE))
return false;
if(wnd_id==0)
{
this.m_x=x;
this.m_y=y;
this.m_w=w;
this.m_h=h;
}
::ObjectSetInteger(this.m_chart_id,this.m_name+(string)wnd_id,OBJPROP_SELECTABLE,false);
::ObjectSetInteger(this.m_chart_id,this.m_name+(string)wnd_id,OBJPROP_SELECTED,false);
::ObjectSetInteger(this.m_chart_id,this.m_name+(string)wnd_id,OBJPROP_HIDDEN,true);
return true;
}
//+------------------------------------------------------------------+
//| CWnd !>740QB >:=> |
//+------------------------------------------------------------------+
bool CWnd::CreateWindow(const string caption_text,const int x,const int y,const int w,const int h,const bool header,bool movable)
{
if(!this.CreateCanvas(this.m_canvas,0,x,y,w,h))
return false;
this.m_header_on=header;
if(!header)
this.m_y_act=0;
this.m_movable=movable;
this.m_caption=caption_text;
this.m_canvas.Erase(::ColorToARGB(this.m_color_bg,this.m_alpha_bg));
this.m_canvas.Rectangle(0,0,this.m_w-1,this.m_h-1,::ColorToARGB(this.m_color_border));
this.DrawHeaderArea(this.m_caption);
this.m_canvas.Update(true);
if(!this.CreateCanvas(this.m_field,1,this.m_x+1,this.m_y+this.m_y_act+1,this.m_w-2,this.m_h-this.m_y_act-2))
return false;
return true;
}
//+------------------------------------------------------------------+
//| 7<5=O5B @07<5@K >:=0 |
//+------------------------------------------------------------------+
void CWnd::Resize(const int w,const int h)
{
this.m_w=w;
this.m_h=h;
this.m_canvas.Resize(this.m_w,this.m_h);
this.m_field.Resize(this.m_w-2,this.m_h-this.m_y_act-2);
this.m_canvas.Erase(::ColorToARGB(this.m_color_bg,this.m_alpha_bg));
this.m_canvas.Rectangle(0,0,this.m_w-1,this.m_h-1,::ColorToARGB(this.m_color_border));
this.DrawHeaderArea(this.m_caption);
this.m_canvas.Update(false);
this.m_field.Update(true);
}
//+------------------------------------------------------------------+
//| CWnd 8AC5B 703>;>2>: |
//+------------------------------------------------------------------+
void CWnd::DrawHeaderArea(const string caption)
{
if(!this.m_header_on) return;
this.m_canvas.FillRectangle(0,0,this.m_w,this.m_y_act,::ColorToARGB(this.m_color_bg_header,this.m_alpha_head));
this.m_canvas.FontSet(this.m_caption_font,this.m_caption_font_size,FW_NORMAL);
this.m_canvas.TextOut(this.m_x_caption,this.m_y_act/2,caption,::ColorToARGB(this.m_color_caption),this.m_caption_alignment);
}
//+------------------------------------------------------------------+
//| CWnd 5@5@8A>2K205B 703>;>2>: |
//+------------------------------------------------------------------+
void CWnd::RedrawHeaderArea(const color clr_area,const color clr_caption)
{
if(!this.m_header_on) return;
this.m_canvas.FillRectangle(0,0,this.m_w,this.m_y_act,::ColorToARGB(clr_area,this.m_alpha_head));
this.m_canvas.FontSet(this.m_caption_font,this.m_caption_font_size,FW_NORMAL);
this.m_canvas.TextOut(this.m_x_caption,this.m_y_act/2,this.m_caption,::ColorToARGB(clr_caption),this.m_caption_alignment);
this.m_canvas.Update();
}
//+------------------------------------------------------------------+
//| 8AC5B 25@B8:0;L=CN @0745;8B5;L=CN ;8=8N |
//+------------------------------------------------------------------+
void CWnd::DrawSeparateVLine(const int x,const int y1,const int y2,const color clr1,const color clr2,const uchar w=1)
{
this.m_field.LineVertical(x,y1,y2,::ColorToARGB(clr1,this.m_alpha_bg));
this.m_field.LineVertical(x+w,y1,y2,::ColorToARGB(clr2,this.m_alpha_bg));
}
//+------------------------------------------------------------------+
//| 8AC5B 3>@87>=B0;L=CN @0745;8B5;L=CN ;8=8N |
//+------------------------------------------------------------------+
void CWnd::DrawSeparateHLine(const int x1,const int x2,const int y,const color clr1,const color clr2,const uchar w=1)
{
this.m_field.LineHorizontal(x1,x2,y,::ColorToARGB(clr1,this.m_alpha_bg));
this.m_field.LineHorizontal(x1,x2,y+w,::ColorToARGB(clr2,this.m_alpha_bg));
}
//+------------------------------------------------------------------+
//| >72@0I05B F25B A =>2>9 F25B>2>9 A>AB02;ONI59 |
//+------------------------------------------------------------------+
color CWnd::NewColor(color base_color,int shift_red,int shift_green,int shift_blue)
{
double clR=0,clG=0,clB=0;
this.ColorToRGB(base_color,clR,clG,clB);
double clRn=(clR+shift_red < 0 ? 0 : clR+shift_red > 255 ? 255 : clR+shift_red);
double clGn=(clG+shift_green< 0 ? 0 : clG+shift_green> 255 ? 255 : clG+shift_green);
double clBn=(clB+shift_blue < 0 ? 0 : clB+shift_blue > 255 ? 255 : clB+shift_blue);
return this.RGBToColor(clRn,clGn,clBn);
}
//+------------------------------------------------------------------+
//| @5>1@07>20=85 RGB 2 const color |
//+------------------------------------------------------------------+
color CWnd::RGBToColor(const double r,const double g,const double b)
{
int int_r=(int)::round(r);
int int_g=(int)::round(g);
int int_b=(int)::round(b);
int clr=0;
//---
clr=int_b;
clr<<=8;
clr|=int_g;
clr<<=8;
clr|=int_r;
//---
return (color)clr;
}
//+------------------------------------------------------------------+
//| >;CG5=85 7=0G5=89 :><?>=5=B>2 RGB |
//+------------------------------------------------------------------+
void CWnd::ColorToRGB(const color clr,double &r,double &g,double &b)
{
r=GetR(clr);
g=GetG(clr);
b=GetB(clr);
}
//+------------------------------------------------------------------+
//| >72@0I05B =08<5=>20=85 B09<D@59<0 |
//+------------------------------------------------------------------+
string CWnd::TimeframeToString(const ENUM_TIMEFRAMES timeframe)
{
return ::StringSubstr(::EnumToString(timeframe==PERIOD_CURRENT ? Period() : timeframe),7);
}
//+------------------------------------------------------------------+
//| #AB0=02;8205B F25B0 ?0=5;8 |
//+------------------------------------------------------------------+
void CWnd::SetColors(const color clr_bg,const color clr_bd,const color clr_hd,const color clr_capt,const color clr_text,uchar alpha_bg=128,uchar alpha_hd=200)
{
this.m_color_bg=clr_bg;
this.m_color_border=clr_bd;
this.m_color_bg_header=clr_hd;
this.m_color_caption=clr_capt;
this.m_color_texts=clr_text;
this.m_alpha_bg=alpha_bg;
this.m_alpha_head=alpha_hd;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| ;0AA AGQBG8: B09<5@0 |
//+------------------------------------------------------------------+
class CTimerCounter
{
private:
ulong m_timer_counter;
ulong m_timer_step;
ulong m_timer_pause;
public:
void SetParams(const ulong step,const ulong pause) { this.m_timer_step=step; this.m_timer_pause=pause; }
bool IsTimeDone(void);
CTimerCounter(void) : m_timer_counter(0),m_timer_step(16),m_timer_pause(250){;}
~CTimerCounter(void){;}
};
//+------------------------------------------------------------------+
//| CTimerCounter ?@>25@O5B >:>=G0=85 ?0C7K |
//+------------------------------------------------------------------+
bool CTimerCounter::IsTimeDone(void)
{
if(this.m_timer_counter>ULONG_MAX)
this.m_timer_counter=0;
if(this.m_timer_counter<this.m_timer_pause)
{
this.m_timer_counter+=this.m_timer_step;
return false;
}
this.m_timer_counter=0;
return true;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| ;0AA =48:0B>@0 |
//+------------------------------------------------------------------+
#include <Indicators\Indicator.mqh>
class CIndicatorsBase : public CIndicator
{
protected:
CTimerCounter m_counter_time;
CTimerCounter m_counter_refresh;
MqlParam m_params[];
string m_name_indicator;
bool m_counter_refresh_done;
bool m_counter_time_done;
int m_type;
int m_num_params;
int m_prev_calculated;
bool m_handle_success;
int m_refresh_flags;
datetime Time(const int shift) const { datetime array[]; return(::CopyTime(this.Symbol(),this.Period(),1,1,array)==1 ? array[0]: 0); }
string SetName(const ENUM_INDICATOR type) const { return ::StringSubstr(::EnumToString(type),4); }
virtual bool Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[]);
public:
string TimeframeDescription(void) const { return ::StringSubstr(::EnumToString(this.m_period==PERIOD_CURRENT ? ::Period() : this.m_period),7); }
string Name(void) const { return this.m_name_indicator; }
int PrevCalculated(void) const { return this.m_prev_calculated; }
bool IsCounterRefreshDone(void) { return this.m_counter_refresh_done; }
bool IsCounterTimeDone(void) { return this.m_counter_time_done; }
void SetType(const int type) { this.m_type=type; }
void SetCounterTime(const uint step,const uint pause);
void SetCounterRefresh(const uint step,const uint pause);
void SetRefreshFlags(const bool refresh_current,const int refresh_periods=OBJ_ALL_PERIODS);
bool CheckLoadHistory(void) { return CSeries::CheckLoadHistory(this.BufferSize()); }
bool Create(const string indicator_name,const int buffers_num);
bool Create(const ENUM_INDICATOR indicator_type,const int buffers_num);
void Refresh(void);
template<typename T>
void SetParameter(const T value);
void OnTimer(void);
virtual int Type(void) const { return this.m_type; }
CIndicatorsBase(const string symbol_name,const ENUM_TIMEFRAMES timeframe,const int type_id);
~CIndicatorsBase(void);
};
//+------------------------------------------------------------------+
//| CIndicatorsBase :>=AB@C:B>@ |
//+------------------------------------------------------------------+
CIndicatorsBase::CIndicatorsBase(const string symbol_name,const ENUM_TIMEFRAMES timeframe,const int type_id) : m_refresh_flags(OBJ_ALL_PERIODS),
m_prev_calculated(WRONG_VALUE),
m_handle_success(false),
m_num_params(0),
m_counter_refresh_done(false),
m_counter_time_done(false),
m_type(type_id)
{
this.SetSymbolPeriod(symbol_name,timeframe);
this.m_refresh_current=false;
this.SetCounterRefresh(16,250);
this.SetCounterTime(16,90000);
}
//+------------------------------------------------------------------+
//| CIndicatorsBase 45AB@C:B>@ |
//+------------------------------------------------------------------+
CIndicatorsBase::~CIndicatorsBase(void)
{
this.m_handle_success=false;
this.m_handle=INVALID_HANDLE;
this.m_buffers_total=0;
this.m_prev_calculated=0;
this.m_num_params=0;
this.m_counter_time_done=false;
this.m_counter_refresh_done=false;
}
//+------------------------------------------------------------------+
//| CIndicatorsBase "09<5@ |
//+------------------------------------------------------------------+
void CIndicatorsBase::OnTimer(void)
{
this.m_counter_time_done=this.m_counter_time.IsTimeDone();
if(this.m_counter_time_done)
this.Time(1);
this.m_counter_refresh_done=this.m_counter_refresh.IsTimeDone();
}
//+------------------------------------------------------------------+
//| CIndicatorsBase #AB0=>2:0 AGQBG8:0 B09<5@0 2@5<5=8 |
//+------------------------------------------------------------------+
void CIndicatorsBase::SetCounterTime(const uint step,const uint pause)
{
this.m_counter_time.SetParams(step,pause);
}
//+------------------------------------------------------------------+
//| CIndicatorsBase #AB0=>2:0 AGQBG8:0 B09<5@0 >1=>2;5=8O |
//+------------------------------------------------------------------+
void CIndicatorsBase::SetCounterRefresh(const uint step,const uint pause)
{
this.m_counter_refresh.SetParams(step,pause);
}
//+------------------------------------------------------------------+
//| CIndicatorsBase !>740QB 8=48:0B>@ ?> 8<5=8 |
//+------------------------------------------------------------------+
bool CIndicatorsBase::Create(const string indicator_name,const int buffers_num)
{
if(this.m_num_params==0)
{
::Print(__FUNCSIG__,": Error. First, you need to set the indicator parameters: SetParameter()");
this.m_handle_success=false;
this.m_handle=INVALID_HANDLE;
this.m_buffers_total=0;
this.m_num_params=0;
return false;
}
//---
this.m_name_indicator=indicator_name;
this.m_buffers_total=(buffers_num<1 ? 1 : buffers_num>512 ? 512 : buffers_num);
int size=::ArraySize(this.m_params);
::ArrayResize(this.m_params,size+1);
for(int i=size;i>0;i--)
{
this.m_params[i].type=this.m_params[i-1].type;
this.m_params[i].double_value=this.m_params[i-1].double_value;
this.m_params[i].integer_value=this.m_params[i-1].integer_value;
this.m_params[i].string_value=this.m_params[i-1].string_value;
}
this.m_params[0].type=TYPE_STRING;
this.m_params[0].string_value=this.m_name_indicator;
this.m_num_params++;
//---
::ResetLastError();
this.m_handle_success=CIndicator::Create(this.m_symbol,this.m_period,IND_CUSTOM,this.m_num_params,this.m_params);
if(!this.m_handle_success)
{
::Print(__FUNCSIG__,": Error creating ",this.Name(),": ",::GetLastError());
this.m_handle_success=false;
this.m_handle=INVALID_HANDLE;
this.m_buffers_total=0;
this.m_num_params=0;
return false;
}
return this.m_handle_success;
}
//+------------------------------------------------------------------+
//| CIndicatorsBase !>740QB 8=48:0B>@ ?> B8?C |
//+------------------------------------------------------------------+
bool CIndicatorsBase::Create(const ENUM_INDICATOR indicator_type,const int buffers_num)
{
if(this.m_num_params==0)
{
::Print(__FUNCSIG__,": Error. First, you need to set the indicator parameters: SetParameter()");
this.m_handle_success=false;
this.m_handle=INVALID_HANDLE;
this.m_buffers_total=0;
this.m_num_params=0;
return false;
}
if(indicator_type==IND_CUSTOM)
{
::Print(__FUNCSIG__,": Error. To create a custom indicator, use the Create(const string indicator_name,const int buffers_num) method.");
this.m_handle_success=false;
this.m_handle=INVALID_HANDLE;
this.m_buffers_total=0;
this.m_num_params=0;
return false;
}
//---
this.m_name_indicator=this.SetName(indicator_type);
CSeries::m_buffers_total=(buffers_num<1 ? 1 : buffers_num>512 ? 512 : buffers_num);
//---
::ResetLastError();
this.m_handle_success=CIndicator::Create(this.m_symbol,this.m_period,indicator_type,this.m_num_params,this.m_params);
if(!this.m_handle_success)
{
::Print(__FUNCSIG__,": Error creating ",this.Name(),": ",::GetLastError());
this.m_handle_success=false;
this.m_handle=INVALID_HANDLE;
this.m_buffers_total=0;
this.m_num_params=0;
return false;
}
return this.m_handle_success;
}
//+------------------------------------------------------------------+
//| CIndicatorsBase 8=8F80;870F8O |
//+------------------------------------------------------------------+
bool CIndicatorsBase::Initialize(const string symbol,const ENUM_TIMEFRAMES period,const int num_params,const MqlParam ¶ms[])
{
if(CIndicator::CreateBuffers(symbol,period,m_buffers_total))
{
//--- string of status of drawing
CSeries::m_name=this.m_name_indicator+" "+symbol+" "+this.TimeframeDescription()+" "+params[0].string_value;
CIndicator::m_status="("+this.m_name_indicator+" "+symbol+" "+this.TimeframeDescription();
for(int i=(this.m_type==IND_CUSTOM ? 1 : 0);i<num_params;i++)
{
switch(params[i].type)
{
case TYPE_BOOL : CIndicator::m_status+=","+((params[i].integer_value) ? "true" : "false"); break;
case TYPE_CHAR : case TYPE_UCHAR: case TYPE_SHORT: case TYPE_USHORT:
case TYPE_INT : case TYPE_UINT: case TYPE_LONG:
case TYPE_ULONG : CIndicator::m_status+=","+IntegerToString(params[i].integer_value); break;
case TYPE_COLOR : CIndicator::m_status+=","+ColorToString((color)params[i].integer_value); break;
case TYPE_DATETIME: CIndicator::m_status+=","+TimeToString(params[i].integer_value); break;
case TYPE_FLOAT :
case TYPE_DOUBLE : CIndicator::m_status+=","+DoubleToString(params[i].double_value,2); break;
case TYPE_STRING : CIndicator::m_status+=",'"+params[i].string_value+"'"; break;
default : break;
}
}
CIndicator::m_status+=") Handle="+IntegerToString(CIndicator::m_handle);
//--- create buffers
for(int i=0;i<m_buffers_total;i++)
((CIndicatorBuffer*)At(i)).Name("LINE "+IntegerToString(i));
//--- ok
return true;
}
//--- error
return false;
}
//+------------------------------------------------------------------+
//| CIndicatorsBase 1=>2;O5B 8=48:0B>@ |
//+------------------------------------------------------------------+
void CIndicatorsBase::Refresh(void)
{
this.SetRefreshFlags(CIndicator::BarsCalculated()==this.m_prev_calculated,this.m_refresh_flags);
if(this.m_prev_calculated!=CIndicator::BarsCalculated())
{
this.m_prev_calculated=CIndicator::BarsCalculated();
}
CIndicator::Refresh(this.m_refresh_flags);
}
//+------------------------------------------------------------------+
//| CIndicatorsBase CAB0=>2:0 D;03>2 >1=>2;5=8O |
//+------------------------------------------------------------------+
void CIndicatorsBase::SetRefreshFlags(const bool refresh_current,const int refresh_periods=OBJ_ALL_PERIODS)
{
CSeries::RefreshCurrent(refresh_current);
this.m_refresh_flags=refresh_periods;
}
//+------------------------------------------------------------------+
//| CIndicatorsBase #AB0=>2:0 >4=>3> ?0@0<5B@0 |
//+------------------------------------------------------------------+
template<typename T>
void CIndicatorsBase::SetParameter(const T value)
{
string type=typename(value);
this.m_num_params++;
if(::ArraySize(this.m_params)<this.m_num_params)
::ArrayResize(this.m_params,this.m_num_params);
if(type=="string")
{
this.m_params[this.m_num_params-1].type=TYPE_STRING;
this.m_params[this.m_num_params-1].string_value=(string)value;
}
else if(type=="bool")
{
this.m_params[this.m_num_params-1].type=TYPE_BOOL;
this.m_params[this.m_num_params-1].integer_value=(bool)value;
}
else if(type=="char")
{
this.m_params[this.m_num_params-1].type=TYPE_CHAR;
this.m_params[this.m_num_params-1].integer_value=(char)value;
}
else if(type=="uchar")
{
this.m_params[this.m_num_params-1].type=TYPE_UCHAR;
this.m_params[this.m_num_params-1].integer_value=(uchar)value;
}
else if(type=="short")
{
this.m_params[this.m_num_params-1].type=TYPE_SHORT;
this.m_params[this.m_num_params-1].integer_value=(short)value;
}
else if(type=="ushort")
{
this.m_params[this.m_num_params-1].type=TYPE_USHORT;
this.m_params[this.m_num_params-1].integer_value=(ushort)value;
}
else if(type=="color")
{
this.m_params[this.m_num_params-1].type=TYPE_COLOR;
this.m_params[this.m_num_params-1].integer_value=(color)value;
}
else if(type=="int")
{
this.m_params[this.m_num_params-1].type=TYPE_INT;
this.m_params[this.m_num_params-1].integer_value=(int)value;
}
else if(type=="uint")
{
this.m_params[this.m_num_params-1].type=TYPE_UINT;
this.m_params[this.m_num_params-1].integer_value=(uint)value;
}
else if(type=="datetime")
{
this.m_params[this.m_num_params-1].type=TYPE_DATETIME;
this.m_params[this.m_num_params-1].integer_value=(datetime)value;
}
else if(type=="long")
{
this.m_params[this.m_num_params-1].type=TYPE_LONG;
this.m_params[this.m_num_params-1].integer_value=(long)value;
}
else if(type=="ulong")
{
this.m_params[this.m_num_params-1].type=TYPE_ULONG;
this.m_params[this.m_num_params-1].integer_value=(long)value;
}
else if(type=="float")
{
this.m_params[this.m_num_params-1].type=TYPE_FLOAT;
this.m_params[this.m_num_params-1].double_value=(float)value;
}
else if(type=="double")
{
this.m_params[this.m_num_params-1].type=TYPE_DOUBLE;
this.m_params[this.m_num_params-1].double_value=(double)value;
}
}
//+------------------------------------------------------------------+
//| ;0AA-:>;;5:F8O 8=48:0B>@>2 |
//+------------------------------------------------------------------+
class CIndCollection : public CObject
{
protected:
CTimerCounter m_counter_time;
CTimerCounter m_counter_refresh;
CArrayObj m_list_ind;
string m_symbol;
ENUM_TIMEFRAMES m_timeframe;
bool m_counter_refresh_done;
bool m_counter_time_done;
int m_index_x;
int m_index_y;
int m_digits;
double m_point;
datetime Time(const int shift) const { datetime array[]; return(::CopyTime(this.m_symbol,this.m_timeframe,1,1,array)==1 ? array[0]: 0); }
public:
CIndicatorsBase* GetIndByID(const int ind_id);
CArrayObj* GetList(void) { return &m_list_ind; }
bool Add(CIndicatorsBase* ind) { return this.m_list_ind.Add(ind); }
void SetIndexX(const int x) { this.m_index_x=x; }
void SetIndexY(const int y) { this.m_index_y=y; }
bool IsCounterRefreshDone(void) { return this.m_counter_refresh_done; }
bool IsCounterTimeDone(void) { return this.m_counter_time_done; }
double Point(void) const { return this.m_point; }
int Digits(void) const { return this.m_digits; }
int IndexX(void) const { return this.m_index_x; }
int IndexY(void) const { return this.m_index_y; }
string Symbol(void) const { return this.m_symbol; }
ENUM_TIMEFRAMES Timeframe(void) const { return this.m_timeframe; }
string TimeframeDescription(void) const { return ::StringSubstr(::EnumToString(this.m_timeframe),7);}
void SetCounterTime(const uint step,const uint pause);
void SetCounterRefresh(const uint step,const uint pause);
void OnTimer(void);
void Refresh(void);
CIndCollection(const string symbol_name,const ENUM_TIMEFRAMES timeframe);
~CIndCollection(void);
};
//+------------------------------------------------------------------+
//| CIndCollection :>=AB@C:B>@ |
//+------------------------------------------------------------------+
CIndCollection::CIndCollection(const string symbol_name,const ENUM_TIMEFRAMES timeframe) : m_index_x(0),
m_index_y(0),
m_counter_refresh_done(false),
m_counter_time_done(false)
{
this.m_symbol=(symbol_name=="" || symbol_name==NULL ? ::Symbol() : symbol_name);
this.m_timeframe=(timeframe==PERIOD_CURRENT ? ::Period() : timeframe);
this.m_digits=(int)::SymbolInfoInteger(this.m_symbol,SYMBOL_DIGITS);
this.m_point=::SymbolInfoDouble(this.m_symbol,SYMBOL_POINT);
this.SetCounterRefresh(16,250);
this.SetCounterTime(16,90000);
}
//+------------------------------------------------------------------+
//| CIndCollection 45AB@C:B>@ |
//+------------------------------------------------------------------+
CIndCollection::~CIndCollection(void)
{
this.m_counter_time_done=false;
this.m_counter_refresh_done=false;
}
//+------------------------------------------------------------------+
//| CIndCollection 1=>2;O5B :>;;5:F8N 8=48:0B>@>2 |
//+------------------------------------------------------------------+
void CIndCollection::Refresh(void)
{
int total=this.m_list_ind.Total();
for(int i=0;i<total;i++)
{
CIndicatorsBase* ind=this.m_list_ind.At(i);
if(ind==NULL)
continue;
ind.Refresh();
}
}
//+------------------------------------------------------------------+
//| CIndCollection "09<5@ |
//+------------------------------------------------------------------+
void CIndCollection::OnTimer(void)
{
this.m_counter_time_done=this.m_counter_time.IsTimeDone();
if(this.m_counter_time_done)
{
this.Time(1);
}
this.m_counter_refresh_done=this.m_counter_refresh.IsTimeDone();
}
//+------------------------------------------------------------------+
//| CIndCollection #AB0=>2:0 AGQBG8:0 B09<5@0 2@5<5=8 |
//+------------------------------------------------------------------+
void CIndCollection::SetCounterTime(const uint step,const uint pause)
{
this.m_counter_time.SetParams(step,pause);
}
//+------------------------------------------------------------------+
//| CIndCollection #AB0=>2:0 AGQBG8:0 B09<5@0 >1=>2;5=8O |
//+------------------------------------------------------------------+
void CIndCollection::SetCounterRefresh(const uint step,const uint pause)
{
this.m_counter_refresh.SetParams(step,pause);
}
//+------------------------------------------------------------------+
//| CIndCollection 2>72@0I05B C:070B5;L =0 8=48:0B>@ ?> B8?C |
//+------------------------------------------------------------------+
CIndicatorsBase* CIndCollection::GetIndByID(const int ind_id)
{
int total=this.m_list_ind.Total();
for(int i=0;i<total;i++)
{
CIndicatorsBase* ind=this.m_list_ind.At(i);
if(ind.Type()==ind_id)
return ind;
}
return NULL;
}
//+------------------------------------------------------------------+
//| ;0AA B09<D@59< |
//+------------------------------------------------------------------+
class CTimeframe : public CObject
{
private:
ENUM_TIMEFRAMES m_timeframe;
string m_symbol;
datetime m_last_alert_time;
int m_status;
int m_index_x;
public:
ENUM_TIMEFRAMES Timeframe(void) const { return this.m_timeframe; }
string Symbol(void) const { return this.m_symbol; }
int Status(void) const { return this.m_status; }
int IndexX(void) const { return this.m_index_x; }
void SetAlertTime(const datetime time) { this.m_last_alert_time=time; }
void SetIndexX(const int index) { this.m_index_x=index; }
void SetStatus(const int status) { this.m_status=status; }
datetime LastAlertTime(void) const { return this.m_last_alert_time; }
string TimeframeDescription(void) const { return ::StringSubstr(::EnumToString(this.m_timeframe==PERIOD_CURRENT ? ::Period() : this.m_timeframe),7); }
CTimeframe(const string symbol,const ENUM_TIMEFRAMES timeframe);
~CTimeframe(void){;}
};
//+------------------------------------------------------------------+
//| CTimeframe :>=AB@C:B>@ |
//+------------------------------------------------------------------+
CTimeframe::CTimeframe(const string symbol,const ENUM_TIMEFRAMES timeframe) : m_status(0),m_last_alert_time(0)
{
this.m_symbol=(symbol==NULL || symbol=="" ? ::Symbol() : symbol);
this.m_timeframe=(timeframe==PERIOD_CURRENT ? ::Period() : timeframe);
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| ;0AA A8<2>; |
//+------------------------------------------------------------------+
class CSymbol : public CObject
{
private:
CArrayObj m_list_timeframe;
string m_symbol;
int m_index_y;
datetime m_last_alert_time;
bool CheckTimeframe(const ENUM_TIMEFRAMES timeframe);
public:
CTimeframe* GetPointerTF(const ENUM_TIMEFRAMES timeframe);
CArrayObj* GetListTimeframes(void) { return &this.m_list_timeframe; }
void SetIndexY(const int index) { this.m_index_y=index; }
void SetAlertTime(const datetime time) { this.m_last_alert_time=time; }
int IndexY(void) const { return this.m_index_y; }
string Symbol(void) const { return this.m_symbol; }
datetime LastAlertTime(void) const { return this.m_last_alert_time; }
bool CheckSyncTFsByValue(const int value);
int CheckSyncAllTFs(int &value);
int CheckSigOneTF(const ENUM_TIMEFRAMES timeframe);
bool AddTimeframe(const ENUM_TIMEFRAMES timeframe);
void SetStatusTF(const ENUM_TIMEFRAMES timeframe,const int status);
CSymbol(const string symbol);
~CSymbol(void){;}
};
//+------------------------------------------------------------------+
//| CSymbol :>=AB@C:B>@ |
//+------------------------------------------------------------------+
CSymbol::CSymbol(const string symbol) : m_last_alert_time(0)
{
this.m_symbol=(symbol==NULL || symbol=="" ? ::Symbol() : symbol);
this.m_list_timeframe.Clear();
}
//+------------------------------------------------------------------+
//| >72@0I05B D0:B A8=E@>=870F88 2A5E B09<D@59<>2 ?> 7=0G5=8N |
//+------------------------------------------------------------------+
bool CSymbol::CheckSyncTFsByValue(const int value)
{
int total=this.m_list_timeframe.Total();
if(total<2)
return false;
this.m_list_timeframe.Sort();
CTimeframe* first=this.m_list_timeframe.At(0);
if(first==NULL || first.Status()!=value)
return false;
int tfs=1;
for(int i=1;i<total;i++)
{
CTimeframe* obj=this.m_list_timeframe.At(i);
if(obj==NULL || obj.Status()!=first.Status())
return false;
tfs++;
}
return(tfs==total ? true : false);
}
//+------------------------------------------------------------------+
//| >72@0I05B 7=0G5=85 A8=E@>=870F88 2A5E B09<D@59<>2 |
//+------------------------------------------------------------------+
int CSymbol::CheckSyncAllTFs(int &value)
{
int total=this.m_list_timeframe.Total();
if(total<2)
return 0;
this.m_list_timeframe.Sort();
CTimeframe* first=this.m_list_timeframe.At(0);
if(first==NULL || first.Status()==0)
return 0;
int tfs=1;
for(int i=1;i<total;i++)
{
CTimeframe* obj=this.m_list_timeframe.At(i);
if(obj==NULL || obj.Status()!=first.Status())
return 0;
tfs++;
}
if(tfs==total)
{
value=first.Status();
return tfs;
}
return 0;
}
//+------------------------------------------------------------------+
//| >72@0I05B 7=0G5=85 A83=0;0 =0 B09<D@59<5 |
//+------------------------------------------------------------------+
int CSymbol::CheckSigOneTF(const ENUM_TIMEFRAMES timeframe)
{
if(this.m_list_timeframe.Total()<1)
return 0;
CTimeframe* obj=this.GetPointerTF(timeframe);
return(obj!=NULL ? obj.Status() : 0);
}
//+------------------------------------------------------------------+
//| #AB0=02;8205B AB0BCA B09<D@59<0 |
//+------------------------------------------------------------------+
void CSymbol::SetStatusTF(const ENUM_TIMEFRAMES timeframe,const int status)
{
CTimeframe* tf=this.GetPointerTF(timeframe);
if(tf==NULL)
return;
tf.SetStatus(status);
}
//+------------------------------------------------------------------+
//| >72@0I05B C:070B5;L =0 >1J5:B-B09<D@59< |
//+------------------------------------------------------------------+
CTimeframe* CSymbol::GetPointerTF(const ENUM_TIMEFRAMES timeframe)
{
int total=this.m_list_timeframe.Total();
for(int i=0;i<total;i++)
{
CTimeframe* obj=this.m_list_timeframe.At(i);
if(obj==NULL)
continue;
if(obj.Timeframe()==timeframe)
return obj;
}
return NULL;
}
//+------------------------------------------------------------------+
//| CSymbol 2>72@0I05B =0;8G85 B09<D@59<0 2 A?8A:5 |
//+------------------------------------------------------------------+
bool CSymbol::CheckTimeframe(const ENUM_TIMEFRAMES timeframe)
{
int total=this.m_list_timeframe.Total();
for(int i=0;i<total;i++)
{
CTimeframe* obj=this.m_list_timeframe.At(i);
if(obj==NULL)
continue;
if(obj.Timeframe()==timeframe)
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| CSymbol 4>102;O5B B09<D@59< |
//+------------------------------------------------------------------+
bool CSymbol::AddTimeframe(const ENUM_TIMEFRAMES timeframe)
{
if(!this.CheckTimeframe(timeframe))
{
CTimeframe* tf=new CTimeframe(this.m_symbol,timeframe);
if(tf==NULL)
return false;
if(this.m_list_timeframe.Add(tf))
return true;
}
return false;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| ;0AA A>>1I5=8O |
//+------------------------------------------------------------------+
class CMessage : public CObject
{
private:
string m_message;
int m_mess_id;
public:
int GetID(void) const { return this.m_mess_id; }
string GetMessage(void) const { return this.m_message; }
CMessage(const int id,const string message) : m_mess_id(id),m_message(message) {}
~CMessage(void){;}
};
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| ;0AA A>>1I5=89 0;5@B>2 |
//+------------------------------------------------------------------+
class CAlertsMess
{
private:
CArrayObj m_list_messages;
public:
bool Add(const int id,const string message);
string Message(const int id);
CAlertsMess(void){;}
~CAlertsMess(void){;}
};
//+------------------------------------------------------------------+
//| CAlertsMess 4>102;O5B A>>1H5=85 2 A?8A>: |
//+------------------------------------------------------------------+
bool CAlertsMess::Add(const int id,const string message)
{
CMessage* mess=new CMessage(id,message);
return(mess==NULL || !this.m_list_messages.Add(mess) ? false : true);
}
//+------------------------------------------------------------------+
//| >72@0H05B A>>1I5=85 ?> 845=B8D8:0B>@C |
//+------------------------------------------------------------------+
string CAlertsMess::Message(const int id)
{
int total=this.m_list_messages.Total();
for(int i=0;i<total;i++)
{
CMessage* mess=this.m_list_messages.At(i);
if(mess==NULL)
continue;
if(mess.GetID()==id)
return mess.GetMessage();
}
return NULL;
}
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| =48:0B>@ |
//+------------------------------------------------------------------+
#property description "Multitimeframe Multi Currency Pair Scanner Dashboard"
#property version "1.0"
#include <Arrays\ArrayObj.mqh>
#include <Arrays\ArrayString.mqh>
#include <Arrays\ArrayInt.mqh>
#property indicator_separate_window
#property indicator_buffers 0
#property indicator_plots 0
//--- defines
#define IND_ID_STO_RSI IND_CUSTOM+1
#define IND_ID_STOCHASTIC IND_CUSTOM+2
#define IND_ID_ADX IND_CUSTOM+3
#define IND_ID_WPR IND_CUSTOM+4
#define SIG_STATUS_NL 0
#define SIG_STATUS_UP 1
#define SIG_STATUS_DN -1
#define BUFFERS_TOTAL_STO_RSI 2
#define BUFFERS_TOTAL_STO 2
#define BUFFERS_TOTAL_ADX 3
#define BUFFERS_TOTAL_WPR 1
//--- enums
enum ENUM_INPUT_YES_NO
{
INPUT_YES = 1, // Yes
INPUT_NO = 0 // No
};
//--- input parameters
input uint InpPeriodADX = 14; // ADX period
input uint InpPeriodKStoch = 5; // Stochastic period %K
input uint InpPeriodDStoch = 3; // Stochactic period %D
input uint InpSlowingStoch = 3; // Stochastic slowing
input double InpOverboughtStoch = 80; // Stochastic overbought
input double InpOversoldStoch = 20; // Stochastic oversold
input uint InpPeriodKStochRSI = 14; // StochasticRSI period %K
input uint InpPeriodDStochRSI = 3; // StochasticRSI period %D
input uint InpSlowingStochRSI = 5; // StochasticRSI slowing
input uint InpPeriodRSIStochRSI = 14; // StochasticRSI RSI period
input double InpOverboughtStochRSI = 90; // StochasticRSI overbought
input double InpOversoldStochRSI = 10; // StochasticRSI oversold
input uint InpPeriodWPR = 14; // WPR period
input double InpOverboughtWPR = -20; // WPR overbought
input double InpOversoldWPR = -80; // WPR oversold
input string InpSymbols="EURUSD,EURJPY,USDJPY,GBPUSD,GBPJPY,EURGBP,AUDUSD,NZDUSD"; // Symbols list (Comma Separated Pairs, empty - current symbol)
input ENUM_INPUT_YES_NO InpUseM1 = INPUT_YES; // Use 1 minute timeframe
input ENUM_INPUT_YES_NO InpUseM2 = INPUT_NO; // Use 2 minute timeframe
input ENUM_INPUT_YES_NO InpUseM3 = INPUT_NO; // Use 3 minute timeframe
input ENUM_INPUT_YES_NO InpUseM4 = INPUT_NO; // Use 4 minute timeframe
input ENUM_INPUT_YES_NO InpUseM5 = INPUT_YES; // Use 5 minute timeframe
input ENUM_INPUT_YES_NO InpUseM6 = INPUT_NO; // Use 6 minute timeframe
input ENUM_INPUT_YES_NO InpUseM10 = INPUT_NO; // Use 10 minute timeframe
input ENUM_INPUT_YES_NO InpUseM12 = INPUT_NO; // Use 12 minute timeframe
input ENUM_INPUT_YES_NO InpUseM15 = INPUT_YES; // Use 15 minute timeframe
input ENUM_INPUT_YES_NO InpUseM20 = INPUT_NO; // Use 20 minute timeframe
input ENUM_INPUT_YES_NO InpUseM30 = INPUT_YES; // Use 30 minute timeframe
input ENUM_INPUT_YES_NO InpUseH1 = INPUT_YES; // Use 1 hour timeframe
input ENUM_INPUT_YES_NO InpUseH2 = INPUT_NO; // Use 2 hour timeframe
input ENUM_INPUT_YES_NO InpUseH3 = INPUT_NO; // Use 3 hour timeframe
input ENUM_INPUT_YES_NO InpUseH4 = INPUT_YES; // Use 4 hour timeframe
input ENUM_INPUT_YES_NO InpUseH6 = INPUT_NO; // Use 6 hour timeframe
input ENUM_INPUT_YES_NO InpUseH8 = INPUT_NO; // Use 8 hour timeframe
input ENUM_INPUT_YES_NO InpUseH12 = INPUT_NO; // Use 12 hour timeframe
input ENUM_INPUT_YES_NO InpUseD1 = INPUT_YES; // Use 1 Day timeframe
input ENUM_INPUT_YES_NO InpUseW1 = INPUT_NO; // Use 1 Week timeframe
input ENUM_INPUT_YES_NO InpUseMN1 = INPUT_NO; // Use 1 Month timeframe
input ENUM_INPUT_YES_NO InpUseAlert = INPUT_YES; // Use alerts if all timeframes is synchronized
input uchar InpAlertInterval = 5; // Alert interval (min)
input uint InpCoordX = 1; // Panel: X-coordinate
input uint InpCoordY = 1; // Panel: Y-coordinate
input color InpColorPanel = C'240,240,240'; // Panel: Background color
input color InpColorBorder = C'200,200,200'; // Panel: Border color
input color InpColorLabels = clrSlateGray; // Panel: Texts color
input color InpColorUP = clrGreen; // Panel: Scanner up direction color
input color InpColorDN = clrRed; // Panel: Scanner down direction color
input color InpColorNL = clrLightGray; // Panel: Scanner neutral direction color
input uchar InpAlphaBackgrnd = 128; // Panel: Background opacity
//--- global variables
CArrayString list_symbols;
CArrayInt list_timeframes;
CArrayObj list_ind;
CArrayObj list_sync;
CAlertsMess messages;
CWnd panel;
//--- indicators
int period_adx;
int period_k_sto_rsi;
int period_d_sto_rsi;
int slowing_sto_rsi;
int period_rsi_sto_rsi;
int period_k_sto;
int period_d_sto;
int slowing_sto;
int period_wpr;
double overbought_sto;
double oversold_sto;
double overbought_sto_rsi;
double oversold_sto_rsi;
double overbought_wpr;
double oversold_wpr;
//---
string custom_ind_name;
string array_symbols[];
string gv_name;
int alerts_interval;
//+------------------------------------------------------------------+
//| Custom indicator initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- timer
EventSetMillisecondTimer(16);
//--- setting indicator parameters
gv_name="MTF_MCP_Scanner";
custom_ind_name="Stochastic_RSI";
alerts_interval=int(InpAlertInterval<1 ? 1 : InpAlertInterval);
//--- indicators
period_adx=int(InpPeriodADX<1 ? 1 : InpPeriodADX);
period_k_sto_rsi=int(InpPeriodKStochRSI<1 ? 1 : InpPeriodKStochRSI);
period_d_sto_rsi=int(InpPeriodDStochRSI<1 ? 1 : InpPeriodDStochRSI);
slowing_sto_rsi=int(InpSlowingStochRSI<1 ? 1 : InpSlowingStochRSI);
period_rsi_sto_rsi=int(InpPeriodRSIStochRSI<1 ? 1 : InpPeriodRSIStochRSI);
period_k_sto=int(InpPeriodKStoch<1 ? 1 : InpPeriodKStoch);
period_d_sto=int(InpPeriodDStoch<1 ? 1 : InpPeriodDStoch);
slowing_sto=int(InpSlowingStoch<1 ? 1 : InpSlowingStoch);
period_wpr=int(InpPeriodWPR<1 ? 1 : InpPeriodWPR);
overbought_sto_rsi=(InpOverboughtStochRSI>100 ? 100 : InpOverboughtStochRSI<0.1 ? 0.1 : InpOverboughtStochRSI);
oversold_sto_rsi=(InpOversoldStochRSI<0 ? 0 : InpOversoldStochRSI>=overbought_sto_rsi ? overbought_sto_rsi-0.1 : InpOversoldStochRSI);
overbought_sto=(InpOverboughtStoch>100 ? 100 : InpOverboughtStoch<0.1 ? 0.1 : InpOverboughtStoch);
oversold_sto=(InpOversoldStoch<0 ? 0 : InpOversoldStoch>=overbought_sto ? overbought_sto-0.1 : InpOversoldStoch);
double ob=-fabs(InpOverboughtWPR);
double os=-fabs(InpOversoldWPR);
overbought_wpr=(ob>0 ? 0 : ob<-99.0 ? -99.0 : ob);
oversold_wpr=(os<-100.0 ? -100.0 : os>=overbought_wpr ? overbought_wpr-1.0 : os);
if(overbought_wpr<=oversold_wpr) overbought_wpr=oversold_wpr+1.0;
//---
if(!ArraysPreparing())
{
Print("Error. Failed to prepare working arrays.");
return INIT_FAILED;
}
//--- Set messages
messages.Add(SIG_STATUS_UP,"SYMBOL All timeframes are synchronized: up direction");
messages.Add(SIG_STATUS_DN,"SYMBOL All timeframes are synchronized: down direction");
//---
list_sync.Clear();
list_ind.Clear();
int total_sym=list_symbols.Total();
int total_tfs=list_timeframes.Total();
for(int s=0;s<total_sym;s++)
{
for(int t=0;t<total_tfs;t++)
{
ENUM_TIMEFRAMES timeframe=(ENUM_TIMEFRAMES)list_timeframes.At(t);
string symbol=list_symbols.At(s);
CIndCollection* collection=new CIndCollection(symbol,timeframe);
if(collection==NULL)
continue;
//--- Set coordinates
collection.SetIndexX(t);
collection.SetIndexY(s);
//--- Add StochasticRSI into array_obj list
CIndicatorsBase* sto_rsi=new CIndicatorsBase(symbol,timeframe,IND_ID_STO_RSI);
if(sto_rsi!=NULL)
{
collection.Add(sto_rsi);
sto_rsi.SetParameter(period_k_sto_rsi); // Set StochasticRSI %K Period
sto_rsi.SetParameter(period_d_sto_rsi); // Set StochasticRSI %D Period
sto_rsi.SetParameter(slowing_sto_rsi); // Set StochasticRSI Slowing
sto_rsi.SetParameter(period_rsi_sto_rsi); // Set StochasticRSI Period RSI
sto_rsi.SetParameter(overbought_sto_rsi); // Set StochasticRSI Overbought
sto_rsi.SetParameter(oversold_sto_rsi); // Set StochasticRSI Oversold
if(!sto_rsi.Create(custom_ind_name,BUFFERS_TOTAL_STO_RSI))
{
Print(sto_rsi.Symbol()," ",sto_rsi.TimeframeDescription(),": Failed to create ",sto_rsi.Name(),"'s handle. Please restart the indicator");
delete sto_rsi;
return INIT_FAILED;
}
else
{
sto_rsi.SetRefreshFlags(true,OBJ_ALL_PERIODS);
sto_rsi.Refresh();
//Print(sto_rsi.Status());
}
}
//--- Add Stochastic into array_obj list
CIndicatorsBase* sto=new CIndicatorsBase(symbol,timeframe,IND_ID_STOCHASTIC);
if(sto!=NULL)
{
collection.Add(sto);
sto.SetParameter(period_k_sto); // Set Stochastic %K Period
sto.SetParameter(period_d_sto); // Set Stochastic %D Period
sto.SetParameter(slowing_sto); // Set Stochastic Slowing
sto.SetParameter((int)MODE_SMA); // Set Stochastic MA method
sto.SetParameter((int)STO_LOWHIGH); // Set Stochastic Price field
if(!sto.Create(IND_STOCHASTIC,BUFFERS_TOTAL_STO))
{
Print(sto.Symbol()," ",sto.TimeframeDescription(),": Failed to create ",sto.Name(),"'s handle. Please restart the indicator");
delete sto;
return INIT_FAILED;
}
else
{
sto.SetRefreshFlags(true,OBJ_ALL_PERIODS);
sto.Refresh();
//Print(sto.Status());
}
}
//--- Add ADX into array_obj list
CIndicatorsBase* adx=new CIndicatorsBase(symbol,timeframe,IND_ID_ADX);
if(adx!=NULL)
{
collection.Add(adx);
adx.SetParameter(period_adx); // Set ADX Period
if(!adx.Create(IND_ADX,BUFFERS_TOTAL_ADX))
{
Print(adx.Symbol()," ",adx.TimeframeDescription(),": Failed to create ",adx.Name(),"'s handle. Please restart the indicator");
delete adx;
return INIT_FAILED;
}
else
{
adx.SetRefreshFlags(true,OBJ_ALL_PERIODS);
adx.Refresh();
//Print(adx.Status());
}
}
//--- Add WPR into array_obj list
CIndicatorsBase* wpr=new CIndicatorsBase(symbol,timeframe,IND_ID_WPR);
if(wpr!=NULL)
{
collection.Add(wpr);
wpr.SetParameter(period_wpr); // Set WPR Period
if(!wpr.Create(IND_WPR,BUFFERS_TOTAL_WPR))
{
Print(wpr.Symbol()," ",wpr.TimeframeDescription(),": Failed to create ",wpr.Name(),"'s handle. Please restart the indicator");
delete wpr;
return INIT_FAILED;
}
else
{
wpr.SetRefreshFlags(true,OBJ_ALL_PERIODS);
wpr.Refresh();
//Print(wpr.Status());
}
}
//--- Add symbol to the sync symbols list
if(InpUseAlert)
{
if(!IsPresentSymbolInSyncList(symbol))
{
CSymbol* sy=new CSymbol(symbol);
if(sy!=NULL)
{
sy.SetIndexY(s);
list_sync.Add(sy);
}
}
//--- Add timeframe to the sync symbol
CSymbol* sy=GetSyncSymbol(symbol);
if(sy!=NULL)
{
sy.AddTimeframe(timeframe);
CTimeframe* tf=sy.GetPointerTF(timeframe);
if(tf!=NULL)
tf.SetIndexX(t);
}
}
//--- Add collection to the indicators list
list_ind.Add(collection);
}
}
//--- 0=5;L
int w=180,h=74;
int x=int(!GlobalVariableCheck(gv_name+"_GVX") ? int(ChartGetInteger(0,CHART_WIDTH_IN_PIXELS)-w-InpCoordX) : GlobalVariableGet(gv_name+"_GVX"));
int y=int(!GlobalVariableCheck(gv_name+"_GVY") ? (int)InpCoordY : GlobalVariableGet(gv_name+"_GVY"));
panel.SetColors(InpColorPanel,InpColorBorder,clrNONE,clrNONE,InpColorLabels,InpAlphaBackgrnd,255);
string name=gv_name;
StringReplace(name,"_"," ");
if(!panel.CreateWindow(name,x,y,w,h,false,true))
{
Print("Failed to create panel. Please restart the indicator");
return INIT_FAILED;
}
RedrawField();
//---
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[])
{
//---
RedrawField();
//--- return value of prev_calculated for next call
return(rates_total);
}
//+------------------------------------------------------------------+
//| Custom indicator timer function |
//+------------------------------------------------------------------+
void OnTimer()
{
static long last_time=0;
MqlTick tick;
bool refresh=false;
int total=list_ind.Total();
for(int i=0;i<total;i++)
{
CIndCollection* collection=list_ind.At(i);
if(collection==NULL)
continue;
collection.OnTimer();
if(collection.IsCounterRefreshDone())
{
if(SymbolInfoTick(collection.Symbol(),tick))
{
if(tick.time_msc>last_time)
{
last_time=tick.time_msc;
refresh=true;
}
}
}
}
if(refresh)
RedrawField();
}
//+------------------------------------------------------------------+
//| Cart event function |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,
const long &lparam,
const double &dparam,
const string &sparam)
{
panel.OnChartEvent(id,lparam,dparam,sparam);
}
//+------------------------------------------------------------------+
//| 1=>2;O5B 40==K5 ?0=5;8 |
//+------------------------------------------------------------------+
void RedrawField(void)
{
int row=list_symbols.Total();
int col=list_timeframes.Total();
CCanvas *canvas=panel.GetFieldCanvas();
if(canvas==NULL)
{
Print(__FUNCTION__,": Error: Canvas not available.");
return;
}
int shiftV=14,shiftH=36,startH=56,startV=15;
panel.Resize(startH+col*shiftH,shiftV+row*shiftV+3);
canvas.Erase(ColorToARGB(panel.ColorBackground(),0));
panel.DrawSeparateHLine(1,canvas.Width()-2,13,panel.NewColor(panel.ColorBackground(),-5,-5,-5),panel.NewColor(panel.ColorBackground(),45,45,45));
panel.DrawSeparateVLine(50,14,canvas.Height()-2,panel.NewColor(panel.ColorBackground(),-5,-5,-5),panel.NewColor(panel.ColorBackground(),45,45,45));
//---
int total=list_ind.Total();
for(int i=0;i<total;i++)
{
CIndCollection* collection=list_ind.At(i);
if(collection==NULL)
continue;
collection.Refresh();
int x=collection.IndexX();
int y=collection.IndexY();
if(y==0)
{
string tf=collection.TimeframeDescription();
canvas.FontSet(panel.NameCaptionFont(),-80,FW_BLACK);
canvas.TextOut(startH+(shiftH/2)-4+x*shiftH,0,tf,ColorToARGB(panel.ColorTexts()),TA_CENTER);
if(x==0)
canvas.TextOut(22,0,"Pairs",ColorToARGB(panel.ColorTexts()),TA_CENTER);
}
if(x==0)
{
canvas.FontSet(panel.NameCaptionFont(),-80,FW_BLACK);
canvas.TextOut(4,startV+y*shiftV,collection.Symbol(),ColorToARGB(panel.ColorTexts()));
}
int gx=startH+(shiftH/2)-4+x*shiftH;
int gy=startV+6+y*shiftV;
panel.DrawSeparateVLine(gx+shiftH-shiftH/2,14,canvas.Height()-2,panel.NewColor(panel.ColorBackground(),-5,-5,-5),panel.NewColor(panel.ColorBackground(),45,45,45));
//--- StochRSI D
double sto_rsi_d0=0;
CIndicatorsBase* sto_rsi=collection.GetIndByID(IND_ID_STO_RSI);
if(sto_rsi!=NULL)
{
sto_rsi_d0=sto_rsi.GetData(1,0);
}
//--- Stoch K,D
double sto_k0=0,sto_d0=0;
CIndicatorsBase* sto=collection.GetIndByID(IND_ID_STOCHASTIC);
if(sto!=NULL)
{
sto_k0=sto.GetData(MAIN_LINE,0);
sto_d0=sto.GetData(SIGNAL_LINE,0);
}
//--- DMI Positive,Negative
double dip0=0,dim0=0;
CIndicatorsBase* adx=collection.GetIndByID(IND_ID_ADX);
if(adx!=NULL)
{
dip0=adx.GetData(PLUSDI_LINE,0);
dim0=adx.GetData(MINUSDI_LINE,0);
}
//--- WPR
double wpr0=0;
CIndicatorsBase* wpr=collection.GetIndByID(IND_ID_WPR);
if(wpr!=NULL)
{
wpr0=wpr.GetData(0,0);
}
int direction=
(
dip0>dim0 && sto_k0>sto_d0 && sto_d0<overbought_sto && sto_rsi_d0<overbought_sto_rsi && wpr0<overbought_wpr ? SIG_STATUS_UP :
dim0>dip0 && sto_k0<sto_d0 && sto_d0>oversold_sto && sto_rsi_d0 > oversold_sto_rsi && wpr0>oversold_wpr ? SIG_STATUS_DN : SIG_STATUS_NL
);
color clr_ind=InpColorNL;
if(direction==SIG_STATUS_UP)
{
clr_ind=InpColorUP;
TriangleUp(canvas,gx,gy,clr_ind,panel.NewColor(clr_ind,40,40,40));
SetSyncStatus(collection.Symbol(),collection.Timeframe(),SIG_STATUS_UP);
}
else if(direction==SIG_STATUS_DN)
{
clr_ind=InpColorDN;
TriangleDown(canvas,gx,gy,clr_ind,panel.NewColor(clr_ind,40,40,40));
SetSyncStatus(collection.Symbol(),collection.Timeframe(),SIG_STATUS_DN);
}
else
{
clr_ind=InpColorNL;
TriangleRight(canvas,gx,gy,panel.NewColor(clr_ind,-40,-40,-40),panel.NewColor(clr_ind,40,40,40));
SetSyncStatus(collection.Symbol(),collection.Timeframe(),SIG_STATUS_NL);
}
}
if(InpUseAlert)
{
AlertAllSyncProcess(canvas,startH,shiftH,startV,shiftV);
//AlertOneTFProcess(canvas,startH,shiftH,startV,shiftV);
}
canvas.Update(true);
}
//+------------------------------------------------------------------+
//| 8AC5B B@5C3>;L=8: 225@E |
//+------------------------------------------------------------------+
void TriangleUp(CCanvas *canvas,const int x,const int y,const color clr_bd,const color clr_bg)
{
if(canvas==NULL)
return;
int x1=x-4;
int y1=y+2;
int x2=x;
int y2=y-2;
int x3=x+4;
int y3=y1;
canvas.FillTriangle(x1,y1,x2,y2,x3,y3,ColorToARGB(clr_bg));
canvas.TriangleWu(x1,y1,x2,y2,x3,y3,ColorToARGB(clr_bd),STYLE_SOLID);
}
//+------------------------------------------------------------------+
//| 8AC5B B@5C3>;L=8: 2=87 |
//+------------------------------------------------------------------+
void TriangleDown(CCanvas *canvas,const int x,const int y,const color clr_bd,const color clr_bg)
{
if(canvas==NULL)
return;
int x1=x-4;
int y1=y-2;
int x2=x;
int y2=y+2;
int x3=x+4;
int y3=y1;
canvas.FillTriangle(x1,y1,x2,y2,x3,y3,ColorToARGB(clr_bg));
canvas.TriangleWu(x1,y1,x2,y2,x3,y3,ColorToARGB(clr_bd),STYLE_SOLID);
}
//+------------------------------------------------------------------+
//| 8AC5B B@5C3>;L=8: 2?@02> |
//+------------------------------------------------------------------+
void TriangleRight(CCanvas* canvas,const int x,const int y,const color clr_bd,const color clr_bg)
{
if(canvas==NULL)
return;
int x1=x-2;
int y1=y-3;
int x2=x+3;
int y2=y;
int x3=x-2;
int y3=y+3;
canvas.FillTriangle(x1,y1,x2,y2,x3,y3,ColorToARGB(clr_bg));
canvas.TriangleWu(x1,y1,x2,y2,x3,y3,ColorToARGB(clr_bd),STYLE_SOLID);
}
//+------------------------------------------------------------------+
//| 8AC5B :@C3 |
//+------------------------------------------------------------------+
void Circle(CCanvas *canvas,const int x,const int y,const double r,const color clr_bd,const color clr_bg)
{
if(canvas==NULL)
return;
canvas.FillCircle(x,y,(int)r,ColorToARGB(clr_bg));
canvas.CircleWu(x,y,r,ColorToARGB(clr_bd),STYLE_SOLID);
}
//+------------------------------------------------------------------+
//| 8AC5B ?@O<>C3>;L=8: |
//+------------------------------------------------------------------+
void Rectangle(CCanvas* canvas,const int x,const int y,const int h,const int w,const color clr_bd,const color clr_bg)
{
if(canvas==NULL)
return;
int h2=(int)ceil(h/2);
int w2=(int)ceil(w/2);
int x1=x-h2;
int y1=y-w2;
int x2=x+h2;
int y2=y+w2;
canvas.FillRectangle(x1,y1,x2,y2,ColorToARGB(clr_bg));
canvas.Rectangle(x1,y1,x2,y2,ColorToARGB(clr_bd));
}
//+------------------------------------------------------------------+
//| @>25@:0 A8=E@>=870F88 8 2K2>4 0;5@B>2 |
//+------------------------------------------------------------------+
void AlertAllSyncProcess(CCanvas* canvas,const int startH,const int shiftH,const int startV,const int shiftV)
{
int total_sync=list_sync.Total();
for(int i=0;i<total_sync;i++)
{
CSymbol* sync=list_sync.At(i);
if(sync==NULL)
continue;
int value_sync=0;
int num_sync=sync.CheckSyncAllTFs(value_sync);
if(num_sync>1)
{
string text="";
color clr_sig=InpColorNL;
int y=sync.IndexY();
int gy=startV+6+y*shiftV;
CArrayObj* list_tf=sync.GetListTimeframes();
if(list_tf==NULL)
continue;
int total_tf=list_tf.Total();
for(int j=0;j<total_tf;j++)
{
CTimeframe* obj_tf=list_tf.At(j);
if(obj_tf==NULL)
continue;
int x=obj_tf.IndexX();
int gx=startH+(shiftH/2)-4+x*shiftH;
//---
text=messages.Message(value_sync);
StringReplace(text,"SYMBOL",sync.Symbol());
if(value_sync==1)
{
clr_sig=InpColorUP;
TriangleUp(canvas,gx-10,gy,clr_sig,panel.NewColor(clr_sig,40,40,40));
TriangleUp(canvas,gx+10,gy,clr_sig,panel.NewColor(clr_sig,40,40,40));
}
else if(value_sync==-1)
{
StringReplace(text,"SYMBOL",sync.Symbol());
clr_sig=InpColorDN;
TriangleDown(canvas,gx-10,gy,clr_sig,panel.NewColor(clr_sig,40,40,40));
TriangleDown(canvas,gx+10,gy,clr_sig,panel.NewColor(clr_sig,40,40,40));
}
}
//--- Alert
if(long(TimeCurrent()-sync.LastAlertTime())>long(alerts_interval*60))
{
Alert(text);
sync.SetAlertTime(TimeCurrent());
}
}
}
}
//+------------------------------------------------------------------+
//| @>25@:0 A83=0;>2 =0 B09<D@59<0E 8 2K2>4 0;5@B>2 |
//+------------------------------------------------------------------+
void AlertOneTFProcess(CCanvas* canvas,const int startH,const int shiftH,const int startV,const int shiftV)
{
int total_sync=list_sync.Total();
for(int i=0;i<total_sync;i++)
{
CSymbol* sync=list_sync.At(i);
if(sync==NULL)
continue;
string text="";
color clr_sig=InpColorNL;
int y=sync.IndexY();
int gy=startV+6+y*shiftV;
CArrayObj* list_tf=sync.GetListTimeframes();
int total_tf=list_tf.Total();
for(int j=0;j<total_tf;j++)
{
CTimeframe* obj_tf=list_tf.At(j);
if(obj_tf==NULL)
continue;
ENUM_TIMEFRAMES tf=obj_tf.Timeframe();
int signal=sync.CheckSigOneTF(tf);
if(signal!=0)
{
text=messages.Message(signal);
StringReplace(text,"SYMBOL",sync.Symbol());
StringReplace(text,"TIMEFRAME",obj_tf.TimeframeDescription());
//---
int x=obj_tf.IndexX();
int gx=startH+(shiftH/2)-4+x*shiftH;
//---
if(signal==SIG_STATUS_UP)
{
//text=messages.Message(SIG_STATUS_B_DS);
//StringReplace(text,"SYMBOL",sync.Symbol());
//StringReplace(text,"TIMEFRAME",obj_tf.TimeframeDescription());
//clr_sig=InpColorUP;
//TriangleUp(canvas,gx-20,gy,clr_sig,panel.NewColor(clr_sig,40,40,40));
//TriangleUp(canvas,gx+10,gy,clr_sig,panel.NewColor(clr_sig,40,40,40));
}
else if(signal==SIG_STATUS_DN)
{
//text=messages.Message(SIG_STATUS_S_DS);
//StringReplace(text,"SYMBOL",sync.Symbol());
//StringReplace(text,"TIMEFRAME",obj_tf.TimeframeDescription());
//clr_sig=InpColorDN;
//TriangleUp(canvas,gx-20,gy,clr_sig,panel.NewColor(clr_sig,40,40,40));
//TriangleUp(canvas,gx+10,gy,clr_sig,panel.NewColor(clr_sig,40,40,40));
}
//--- Alert
if(long(TimeCurrent()-obj_tf.LastAlertTime())>long(alerts_interval*60))
{
Alert(text);
obj_tf.SetAlertTime(TimeCurrent());
}
}
}
}
}
//+------------------------------------------------------------------+
//| >72@0I05B D0:B =0;8G8O A8<2>;0 2 A?8A:5 A8=E@. A8<2>;>2 |
//+------------------------------------------------------------------+
bool IsPresentSymbolInSyncList(const string symbol)
{
int total=list_sync.Total();
for(int i=0;i<total;i++)
{
CSymbol* obj=list_sync.At(i);
if(obj==NULL)
continue;
if(obj.Symbol()==symbol)
return true;
}
return false;
}
//+------------------------------------------------------------------+
//| >72@0I05B >1J5:B-A8<2>; 87 A?8A:0 A8=E@. A8<2>;>2 |
//+------------------------------------------------------------------+
CSymbol* GetSyncSymbol(const string symbol)
{
int total=list_sync.Total();
for(int i=0;i<total;i++)
{
CSymbol* obj=list_sync.At(i);
if(obj==NULL)
continue;
if(obj.Symbol()==symbol)
return obj;
}
return NULL;
}
//+------------------------------------------------------------------+
//| #AB0=02;8205B AB0BCA A8=E@. A8<2>;0 8 B09<D@59<0 |
//+------------------------------------------------------------------+
void SetSyncStatus(const string symbol,const ENUM_TIMEFRAMES timeframe,const int status)
{
int total=list_sync.Total();
for(int i=0;i<total;i++)
{
CSymbol* sync=list_sync.At(i);
if(sync==NULL || sync.Symbol()!=symbol)
continue;
sync.SetStatusTF(timeframe,status);
}
}
//+------------------------------------------------------------------+
//| @>25@:0 A8<2>;0 |
//+------------------------------------------------------------------+
bool SymbolCheck(const string symbol_name)
{
long select=0;
ResetLastError();
if(!SymbolInfoInteger(symbol_name,SYMBOL_SELECT,select))
{
int err=GetLastError();
Print("Error: ",err," Symbol ",symbol_name," does not exist");
return false;
}
else
{
if(select) return true;
ResetLastError();
if(!SymbolSelect(symbol_name,true))
{
int err=GetLastError();
Print("Error selected ",symbol_name,": ",err);
}
}
return false;
}
//+------------------------------------------------------------------+
//| >72@0I05B D0:B =0;8G8O A8<2>;0 2 A?8A:5 |
//+------------------------------------------------------------------+
bool IsPresentSymbol(const string symbol)
{
list_symbols.Sort();
return(list_symbols.Search(symbol)>WRONG_VALUE);
}
//+------------------------------------------------------------------+
//| >72@0I05B 8=45:A A8<2>;0 2 A?8A:5 |
//+------------------------------------------------------------------+
int IndexSymbol(const string symbol_name)
{
int total=list_symbols.Total();
for(int i=0;i<total;i++)
if(list_symbols.At(i)==symbol_name)
return i;
return WRONG_VALUE;
}
//+------------------------------------------------------------------+
//| >72@0I05B 8=45:A B09<D@59<0 2 A?8A:5 |
//+------------------------------------------------------------------+
int IndexTimeframe(const ENUM_TIMEFRAMES timeframe)
{
int total=list_timeframes.Total();
for(int i=0;i<total;i++)
if((ENUM_TIMEFRAMES)list_timeframes.At(i)==timeframe)
return i;
return WRONG_VALUE;
}
//+------------------------------------------------------------------+
//| >43>B>2:0 <0AA82>2 2E>4=KE ?0@0<5B@>2 |
//+------------------------------------------------------------------+
bool ArraysPreparing(void)
{
if(InpSymbols=="" || InpSymbols==NULL)
{
ArrayResize(array_symbols,1);
array_symbols[0]=Symbol();
}
else
{
string value=","+InpSymbols;
int total=StringSplit(InpSymbols,StringGetCharacter(value,0),array_symbols);
ResetLastError();
if(total<=0)
{
string end=(total==0 ? "Symbols string is empty." : "Error: "+(string)GetLastError());
Print("Failed to get the array of symbols. ",end);
return false;
}
for(int i=0;i<total;i++)
SymbolCheck(array_symbols[i]);
}
int total=ArraySize(array_symbols);
list_symbols.Clear();
for(int i=0;i<total;i++)
{
if(!IsPresentSymbol(array_symbols[i]))
if(SymbolCheck(array_symbols[i]))
list_symbols.Add(array_symbols[i]);
}
//---
list_timeframes.Clear();
for(int i=0;i<21;i++)
{
int tf=GetInputTimeframe(i);
if(tf==WRONG_VALUE)
continue;
list_timeframes.Add((int)tf);
}
if(list_timeframes.Total()==0)
list_timeframes.Add(Period());
return true;
}
//+------------------------------------------------------------------+
//| >72@0I05B 2E>4=>9 ?0@0<5B@ B09<D@59<0 ?> 8=45:AC |
//+------------------------------------------------------------------+
int GetInputTimeframe(const int index)
{
switch(index)
{
case 0 : return (InpUseM1 ? PERIOD_M1 : WRONG_VALUE);
case 1 : return (InpUseM2 ? PERIOD_M2 : WRONG_VALUE);
case 2 : return (InpUseM3 ? PERIOD_M3 : WRONG_VALUE);
case 3 : return (InpUseM4 ? PERIOD_M4 : WRONG_VALUE);
case 4 : return (InpUseM5 ? PERIOD_M5 : WRONG_VALUE);
case 5 : return (InpUseM6 ? PERIOD_M6 : WRONG_VALUE);
case 6 : return (InpUseM10 ? PERIOD_M10 : WRONG_VALUE);
case 7 : return (InpUseM12 ? PERIOD_M12 : WRONG_VALUE);
case 8 : return (InpUseM15 ? PERIOD_M15 : WRONG_VALUE);
case 9 : return (InpUseM20 ? PERIOD_M20 : WRONG_VALUE);
case 10 : return (InpUseM30 ? PERIOD_M30 : WRONG_VALUE);
case 11 : return (InpUseH1 ? PERIOD_H1 : WRONG_VALUE);
case 12 : return (InpUseH2 ? PERIOD_H2 : WRONG_VALUE);
case 13 : return (InpUseH3 ? PERIOD_H3 : WRONG_VALUE);
case 14 : return (InpUseH4 ? PERIOD_H4 : WRONG_VALUE);
case 15 : return (InpUseH6 ? PERIOD_H6 : WRONG_VALUE);
case 16 : return (InpUseH8 ? PERIOD_H8 : WRONG_VALUE);
case 17 : return (InpUseH12 ? PERIOD_H12 : WRONG_VALUE);
case 18 : return (InpUseD1 ? PERIOD_D1 : WRONG_VALUE);
case 19 : return (InpUseW1 ? PERIOD_W1 : WRONG_VALUE);
default : return (InpUseMN1 ? PERIOD_MN1 : WRONG_VALUE);
}
}
//+------------------------------------------------------------------+
Comments
Markdown Formatting Guide
# H1
## H2
### H3
**bold text**
*italicized text*
[title](https://www.example.com)

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