//+------------------------------------------------------------------+ //| TesterSpeed.mq4 | //| Copyright © 2015, Zoltan Meszaros | //+------------------------------------------------------------------+ #ifndef __VERSION #define __VERSION "1.00" #endif #property copyright "Copyright © 2015, Zoltan Meszaros" #property version __VERSION #property strict #property indicator_chart_window #property description "Tester Speed Equalizer" #property description "Metatrader Strategy Tester speed controler." #property description " " #property description "Requirement:" #property description " - Checked \'Allow DLL imports\' before running the indicator." #property indicator_plots 0 #property indicator_buffers 0 #property indicator_minimum 0.0 #property indicator_maximum 0.0 #import "kernel32.dll" int SleepEx(int dwMilliseconds, bool alert); #import #define INDENT_LEFT 5 #define INDENT_TOP 5 #define INDENT_RIGHT 5 #define INDENT_BOTTOM 5 #define CONTROLS_GAP_X 10 #define CONTROLS_GAP_Y 10 #define EDIT_WIDTH 50 #define EDIT_HEIGHT 20 #define LABEL_WIDTH 90 #define LABEL_HEIGHT 20 #define BUTTON_WIDTH 80 #define BUTTON_HEIGHT 26 #define NUMBERS "0123456789" #define SHORTNAME "Tester Speed Equalizer" #include #include #include #include extern int Speed = -1; //Speed extern int SkipTick = 0; //Skip Tick extern int Step = 5; //Step //+------------------------------------------------------------------+ //| CPanelDialog | //+------------------------------------------------------------------+ #ifndef __CPANELDIALOG #define __CPANELDIALOG class CPanelDialog : public CAppDialog { private: int m_step; int m_skip; int m_speed; bool m_close; CEdit m_edit1; CEdit m_edit2; CLabel m_label1; CLabel m_label2; CButton m_button1; CButton m_button2UP; CButton m_button2DOWN; CButton m_button3UP; CButton m_button3DOWN; bool CreateEdit(CEdit &_edit, const string _name, const int _x1, const int _y1, const int _x2, const int _y2, const bool _readOnly=false); bool CreateLabel(CLabel &_lbl, const string _name, const int _x1, const int _y1, const int _x2, const int _y2, const string _str, const int _fontSize, const int _clr); bool CreateButton(CButton &_button, const string _name, const int _x1, const int _y1, const int _x2, const int _y2, const string _str, const int _fontSize, const int _clr); public: CPanelDialog(void); ~CPanelDialog(void); void setup(int, int, int); int getSkip() const { return m_skip; } int getSpeed() const { return m_speed; } bool isClosed() const { return m_close; } virtual bool OnEvent(const int _id, const long &_lparam, const double &_dparam, const string &_sparam); virtual bool Create(const long _chart, const string _name, const int _subwin, const int _x1, const int _y1, const int _x2, const int _y2); protected: void setSkip(int); void setSpeed(int); bool CreateEdit1(void); bool CreateEdit2(void); bool CreateLabel1(void); bool CreateLabel2(void); bool CreateButton1(void); bool CreateButton2UP(void); bool CreateButton2DOWN(void); bool CreateButton3UP(void); bool CreateButton3DOWN(void); void OnClickButton1(void); void OnClickButton2UP(void); void OnClickButton2DOWN(void); void OnClickButton3UP(void); void OnClickButton3DOWN(void); virtual void OnClickButtonClose(void); }; EVENT_MAP_BEGIN(CPanelDialog) ON_EVENT(ON_CLICK, m_button1, OnClickButton1) ON_EVENT(ON_CLICK, m_button2UP, OnClickButton2UP) ON_EVENT(ON_CLICK, m_button2DOWN, OnClickButton2DOWN) ON_EVENT(ON_CLICK, m_button3UP, OnClickButton3UP) ON_EVENT(ON_CLICK, m_button3DOWN, OnClickButton3DOWN) EVENT_MAP_END(CAppDialog) CPanelDialog::CPanelDialog(void) { m_step = 0; m_skip = 0; m_speed = 0; m_close = false; } CPanelDialog::~CPanelDialog(void) { } void CPanelDialog::setup(int _speed, int _skip, int _step) { setSkip(_skip); setSpeed(_speed); m_step = (_step < 1 ? 1 : _step); } void CPanelDialog::setSpeed(int _speed) { m_speed = _speed; m_edit1.Text(IntegerToString(_speed)); } void CPanelDialog::setSkip(int _skip) { m_skip = _skip; m_edit2.Text(IntegerToString(_skip)); } bool CPanelDialog::Create(const long _chart, const string _name, const int _subwin, const int _x1, const int _y1, const int _x2, const int _y2) { if(!CAppDialog::Create(_chart, _name, _subwin, _x1, _y1, _x2, _y2)) return(false); if(!CreateEdit1()) return(false); if(!CreateEdit2()) return(false); if(!CreateLabel1()) return(false); if(!CreateLabel2()) return(false); if(!CreateButton1()) return(false); if(!CreateButton2UP()) return(false); if(!CreateButton2DOWN()) return(false); if(!CreateButton3UP()) return(false); if(!CreateButton3DOWN()) return(false); return(true); } bool CPanelDialog::CreateEdit1(void) { int x1 = INDENT_LEFT + LABEL_WIDTH + 22; int y1 = INDENT_TOP + 1; int x2 = x1 + EDIT_WIDTH; int y2 = y1 + EDIT_HEIGHT; return(CreateEdit(m_edit1, m_name+"Edit1", x1, y1, x2, y2)); } bool CPanelDialog::CreateEdit2(void) { int x1 = INDENT_LEFT + LABEL_WIDTH + 22; int y1 = INDENT_TOP + 25; int x2 = x1 + EDIT_WIDTH; int y2 = y1 + EDIT_HEIGHT; return(CreateEdit(m_edit2, m_name+"Edit2", x1, y1, x2, y2)); } bool CPanelDialog::CreateLabel1(void) { int x1 = INDENT_LEFT; int y1 = INDENT_TOP; int x2 = x1 + LABEL_WIDTH; int y2 = y1 + LABEL_HEIGHT; return(CreateLabel(m_label1, m_name+"Label1", x1, y1, x2, y2, "Speed:", 11, clrBlack)); } bool CPanelDialog::CreateLabel2(void) { int x1 = INDENT_LEFT; int y1 = INDENT_TOP + 23; int x2 = x1 + LABEL_WIDTH; int y2 = y1 + LABEL_HEIGHT; return(CreateLabel(m_label2, m_name+"Label2", x1, y1, x2, y2, "Skip Tick:", 11, clrBlack)); } bool CPanelDialog::CreateButton1(void) { int x1 = ((ClientAreaWidth() - BUTTON_WIDTH) / 2); int y1 = INDENT_TOP + 50; int x2 = x1 + BUTTON_WIDTH; int y2 = y1 + EDIT_HEIGHT; return(CreateButton(m_button1, m_name+"Button1", x1, y1, x2, y2, "Accept", 12, clrBlack)); } bool CPanelDialog::CreateButton2UP(void) { int x1 = INDENT_LEFT + LABEL_WIDTH + EDIT_WIDTH + 24; int y1 = INDENT_TOP + 2; int x2 = x1 + 20; int y2 = y1 + EDIT_HEIGHT - 2; return(CreateButton(m_button2UP, m_name+"Button2UP", x1, y1, x2, y2, ">", 14, clrBlack)); } bool CPanelDialog::CreateButton2DOWN(void) { int x1 = INDENT_LEFT + LABEL_WIDTH; int y1 = INDENT_TOP + 2; int x2 = x1 + 20; int y2 = y1 + EDIT_HEIGHT - 2; return(CreateButton(m_button2DOWN, m_name+"Button2DOWN", x1, y1, x2, y2, "<", 14, clrBlack)); } bool CPanelDialog::CreateButton3UP(void) { int x1 = INDENT_LEFT + LABEL_WIDTH + EDIT_WIDTH + 24; int y1 = INDENT_TOP + 26; int x2 = x1 + 20; int y2 = y1 + EDIT_HEIGHT - 2; return(CreateButton(m_button3UP, m_name+"Button3UP", x1, y1, x2, y2, ">", 14, clrBlack)); } bool CPanelDialog::CreateButton3DOWN(void) { int x1 = INDENT_LEFT + LABEL_WIDTH; int y1 = INDENT_TOP + 26; int x2 = x1 + 20; int y2 = y1 + EDIT_HEIGHT - 2; return(CreateButton(m_button3DOWN, m_name+"Button3DOWN", x1, y1, x2, y2, "<", 14, clrBlack)); } bool CPanelDialog::CreateEdit(CEdit &_edit, const string _name, const int _x1, const int _y1, const int _x2, const int _y2, const bool _readOnly=false) { if(!_edit.Create(m_chart_id, _name, m_subwin, _x1, _y1, _x2, _y2)) return(false); if(!_edit.ReadOnly(_readOnly)) return(false); if(!Add(_edit)) return(false); return(true); } bool CPanelDialog::CreateLabel(CLabel &_lbl, const string _name, const int _x1, const int _y1, const int _x2, const int _y2, const string _str, const int _fontSize, const int _clr) { if(!_lbl.Create(m_chart_id, _name, m_subwin, _x1, _y1, _x2, _y2)) return(false); if(!_lbl.Text(_str)) return(false); if(!_lbl.FontSize(_fontSize)) return(false); if(!_lbl.Color(_clr)) return(false); if(!Add(_lbl)) return(false); return(true); } bool CPanelDialog::CreateButton(CButton &_button, const string _name, const int _x1, const int _y1, const int _x2, const int _y2, const string _str, const int _fontSize, const int _clr) { if(!_button.Create(m_chart_id, _name, m_subwin, _x1, _y1, _x2, _y2)) return(false); if(!_button.Text(_str)) return(false); if(!_button.FontSize(_fontSize)) return(false); if(!_button.Color(_clr)) return(false); if(!Add(_button)) return(false); return(true); } void CPanelDialog::OnClickButtonClose(void) { m_close = true; CAppDialog::OnClickButtonClose(); } void CPanelDialog::OnClickButton1(void) { if(stringIsDigit(m_edit1.Text())) { int speed = (int)StringToInteger(m_edit1.Text()); if(speed < 0) setSpeed(speed); else setSpeed((-1)*speed); } else setSpeed(m_speed); if(stringIsDigit(m_edit2.Text())) { int skip = (int)StringToInteger(m_edit2.Text()); if(skip > 0) setSkip(skip); else setSkip(0); } else setSkip(m_skip); } void CPanelDialog::OnClickButton2UP(void) { if(stringIsDigit(m_edit1.Text())) { int speed = (int)StringToInteger(m_edit1.Text()); speed += m_step; if(speed < 0) setSpeed(speed); else setSpeed(0); } } void CPanelDialog::OnClickButton2DOWN(void) { if(stringIsDigit(m_edit1.Text())) { int speed = (int)StringToInteger(m_edit1.Text()); speed -= m_step; setSpeed(speed); } } void CPanelDialog::OnClickButton3UP(void) { if(stringIsDigit(m_edit2.Text())) { int skip = (int)StringToInteger(m_edit2.Text()); skip += m_step; setSkip(skip); } } void CPanelDialog::OnClickButton3DOWN(void) { if(stringIsDigit(m_edit2.Text())) { int skip = (int)StringToInteger(m_edit2.Text()); skip -= m_step; if(skip > 0) setSkip(skip); else setSkip(0); } } #endif CPanelDialog* ExtDialog = NULL; int OnInit() { IndicatorBuffers(0); IndicatorSetString(INDICATOR_SHORTNAME, SHORTNAME); if(!IsDllsAllowed()) { Print("DLL call is not allowed! Indicator cannot run."); return(INIT_FAILED); } Speed = (-1) * MathAbs(Speed); ExtDialog = new CPanelDialog(); if(CheckPointer(ExtDialog) == POINTER_INVALID) return(INIT_FAILED); if(!ExtDialog.Create(0, SHORTNAME, 0, 20, 20, 225, 130)) return(INIT_FAILED); if(!ExtDialog.Run()) return(INIT_FAILED); ExtDialog.setup(Speed, SkipTick, Step); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { if(CheckPointer(ExtDialog) == POINTER_DYNAMIC) { ExtDialog.Destroy(reason); delete ExtDialog; ExtDialog = NULL; } if(!IsTesting()) ChartIndicatorDelete(0, ChartWindowFind(), SHORTNAME); } 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 skip = 0; int speed = 0; static int skipTick = 0; if(CheckPointer(ExtDialog) == POINTER_DYNAMIC) { skip = ExtDialog.getSkip(); speed = MathAbs(ExtDialog.getSpeed()); if(ExtDialog.isClosed()) OnDeinit(REASON_REMOVE); } if(skipTick < skip) { skipTick++; return(0); } skipTick = 0; if(speed > 0) SleepEx(speed, false); return(rates_total); } void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { if(CheckPointer(ExtDialog) == POINTER_DYNAMIC) ExtDialog.ChartEvent(id, lparam, dparam, sparam); } bool isDigit(string _number, bool _double=false) { string numbers = (_double ? StringConcatenate(NUMBERS, ".") : NUMBERS); if(StringFind(numbers, StringSubstr(_number+" ", 0, 1)) < 0) return(false); return(true); } bool stringIsDigit(string _str, bool _double=false) { bool result = true; StringReplace(_str, "-", ""); string str = StringTrimLeft(StringTrimRight(_str)); int lenght = StringLen(str); if(lenght < 1) return(false); for(int i = 0; i < lenght; i++) { if(!isDigit(StringSubstr(str, i, 1), _double)) { result = false; break; } } return(result); }