First commit [09/03/2018]

This commit is contained in:
Pierre8rTeam
2018-03-09 16:43:19 +01:00
commit 25e9006a0b
375 changed files with 294601 additions and 0 deletions
+3
View File
@@ -0,0 +1,3 @@
*.dat
*.ex5
*.log
+168
View File
@@ -0,0 +1,168 @@
//+------------------------------------------------------------------+
//| ExpertMACD.mq5 |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009-2017, MetaQuotes Software Corp."
#property link "http://www.mql5.com"
#property version "1.00"
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
#include <Expert\Signal\SignalMACD.mqh>
#include <Expert\Trailing\TrailingNone.mqh>
#include <Expert\Money\MoneyNone.mqh>
//+------------------------------------------------------------------+
//| Inputs |
//+------------------------------------------------------------------+
//--- inputs for expert
input string Inp_Expert_Title ="ExpertMACD";
int Expert_MagicNumber =10981;
bool Expert_EveryTick =false;
//--- inputs for signal
input int Inp_Signal_MACD_PeriodFast =12;
input int Inp_Signal_MACD_PeriodSlow =24;
input int Inp_Signal_MACD_PeriodSignal=9;
input int Inp_Signal_MACD_TakeProfit =50;
input int Inp_Signal_MACD_StopLoss =20;
//+------------------------------------------------------------------+
//| Global expert object |
//+------------------------------------------------------------------+
CExpert ExtExpert;
//+------------------------------------------------------------------+
//| Initialization function of the expert |
//+------------------------------------------------------------------+
int OnInit(void)
{
//--- Initializing expert
if(!ExtExpert.Init(Symbol(),Period(),Expert_EveryTick,Expert_MagicNumber))
{
//--- failed
printf(__FUNCTION__+": error initializing expert");
ExtExpert.Deinit();
return(-1);
}
//--- Creation of signal object
CSignalMACD *signal=new CSignalMACD;
if(signal==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating signal");
ExtExpert.Deinit();
return(-2);
}
//--- Add signal to expert (will be deleted automatically))
if(!ExtExpert.InitSignal(signal))
{
//--- failed
printf(__FUNCTION__+": error initializing signal");
ExtExpert.Deinit();
return(-3);
}
//--- Set signal parameters
signal.PeriodFast(Inp_Signal_MACD_PeriodFast);
signal.PeriodSlow(Inp_Signal_MACD_PeriodSlow);
signal.PeriodSignal(Inp_Signal_MACD_PeriodSignal);
signal.TakeLevel(Inp_Signal_MACD_TakeProfit);
signal.StopLevel(Inp_Signal_MACD_StopLoss);
//--- Check signal parameters
if(!signal.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error signal parameters");
ExtExpert.Deinit();
return(-4);
}
//--- Creation of trailing object
CTrailingNone *trailing=new CTrailingNone;
if(trailing==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating trailing");
ExtExpert.Deinit();
return(-5);
}
//--- Add trailing to expert (will be deleted automatically))
if(!ExtExpert.InitTrailing(trailing))
{
//--- failed
printf(__FUNCTION__+": error initializing trailing");
ExtExpert.Deinit();
return(-6);
}
//--- Set trailing parameters
//--- Check trailing parameters
if(!trailing.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error trailing parameters");
ExtExpert.Deinit();
return(-7);
}
//--- Creation of money object
CMoneyNone *money=new CMoneyNone;
if(money==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating money");
ExtExpert.Deinit();
return(-8);
}
//--- Add money to expert (will be deleted automatically))
if(!ExtExpert.InitMoney(money))
{
//--- failed
printf(__FUNCTION__+": error initializing money");
ExtExpert.Deinit();
return(-9);
}
//--- Set money parameters
//--- Check money parameters
if(!money.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error money parameters");
ExtExpert.Deinit();
return(-10);
}
//--- Tuning of all necessary indicators
if(!ExtExpert.InitIndicators())
{
//--- failed
printf(__FUNCTION__+": error initializing indicators");
ExtExpert.Deinit();
return(-11);
}
//--- succeed
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Deinitialization function of the expert |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ExtExpert.Deinit();
}
//+------------------------------------------------------------------+
//| Function-event handler "tick" |
//+------------------------------------------------------------------+
void OnTick(void)
{
ExtExpert.OnTick();
}
//+------------------------------------------------------------------+
//| Function-event handler "trade" |
//+------------------------------------------------------------------+
void OnTrade(void)
{
ExtExpert.OnTrade();
}
//+------------------------------------------------------------------+
//| Function-event handler "timer" |
//+------------------------------------------------------------------+
void OnTimer(void)
{
ExtExpert.OnTimer();
}
//+------------------------------------------------------------------+
+175
View File
@@ -0,0 +1,175 @@
//+------------------------------------------------------------------+
//| ExpertMAMA.mq5 |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009-2017, MetaQuotes Software Corp."
#property link "http://www.mql5.com"
#property version "1.00"
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
#include <Expert\Signal\SignalMA.mqh>
#include <Expert\Trailing\TrailingMA.mqh>
#include <Expert\Money\MoneyNone.mqh>
//+------------------------------------------------------------------+
//| Inputs |
//+------------------------------------------------------------------+
//--- inputs for expert
input string Inp_Expert_Title ="ExpertMAMA";
int Expert_MagicNumber =12003;
bool Expert_EveryTick =false;
//--- inputs for signal
input int Inp_Signal_MA_Period =12;
input int Inp_Signal_MA_Shift =6;
input ENUM_MA_METHOD Inp_Signal_MA_Method =MODE_SMA;
input ENUM_APPLIED_PRICE Inp_Signal_MA_Applied =PRICE_CLOSE;
//--- inputs for trailing
input int Inp_Trailing_MA_Period =12;
input int Inp_Trailing_MA_Shift =0;
input ENUM_MA_METHOD Inp_Trailing_MA_Method =MODE_SMA;
input ENUM_APPLIED_PRICE Inp_Trailing_MA_Applied=PRICE_CLOSE;
//+------------------------------------------------------------------+
//| Global expert object |
//+------------------------------------------------------------------+
CExpert ExtExpert;
//+------------------------------------------------------------------+
//| Initialization function of the expert |
//+------------------------------------------------------------------+
int OnInit(void)
{
//--- Initializing expert
if(!ExtExpert.Init(Symbol(),Period(),Expert_EveryTick,Expert_MagicNumber))
{
//--- failed
printf(__FUNCTION__+": error initializing expert");
ExtExpert.Deinit();
return(-1);
}
//--- Creation of signal object
CSignalMA *signal=new CSignalMA;
if(signal==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating signal");
ExtExpert.Deinit();
return(-2);
}
//--- Add signal to expert (will be deleted automatically))
if(!ExtExpert.InitSignal(signal))
{
//--- failed
printf(__FUNCTION__+": error initializing signal");
ExtExpert.Deinit();
return(-3);
}
//--- Set signal parameters
signal.PeriodMA(Inp_Signal_MA_Period);
signal.Shift(Inp_Signal_MA_Shift);
signal.Method(Inp_Signal_MA_Method);
signal.Applied(Inp_Signal_MA_Applied);
//--- Check signal parameters
if(!signal.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error signal parameters");
ExtExpert.Deinit();
return(-4);
}
//--- Creation of trailing object
CTrailingMA *trailing=new CTrailingMA;
if(trailing==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating trailing");
ExtExpert.Deinit();
return(-5);
}
//--- Add trailing to expert (will be deleted automatically))
if(!ExtExpert.InitTrailing(trailing))
{
//--- failed
printf(__FUNCTION__+": error initializing trailing");
ExtExpert.Deinit();
return(-6);
}
//--- Set trailing parameters
trailing.Period(Inp_Trailing_MA_Period);
trailing.Shift(Inp_Trailing_MA_Shift);
trailing.Method(Inp_Trailing_MA_Method);
trailing.Applied(Inp_Trailing_MA_Applied);
//--- Check trailing parameters
if(!trailing.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error trailing parameters");
ExtExpert.Deinit();
return(-7);
}
//--- Creation of money object
CMoneyNone *money=new CMoneyNone;
if(money==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating money");
ExtExpert.Deinit();
return(-8);
}
//--- Add money to expert (will be deleted automatically))
if(!ExtExpert.InitMoney(money))
{
//--- failed
printf(__FUNCTION__+": error initializing money");
ExtExpert.Deinit();
return(-9);
}
//--- Set money parameters
//--- Check money parameters
if(!money.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error money parameters");
ExtExpert.Deinit();
return(-10);
}
//--- Tuning of all necessary indicators
if(!ExtExpert.InitIndicators())
{
//--- failed
printf(__FUNCTION__+": error initializing indicators");
ExtExpert.Deinit();
return(-11);
}
//--- succeed
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Deinitialization function of the expert |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ExtExpert.Deinit();
}
//+------------------------------------------------------------------+
//| Function-event handler "tick" |
//+------------------------------------------------------------------+
void OnTick(void)
{
ExtExpert.OnTick();
}
//+------------------------------------------------------------------+
//| Function-event handler "trade" |
//+------------------------------------------------------------------+
void OnTrade(void)
{
ExtExpert.OnTrade();
}
//+------------------------------------------------------------------+
//| Function-event handler "timer" |
//+------------------------------------------------------------------+
void OnTimer(void)
{
ExtExpert.OnTimer();
}
//+------------------------------------------------------------------+
+171
View File
@@ -0,0 +1,171 @@
//+------------------------------------------------------------------+
//| ExpertMAPSAR.mq5 |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009-2017, MetaQuotes Software Corp."
#property link "http://www.mql5.com"
#property version "1.00"
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
#include <Expert\Signal\SignalMA.mqh>
#include <Expert\Trailing\TrailingParabolicSAR.mqh>
#include <Expert\Money\MoneyNone.mqh>
//+------------------------------------------------------------------+
//| Inputs |
//+------------------------------------------------------------------+
//--- inputs for expert
input string Inp_Expert_Title ="ExpertMAPSAR";
int Expert_MagicNumber =14598;
bool Expert_EveryTick =false;
//--- inputs for signal
input int Inp_Signal_MA_Period =12;
input int Inp_Signal_MA_Shift =6;
input ENUM_MA_METHOD Inp_Signal_MA_Method =MODE_SMA;
input ENUM_APPLIED_PRICE Inp_Signal_MA_Applied =PRICE_CLOSE;
//--- inputs for trailing
input double Inp_Trailing_ParabolicSAR_Step =0.02;
input double Inp_Trailing_ParabolicSAR_Maximum=0.2;
//+------------------------------------------------------------------+
//| Global expert object |
//+------------------------------------------------------------------+
CExpert ExtExpert;
//+------------------------------------------------------------------+
//| Initialization function of the expert |
//+------------------------------------------------------------------+
int OnInit(void)
{
//--- Initializing expert
if(!ExtExpert.Init(Symbol(),Period(),Expert_EveryTick,Expert_MagicNumber))
{
//--- failed
printf(__FUNCTION__+": error initializing expert");
ExtExpert.Deinit();
return(-1);
}
//--- Creation of signal object
CSignalMA *signal=new CSignalMA;
if(signal==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating signal");
ExtExpert.Deinit();
return(-2);
}
//--- Add signal to expert (will be deleted automatically))
if(!ExtExpert.InitSignal(signal))
{
//--- failed
printf(__FUNCTION__+": error initializing signal");
ExtExpert.Deinit();
return(-3);
}
//--- Set signal parameters
signal.PeriodMA(Inp_Signal_MA_Period);
signal.Shift(Inp_Signal_MA_Shift);
signal.Method(Inp_Signal_MA_Method);
signal.Applied(Inp_Signal_MA_Applied);
//--- Check signal parameters
if(!signal.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error signal parameters");
ExtExpert.Deinit();
return(-4);
}
//--- Creation of trailing object
CTrailingPSAR *trailing=new CTrailingPSAR;
if(trailing==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating trailing");
ExtExpert.Deinit();
return(-5);
}
//--- Add trailing to expert (will be deleted automatically))
if(!ExtExpert.InitTrailing(trailing))
{
//--- failed
printf(__FUNCTION__+": error initializing trailing");
ExtExpert.Deinit();
return(-6);
}
//--- Set trailing parameters
trailing.Step(Inp_Trailing_ParabolicSAR_Step);
trailing.Maximum(Inp_Trailing_ParabolicSAR_Maximum);
//--- Check trailing parameters
if(!trailing.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error trailing parameters");
ExtExpert.Deinit();
return(-7);
}
//--- Creation of money object
CMoneyNone *money=new CMoneyNone;
if(money==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating money");
ExtExpert.Deinit();
return(-8);
}
//--- Add money to expert (will be deleted automatically))
if(!ExtExpert.InitMoney(money))
{
//--- failed
printf(__FUNCTION__+": error initializing money");
ExtExpert.Deinit();
return(-9);
}
//--- Set money parameters
//--- Check money parameters
if(!money.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error money parameters");
ExtExpert.Deinit();
return(-10);
}
//--- Tuning of all necessary indicators
if(!ExtExpert.InitIndicators())
{
//--- failed
printf(__FUNCTION__+": error initializing indicators");
ExtExpert.Deinit();
return(-11);
}
//--- succeed
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Deinitialization function of the expert |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ExtExpert.Deinit();
}
//+------------------------------------------------------------------+
//| Function-event handler "tick" |
//+------------------------------------------------------------------+
void OnTick(void)
{
ExtExpert.OnTick();
}
//+------------------------------------------------------------------+
//| Function-event handler "trade" |
//+------------------------------------------------------------------+
void OnTrade(void)
{
ExtExpert.OnTrade();
}
//+------------------------------------------------------------------+
//| Function-event handler "timer" |
//+------------------------------------------------------------------+
void OnTimer(void)
{
ExtExpert.OnTimer();
}
//+------------------------------------------------------------------+
@@ -0,0 +1,176 @@
//+------------------------------------------------------------------+
//| ExpertMAPSARSizeOptimized.mq5 |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009-2017, MetaQuotes Software Corp."
#property link "http://www.mql5.com"
#property version "1.00"
//+------------------------------------------------------------------+
//| Include |
//+------------------------------------------------------------------+
#include <Expert\Expert.mqh>
#include <Expert\Signal\SignalMA.mqh>
#include <Expert\Trailing\TrailingParabolicSAR.mqh>
#include <Expert\Money\MoneySizeOptimized.mqh>
//+------------------------------------------------------------------+
//| Inputs |
//+------------------------------------------------------------------+
//--- inputs for expert
input string Inp_Expert_Title ="ExpertMAPSARSizeOptimized";
int Expert_MagicNumber =27893;
bool Expert_EveryTick =false;
//--- inputs for signal
input int Inp_Signal_MA_Period =12;
input int Inp_Signal_MA_Shift =6;
input ENUM_MA_METHOD Inp_Signal_MA_Method =MODE_SMA;
input ENUM_APPLIED_PRICE Inp_Signal_MA_Applied =PRICE_CLOSE;
//--- inputs for trailing
input double Inp_Trailing_ParabolicSAR_Step =0.02;
input double Inp_Trailing_ParabolicSAR_Maximum =0.2;
//--- inputs for money
input double Inp_Money_SizeOptimized_DecreaseFactor=3.0;
input double Inp_Money_SizeOptimized_Percent =10.0;
//+------------------------------------------------------------------+
//| Global expert object |
//+------------------------------------------------------------------+
CExpert ExtExpert;
//+------------------------------------------------------------------+
//| Initialization function of the expert |
//+------------------------------------------------------------------+
int OnInit(void)
{
//--- Initializing expert
if(!ExtExpert.Init(Symbol(),Period(),Expert_EveryTick,Expert_MagicNumber))
{
//--- failed
printf(__FUNCTION__+": error initializing expert");
ExtExpert.Deinit();
return(-1);
}
//--- Creation of signal object
CSignalMA *signal=new CSignalMA;
if(signal==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating signal");
ExtExpert.Deinit();
return(-2);
}
//--- Add signal to expert (will be deleted automatically))
if(!ExtExpert.InitSignal(signal))
{
//--- failed
printf(__FUNCTION__+": error initializing signal");
ExtExpert.Deinit();
return(-3);
}
//--- Set signal parameters
signal.PeriodMA(Inp_Signal_MA_Period);
signal.Shift(Inp_Signal_MA_Shift);
signal.Method(Inp_Signal_MA_Method);
signal.Applied(Inp_Signal_MA_Applied);
//--- Check signal parameters
if(!signal.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error signal parameters");
ExtExpert.Deinit();
return(-4);
}
//--- Creation of trailing object
CTrailingPSAR *trailing=new CTrailingPSAR;
if(trailing==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating trailing");
ExtExpert.Deinit();
return(-5);
}
//--- Add trailing to expert (will be deleted automatically))
if(!ExtExpert.InitTrailing(trailing))
{
//--- failed
printf(__FUNCTION__+": error initializing trailing");
ExtExpert.Deinit();
return(-6);
}
//--- Set trailing parameters
trailing.Step(Inp_Trailing_ParabolicSAR_Step);
trailing.Maximum(Inp_Trailing_ParabolicSAR_Maximum);
//--- Check trailing parameters
if(!trailing.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error trailing parameters");
ExtExpert.Deinit();
return(-7);
}
//--- Creation of money object
CMoneySizeOptimized *money=new CMoneySizeOptimized;
if(money==NULL)
{
//--- failed
printf(__FUNCTION__+": error creating money");
ExtExpert.Deinit();
return(-8);
}
//--- Add money to expert (will be deleted automatically))
if(!ExtExpert.InitMoney(money))
{
//--- failed
printf(__FUNCTION__+": error initializing money");
ExtExpert.Deinit();
return(-9);
}
//--- Set money parameters
money.DecreaseFactor(Inp_Money_SizeOptimized_DecreaseFactor);
money.Percent(Inp_Money_SizeOptimized_Percent);
//--- Check money parameters
if(!money.ValidationSettings())
{
//--- failed
printf(__FUNCTION__+": error money parameters");
ExtExpert.Deinit();
return(-10);
}
//--- Tuning of all necessary indicators
if(!ExtExpert.InitIndicators())
{
//--- failed
printf(__FUNCTION__+": error initializing indicators");
ExtExpert.Deinit();
return(-11);
}
//--- succeed
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Deinitialization function of the expert |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
ExtExpert.Deinit();
}
//+------------------------------------------------------------------+
//| Function-event handler "tick" |
//+------------------------------------------------------------------+
void OnTick(void)
{
ExtExpert.OnTick();
}
//+------------------------------------------------------------------+
//| Function-event handler "trade" |
//+------------------------------------------------------------------+
void OnTrade(void)
{
ExtExpert.OnTrade();
}
//+------------------------------------------------------------------+
//| Function-event handler "timer" |
//+------------------------------------------------------------------+
void OnTimer(void)
{
ExtExpert.OnTimer();
}
//+------------------------------------------------------------------+
@@ -0,0 +1,353 @@
//+------------------------------------------------------------------+
//| ChartInChart.mq5 |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "2009-2017, MetaQuotes Software Corp."
#property link "http://www.mql5.com"
//--- inputs
input color TextColor=White;
input color BGColor=SteelBlue;
input int XPosition=10;
input int YPosition=10;
input int XSize=450;
input int YSize=300;
//--- variables
int xsize=450;
int ysize=300;
int xdist=10;
int ydist=10;
int scale=1;
int show=1;
int showdates =0;
int showprices=0;
//---
string curr_symbol;
string curr_period_str;
ENUM_TIMEFRAMES curr_period;
ENUM_TIMEFRAMES enper;
//+------------------------------------------------------------------+
//| Initialize expert |
//+------------------------------------------------------------------+
void OnInit()
{
//--- default value for symbol and period
curr_symbol=Symbol();
curr_period=Period();
PeriodToStr(curr_period,curr_period_str);
//--- copy sizes
xsize=XSize;
ysize=YSize;
xdist=XPosition;
ydist=YPosition;
//--- create objects
PIPCreate();
PIPSetParams();
//---
ChartRedraw();
}
//+------------------------------------------------------------------+
//| Process chart events |
//+------------------------------------------------------------------+
void OnChartEvent(const int id,const long& lparam,const double& dparam,const string& sparam)
{
if(id==CHARTEVENT_OBJECT_ENDEDIT && sparam=="PIPSymbol")
{
curr_symbol=ObjectGetString(0,"PIPSymbol",OBJPROP_TEXT);
ObjectSetString(0,"PIPChart",OBJPROP_SYMBOL,curr_symbol);
ChartRedraw();
//--- check symbol
curr_symbol=ObjectGetString(0,"PIPChart",OBJPROP_SYMBOL);
ObjectSetString(0,"PIPSymbol",OBJPROP_TEXT,curr_symbol);
}
else
if(id==CHARTEVENT_OBJECT_ENDEDIT && sparam=="PIPPeriod")
{
string per=ObjectGetString(0,"PIPPeriod",OBJPROP_TEXT);
if(StrToPeriod(per,enper))
{
if(enper) curr_period=enper;
PeriodToStr(curr_period,curr_period_str);
ObjectSetInteger(0,"PIPChart",OBJPROP_PERIOD,curr_period);
ChartRedraw();
}
}
else
if(id==CHARTEVENT_OBJECT_CLICK && sparam=="PIPPricesButton")
{
showprices=(int)ObjectGetInteger(0,"PIPPricesButton",OBJPROP_STATE);
ObjectSetInteger(0,"PIPChart",OBJPROP_PRICE_SCALE,showprices);
ChartRedraw();
}
else
if(id==CHARTEVENT_OBJECT_CLICK && sparam=="PIPDatesButton")
{
showdates=(int)ObjectGetInteger(0,"PIPDatesButton",OBJPROP_STATE);
ObjectSetInteger(0,"PIPChart",OBJPROP_DATE_SCALE,showdates);
ChartRedraw();
}
else
if(id==CHARTEVENT_OBJECT_CLICK && sparam=="PIPPlusButton")
{
ObjectSetInteger(0,"PIPPlusButton",OBJPROP_STATE,0);
if(scale<5)
{
scale++;
ObjectSetInteger(0,"PIPChart",OBJPROP_CHART_SCALE,scale);
}
ChartRedraw();
}
else
if(id==CHARTEVENT_OBJECT_CLICK && sparam=="PIPMinusButton")
{
ObjectSetInteger(0,"PIPMinusButton",OBJPROP_STATE,0);
if(scale>0)
{
scale--;
ObjectSetInteger(0,"PIPChart",OBJPROP_CHART_SCALE,scale);
}
ChartRedraw();
}
else
if(id==CHARTEVENT_OBJECT_CLICK && sparam=="PIPHideButton")
{
ObjectSetInteger(0,"PIPHideButton",OBJPROP_STATE,0);
if(show)
{
//--- hide chart
ObjectSetString(0,"PIPHideButton",OBJPROP_TEXT,"\n");
PIPHideChart();
}
else
{
//--- restore chart
PIPSetParams();
}
//--- change state
show=1-show;
ChartRedraw();
}
}
//+------------------------------------------------------------------+
//| Deinitialize expert |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- delete all our objects
PIPDelete();
//---
ChartRedraw();
}
//+------------------------------------------------------------------+
//| Create objects |
//+------------------------------------------------------------------+
void PIPCreate()
{
ObjectCreate(0,"PIPSymbol",OBJ_EDIT,0,0,0,0,0);
ObjectCreate(0,"PIPPeriod",OBJ_EDIT,0,0,0,0,0);
ObjectCreate(0,"PIPPlusButton",OBJ_BUTTON,0,0,0,0,0);
ObjectCreate(0,"PIPMinusButton",OBJ_BUTTON,0,0,0,0,0);
ObjectCreate(0,"PIPHideButton",OBJ_BUTTON,0,0,0,0,0);
ObjectCreate(0,"PIPDatesButton",OBJ_BUTTON,0,0,0,0,0);
ObjectCreate(0,"PIPPricesButton",OBJ_BUTTON,0,0,0,0,0);
ObjectCreate(0,"PIPChart",OBJ_CHART,0,0,0,0,0);
}
//+------------------------------------------------------------------+
//| Delete objects |
//+------------------------------------------------------------------+
void PIPDelete()
{
ObjectDelete(0,"PIPSymbol");
ObjectDelete(0,"PIPPeriod");
ObjectDelete(0,"PIPPlusButton");
ObjectDelete(0,"PIPMinusButton");
ObjectDelete(0,"PIPHideButton");
ObjectDelete(0,"PIPDatesButton");
ObjectDelete(0,"PIPPricesButton");
ObjectDelete(0,"PIPChart");
}
//+------------------------------------------------------------------+
//| Set objects params |
//+------------------------------------------------------------------+
void PIPSetParams()
{
//--- check size
if(xsize<250) xsize=250;
if(ysize<100) ysize=100;
//--- Symbol
ObjectSetInteger(0,"PIPSymbol",OBJPROP_COLOR,TextColor);
ObjectSetInteger(0,"PIPSymbol",OBJPROP_BGCOLOR,BGColor);
ObjectSetInteger(0,"PIPSymbol",OBJPROP_XDISTANCE,xdist);
ObjectSetInteger(0,"PIPSymbol",OBJPROP_YDISTANCE,ydist);
ObjectSetInteger(0,"PIPSymbol",OBJPROP_XSIZE,xsize-198);
ObjectSetInteger(0,"PIPSymbol",OBJPROP_YSIZE,18);
ObjectSetString(0,"PIPSymbol",OBJPROP_FONT,"Arial");
ObjectSetString(0,"PIPSymbol",OBJPROP_TEXT,curr_symbol);
ObjectSetInteger(0,"PIPSymbol",OBJPROP_FONTSIZE,10);
ObjectSetInteger(0,"PIPSymbol",OBJPROP_SELECTABLE,0);
//--- Period
ObjectSetInteger(0,"PIPPeriod",OBJPROP_COLOR,TextColor);
ObjectSetInteger(0,"PIPPeriod",OBJPROP_BGCOLOR,BGColor);
ObjectSetInteger(0,"PIPPeriod",OBJPROP_XDISTANCE,xdist+xsize-197);
ObjectSetInteger(0,"PIPPeriod",OBJPROP_YDISTANCE,ydist);
ObjectSetInteger(0,"PIPPeriod",OBJPROP_XSIZE,40);
ObjectSetInteger(0,"PIPPeriod",OBJPROP_YSIZE,18);
ObjectSetString(0,"PIPPeriod",OBJPROP_FONT,"Arial");
ObjectSetString(0,"PIPPeriod",OBJPROP_TEXT,curr_period_str);
ObjectSetInteger(0,"PIPPeriod",OBJPROP_FONTSIZE,10);
ObjectSetInteger(0,"PIPPeriod",OBJPROP_SELECTABLE,0);
//--- Dates
ObjectSetInteger(0,"PIPDatesButton",OBJPROP_COLOR,TextColor);
ObjectSetInteger(0,"PIPDatesButton",OBJPROP_BGCOLOR,BGColor);
ObjectSetInteger(0,"PIPDatesButton",OBJPROP_XDISTANCE,xdist+xsize-156);
ObjectSetInteger(0,"PIPDatesButton",OBJPROP_YDISTANCE,ydist);
ObjectSetInteger(0,"PIPDatesButton",OBJPROP_XSIZE,49);
ObjectSetInteger(0,"PIPDatesButton",OBJPROP_YSIZE,18);
ObjectSetString(0,"PIPDatesButton",OBJPROP_TEXT,"Dates");
ObjectSetString(0,"PIPDatesButton",OBJPROP_FONT,"Arial");
ObjectSetInteger(0,"PIPDatesButton",OBJPROP_FONTSIZE,10);
ObjectSetInteger(0,"PIPDatesButton",OBJPROP_STATE,showdates);
ObjectSetInteger(0,"PIPDatesButton",OBJPROP_SELECTABLE,0);
//--- Prices
ObjectSetInteger(0,"PIPPricesButton",OBJPROP_COLOR,TextColor);
ObjectSetInteger(0,"PIPPricesButton",OBJPROP_BGCOLOR,BGColor);
ObjectSetInteger(0,"PIPPricesButton",OBJPROP_XDISTANCE,xdist+xsize-106);
ObjectSetInteger(0,"PIPPricesButton",OBJPROP_YDISTANCE,ydist);
ObjectSetInteger(0,"PIPPricesButton",OBJPROP_XSIZE,49);
ObjectSetInteger(0,"PIPPricesButton",OBJPROP_YSIZE,18);
ObjectSetString(0,"PIPPricesButton",OBJPROP_TEXT,"Prices");
ObjectSetString(0,"PIPPricesButton",OBJPROP_FONT,"Arial");
ObjectSetInteger(0,"PIPPricesButton",OBJPROP_FONTSIZE,10);
ObjectSetInteger(0,"PIPPricesButton",OBJPROP_STATE,showprices);
ObjectSetInteger(0,"PIPPricesButton",OBJPROP_SELECTABLE,0);
//--- Scale +
ObjectSetInteger(0,"PIPPlusButton",OBJPROP_COLOR,TextColor);
ObjectSetInteger(0,"PIPPlusButton",OBJPROP_BGCOLOR,BGColor);
ObjectSetInteger(0,"PIPPlusButton",OBJPROP_XDISTANCE,xdist+xsize-56);
ObjectSetInteger(0,"PIPPlusButton",OBJPROP_YDISTANCE,ydist);
ObjectSetInteger(0,"PIPPlusButton",OBJPROP_XSIZE,18);
ObjectSetInteger(0,"PIPPlusButton",OBJPROP_YSIZE,18);
ObjectSetString(0,"PIPPlusButton",OBJPROP_TEXT,"+");
ObjectSetString(0,"PIPPlusButton",OBJPROP_FONT,"Arial");
ObjectSetInteger(0,"PIPPlusButton",OBJPROP_FONTSIZE,10);
ObjectSetInteger(0,"PIPPlusButton",OBJPROP_STATE,0);
ObjectSetInteger(0,"PIPPlusButton",OBJPROP_SELECTABLE,0);
//--- Scale -
ObjectSetInteger(0,"PIPMinusButton",OBJPROP_COLOR,TextColor);
ObjectSetInteger(0,"PIPMinusButton",OBJPROP_BGCOLOR,BGColor);
ObjectSetInteger(0,"PIPMinusButton",OBJPROP_XDISTANCE,xdist+xsize-37);
ObjectSetInteger(0,"PIPMinusButton",OBJPROP_YDISTANCE,ydist);
ObjectSetInteger(0,"PIPMinusButton",OBJPROP_XSIZE,18);
ObjectSetInteger(0,"PIPMinusButton",OBJPROP_YSIZE,18);
ObjectSetString(0,"PIPMinusButton",OBJPROP_TEXT,"-");
ObjectSetString(0,"PIPMinusButton",OBJPROP_FONT,"Arial");
ObjectSetInteger(0,"PIPMinusButton",OBJPROP_FONTSIZE,10);
ObjectSetInteger(0,"PIPMinusButton",OBJPROP_STATE,0);
ObjectSetInteger(0,"PIPMinusButton",OBJPROP_SELECTABLE,0);
//--- Hide/Show
ObjectSetInteger(0,"PIPHideButton",OBJPROP_COLOR,TextColor);
ObjectSetInteger(0,"PIPHideButton",OBJPROP_BGCOLOR,BGColor);
ObjectSetInteger(0,"PIPHideButton",OBJPROP_XDISTANCE,xdist+xsize-18);
ObjectSetInteger(0,"PIPHideButton",OBJPROP_YDISTANCE,ydist);
ObjectSetInteger(0,"PIPHideButton",OBJPROP_XSIZE,18);
ObjectSetInteger(0,"PIPHideButton",OBJPROP_YSIZE,18);
ObjectSetString(0,"PIPHideButton",OBJPROP_TEXT,"_");
ObjectSetString(0,"PIPHideButton",OBJPROP_FONT,"Arial");
ObjectSetInteger(0,"PIPHideButton",OBJPROP_FONTSIZE,8);
ObjectSetInteger(0,"PIPHideButton",OBJPROP_STATE,0);
ObjectSetInteger(0,"PIPHideButton",OBJPROP_SELECTABLE,0);
//--- Chart
ObjectSetString(0,"PIPChart",OBJPROP_SYMBOL,curr_symbol);
ObjectSetInteger(0,"PIPChart",OBJPROP_PERIOD,curr_period);
ObjectSetInteger(0,"PIPChart",OBJPROP_XDISTANCE,xdist);
ObjectSetInteger(0,"PIPChart",OBJPROP_YDISTANCE,ydist+20);
ObjectSetInteger(0,"PIPChart",OBJPROP_XSIZE,xsize);
ObjectSetInteger(0,"PIPChart",OBJPROP_YSIZE,ysize);
ObjectSetInteger(0,"PIPChart",OBJPROP_DATE_SCALE,showdates);
ObjectSetInteger(0,"PIPChart",OBJPROP_PRICE_SCALE,showprices);
ObjectSetInteger(0,"PIPChart",OBJPROP_SELECTABLE,0);
ObjectSetInteger(0,"PIPChart",OBJPROP_CHART_SCALE,scale);
}
//+------------------------------------------------------------------+
//| Hide chart object |
//+------------------------------------------------------------------+
void PIPHideChart()
{
ObjectSetInteger(0,"PIPChart",OBJPROP_XDISTANCE,-1);
ObjectSetInteger(0,"PIPChart",OBJPROP_YDISTANCE,-1);
ObjectSetInteger(0,"PIPChart",OBJPROP_XSIZE,0);
ObjectSetInteger(0,"PIPChart",OBJPROP_YSIZE,0);
}
//+------------------------------------------------------------------+
//| Convert string to history period |
//+------------------------------------------------------------------+
bool StrToPeriod(const string strper,ENUM_TIMEFRAMES& period)
{
bool res=true;
//--- ìåñÿö
if(strper=="MN" || strper=="MN1" || strper=="MONTH" || strper=="MONTHLY") period=PERIOD_MN1;
//--- íåäåëÿ
else if(strper=="W" || strper=="W1" || strper=="WEEK" || strper=="10080" || strper=="WEEKLY") period=PERIOD_W1;
//--- äåíü
else if(strper=="D" || strper=="D1" || strper=="DAY" || strper=="1440" || strper=="DAILY") period=PERIOD_D1;
//--- ÷àñîâêè
else if(strper=="H" || strper=="H1" || strper=="HOUR" || strper=="60") period=PERIOD_H1;
else if(strper=="H12" || strper=="720") period=PERIOD_H12;
else if(strper=="H8" || strper=="480") period=PERIOD_H8;
else if(strper=="H6" || strper=="360") period=PERIOD_H6;
else if(strper=="H4" || strper=="240") period=PERIOD_H4;
else if(strper=="H3" || strper=="180") period=PERIOD_H3;
else if(strper=="H2" || strper=="120") period=PERIOD_H2;
//--- ìèíóòêè
else if(strper=="M" || strper=="M1" || strper=="MIN" || strper=="1" || strper=="MINUTE") period=PERIOD_M1;
else if(strper=="M30" || strper=="30") period=PERIOD_M30;
else if(strper=="M20" || strper=="20") period=PERIOD_M20;
else if(strper=="M15" || strper=="15") period=PERIOD_M15;
else if(strper=="M12" || strper=="12") period=PERIOD_M12;
else if(strper=="M10" || strper=="10") period=PERIOD_M10;
else if(strper=="M6" || strper=="6") period=PERIOD_M6;
else if(strper=="M5" || strper=="5") period=PERIOD_M5;
else if(strper=="M4" || strper=="4") period=PERIOD_M4;
else if(strper=="M3" || strper=="3") period=PERIOD_M3;
else if(strper=="M2" || strper=="2") period=PERIOD_M2;
//--- íå ïîëó÷èëîñü
else res=false;
//---
return(res);
}
//+------------------------------------------------------------------+
//| Convert history period to string |
//+------------------------------------------------------------------+
bool PeriodToStr(ENUM_TIMEFRAMES period,string& strper)
{
bool res=true;
//---
switch(period)
{
case PERIOD_MN1 : strper="MN1"; break;
case PERIOD_W1 : strper="W1"; break;
case PERIOD_D1 : strper="D1"; break;
case PERIOD_H1 : strper="H1"; break;
case PERIOD_H2 : strper="H2"; break;
case PERIOD_H3 : strper="H3"; break;
case PERIOD_H4 : strper="H4"; break;
case PERIOD_H6 : strper="H6"; break;
case PERIOD_H8 : strper="H8"; break;
case PERIOD_H12 : strper="H12"; break;
case PERIOD_M1 : strper="M1"; break;
case PERIOD_M2 : strper="M2"; break;
case PERIOD_M3 : strper="M3"; break;
case PERIOD_M4 : strper="M4"; break;
case PERIOD_M5 : strper="M5"; break;
case PERIOD_M6 : strper="M6"; break;
case PERIOD_M10 : strper="M10"; break;
case PERIOD_M12 : strper="M12"; break;
case PERIOD_M15 : strper="M15"; break;
case PERIOD_M20 : strper="M20"; break;
case PERIOD_M30 : strper="M30"; break;
default : res=false;
}
//---
return(res);
}
//+------------------------------------------------------------------+
+45
View File
@@ -0,0 +1,45 @@
//+------------------------------------------------------------------+
//| Controls.mq5 |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2009-2017, MetaQuotes Software Corp."
#property link "http://www.mql5.com"
#property version "1.00"
#include "ControlsDialog.mqh"
//+------------------------------------------------------------------+
//| Global Variables |
//+------------------------------------------------------------------+
CControlsDialog ExtDialog;
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//--- create application dialog
if(!ExtDialog.Create(0,"Controls",0,20,20,360,324))
return(INIT_FAILED);
//--- run application
ExtDialog.Run();
//--- succeed
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//--- destroy dialog
ExtDialog.Destroy(reason);
}
//+------------------------------------------------------------------+
//| Expert chart event function |
//+------------------------------------------------------------------+
void OnChartEvent(const int id, // event ID
const long& lparam, // event parameter of the long type
const double& dparam, // event parameter of the double type
const string& sparam) // event parameter of the string type
{
ExtDialog.ChartEvent(id,lparam,dparam,sparam);
}
//+------------------------------------------------------------------+
@@ -0,0 +1,427 @@
//+------------------------------------------------------------------+
//| ControlsDialog.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include <Controls\Dialog.mqh>
#include <Controls\Button.mqh>
#include <Controls\Edit.mqh>
#include <Controls\DatePicker.mqh>
#include <Controls\ListView.mqh>
#include <Controls\ComboBox.mqh>
#include <Controls\SpinEdit.mqh>
#include <Controls\RadioGroup.mqh>
#include <Controls\CheckGroup.mqh>
//+------------------------------------------------------------------+
//| defines |
//+------------------------------------------------------------------+
//--- indents and gaps
#define INDENT_LEFT (11) // indent from left (with allowance for border width)
#define INDENT_TOP (11) // indent from top (with allowance for border width)
#define INDENT_RIGHT (11) // indent from right (with allowance for border width)
#define INDENT_BOTTOM (11) // indent from bottom (with allowance for border width)
#define CONTROLS_GAP_X (5) // gap by X coordinate
#define CONTROLS_GAP_Y (5) // gap by Y coordinate
//--- for buttons
#define BUTTON_WIDTH (100) // size by X coordinate
#define BUTTON_HEIGHT (20) // size by Y coordinate
//--- for the indication area
#define EDIT_HEIGHT (20) // size by Y coordinate
//--- for group controls
#define GROUP_WIDTH (150) // size by X coordinate
#define LIST_HEIGHT (179) // size by Y coordinate
#define RADIO_HEIGHT (56) // size by Y coordinate
#define CHECK_HEIGHT (93) // size by Y coordinate
//+------------------------------------------------------------------+
//| Class CControlsDialog |
//| Usage: main dialog of the Controls application |
//+------------------------------------------------------------------+
class CControlsDialog : public CAppDialog
{
private:
CEdit m_edit; // the display field object
CButton m_button1; // the button object
CButton m_button2; // the button object
CButton m_button3; // the fixed button object
CSpinEdit m_spin_edit; // the up-down object
CDatePicker m_date; // the datepicker object
CListView m_list_view; // the list object
CComboBox m_combo_box; // the dropdown list object
CRadioGroup m_radio_group; // the radio buttons group object
CCheckGroup m_check_group; // the check box group object
public:
CControlsDialog(void);
~CControlsDialog(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
protected:
//--- create dependent controls
bool CreateEdit(void);
bool CreateButton1(void);
bool CreateButton2(void);
bool CreateButton3(void);
bool CreateSpinEdit(void);
bool CreateDate(void);
bool CreateListView(void);
bool CreateComboBox(void);
bool CreateRadioGroup(void);
bool CreateCheckGroup(void);
//--- handlers of the dependent controls events
void OnClickButton1(void);
void OnClickButton2(void);
void OnClickButton3(void);
void OnChangeSpinEdit(void);
void OnChangeDate(void);
void OnChangeListView(void);
void OnChangeComboBox(void);
void OnChangeRadioGroup(void);
void OnChangeCheckGroup(void);
};
//+------------------------------------------------------------------+
//| Event Handling |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CControlsDialog)
ON_EVENT(ON_CLICK,m_button1,OnClickButton1)
ON_EVENT(ON_CLICK,m_button2,OnClickButton2)
ON_EVENT(ON_CLICK,m_button3,OnClickButton3)
ON_EVENT(ON_CHANGE,m_spin_edit,OnChangeSpinEdit)
ON_EVENT(ON_CHANGE,m_date,OnChangeDate)
ON_EVENT(ON_CHANGE,m_list_view,OnChangeListView)
ON_EVENT(ON_CHANGE,m_combo_box,OnChangeComboBox)
ON_EVENT(ON_CHANGE,m_radio_group,OnChangeRadioGroup)
ON_EVENT(ON_CHANGE,m_check_group,OnChangeCheckGroup)
EVENT_MAP_END(CAppDialog)
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CControlsDialog::CControlsDialog(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CControlsDialog::~CControlsDialog(void)
{
}
//+------------------------------------------------------------------+
//| Create |
//+------------------------------------------------------------------+
bool CControlsDialog::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);
//--- create dependent controls
if(!CreateEdit())
return(false);
if(!CreateButton1())
return(false);
if(!CreateButton2())
return(false);
if(!CreateButton3())
return(false);
if(!CreateSpinEdit())
return(false);
if(!CreateListView())
return(false);
if(!CreateDate())
return(false);
if(!CreateRadioGroup())
return(false);
if(!CreateCheckGroup())
return(false);
if(!CreateComboBox())
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the display field |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateEdit(void)
{
//--- coordinates
int x1=INDENT_LEFT;
int y1=INDENT_TOP;
int x2=ClientAreaWidth()-INDENT_RIGHT;
int y2=y1+EDIT_HEIGHT;
//--- create
if(!m_edit.Create(m_chart_id,m_name+"Edit",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_edit.ReadOnly(true))
return(false);
if(!Add(m_edit))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "Button1" button |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateButton1(void)
{
//--- coordinates
int x1=INDENT_LEFT;
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y);
int x2=x1+BUTTON_WIDTH;
int y2=y1+BUTTON_HEIGHT;
//--- create
if(!m_button1.Create(m_chart_id,m_name+"Button1",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_button1.Text("Button1"))
return(false);
if(!Add(m_button1))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "Button2" button |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateButton2(void)
{
//--- coordinates
int x1=INDENT_LEFT+(BUTTON_WIDTH+CONTROLS_GAP_X);
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y);
int x2=x1+BUTTON_WIDTH;
int y2=y1+BUTTON_HEIGHT;
//--- create
if(!m_button2.Create(m_chart_id,m_name+"Button2",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_button2.Text("Button2"))
return(false);
if(!Add(m_button2))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "Button3" fixed button |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateButton3(void)
{
//--- coordinates
int x1=INDENT_LEFT+2*(BUTTON_WIDTH+CONTROLS_GAP_X);
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y);
int x2=x1+BUTTON_WIDTH;
int y2=y1+BUTTON_HEIGHT;
//--- create
if(!m_button3.Create(m_chart_id,m_name+"Button3",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_button3.Text("Locked"))
return(false);
if(!Add(m_button3))
return(false);
m_button3.Locking(true);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "SpinEdit" element |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateSpinEdit(void)
{
//--- coordinates
int x1=INDENT_LEFT;
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+(BUTTON_HEIGHT+CONTROLS_GAP_Y);
int x2=x1+GROUP_WIDTH;
int y2=y1+EDIT_HEIGHT;
//--- create
if(!m_spin_edit.Create(m_chart_id,m_name+"SpinEdit",m_subwin,x1,y1,x2,y2))
return(false);
if(!Add(m_spin_edit))
return(false);
m_spin_edit.MinValue(10);
m_spin_edit.MaxValue(1000);
m_spin_edit.Value(100);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "DatePicker" element |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateDate(void)
{
//--- coordinates
int x1=INDENT_LEFT+GROUP_WIDTH+2*CONTROLS_GAP_X;
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+(BUTTON_HEIGHT+CONTROLS_GAP_Y);
int x2=x1+GROUP_WIDTH;
int y2=y1+EDIT_HEIGHT;
//--- create
if(!m_date.Create(m_chart_id,m_name+"Date",m_subwin,x1,y1,x2,y2))
return(false);
if(!Add(m_date))
return(false);
m_date.Value(TimeCurrent());
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "ListView" element |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateListView(void)
{
//--- coordinates
int x1=INDENT_LEFT+GROUP_WIDTH+2*CONTROLS_GAP_X;
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+
(BUTTON_HEIGHT+CONTROLS_GAP_Y)+
(EDIT_HEIGHT+2*CONTROLS_GAP_Y);
int x2=x1+GROUP_WIDTH;
int y2=y1+LIST_HEIGHT-CONTROLS_GAP_Y;
//--- create
if(!m_list_view.Create(m_chart_id,m_name+"ListView",m_subwin,x1,y1,x2,y2))
return(false);
if(!Add(m_list_view))
return(false);
//--- fill out with strings
for(int i=0;i<16;i++)
if(!m_list_view.AddItem("Item "+IntegerToString(i)))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "ComboBox" element |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateComboBox(void)
{
//--- coordinates
int x1=INDENT_LEFT;
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+
(BUTTON_HEIGHT+CONTROLS_GAP_Y)+
(EDIT_HEIGHT+CONTROLS_GAP_Y);
int x2=x1+GROUP_WIDTH;
int y2=y1+EDIT_HEIGHT;
//--- create
if(!m_combo_box.Create(m_chart_id,m_name+"ComboBox",m_subwin,x1,y1,x2,y2))
return(false);
if(!Add(m_combo_box))
return(false);
//--- fill out with strings
for(int i=0;i<16;i++)
if(!m_combo_box.ItemAdd("Item "+IntegerToString(i)))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "RadioGroup" element |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateRadioGroup(void)
{
//--- coordinates
int x1=INDENT_LEFT;
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+
(BUTTON_HEIGHT+CONTROLS_GAP_Y)+
(EDIT_HEIGHT+CONTROLS_GAP_Y)+
(EDIT_HEIGHT+CONTROLS_GAP_Y);
int x2=x1+GROUP_WIDTH;
int y2=y1+RADIO_HEIGHT;
//--- create
if(!m_radio_group.Create(m_chart_id,m_name+"RadioGroup",m_subwin,x1,y1,x2,y2))
return(false);
if(!Add(m_radio_group))
return(false);
//--- fill out with strings
for(int i=0;i<3;i++)
if(!m_radio_group.AddItem("Item "+IntegerToString(i),1<<i))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "CheckGroup" element |
//+------------------------------------------------------------------+
bool CControlsDialog::CreateCheckGroup(void)
{
//--- coordinates
int x1=INDENT_LEFT;
int y1=INDENT_TOP+(EDIT_HEIGHT+CONTROLS_GAP_Y)+
(BUTTON_HEIGHT+CONTROLS_GAP_Y)+
(EDIT_HEIGHT+CONTROLS_GAP_Y)+
(EDIT_HEIGHT+CONTROLS_GAP_Y)+
(RADIO_HEIGHT+CONTROLS_GAP_Y);
int x2=x1+GROUP_WIDTH;
int y2=y1+CHECK_HEIGHT;
//--- create
if(!m_check_group.Create(m_chart_id,m_name+"CheckGroup",m_subwin,x1,y1,x2,y2))
return(false);
if(!Add(m_check_group))
return(false);
//--- fill out with strings
for(int i=0;i<5;i++)
if(!m_check_group.AddItem("Item "+IntegerToString(i),1<<i))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickButton1(void)
{
m_edit.Text(__FUNCTION__);
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickButton2(void)
{
m_edit.Text(__FUNCTION__);
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnClickButton3(void)
{
if(m_button3.Pressed())
m_edit.Text(__FUNCTION__+"On");
else
m_edit.Text(__FUNCTION__+"Off");
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeSpinEdit()
{
m_edit.Text(__FUNCTION__+" : Value="+IntegerToString(m_spin_edit.Value()));
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeDate(void)
{
m_edit.Text(__FUNCTION__+" \""+TimeToString(m_date.Value(),TIME_DATE)+"\"");
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeListView(void)
{
m_edit.Text(__FUNCTION__+" \""+m_list_view.Select()+"\"");
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeComboBox(void)
{
m_edit.Text(__FUNCTION__+" \""+m_combo_box.Select()+"\"");
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeRadioGroup(void)
{
m_edit.Text(__FUNCTION__+" : Value="+IntegerToString(m_radio_group.Value()));
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CControlsDialog::OnChangeCheckGroup(void)
{
m_edit.Text(__FUNCTION__+" : Value="+IntegerToString(m_check_group.Value()));
}
//+------------------------------------------------------------------+
+451
View File
@@ -0,0 +1,451 @@
//+------------------------------------------------------------------+
//| MACD Sample.mq5 |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2009-2017, MetaQuotes Software Corp."
#property link "http://www.mql5.com"
#property version "5.50"
#property description "It is important to make sure that the expert works with a normal"
#property description "chart and the user did not make any mistakes setting input"
#property description "variables (Lots, TakeProfit, TrailingStop) in our case,"
#property description "we check TakeProfit on a chart of more than 2*trend_period bars"
#define MACD_MAGIC 1234502
//---
#include <Trade\Trade.mqh>
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\AccountInfo.mqh>
//---
input double InpLots =0.1; // Lots
input int InpTakeProfit =50; // Take Profit (in pips)
input int InpTrailingStop =30; // Trailing Stop Level (in pips)
input int InpMACDOpenLevel =3; // MACD open level (in pips)
input int InpMACDCloseLevel=2; // MACD close level (in pips)
input int InpMATrendPeriod =26; // MA trend period
//---
int ExtTimeOut=10; // time out in seconds between trade operations
//+------------------------------------------------------------------+
//| MACD Sample expert class |
//+------------------------------------------------------------------+
class CSampleExpert
{
protected:
double m_adjusted_point; // point value adjusted for 3 or 5 points
CTrade m_trade; // trading object
CSymbolInfo m_symbol; // symbol info object
CPositionInfo m_position; // trade position object
CAccountInfo m_account; // account info wrapper
//--- indicators
int m_handle_macd; // MACD indicator handle
int m_handle_ema; // moving average indicator handle
//--- indicator buffers
double m_buff_MACD_main[]; // MACD indicator main buffer
double m_buff_MACD_signal[]; // MACD indicator signal buffer
double m_buff_EMA[]; // EMA indicator buffer
//--- indicator data for processing
double m_macd_current;
double m_macd_previous;
double m_signal_current;
double m_signal_previous;
double m_ema_current;
double m_ema_previous;
//---
double m_macd_open_level;
double m_macd_close_level;
double m_traling_stop;
double m_take_profit;
public:
CSampleExpert(void);
~CSampleExpert(void);
bool Init(void);
void Deinit(void);
bool Processing(void);
protected:
bool InitCheckParameters(const int digits_adjust);
bool InitIndicators(void);
bool LongClosed(void);
bool ShortClosed(void);
bool LongModified(void);
bool ShortModified(void);
bool LongOpened(void);
bool ShortOpened(void);
};
//--- global expert
CSampleExpert ExtExpert;
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CSampleExpert::CSampleExpert(void) : m_adjusted_point(0),
m_handle_macd(INVALID_HANDLE),
m_handle_ema(INVALID_HANDLE),
m_macd_current(0),
m_macd_previous(0),
m_signal_current(0),
m_signal_previous(0),
m_ema_current(0),
m_ema_previous(0),
m_macd_open_level(0),
m_macd_close_level(0),
m_traling_stop(0),
m_take_profit(0)
{
ArraySetAsSeries(m_buff_MACD_main,true);
ArraySetAsSeries(m_buff_MACD_signal,true);
ArraySetAsSeries(m_buff_EMA,true);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CSampleExpert::~CSampleExpert(void)
{
}
//+------------------------------------------------------------------+
//| Initialization and checking for input parameters |
//+------------------------------------------------------------------+
bool CSampleExpert::Init(void)
{
//--- initialize common information
m_symbol.Name(Symbol()); // symbol
m_trade.SetExpertMagicNumber(MACD_MAGIC); // magic
m_trade.SetMarginMode();
m_trade.SetTypeFillingBySymbol(Symbol());
//--- tuning for 3 or 5 digits
int digits_adjust=1;
if(m_symbol.Digits()==3 || m_symbol.Digits()==5)
digits_adjust=10;
m_adjusted_point=m_symbol.Point()*digits_adjust;
//--- set default deviation for trading in adjusted points
m_macd_open_level =InpMACDOpenLevel*m_adjusted_point;
m_macd_close_level=InpMACDCloseLevel*m_adjusted_point;
m_traling_stop =InpTrailingStop*m_adjusted_point;
m_take_profit =InpTakeProfit*m_adjusted_point;
//--- set default deviation for trading in adjusted points
m_trade.SetDeviationInPoints(3*digits_adjust);
//---
if(!InitCheckParameters(digits_adjust))
return(false);
if(!InitIndicators())
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Checking for input parameters |
//+------------------------------------------------------------------+
bool CSampleExpert::InitCheckParameters(const int digits_adjust)
{
//--- initial data checks
if(InpTakeProfit*digits_adjust<m_symbol.StopsLevel())
{
printf("Take Profit must be greater than %d",m_symbol.StopsLevel());
return(false);
}
if(InpTrailingStop*digits_adjust<m_symbol.StopsLevel())
{
printf("Trailing Stop must be greater than %d",m_symbol.StopsLevel());
return(false);
}
//--- check for right lots amount
if(InpLots<m_symbol.LotsMin() || InpLots>m_symbol.LotsMax())
{
printf("Lots amount must be in the range from %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax());
return(false);
}
if(MathAbs(InpLots/m_symbol.LotsStep()-MathRound(InpLots/m_symbol.LotsStep()))>1.0E-10)
{
printf("Lots amount is not corresponding with lot step %f",m_symbol.LotsStep());
return(false);
}
//--- warning
if(InpTakeProfit<=InpTrailingStop)
printf("Warning: Trailing Stop must be less than Take Profit");
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Initialization of the indicators |
//+------------------------------------------------------------------+
bool CSampleExpert::InitIndicators(void)
{
//--- create MACD indicator
if(m_handle_macd==INVALID_HANDLE)
if((m_handle_macd=iMACD(NULL,0,12,26,9,PRICE_CLOSE))==INVALID_HANDLE)
{
printf("Error creating MACD indicator");
return(false);
}
//--- create EMA indicator and add it to collection
if(m_handle_ema==INVALID_HANDLE)
if((m_handle_ema=iMA(NULL,0,InpMATrendPeriod,0,MODE_EMA,PRICE_CLOSE))==INVALID_HANDLE)
{
printf("Error creating EMA indicator");
return(false);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Check for long position closing |
//+------------------------------------------------------------------+
bool CSampleExpert::LongClosed(void)
{
bool res=false;
//--- should it be closed?
if(m_macd_current>0)
if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous)
if(m_macd_current>m_macd_close_level)
{
//--- close position
if(m_trade.PositionClose(Symbol()))
printf("Long position by %s to be closed",Symbol());
else
printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment());
//--- processed and cannot be modified
res=true;
}
//--- result
return(res);
}
//+------------------------------------------------------------------+
//| Check for short position closing |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortClosed(void)
{
bool res=false;
//--- should it be closed?
if(m_macd_current<0)
if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous)
if(MathAbs(m_macd_current)>m_macd_close_level)
{
//--- close position
if(m_trade.PositionClose(Symbol()))
printf("Short position by %s to be closed",Symbol());
else
printf("Error closing position by %s : '%s'",Symbol(),m_trade.ResultComment());
//--- processed and cannot be modified
res=true;
}
//--- result
return(res);
}
//+------------------------------------------------------------------+
//| Check for long position modifying |
//+------------------------------------------------------------------+
bool CSampleExpert::LongModified(void)
{
bool res=false;
//--- check for trailing stop
if(InpTrailingStop>0)
{
if(m_symbol.Bid()-m_position.PriceOpen()>m_adjusted_point*InpTrailingStop)
{
double sl=NormalizeDouble(m_symbol.Bid()-m_traling_stop,m_symbol.Digits());
double tp=m_position.TakeProfit();
if(m_position.StopLoss()<sl || m_position.StopLoss()==0.0)
{
//--- modify position
if(m_trade.PositionModify(Symbol(),sl,tp))
printf("Long position by %s to be modified",Symbol());
else
{
printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment());
printf("Modify parameters : SL=%f,TP=%f",sl,tp);
}
//--- modified and must exit from expert
res=true;
}
}
}
//--- result
return(res);
}
//+------------------------------------------------------------------+
//| Check for short position modifying |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortModified(void)
{
bool res=false;
//--- check for trailing stop
if(InpTrailingStop>0)
{
if((m_position.PriceOpen()-m_symbol.Ask())>(m_adjusted_point*InpTrailingStop))
{
double sl=NormalizeDouble(m_symbol.Ask()+m_traling_stop,m_symbol.Digits());
double tp=m_position.TakeProfit();
if(m_position.StopLoss()>sl || m_position.StopLoss()==0.0)
{
//--- modify position
if(m_trade.PositionModify(Symbol(),sl,tp))
printf("Short position by %s to be modified",Symbol());
else
{
printf("Error modifying position by %s : '%s'",Symbol(),m_trade.ResultComment());
printf("Modify parameters : SL=%f,TP=%f",sl,tp);
}
//--- modified and must exit from expert
res=true;
}
}
}
//--- result
return(res);
}
//+------------------------------------------------------------------+
//| Check for long position opening |
//+------------------------------------------------------------------+
bool CSampleExpert::LongOpened(void)
{
bool res=false;
//--- check for long position (BUY) possibility
if(m_macd_current<0)
if(m_macd_current>m_signal_current && m_macd_previous<m_signal_previous)
if(MathAbs(m_macd_current)>(m_macd_open_level) && m_ema_current>m_ema_previous)
{
double price=m_symbol.Ask();
double tp =m_symbol.Bid()+m_take_profit;
//--- check for free money
if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_BUY,InpLots,price)<0.0)
printf("We have no money. Free Margin = %f",m_account.FreeMargin());
else
{
//--- open position
if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_BUY,InpLots,price,0.0,tp))
printf("Position by %s to be opened",Symbol());
else
{
printf("Error opening BUY position by %s : '%s'",Symbol(),m_trade.ResultComment());
printf("Open parameters : price=%f,TP=%f",price,tp);
}
}
//--- in any case we must exit from expert
res=true;
}
//--- result
return(res);
}
//+------------------------------------------------------------------+
//| Check for short position opening |
//+------------------------------------------------------------------+
bool CSampleExpert::ShortOpened(void)
{
bool res=false;
//--- check for short position (SELL) possibility
if(m_macd_current>0)
if(m_macd_current<m_signal_current && m_macd_previous>m_signal_previous)
if(m_macd_current>(m_macd_open_level) && m_ema_current<m_ema_previous)
{
double price=m_symbol.Bid();
double tp =m_symbol.Ask()-m_take_profit;
//--- check for free money
if(m_account.FreeMarginCheck(Symbol(),ORDER_TYPE_SELL,InpLots,price)<0.0)
printf("We have no money. Free Margin = %f",m_account.FreeMargin());
else
{
//--- open position
if(m_trade.PositionOpen(Symbol(),ORDER_TYPE_SELL,InpLots,price,0.0,tp))
printf("Position by %s to be opened",Symbol());
else
{
printf("Error opening SELL position by %s : '%s'",Symbol(),m_trade.ResultComment());
printf("Open parameters : price=%f,TP=%f",price,tp);
}
}
//--- in any case we must exit from expert
res=true;
}
//--- result
return(res);
}
//+------------------------------------------------------------------+
//| main function returns true if any position processed |
//+------------------------------------------------------------------+
bool CSampleExpert::Processing(void)
{
//--- refresh rates
if(!m_symbol.RefreshRates())
return(false);
//--- refresh indicators
if(BarsCalculated(m_handle_macd)<2 || BarsCalculated(m_handle_ema)<2)
return(false);
if(CopyBuffer(m_handle_macd,0,0,2,m_buff_MACD_main) !=2 ||
CopyBuffer(m_handle_macd,1,0,2,m_buff_MACD_signal)!=2 ||
CopyBuffer(m_handle_ema,0,0,2,m_buff_EMA) !=2)
return(false);
// m_indicators.Refresh();
//--- to simplify the coding and speed up access
//--- data are put into internal variables
m_macd_current =m_buff_MACD_main[0];
m_macd_previous =m_buff_MACD_main[1];
m_signal_current =m_buff_MACD_signal[0];
m_signal_previous=m_buff_MACD_signal[1];
m_ema_current =m_buff_EMA[0];
m_ema_previous =m_buff_EMA[1];
//--- it is important to enter the market correctly,
//--- but it is more important to exit it correctly...
//--- first check if position exists - try to select it
if(m_position.Select(Symbol()))
{
if(m_position.PositionType()==POSITION_TYPE_BUY)
{
//--- try to close or modify long position
if(LongClosed())
return(true);
if(LongModified())
return(true);
}
else
{
//--- try to close or modify short position
if(ShortClosed())
return(true);
if(ShortModified())
return(true);
}
}
//--- no opened position identified
else
{
//--- check for long position (BUY) possibility
if(LongOpened())
return(true);
//--- check for short position (SELL) possibility
if(ShortOpened())
return(true);
}
//--- exit without position processing
return(false);
}
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit(void)
{
//--- create all necessary objects
if(!ExtExpert.Init())
return(INIT_FAILED);
//--- secceed
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert new tick handling function |
//+------------------------------------------------------------------+
void OnTick(void)
{
static datetime limit_time=0; // last trade processing time + timeout
//--- don't process if timeout
if(TimeCurrent()>=limit_time)
{
//--- check for data
if(Bars(Symbol(),Period())>2*InpMATrendPeriod)
{
//--- change limit time by timeout in seconds if processed
if(ExtExpert.Processing())
limit_time=TimeCurrent()+ExtTimeOut;
}
}
}
//+------------------------------------------------------------------+
@@ -0,0 +1,233 @@
//+------------------------------------------------------------------+
//| Moving Averages.mq5 |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2009-2017, MetaQuotes Software Corp."
#property link "http://www.mql5.com"
#property version "1.00"
#include <Trade\Trade.mqh>
input double MaximumRisk = 0.02; // Maximum Risk in percentage
input double DecreaseFactor = 3; // Descrease factor
input int MovingPeriod = 12; // Moving Average period
input int MovingShift = 6; // Moving Average shift
//---
int ExtHandle=0;
bool ExtHedging=false;
CTrade ExtTrade;
#define MA_MAGIC 1234501
//+------------------------------------------------------------------+
//| Calculate optimal lot size |
//+------------------------------------------------------------------+
double TradeSizeOptimized(void)
{
double price=0.0;
double margin=0.0;
//--- select lot size
if(!SymbolInfoDouble(_Symbol,SYMBOL_ASK,price))
return(0.0);
if(!OrderCalcMargin(ORDER_TYPE_BUY,_Symbol,1.0,price,margin))
return(0.0);
if(margin<=0.0)
return(0.0);
double lot=NormalizeDouble(AccountInfoDouble(ACCOUNT_MARGIN_FREE)*MaximumRisk/margin,2);
//--- calculate number of losses orders without a break
if(DecreaseFactor>0)
{
//--- select history for access
HistorySelect(0,TimeCurrent());
//---
int orders=HistoryDealsTotal(); // total history deals
int losses=0; // number of losses orders without a break
for(int i=orders-1;i>=0;i--)
{
ulong ticket=HistoryDealGetTicket(i);
if(ticket==0)
{
Print("HistoryDealGetTicket failed, no trade history");
break;
}
//--- check symbol
if(HistoryDealGetString(ticket,DEAL_SYMBOL)!=_Symbol)
continue;
//--- check Expert Magic number
if(HistoryDealGetInteger(ticket,DEAL_MAGIC)!=MA_MAGIC)
continue;
//--- check profit
double profit=HistoryDealGetDouble(ticket,DEAL_PROFIT);
if(profit>0.0)
break;
if(profit<0.0)
losses++;
}
//---
if(losses>1)
lot=NormalizeDouble(lot-lot*losses/DecreaseFactor,1);
}
//--- normalize and check limits
double stepvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_STEP);
lot=stepvol*NormalizeDouble(lot/stepvol,0);
double minvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MIN);
if(lot<minvol)
lot=minvol;
double maxvol=SymbolInfoDouble(_Symbol,SYMBOL_VOLUME_MAX);
if(lot>maxvol)
lot=maxvol;
//--- return trading volume
return(lot);
}
//+------------------------------------------------------------------+
//| Check for open position conditions |
//+------------------------------------------------------------------+
void CheckForOpen(void)
{
MqlRates rt[2];
//--- go trading only for first ticks of new bar
if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
{
Print("CopyRates of ",_Symbol," failed, no history");
return;
}
if(rt[1].tick_volume>1)
return;
//--- get current Moving Average
double ma[1];
if(CopyBuffer(ExtHandle,0,0,1,ma)!=1)
{
Print("CopyBuffer from iMA failed, no data");
return;
}
//--- check signals
ENUM_ORDER_TYPE signal=WRONG_VALUE;
if(rt[0].open>ma[0] && rt[0].close<ma[0])
signal=ORDER_TYPE_SELL; // sell conditions
else
{
if(rt[0].open<ma[0] && rt[0].close>ma[0])
signal=ORDER_TYPE_BUY; // buy conditions
}
//--- additional checking
if(signal!=WRONG_VALUE)
{
if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>100)
ExtTrade.PositionOpen(_Symbol,signal,TradeSizeOptimized(),
SymbolInfoDouble(_Symbol,signal==ORDER_TYPE_SELL ? SYMBOL_BID:SYMBOL_ASK),
0,0);
}
//---
}
//+------------------------------------------------------------------+
//| Check for close position conditions |
//+------------------------------------------------------------------+
void CheckForClose(void)
{
MqlRates rt[2];
//--- go trading only for first ticks of new bar
if(CopyRates(_Symbol,_Period,0,2,rt)!=2)
{
Print("CopyRates of ",_Symbol," failed, no history");
return;
}
if(rt[1].tick_volume>1)
return;
//--- get current Moving Average
double ma[1];
if(CopyBuffer(ExtHandle,0,0,1,ma)!=1)
{
Print("CopyBuffer from iMA failed, no data");
return;
}
//--- positions already selected before
bool signal=false;
long type=PositionGetInteger(POSITION_TYPE);
if(type==(long)POSITION_TYPE_BUY && rt[0].open>ma[0] && rt[0].close<ma[0])
signal=true;
if(type==(long)POSITION_TYPE_SELL && rt[0].open<ma[0] && rt[0].close>ma[0])
signal=true;
//--- additional checking
if(signal)
{
if(TerminalInfoInteger(TERMINAL_TRADE_ALLOWED) && Bars(_Symbol,_Period)>100)
ExtTrade.PositionClose(_Symbol,3);
}
//---
}
//+------------------------------------------------------------------+
//| Position select depending on netting or hedging |
//+------------------------------------------------------------------+
bool SelectPosition()
{
bool res=false;
//--- check position in Hedging mode
if(ExtHedging)
{
uint total=PositionsTotal();
for(uint i=0; i<total; i++)
{
string position_symbol=PositionGetSymbol(i);
if(_Symbol==position_symbol && MA_MAGIC==PositionGetInteger(POSITION_MAGIC))
{
res=true;
break;
}
}
}
//--- check position in Netting mode
else
{
if(!PositionSelect(_Symbol))
return(false);
else
return(PositionGetInteger(POSITION_MAGIC)==MA_MAGIC); //---check Magic number
}
//--- result for Hedging mode
return(res);
}
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit(void)
{
//--- prepare trade class to control positions if hedging mode is active
ExtHedging=((ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE)==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING);
ExtTrade.SetExpertMagicNumber(MA_MAGIC);
ExtTrade.SetMarginMode();
ExtTrade.SetTypeFillingBySymbol(Symbol());
//--- Moving Average indicator
ExtHandle=iMA(_Symbol,_Period,MovingPeriod,MovingShift,MODE_SMA,PRICE_CLOSE);
if(ExtHandle==INVALID_HANDLE)
{
printf("Error creating MA indicator");
return(INIT_FAILED);
}
//--- ok
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick(void)
{
//---
if(SelectPosition())
CheckForClose();
else
CheckForOpen();
//---
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
}
//+------------------------------------------------------------------+
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

+182
View File
@@ -0,0 +1,182 @@
//+------------------------------------------------------------------+
//| Array.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include <Object.mqh>
//+------------------------------------------------------------------+
//| Class CArray |
//| Purpose: Base class of dynamic arrays. |
//| Derives from class CObject. |
//+------------------------------------------------------------------+
class CArray : public CObject
{
protected:
int m_step_resize; // increment size of the array
int m_data_total; // number of elements
int m_data_max; // maximmum size of the array without memory reallocation
int m_sort_mode; // mode of array sorting
public:
CArray(void);
~CArray(void);
//--- methods of access to protected data
int Step(void) const { return(m_step_resize); }
bool Step(const int step);
int Total(void) const { return(m_data_total); }
int Available(void) const { return(m_data_max-m_data_total); }
int Max(void) const { return(m_data_max); }
bool IsSorted(const int mode=0) const { return(m_sort_mode==mode); }
int SortMode(void) const { return(m_sort_mode); }
//--- cleaning method
void Clear(void) { m_data_total=0; }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
//--- sorting method
void Sort(const int mode=0);
protected:
virtual void QuickSort(int beg,int end,const int mode=0) { m_sort_mode=-1; }
//--- templates for methods of searching for minimum and maximum
template<typename T>
int Minimum(const T &data[],const int start,const int count) const;
template<typename T>
int Maximum(const T &data[],const int start,const int count) const;
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CArray::CArray(void) : m_step_resize(16),
m_data_total(0),
m_data_max(0),
m_sort_mode(-1)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CArray::~CArray(void)
{
}
//+------------------------------------------------------------------+
//| Method Set for variable m_step_resize |
//+------------------------------------------------------------------+
bool CArray::Step(const int step)
{
//--- check
if(step>0)
{
m_step_resize=step;
return(true);
}
//--- failure
return(false);
}
//+------------------------------------------------------------------+
//| Sorting an array in ascending order |
//+------------------------------------------------------------------+
void CArray::Sort(const int mode)
{
//--- check
if(IsSorted(mode))
return;
m_sort_mode=mode;
if(m_data_total<=1)
return;
//--- sort
QuickSort(0,m_data_total-1,mode);
}
//+------------------------------------------------------------------+
//| Writing header of array to file |
//+------------------------------------------------------------------+
bool CArray::Save(const int file_handle)
{
//--- check handle
if(file_handle!=INVALID_HANDLE)
{
//--- write start marker - 0xFFFFFFFFFFFFFFFF
if(FileWriteLong(file_handle,-1)==sizeof(long))
{
//--- write array type
if(FileWriteInteger(file_handle,Type(),INT_VALUE)==INT_VALUE)
return(true);
}
}
//--- failure
return(false);
}
//+------------------------------------------------------------------+
//| Reading header of array from file |
//+------------------------------------------------------------------+
bool CArray::Load(const int file_handle)
{
//--- check handle
if(file_handle!=INVALID_HANDLE)
{
//--- read and check start marker - 0xFFFFFFFFFFFFFFFF
if(FileReadLong(file_handle)==-1)
{
//--- read and check array type
if(FileReadInteger(file_handle,INT_VALUE)==Type())
return(true);
}
}
//--- failure
return(false);
}
//+------------------------------------------------------------------+
//| Find minimum of array |
//+------------------------------------------------------------------+
template<typename T>
int CArray::Minimum(const T &data[],const int start,const int count) const
{
int real_count;
//--- check for empty array
if(m_data_total<1)
{
SetUserError(ERR_USER_ARRAY_IS_EMPTY);
return(-1);
}
//--- check for start is out of range
if(start<0 || start>=m_data_total)
{
SetUserError(ERR_USER_ITEM_NOT_FOUND);
return(-1);
}
//--- compute count of elements
real_count=(count==WHOLE_ARRAY || start+count>m_data_total) ? m_data_total-start : count;
#ifdef __MQL5__
return(ArrayMinimum(data,start,real_count));
#else
return(ArrayMinimum(data,real_count,start));
#endif
}
//+------------------------------------------------------------------+
//| Find maximum of array |
//+------------------------------------------------------------------+
template<typename T>
int CArray::Maximum(const T &data[],const int start,const int count) const
{
int real_count;
//--- check for empty array
if(m_data_total<1)
{
SetUserError(ERR_USER_ARRAY_IS_EMPTY);
return(-1);
}
//--- check for start is out of range
if(start<0 || start>=m_data_total)
{
SetUserError(ERR_USER_ITEM_NOT_FOUND);
return(-1);
}
//--- compute count of elements
real_count=(count==WHOLE_ARRAY || start+count>m_data_total) ? m_data_total-start : count;
#ifdef __MQL5__
return(ArrayMaximum(data,start,real_count));
#else
return(ArrayMaximum(data,real_count,start));
#endif
}
//+------------------------------------------------------------------+
+771
View File
@@ -0,0 +1,771 @@
//+------------------------------------------------------------------+
//| ArrayChar.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "Array.mqh"
//+------------------------------------------------------------------+
//| Class CArrayChar. |
//| Purpose: Class of dynamic array of variables |
//| of char or uchar type. |
//| Derives from class CArray. |
//+------------------------------------------------------------------+
class CArrayChar : public CArray
{
protected:
char m_data[]; // data array
public:
CArrayChar(void);
~CArrayChar(void);
//--- method of identifying the object
virtual int Type(void) const { return(TYPE_CHAR); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
//--- methods of managing dynamic memory
bool Reserve(const int size);
bool Resize(const int size);
bool Shutdown(void);
//--- methods of filling the array
bool Add(const char element);
bool AddArray(const char &src[]);
bool AddArray(const CArrayChar *src);
bool Insert(const char element,const int pos);
bool InsertArray(const char &src[],const int pos);
bool InsertArray(const CArrayChar *src,const int pos);
bool AssignArray(const char &src[]);
bool AssignArray(const CArrayChar *src);
//--- method of access to the array
char At(const int index) const;
char operator[](const int index) const { return(At(index)); }
//--- methods of searching for minimum and maximum
int Minimum(const int start,const int count) const { return(Minimum(m_data,start,count)); }
int Maximum(const int start,const int count) const { return(Maximum(m_data,start,count)); }
//--- methods of changing
bool Update(const int index,const char element);
bool Shift(const int index,const int shift);
//--- methods of deleting
bool Delete(const int index);
bool DeleteRange(int from,int to);
//--- methods for comparing arrays
bool CompareArray(const char &array[]) const;
bool CompareArray(const CArrayChar *array) const;
//--- methods for working with the sorted array
bool InsertSort(const char element);
int Search(const char element) const;
int SearchGreat(const char element) const;
int SearchLess(const char element) const;
int SearchGreatOrEqual(const char element) const;
int SearchLessOrEqual(const char element) const;
int SearchFirst(const char element) const;
int SearchLast(const char element) const;
int SearchLinear(const char element) const;
protected:
virtual void QuickSort(int beg,int end,const int mode=0);
int QuickSearch(const char element) const;
int MemMove(const int dest,const int src,int count);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CArrayChar::CArrayChar(void)
{
//--- initialize protected data
m_data_max=ArraySize(m_data);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CArrayChar::~CArrayChar(void)
{
if(m_data_max!=0)
Shutdown();
}
//+------------------------------------------------------------------+
//| Moving the memory within a single array |
//+------------------------------------------------------------------+
int CArrayChar::MemMove(const int dest,const int src,int count)
{
int i;
//--- check parameters
if(dest<0 || src<0 || count<0)
return(-1);
//--- check count
if(src+count>m_data_total)
count=m_data_total-src;
if(count<0)
return(-1);
//--- no need to copy
if(dest==src || count==0)
return(dest);
//--- check data total
if(dest+count>m_data_total)
{
if(m_data_max<dest+count)
return(-1);
m_data_total=dest+count;
}
//--- copy
if(dest<src)
{
//--- copy from left to right
for(i=0;i<count;i++)
m_data[dest+i]=m_data[src+i];
}
else
{
//--- copy from right to left
for(i=count-1;i>=0;i--)
m_data[dest+i]=m_data[src+i];
}
//--- successful
return(dest);
}
//+------------------------------------------------------------------+
//| Request for more memory in an array. Checks if the requested |
//| number of free elements already exists; allocates additional |
//| memory with a given step |
//+------------------------------------------------------------------+
bool CArrayChar::Reserve(const int size)
{
int new_size;
//--- check
if(size<=0)
return(false);
//--- resize array
if(Available()<size)
{
new_size=m_data_max+m_step_resize*(1+(size-Available())/m_step_resize);
if(new_size<0)
//--- overflow occurred when calculating new_size
return(false);
if((m_data_max=ArrayResize(m_data,new_size))==-1)
m_data_max=ArraySize(m_data);
}
//--- result
return(Available()>=size);
}
//+------------------------------------------------------------------+
//| Resizing (with removal of elements on the right) |
//+------------------------------------------------------------------+
bool CArrayChar::Resize(const int size)
{
int new_size;
//--- check
if(size<0)
return(false);
//--- resize array
new_size=m_step_resize*(1+size/m_step_resize);
if(m_data_max!=new_size)
{
if((m_data_max=ArrayResize(m_data,new_size))==-1)
{
m_data_max=ArraySize(m_data);
return(false);
}
}
if(m_data_total>size)
m_data_total=size;
//--- result
return(m_data_max==new_size);
}
//+------------------------------------------------------------------+
//| Complete cleaning of the array with the release of memory |
//+------------------------------------------------------------------+
bool CArrayChar::Shutdown(void)
{
//--- check
if(m_data_max==0)
return(true);
//--- clean
if(ArrayResize(m_data,0)==-1)
return(false);
m_data_total=0;
m_data_max=0;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array |
//+------------------------------------------------------------------+
bool CArrayChar::Add(const char element)
{
//--- check/reserve elements of array
if(!Reserve(1))
return(false);
//--- add
m_data[m_data_total++]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array from another array |
//+------------------------------------------------------------------+
bool CArrayChar::AddArray(const char &src[])
{
int num=ArraySize(src);
//--- check/reserve elements of array
if(!Reserve(num))
return(false);
//--- add
for(int i=0;i<num;i++)
m_data[m_data_total++]=src[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array from another array |
//+------------------------------------------------------------------+
bool CArrayChar::AddArray(const CArrayChar *src)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.Total();
if(!Reserve(num))
return(false);
//--- add
for(int i=0;i<num;i++)
m_data[m_data_total++]=src.m_data[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting an element in the specified position |
//+------------------------------------------------------------------+
bool CArrayChar::Insert(const char element,const int pos)
{
//--- check/reserve elements of array
if(pos<0 || !Reserve(1))
return(false);
//--- insert
m_data_total++;
if(pos<m_data_total-1)
{
if(MemMove(pos+1,pos,m_data_total-pos-1)<0)
return(false);
m_data[pos]=element;
}
else
m_data[m_data_total-1]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting elements in the specified position |
//+------------------------------------------------------------------+
bool CArrayChar::InsertArray(const char &src[],const int pos)
{
int num=ArraySize(src);
//--- check/reserve elements of array
if(!Reserve(num))
return(false);
//--- insert
if(MemMove(num+pos,pos,m_data_total-pos)<0)
return(false);
for(int i=0;i<num;i++)
m_data[i+pos]=src[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting elements in the specified position |
//+------------------------------------------------------------------+
bool CArrayChar::InsertArray(const CArrayChar *src,const int pos)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.Total();
if(!Reserve(num))
return(false);
//--- insert
if(MemMove(num+pos,pos,m_data_total-pos)<0)
return(false);
for(int i=0;i<num;i++)
m_data[i+pos]=src.m_data[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Assignment (copying) of another array |
//+------------------------------------------------------------------+
bool CArrayChar::AssignArray(const char &src[])
{
int num=ArraySize(src);
//--- check/reserve elements of array
Clear();
if(m_data_max<num)
{
if(!Reserve(num))
return(false);
}
else
Resize(num);
//--- copy array
for(int i=0;i<num;i++)
{
m_data[i]=src[i];
m_data_total++;
}
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Assignment (copying) of another array |
//+------------------------------------------------------------------+
bool CArrayChar::AssignArray(const CArrayChar *src)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.m_data_total;
Clear();
if(m_data_max<num)
{
if(!Reserve(num))
return(false);
}
else
Resize(num);
//--- copy array
for(int i=0;i<num;i++)
{
m_data[i]=src.m_data[i];
m_data_total++;
}
m_sort_mode=src.SortMode();
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Access to data in the specified position |
//+------------------------------------------------------------------+
char CArrayChar::At(const int index) const
{
//--- check
if(index<0 || index>=m_data_total)
return(CHAR_MAX);
//--- result
return(m_data[index]);
}
//+------------------------------------------------------------------+
//| Updating element in the specified position |
//+------------------------------------------------------------------+
bool CArrayChar::Update(const int index,const char element)
{
//--- check
if(index<0 || index>=m_data_total)
return(false);
//--- update
m_data[index]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Moving element from the specified position |
//| on the specified shift |
//+------------------------------------------------------------------+
bool CArrayChar::Shift(const int index,const int shift)
{
char tmp_char;
//--- check
if(index<0 || index+shift<0 || index+shift>=m_data_total)
return(false);
if(shift==0)
return(true);
//--- move
tmp_char=m_data[index];
if(shift>0)
{
if(MemMove(index,index+1,shift)<0)
return(false);
}
else
{
if(MemMove(index+shift+1,index+shift,-shift)<0)
return(false);
}
m_data[index+shift]=tmp_char;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Deleting element from the specified position |
//+------------------------------------------------------------------+
bool CArrayChar::Delete(const int index)
{
//--- check
if(index<0 || index>=m_data_total)
return(false);
//--- delete
if(index<m_data_total-1 && MemMove(index,index+1,m_data_total-index-1)<0)
return(false);
m_data_total--;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Deleting range of elements |
//+------------------------------------------------------------------+
bool CArrayChar::DeleteRange(int from,int to)
{
//--- check
if(from<0 || to<0)
return(false);
if(from>to || from>=m_data_total)
return(false);
//--- delete
if(to>=m_data_total-1)
to=m_data_total-1;
if(MemMove(from,to+1,m_data_total-to-1)<0)
return(false);
m_data_total-=to-from+1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Equality comparison of two arrays |
//+------------------------------------------------------------------+
bool CArrayChar::CompareArray(const char &array[]) const
{
//--- compare
if(m_data_total!=ArraySize(array))
return(false);
for(int i=0;i<m_data_total;i++)
if(m_data[i]!=array[i])
return(false);
//--- equal
return(true);
}
//+------------------------------------------------------------------+
//| Equality comparison of two arrays |
//+------------------------------------------------------------------+
bool CArrayChar::CompareArray(const CArrayChar *array) const
{
//--- check
if(!CheckPointer(array))
return(false);
//--- compare
if(m_data_total!=array.m_data_total)
return(false);
for(int i=0;i<m_data_total;i++)
if(m_data[i]!=array.m_data[i])
return(false);
//--- equal
return(true);
}
//+------------------------------------------------------------------+
//| Method QuickSort |
//+------------------------------------------------------------------+
void CArrayChar::QuickSort(int beg,int end,const int mode)
{
int i,j;
char p_char;
char t_char;
//--- check
if(beg<0 || end<0)
return;
//--- sort
i=beg;
j=end;
while(i<end)
{
//--- ">>1" is quick division by 2
p_char=m_data[(beg+end)>>1];
while(i<j)
{
while(m_data[i]<p_char)
{
//--- control the output of the array bounds
if(i==m_data_total-1)
break;
i++;
}
while(m_data[j]>p_char)
{
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
if(i<=j)
{
t_char=m_data[i];
m_data[i++]=m_data[j];
m_data[j]=t_char;
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
}
if(beg<j)
QuickSort(beg,j);
beg=i;
j=end;
}
}
//+------------------------------------------------------------------+
//| Inserting element in a sorted array |
//+------------------------------------------------------------------+
bool CArrayChar::InsertSort(const char element)
{
int pos;
//--- check
if(!IsSorted())
return(false);
//--- check/reserve elements of array
if(!Reserve(1))
return(false);
//--- if the array is empty, add an element
if(m_data_total==0)
{
m_data[m_data_total++]=element;
return(true);
}
//--- find position and insert
pos=QuickSearch(element);
if(m_data[pos]>element)
Insert(element,pos);
else
Insert(element,pos+1);
//--- restore the sorting flag after Insert(...)
m_sort_mode=0;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Search of position of element in a array |
//+------------------------------------------------------------------+
int CArrayChar::SearchLinear(const char element) const
{
//--- check
if(m_data_total==0)
return(-1);
//---
for(int i=0;i<m_data_total;i++)
if(m_data[i]==element)
return(i);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Quick search of position of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayChar::QuickSearch(const char element) const
{
int i,j,m=-1;
char t_char;
//--- search
i=0;
j=m_data_total-1;
while(j>=i)
{
//--- ">>1" is quick division by 2
m=(j+i)>>1;
if(m<0 || m>=m_data_total)
break;
t_char=m_data[m];
if(t_char==element)
break;
if(t_char>element)
j=m-1;
else
i=m+1;
}
//--- position
return(m);
}
//+------------------------------------------------------------------+
//| Search of position of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayChar::Search(const char element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is greater than |
//| specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayChar::SearchGreat(const char element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
while(m_data[pos]<=element)
if(++pos==m_data_total)
return(-1);
//--- position
return(pos);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is less than |
//| specified in the sorted array |
//+------------------------------------------------------------------+
int CArrayChar::SearchLess(const char element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
while(m_data[pos]>=element)
if(pos--==0)
return(-1);
//--- position
return(pos);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is greater than or |
//| equal to the specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayChar::SearchGreatOrEqual(const char element) const
{
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
for(int pos=QuickSearch(element);pos<m_data_total;pos++)
if(m_data[pos]>=element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is less than or equal |
//| to the specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayChar::SearchLessOrEqual(const char element) const
{
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
for(int pos=QuickSearch(element);pos>=0;pos--)
if(m_data[pos]<=element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Find position of first appearance of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayChar::SearchFirst(const char element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
{
while(m_data[pos]==element)
if(pos--==0)
break;
return(pos+1);
}
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Find position of last appearance of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayChar::SearchLast(const char element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
{
while(m_data[pos]==element)
if(++pos==m_data_total)
break;
return(pos-1);
}
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Writing array to file |
//+------------------------------------------------------------------+
bool CArrayChar::Save(const int file_handle)
{
int i=0;
//--- check
if(!CArray::Save(file_handle))
return(false);
//--- write array length
if(FileWriteInteger(file_handle,m_data_total,INT_VALUE)!=INT_VALUE)
return(false);
//--- write array
for(i=0;i<m_data_total;i++)
if(FileWriteInteger(file_handle,m_data[i],CHAR_VALUE)!=CHAR_VALUE)
break;
//--- result
return(i==m_data_total);
}
//+------------------------------------------------------------------+
//| Reading array from file |
//+------------------------------------------------------------------+
bool CArrayChar::Load(const int file_handle)
{
int i,num;
//--- check
if(!CArray::Load(file_handle))
return(false);
//--- read array length
num=FileReadInteger(file_handle,INT_VALUE);
//--- read array
Clear();
if(num!=0)
{
if(!Reserve(num))
return(false);
for(i=0;i<num;i++)
{
m_data[i]=(char)FileReadInteger(file_handle,CHAR_VALUE);
m_data_total++;
if(FileIsEnding(file_handle))
break;
}
}
m_sort_mode=-1;
//--- result
return(m_data_total==num);
}
//+------------------------------------------------------------------+
+777
View File
@@ -0,0 +1,777 @@
//+------------------------------------------------------------------+
//| ArrayDouble.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "Array.mqh"
//+------------------------------------------------------------------+
//| Class CArrayDouble. |
//| Puprpose: Class of dynamic array variables of double type. |
//| Derives from class CArray. |
//+------------------------------------------------------------------+
class CArrayDouble : public CArray
{
protected:
double m_data[]; // data array
double m_delta; // search tolerance
public:
CArrayDouble(void);
~CArrayDouble(void);
//--- methods of access to protected data
void Delta(const double delta) { m_delta=MathAbs(delta); }
//--- method of identifying the object
virtual int Type(void) const { return(TYPE_DOUBLE); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
//--- methods of managing dynamic memory
bool Reserve(const int size);
bool Resize(const int size);
bool Shutdown(void);
//--- methods of filling the array
bool Add(const double element);
bool AddArray(const double &src[]);
bool AddArray(const CArrayDouble *src);
bool Insert(const double element,const int pos);
bool InsertArray(const double &src[],const int pos);
bool InsertArray(const CArrayDouble *src,const int pos);
bool AssignArray(const double &src[]);
bool AssignArray(const CArrayDouble *src);
//--- method of access to the array
double At(const int index) const;
double operator[](const int index) const { return(At(index)); }
//--- methods of searching for minimum and maximum
int Minimum(const int start,const int count) const { return(Minimum(m_data,start,count)); }
int Maximum(const int start,const int count) const { return(Maximum(m_data,start,count)); }
//--- methods of changing
bool Update(const int index,const double element);
bool Shift(const int index,const int shift);
//--- methods of deleting
bool Delete(const int index);
bool DeleteRange(int from,int to);
//--- methods for comparing arrays
bool CompareArray(const double &array[]) const;
bool CompareArray(const CArrayDouble *array) const;
//--- methods for working with a sorted array
bool InsertSort(const double element);
int Search(const double element) const;
int SearchGreat(const double element) const;
int SearchLess(const double element) const;
int SearchGreatOrEqual(const double element) const;
int SearchLessOrEqual(const double element) const;
int SearchFirst(const double element) const;
int SearchLast(const double element) const;
int SearchLinear(const double element) const;
protected:
virtual void QuickSort(int beg,int end,const int mode=0);
int QuickSearch(const double element) const;
int MemMove(const int dest,const int src,int count);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CArrayDouble::CArrayDouble(void) : m_delta(0.0)
{
m_data_max=ArraySize(m_data);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CArrayDouble::~CArrayDouble(void)
{
if(m_data_max!=0)
Shutdown();
}
//+------------------------------------------------------------------+
//| Moving the memory within a single array |
//+------------------------------------------------------------------+
int CArrayDouble::MemMove(const int dest,const int src,int count)
{
int i;
//--- check parameters
if(dest<0 || src<0 || count<0)
return(-1);
//--- check count
if(src+count>m_data_total)
count=m_data_total-src;
if(count<0)
return(-1);
//--- no need to copy
if(dest==src || count==0)
return(dest);
//--- check data total
if(dest+count>m_data_total)
{
if(m_data_max<dest+count)
return(-1);
m_data_total=dest+count;
}
//--- copy
if(dest<src)
{
//--- copy from left to right
for(i=0;i<count;i++)
m_data[dest+i]=m_data[src+i];
}
else
{
//--- copy from right to left
for(i=count-1;i>=0;i--)
m_data[dest+i]=m_data[src+i];
}
//--- successful
return(dest);
}
//+------------------------------------------------------------------+
//| Request for more memory in an array. Checks if the requested |
//| number of free elements already exists; allocates additional |
//| memory with a given step |
//+------------------------------------------------------------------+
bool CArrayDouble::Reserve(const int size)
{
int new_size;
//--- check
if(size<=0)
return(false);
//--- resize array
if(Available()<size)
{
new_size=m_data_max+m_step_resize*(1+(size-Available())/m_step_resize);
if(new_size<0)
//--- overflow occurred when calculating new_size
return(false);
if((m_data_max=ArrayResize(m_data,new_size))==-1)
m_data_max=ArraySize(m_data);
}
//--- result
return(Available()>=size);
}
//+------------------------------------------------------------------+
//| Resizing (with removal of elements on the right) |
//+------------------------------------------------------------------+
bool CArrayDouble::Resize(const int size)
{
int new_size;
//--- check
if(size<0)
return(false);
//--- resize array
new_size=m_step_resize*(1+size/m_step_resize);
if(m_data_max!=new_size)
{
if((m_data_max=ArrayResize(m_data,new_size))==-1)
{
m_data_max=ArraySize(m_data);
return(false);
}
}
if(m_data_total>size)
m_data_total=size;
//--- result
return(m_data_max==new_size);
}
//+------------------------------------------------------------------+
//| Complete cleaning of the array with the release of memory |
//+------------------------------------------------------------------+
bool CArrayDouble::Shutdown(void)
{
//--- check
if(m_data_max==0)
return(true);
//--- clean
if(ArrayResize(m_data,0)==-1)
return(false);
m_data_total=0;
m_data_max=0;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array |
//+------------------------------------------------------------------+
bool CArrayDouble::Add(const double element)
{
//--- check/reserve elements of array
if(!Reserve(1))
return(false);
//--- add
m_data[m_data_total++]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array from another array |
//+------------------------------------------------------------------+
bool CArrayDouble::AddArray(const double &src[])
{
int num=ArraySize(src);
//--- check/reserve elements of array
if(!Reserve(num))
return(false);
//--- add
for(int i=0;i<num;i++)
m_data[m_data_total++]=src[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array from another array |
//+------------------------------------------------------------------+
bool CArrayDouble::AddArray(const CArrayDouble *src)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.Total();
if(!Reserve(num))
return(false);
//--- add
for(int i=0;i<num;i++)
m_data[m_data_total++]=src.m_data[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting an element in the specified position |
//+------------------------------------------------------------------+
bool CArrayDouble::Insert(const double element,const int pos)
{
//--- check/reserve elements of array
if(pos<0 || !Reserve(1))
return(false);
//--- insert
m_data_total++;
if(pos<m_data_total-1)
{
if(MemMove(pos+1,pos,m_data_total-pos-1)<0)
return(false);
m_data[pos]=element;
}
else
m_data[m_data_total-1]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting elements in the specified position |
//+------------------------------------------------------------------+
bool CArrayDouble::InsertArray(const double &src[],const int pos)
{
int num=ArraySize(src);
//--- check/reserve elements of array
if(!Reserve(num))
return(false);
//--- insert
if(MemMove(num+pos,pos,m_data_total-pos)<0)
return(false);
for(int i=0;i<num;i++)
m_data[i+pos]=src[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting elements in the specified position |
//+------------------------------------------------------------------+
bool CArrayDouble::InsertArray(const CArrayDouble *src,const int pos)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.Total();
if(!Reserve(num))
return(false);
//--- insert
if(MemMove(num+pos,pos,m_data_total-pos)<0)
return(false);
for(int i=0;i<num;i++)
m_data[i+pos]=src.m_data[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Assignment (copying) of another array |
//+------------------------------------------------------------------+
bool CArrayDouble::AssignArray(const double &src[])
{
int num=ArraySize(src);
//--- check/reserve elements of array
Clear();
if(m_data_max<num)
{
if(!Reserve(num))
return(false);
}
else
Resize(num);
//--- copy array
for(int i=0;i<num;i++)
{
m_data[i]=src[i];
m_data_total++;
}
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Assignment (copying) of another array |
//+------------------------------------------------------------------+
bool CArrayDouble::AssignArray(const CArrayDouble *src)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.m_data_total;
Clear();
if(m_data_max<num)
{
if(!Reserve(num))
return(false);
}
else
Resize(num);
//--- copy array
for(int i=0;i<num;i++)
{
m_data[i]=src.m_data[i];
m_data_total++;
}
m_sort_mode=src.SortMode();
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Access to data in the specified position |
//+------------------------------------------------------------------+
double CArrayDouble::At(const int index) const
{
//--- check
if(index<0 || index>=m_data_total)
return(DBL_MAX);
//--- result
return(m_data[index]);
}
//+------------------------------------------------------------------+
//| Updating element in the specified position |
//+------------------------------------------------------------------+
bool CArrayDouble::Update(const int index,const double element)
{
//--- check
if(index<0 || index>=m_data_total)
return(false);
//--- update
m_data[index]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Moving element from the specified position |
//| on the specified shift |
//+------------------------------------------------------------------+
bool CArrayDouble::Shift(const int index,const int shift)
{
double tmp_double;
//--- check
if(index<0 || index+shift<0 || index+shift>=m_data_total)
return(false);
if(shift==0)
return(true);
//--- move
tmp_double=m_data[index];
if(shift>0)
{
if(MemMove(index,index+1,shift)<0)
return(false);
}
else
{
if(MemMove(index+shift+1,index+shift,-shift)<0)
return(false);
}
m_data[index+shift]=tmp_double;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Deleting element from the specified position |
//+------------------------------------------------------------------+
bool CArrayDouble::Delete(const int index)
{
//--- check
if(index<0 || index>=m_data_total)
return(false);
//--- delete
if(index<m_data_total-1 && MemMove(index,index+1,m_data_total-index-1)<0)
return(false);
m_data_total--;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Deleting range of elements |
//+------------------------------------------------------------------+
bool CArrayDouble::DeleteRange(int from,int to)
{
//--- check
if(from<0 || to<0)
return(false);
if(from>to || from>=m_data_total)
return(false);
//--- delete
if(to>=m_data_total-1)
to=m_data_total-1;
if(MemMove(from,to+1,m_data_total-to-1)<0)
return(false);
m_data_total-=to-from+1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Equality comparison of two arrays |
//+------------------------------------------------------------------+
bool CArrayDouble::CompareArray(const double &array[]) const
{
//--- compare
if(m_data_total!=ArraySize(array))
return(false);
for(int i=0;i<m_data_total;i++)
if(m_data[i]!=array[i])
return(false);
//--- equal
return(true);
}
//+------------------------------------------------------------------+
//| Equality comparison of two arrays |
//+------------------------------------------------------------------+
bool CArrayDouble::CompareArray(const CArrayDouble *array) const
{
//--- check
if(!CheckPointer(array))
return(false);
//--- compare
if(m_data_total!=array.m_data_total)
return(false);
for(int i=0;i<m_data_total;i++)
if(m_data[i]!=array.m_data[i])
return(false);
//--- equal
return(true);
}
//+------------------------------------------------------------------+
//| Method QuickSort |
//+------------------------------------------------------------------+
void CArrayDouble::QuickSort(int beg,int end,const int mode)
{
int i,j;
double p_double,t_double;
//--- check
if(beg<0 || end<0)
return;
//--- sort
i=beg;
j=end;
while(i<end)
{
//--- ">>1" is quick division by 2
p_double=m_data[(beg+end)>>1];
while(i<j)
{
while(m_data[i]<p_double)
{
//--- control the output of the array bounds
if(i==m_data_total-1)
break;
i++;
}
while(m_data[j]>p_double)
{
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
if(i<=j)
{
t_double=m_data[i];
m_data[i++]=m_data[j];
m_data[j]=t_double;
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
}
if(beg<j)
QuickSort(beg,j);
beg=i;
j=end;
}
}
//+------------------------------------------------------------------+
//| Inserting element in a sorted array |
//+------------------------------------------------------------------+
bool CArrayDouble::InsertSort(const double element)
{
int pos;
//--- check
if(!IsSorted())
return(false);
//--- check/reserve elements of array
if(!Reserve(1))
return(false);
//--- if the array is empty, add an element
if(m_data_total==0)
{
m_data[m_data_total++]=element;
return(true);
}
//--- search position and insert
pos=QuickSearch(element);
if(m_data[pos]>element)
Insert(element,pos);
else
Insert(element,pos+1);
//--- restore the sorting flag after Insert(...)
m_sort_mode=0;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Search of position of element in a array |
//+------------------------------------------------------------------+
int CArrayDouble::SearchLinear(const double element) const
{
//--- check
if(m_data_total==0)
return(-1);
//---
for(int i=0;i<m_data_total;i++)
if(MathAbs(m_data[i]-element)<=m_delta)
return(i);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Quick search of position of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayDouble::QuickSearch(const double element) const
{
int i,j,m=-1;
double t_double;
//--- search
i=0;
j=m_data_total-1;
while(j>=i)
{
//--- ">>1" is quick division by 2
m=(j+i)>>1;
if(m<0 || m>=m_data_total)
break;
t_double=m_data[m];
//--- compare with delta
if(MathAbs(t_double-element)<=m_delta)
break;
if(t_double>element)
j=m-1;
else
i=m+1;
}
//--- position
return(m);
}
//+------------------------------------------------------------------+
//| Search of position of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayDouble::Search(const double element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
//--- compare with delta
if(MathAbs(m_data[pos]-element)<=m_delta)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is greater than |
//| specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayDouble::SearchGreat(const double element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
//--- compare with delta
while(m_data[pos]<=element+m_delta)
if(++pos==m_data_total)
return(-1);
//--- position
return(pos);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is less than |
//| specified in the sorted array |
//+------------------------------------------------------------------+
int CArrayDouble::SearchLess(const double element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
//--- compare with delta
while(m_data[pos]>=element-m_delta)
if(pos--==0)
return(-1);
//--- position
return(pos);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is greater than or |
//| equal to the specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayDouble::SearchGreatOrEqual(const double element) const
{
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
for(int pos=QuickSearch(element);pos<m_data_total;pos++)
if(m_data[pos]>=element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is less than or equal |
//| to the specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayDouble::SearchLessOrEqual(const double element) const
{
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
for(int pos=QuickSearch(element);pos>=0;pos--)
if(m_data[pos]<=element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Find position of first appearance of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayDouble::SearchFirst(const double element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
{
//--- compare with delta
while(MathAbs(m_data[pos]-element)<=m_delta)
if(pos--==0)
break;
return(pos+1);
}
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Find position of last appearance of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayDouble::SearchLast(const double element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
{
//--- compare with delta
while(MathAbs(m_data[pos]-element)<=m_delta)
if(++pos==m_data_total)
break;
return(pos-1);
}
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Writing array to file |
//+------------------------------------------------------------------+
bool CArrayDouble::Save(const int file_handle)
{
int i=0;
//--- check
if(!CArray::Save(file_handle))
return(false);
//--- write array length
if(FileWriteInteger(file_handle,m_data_total,INT_VALUE)!=INT_VALUE)
return(false);
//--- write array
for(i=0;i<m_data_total;i++)
if(FileWriteDouble(file_handle,m_data[i])!=sizeof(double))
break;
//--- result
return(i==m_data_total);
}
//+------------------------------------------------------------------+
//| Reading array from file |
//+------------------------------------------------------------------+
bool CArrayDouble::Load(const int file_handle)
{
int i=0,num;
//--- check
if(!CArray::Load(file_handle))
return(false);
//--- read array length
num=FileReadInteger(file_handle,INT_VALUE);
//--- read array
Clear();
if(num!=0)
{
if(!Reserve(num))
return(false);
for(i=0;i<num;i++)
{
m_data[i]=FileReadDouble(file_handle);
m_data_total++;
if(FileIsEnding(file_handle))
break;
}
}
m_sort_mode=-1;
//--- result
return(m_data_total==num);
}
//+------------------------------------------------------------------+
+778
View File
@@ -0,0 +1,778 @@
//+------------------------------------------------------------------+
//| ArrayFloat.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "Array.mqh"
//+------------------------------------------------------------------+
//| Class CArrayFloat. |
//| Purpose: Class of dynamic array of variable |
//| of float type. |
//| Derives from class CArray. |
//+------------------------------------------------------------------+
class CArrayFloat : public CArray
{
protected:
float m_data[]; // data array
float m_delta; // search tolerance
public:
CArrayFloat(void);
~CArrayFloat(void);
//--- methods of access to protected data
void Delta(const float delta) { m_delta=(float)MathAbs(delta); }
//--- method of identifying the object
virtual int Type(void) const { return(TYPE_FLOAT); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
//--- methods of managing dynamic memory
bool Reserve(const int size);
bool Resize(const int size);
bool Shutdown(void);
//--- methods of filling the array
bool Add(const float element);
bool AddArray(const float &src[]);
bool AddArray(const CArrayFloat *src);
bool Insert(const float element,const int pos);
bool InsertArray(const float &src[],const int pos);
bool InsertArray(const CArrayFloat *src,const int pos);
bool AssignArray(const float &src[]);
bool AssignArray(const CArrayFloat *src);
//--- method of access to the array
float At(const int index) const;
float operator[](const int index) const { return(At(index)); }
//--- methods of searching for minimum and maximum
int Minimum(const int start,const int count) const { return(Minimum(m_data,start,count)); }
int Maximum(const int start,const int count) const { return(Maximum(m_data,start,count)); }
//--- methods of changing
bool Update(const int index,const float element);
bool Shift(const int index,const int shift);
//--- methods deleting
bool Delete(const int index);
bool DeleteRange(int from,int to);
//--- methods for comparing arrays
bool CompareArray(const float &array[]) const;
bool CompareArray(const CArrayFloat *array) const;
//--- methods for working with the sorted array
bool InsertSort(const float element);
int Search(const float element) const;
int SearchGreat(const float element) const;
int SearchLess(const float element) const;
int SearchGreatOrEqual(const float element) const;
int SearchLessOrEqual(const float element) const;
int SearchFirst(const float element) const;
int SearchLast(const float element) const;
int SearchLinear(const float element) const;
protected:
virtual void QuickSort(int beg,int end,const int mode=0);
int QuickSearch(const float element) const;
int MemMove(const int dest,const int src,int count);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CArrayFloat::CArrayFloat(void) : m_delta(0.0)
{
//--- initialize protected data
m_data_max=ArraySize(m_data);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CArrayFloat::~CArrayFloat(void)
{
if(m_data_max!=0)
Shutdown();
}
//+------------------------------------------------------------------+
//| Moving the memory within a single array |
//+------------------------------------------------------------------+
int CArrayFloat::MemMove(const int dest,const int src,int count)
{
int i;
//--- check parameters
if(dest<0 || src<0 || count<0)
return(-1);
//--- check count
if(src+count>m_data_total)
count=m_data_total-src;
if(count<0)
return(-1);
//--- no need to copy
if(dest==src || count==0)
return(dest);
//--- check data total
if(dest+count>m_data_total)
{
if(m_data_max<dest+count)
return(-1);
m_data_total=dest+count;
}
//--- copy
if(dest<src)
{
//--- copy from left to right
for(i=0;i<count;i++)
m_data[dest+i]=m_data[src+i];
}
else
{
//--- copy from right to left
for(i=count-1;i>=0;i--)
m_data[dest+i]=m_data[src+i];
}
//--- successful
return(dest);
}
//+------------------------------------------------------------------+
//| Request for more memory in an array. Checks if the requested |
//| number of free elements already exists; allocates additional |
//| memory with a given step |
//+------------------------------------------------------------------+
bool CArrayFloat::Reserve(const int size)
{
int new_size;
//--- check
if(size<=0)
return(false);
//--- resize array
if(Available()<size)
{
new_size=m_data_max+m_step_resize*(1+(size-Available())/m_step_resize);
if(new_size<0)
//--- overflow occurred when calculating new_size
return(false);
if((m_data_max=ArrayResize(m_data,new_size))==-1)
m_data_max=ArraySize(m_data);
}
//--- result
return(Available()>=size);
}
//+------------------------------------------------------------------+
//| Resizing (with removal of elements on the right) |
//+------------------------------------------------------------------+
bool CArrayFloat::Resize(const int size)
{
int new_size;
//--- check
if(size<0)
return(false);
//--- resize array
new_size=m_step_resize*(1+size/m_step_resize);
if(m_data_max!=new_size)
{
if((m_data_max=ArrayResize(m_data,new_size))==-1)
{
m_data_max=ArraySize(m_data);
return(false);
}
}
if(m_data_total>size)
m_data_total=size;
//--- result
return(m_data_max==new_size);
}
//+------------------------------------------------------------------+
//| Complete cleaning of the array with the release of memory |
//+------------------------------------------------------------------+
bool CArrayFloat::Shutdown(void)
{
//--- check
if(m_data_max==0)
return(true);
//--- clean
if(ArrayResize(m_data,0)==-1)
return(false);
m_data_total=0;
m_data_max=0;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array |
//+------------------------------------------------------------------+
bool CArrayFloat::Add(const float element)
{
//--- check/reserve elements of array
if(!Reserve(1))
return(false);
//--- add
m_data[m_data_total++]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array from another array |
//+------------------------------------------------------------------+
bool CArrayFloat::AddArray(const float &src[])
{
int num=ArraySize(src);
//--- check/reserve elements of array
if(!Reserve(num))
return(false);
//--- add
for(int i=0;i<num;i++)
m_data[m_data_total++]=src[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array from another array |
//+------------------------------------------------------------------+
bool CArrayFloat::AddArray(const CArrayFloat *src)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.Total();
if(!Reserve(num))
return(false);
//--- add
for(int i=0;i<num;i++)
m_data[m_data_total++]=src.m_data[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting an element in the specified position |
//+------------------------------------------------------------------+
bool CArrayFloat::Insert(const float element,const int pos)
{
//--- check/reserve elements of array
if(pos<0 || !Reserve(1))
return(false);
//--- insert
m_data_total++;
if(pos<m_data_total-1)
{
if(MemMove(pos+1,pos,m_data_total-pos-1)<0)
return(false);
m_data[pos]=element;
}
else
m_data[m_data_total-1]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting elements in the specified position |
//+------------------------------------------------------------------+
bool CArrayFloat::InsertArray(const float &src[],const int pos)
{
int num=ArraySize(src);
//--- check/reserve elements of array
if(!Reserve(num))
return(false);
//--- insert
if(MemMove(num+pos,pos,m_data_total-pos)<0)
return(false);
for(int i=0;i<num;i++)
m_data[i+pos]=src[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting elements in the specified position |
//+------------------------------------------------------------------+
bool CArrayFloat::InsertArray(const CArrayFloat *src,const int pos)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.Total();
if(!Reserve(num))
return(false);
//--- insert
if(MemMove(num+pos,pos,m_data_total-pos)<0)
return(false);
for(int i=0;i<num;i++)
m_data[i+pos]=src.m_data[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Assignment (copying) of another array |
//+------------------------------------------------------------------+
bool CArrayFloat::AssignArray(const float &src[])
{
int num=ArraySize(src);
//--- check/reserve elements of array
Clear();
if(m_data_max<num)
{
if(!Reserve(num))
return(false);
}
else
Resize(num);
//--- copy array
for(int i=0;i<num;i++)
{
m_data[i]=src[i];
m_data_total++;
}
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Assignment (copying) of another array |
//+------------------------------------------------------------------+
bool CArrayFloat::AssignArray(const CArrayFloat *src)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.m_data_total;
Clear();
if(m_data_max<num)
{
if(!Reserve(num))
return(false);
}
else
Resize(num);
//--- copy array
for(int i=0;i<num;i++)
{
m_data[i]=src.m_data[i];
m_data_total++;
}
m_sort_mode=src.SortMode();
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Access to data in the specified position |
//+------------------------------------------------------------------+
float CArrayFloat::At(const int index) const
{
//--- check
if(index<0 || index>=m_data_total)
return(FLT_MAX);
//--- result
return(m_data[index]);
}
//+------------------------------------------------------------------+
//| Updating element in the specified position |
//+------------------------------------------------------------------+
bool CArrayFloat::Update(const int index,const float element)
{
//--- check
if(index<0 || index>=m_data_total)
return(false);
//--- update
m_data[index]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Moving element from the specified position |
//| on the specified shift |
//+------------------------------------------------------------------+
bool CArrayFloat::Shift(const int index,const int shift)
{
float tmp_float;
//--- check
if(index<0 || index+shift<0 || index+shift>=m_data_total)
return(false);
if(shift==0)
return(true);
//--- move
tmp_float=m_data[index];
if(shift>0)
{
if(MemMove(index,index+1,shift)<0)
return(false);
}
else
{
if(MemMove(index+shift+1,index+shift,-shift)<0)
return(false);
}
m_data[index+shift]=tmp_float;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Deleting element from the specified position |
//+------------------------------------------------------------------+
bool CArrayFloat::Delete(const int index)
{
//--- check
if(index<0 || index>=m_data_total)
return(false);
//--- delete
if(index<m_data_total-1 && MemMove(index,index+1,m_data_total-index-1)<0)
return(false);
m_data_total--;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Deleting range of elements |
//+------------------------------------------------------------------+
bool CArrayFloat::DeleteRange(int from,int to)
{
//--- check
if(from<0 || to<0)
return(false);
if(from>to || from>=m_data_total)
return(false);
//--- delete
if(to>=m_data_total-1)
to=m_data_total-1;
if(MemMove(from,to+1,m_data_total-to-1)<0)
return(false);
m_data_total-=to-from+1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Equality comparison of two arrays |
//+------------------------------------------------------------------+
bool CArrayFloat::CompareArray(const float &array[]) const
{
//--- compare
if(m_data_total!=ArraySize(array))
return(false);
for(int i=0;i<m_data_total;i++)
if(m_data[i]!=array[i])
return(false);
//--- equal
return(true);
}
//+------------------------------------------------------------------+
//| Equality comparison of two arrays |
//+------------------------------------------------------------------+
bool CArrayFloat::CompareArray(const CArrayFloat *array) const
{
//--- check
if(!CheckPointer(array)) return(false);
//--- compare
if(m_data_total!=array.m_data_total)
return(false);
for(int i=0;i<m_data_total;i++)
if(m_data[i]!=array.m_data[i])
return(false);
//--- equal
return(true);
}
//+------------------------------------------------------------------+
//| Method QuickSort |
//+------------------------------------------------------------------+
void CArrayFloat::QuickSort(int beg,int end,const int mode)
{
int i,j;
float p_float,t_float;
//--- check
if(beg<0 || end<0)
return;
//--- sort
i=beg;
j=end;
while(i<end)
{
//--- ">>1" is quick division by 2
p_float=m_data[(beg+end)>>1];
while(i<j)
{
while(m_data[i]<p_float)
{
//--- control the output of the array bounds
if(i==m_data_total-1)
break;
i++;
}
while(m_data[j]>p_float)
{
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
if(i<=j)
{
t_float=m_data[i];
m_data[i++]=m_data[j];
m_data[j]=t_float;
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
}
if(beg<j)
QuickSort(beg,j);
beg=i;
j=end;
}
}
//+------------------------------------------------------------------+
//| Inserting element in a sorted array |
//+------------------------------------------------------------------+
bool CArrayFloat::InsertSort(const float element)
{
int pos;
//--- check
if(!IsSorted())
return(false);
//--- check/reserve elements of array
if(!Reserve(1))
return(false);
//--- if the array is empty, add an element
if(m_data_total==0)
{
m_data[m_data_total++]=element;
return(true);
}
//--- search position and insert
pos=QuickSearch(element);
if(m_data[pos]>element)
Insert(element,pos);
else
Insert(element,pos+1);
//--- restore the sorting flag after Insert(...)
m_sort_mode=0;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Search of position of element in a array |
//+------------------------------------------------------------------+
int CArrayFloat::SearchLinear(const float element) const
{
//--- check
if(m_data_total==0)
return(-1);
//---
for(int i=0;i<m_data_total;i++)
if(MathAbs(m_data[i]-element)<=m_delta)
return(i);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Quick search of position of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayFloat::QuickSearch(const float element) const
{
int i,j,m=-1;
float t_float;
//--- search
i=0;
j=m_data_total-1;
while(j>=i)
{
//--- ">>1" is quick division by 2
m=(j+i)>>1;
if(m<0 || m>=m_data_total)
break;
t_float=m_data[m];
//--- compare with delta
if(MathAbs(t_float-element)<=m_delta)
break;
if(t_float>element)
j=m-1;
else
i=m+1;
}
//--- position
return(m);
}
//+------------------------------------------------------------------+
//| Search of position of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayFloat::Search(const float element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
//--- compare with delta
if(MathAbs(m_data[pos]-element)<=m_delta)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is greater than |
//| specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayFloat::SearchGreat(const float element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
//--- compare with delta
while(m_data[pos]<=element+m_delta)
if(++pos==m_data_total)
return(-1);
//--- position
return(pos);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is less than |
//| specified in the sorted array |
//+------------------------------------------------------------------+
int CArrayFloat::SearchLess(const float element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
//--- compare with delta
while(m_data[pos]>=element-m_delta)
if(pos--==0)
return(-1);
//--- position
return(pos);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is greater than or |
//| equal to the specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayFloat::SearchGreatOrEqual(const float element) const
{
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
for(int pos=QuickSearch(element);pos<m_data_total;pos++)
if(m_data[pos]>=element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is less than or equal |
//| to the specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayFloat::SearchLessOrEqual(const float element) const
{
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
for(int pos=QuickSearch(element);pos>=0;pos--)
if(m_data[pos]<=element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Find position of first appearance of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayFloat::SearchFirst(const float element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
{
//--- compare with delta
while(MathAbs(m_data[pos]-element)<=m_delta)
if(pos--==0)
break;
return(pos+1);
}
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Find position of last appearance of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayFloat::SearchLast(const float element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
{
//--- compare with delta
while(MathAbs(m_data[pos]-element)<=m_delta)
if(++pos==m_data_total)
break;
return(pos-1);
}
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Writing array to file |
//+------------------------------------------------------------------+
bool CArrayFloat::Save(const int file_handle)
{
int i=0;
//--- check
if(!CArray::Save(file_handle))
return(false);
//--- write array length
if(FileWriteInteger(file_handle,m_data_total,INT_VALUE)!=INT_VALUE)
return(false);
//--- write array
for(i=0;i<m_data_total;i++)
if(FileWriteFloat(file_handle,m_data[i])!=sizeof(float))
break;
//--- result
return(i==m_data_total);
}
//+------------------------------------------------------------------+
//| Reading array from file |
//+------------------------------------------------------------------+
bool CArrayFloat::Load(const int file_handle)
{
int i=0,num;
//--- check
if(!CArray::Load(file_handle))
return(false);
//--- read array length
num=FileReadInteger(file_handle,INT_VALUE);
//--- read array
Clear();
if(num!=0)
{
if(!Reserve(num))
return(false);
for(i=0;i<num;i++)
{
m_data[i]=FileReadFloat(file_handle);
m_data_total++;
if(FileIsEnding(file_handle))
break;
}
}
m_sort_mode=-1;
//--- result
return(m_data_total==num);
}
//+------------------------------------------------------------------+
+770
View File
@@ -0,0 +1,770 @@
//+------------------------------------------------------------------+
//| ArrayInt.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "Array.mqh"
//+------------------------------------------------------------------+
//| Class CArrayInt. |
//| Puprose: Class of dynamic array of variables |
//| of int or uint type. |
//| Derives from class CArray. |
//+------------------------------------------------------------------+
class CArrayInt : public CArray
{
protected:
int m_data[]; // data array
public:
CArrayInt(void);
~CArrayInt(void);
//--- method of identifying the object
virtual int Type(void) const { return(TYPE_INT); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
//--- methods of managing dynamic memory
bool Reserve(const int size);
bool Resize(const int size);
bool Shutdown(void);
//--- methods of filling the array
bool Add(const int element);
bool AddArray(const int &src[]);
bool AddArray(const CArrayInt *src);
bool Insert(const int element,const int pos);
bool InsertArray(const int &src[],const int pos);
bool InsertArray(const CArrayInt *src,const int pos);
bool AssignArray(const int &src[]);
bool AssignArray(const CArrayInt *src);
//--- method of access to the array
int At(const int index) const;
int operator[](const int index) const { return(At(index)); }
//--- methods of searching for minimum and maximum
int Minimum(const int start,const int count) const { return(Minimum(m_data,start,count)); }
int Maximum(const int start,const int count) const { return(Maximum(m_data,start,count)); }
//--- methods of changing
bool Update(const int index,const int element);
bool Shift(const int index,const int shift);
//--- methods of deleting
bool Delete(const int index);
bool DeleteRange(int from,int to);
//--- methods for comparing arrays
bool CompareArray(const int &array[]) const;
bool CompareArray(const CArrayInt *array) const;
//--- methods for working with the sorted array
bool InsertSort(const int element);
int Search(const int element) const;
int SearchGreat(const int element) const;
int SearchLess(const int element) const;
int SearchGreatOrEqual(const int element) const;
int SearchLessOrEqual(const int element) const;
int SearchFirst(const int element) const;
int SearchLast(const int element) const;
int SearchLinear(const int element) const;
protected:
virtual void QuickSort(int beg,int end,const int mode=0);
int QuickSearch(const int element) const;
int MemMove(const int dest,const int src,int count);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CArrayInt::CArrayInt(void)
{
//--- initialize protected data
m_data_max=ArraySize(m_data);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CArrayInt::~CArrayInt(void)
{
if(m_data_max!=0)
Shutdown();
}
//+------------------------------------------------------------------+
//| Moving the memory within a single array |
//+------------------------------------------------------------------+
int CArrayInt::MemMove(const int dest,const int src,int count)
{
int i;
//--- check parameters
if(dest<0 || src<0 || count<0)
return(-1);
//--- check count
if(src+count>m_data_total)
count=m_data_total-src;
if(count<0)
return(-1);
//--- no need to copy
if(dest==src || count==0)
return(dest);
//--- check data total
if(dest+count>m_data_total)
{
if(m_data_max<dest+count)
return(-1);
m_data_total=dest+count;
}
//--- copy
if(dest<src)
{
//--- copy from left to right
for(i=0;i<count;i++)
m_data[dest+i]=m_data[src+i];
}
else
{
//--- copy from right to left
for(i=count-1;i>=0;i--)
m_data[dest+i]=m_data[src+i];
}
//--- successful
return(dest);
}
//+------------------------------------------------------------------+
//| Request for more memory in an array. Checks if the requested |
//| number of free elements already exists; allocates additional |
//| memory with a given step |
//+------------------------------------------------------------------+
bool CArrayInt::Reserve(const int size)
{
int new_size;
//--- check
if(size<=0)
return(false);
//--- resize array
if(Available()<size)
{
new_size=m_data_max+m_step_resize*(1+(size-Available())/m_step_resize);
if(new_size<0)
//--- overflow occurred when calculating new_size
return(false);
if((m_data_max=ArrayResize(m_data,new_size))==-1)
m_data_max=ArraySize(m_data);
}
//--- result
return(Available()>=size);
}
//+------------------------------------------------------------------+
//| Resizing (with removal of elements on the right) |
//+------------------------------------------------------------------+
bool CArrayInt::Resize(const int size)
{
int new_size;
//--- check
if(size<0)
return(false);
//--- resize array
new_size=m_step_resize*(1+size/m_step_resize);
if(m_data_max!=new_size)
{
if((m_data_max=ArrayResize(m_data,new_size))==-1)
{
m_data_max=ArraySize(m_data);
return(false);
}
}
if(m_data_total>size)
m_data_total=size;
//--- result
return(m_data_max==new_size);
}
//+------------------------------------------------------------------+
//| Complete cleaning of the array with the release of memory |
//+------------------------------------------------------------------+
bool CArrayInt::Shutdown(void)
{
//--- check
if(m_data_max==0)
return(true);
//--- clean
if(ArrayResize(m_data,0)==-1)
return(false);
m_data_total=0;
m_data_max=0;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array |
//+------------------------------------------------------------------+
bool CArrayInt::Add(const int element)
{
//--- check/reserve elements of array
if(!Reserve(1))
return(false);
//--- add
m_data[m_data_total++]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array from another array |
//+------------------------------------------------------------------+
bool CArrayInt::AddArray(const int &src[])
{
int num=ArraySize(src);
//--- check/reserve elements of array
if(!Reserve(num))
return(false);
//--- add
for(int i=0;i<num;i++)
m_data[m_data_total++]=src[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array from another array |
//+------------------------------------------------------------------+
bool CArrayInt::AddArray(const CArrayInt *src)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.Total();
if(!Reserve(num))
return(false);
//--- add
for(int i=0;i<num;i++)
m_data[m_data_total++]=src.m_data[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting an element in the specified position |
//+------------------------------------------------------------------+
bool CArrayInt::Insert(const int element,const int pos)
{
//--- check/reserve elements of array
if(pos<0 || !Reserve(1))
return(false);
//--- insert
m_data_total++;
if(pos<m_data_total-1)
{
if(MemMove(pos+1,pos,m_data_total-pos-1)<0)
return(false);
m_data[pos]=element;
}
else
m_data[m_data_total-1]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting elements in the specified position |
//+------------------------------------------------------------------+
bool CArrayInt::InsertArray(const int &src[],const int pos)
{
int num=ArraySize(src);
//--- check/reserve elements of array
if(!Reserve(num))
return(false);
//--- insert
if(MemMove(num+pos,pos,m_data_total-pos)<0)
return(false);
for(int i=0;i<num;i++)
m_data[i+pos]=src[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting elements in the specified position |
//+------------------------------------------------------------------+
bool CArrayInt::InsertArray(const CArrayInt *src,const int pos)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.Total();
if(!Reserve(num))
return(false);
//--- insert
if(MemMove(num+pos,pos,m_data_total-pos)<0)
return(false);
for(int i=0;i<num;i++)
m_data[i+pos]=src.m_data[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Assignment (copying) of another array |
//+------------------------------------------------------------------+
bool CArrayInt::AssignArray(const int &src[])
{
int num=ArraySize(src);
//--- check/reserve elements of array
Clear();
if(m_data_max<num)
{
if(!Reserve(num))
return(false);
}
else
Resize(num);
//--- copy array
for(int i=0;i<num;i++)
{
m_data[i]=src[i];
m_data_total++;
}
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Assignment (copying) of another array |
//+------------------------------------------------------------------+
bool CArrayInt::AssignArray(const CArrayInt *src)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.m_data_total;
Clear();
if(m_data_max<num)
{
if(!Reserve(num))
return(false);
}
else
Resize(num);
//--- copy array
for(int i=0;i<num;i++)
{
m_data[i]=src.m_data[i];
m_data_total++;
}
m_sort_mode=src.SortMode();
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Access to data in the specified position |
//+------------------------------------------------------------------+
int CArrayInt::At(const int index) const
{
//--- check
if(index<0 || index>=m_data_total)
return(INT_MAX);
//--- result
return(m_data[index]);
}
//+------------------------------------------------------------------+
//| Updating element in the specified position |
//+------------------------------------------------------------------+
bool CArrayInt::Update(const int index,const int element)
{
//--- check
if(index<0 || index>=m_data_total)
return(false);
//--- update
m_data[index]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Moving element from the specified position |
//| on the specified shift |
//+------------------------------------------------------------------+
bool CArrayInt::Shift(const int index,const int shift)
{
int tmp_int;
//--- check
if(index<0 || index+shift<0 || index+shift>=m_data_total)
return(false);
if(shift==0)
return(true);
//--- move
tmp_int=m_data[index];
if(shift>0)
{
if(MemMove(index,index+1,shift)<0)
return(false);
}
else
{
if(MemMove(index+shift+1,index+shift,-shift)<0)
return(false);
}
m_data[index+shift]=tmp_int;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Deleting element from the specified position |
//+------------------------------------------------------------------+
bool CArrayInt::Delete(const int index)
{
//--- check
if(index<0 || index>=m_data_total)
return(false);
//--- delete
if(index<m_data_total-1 && MemMove(index,index+1,m_data_total-index-1)<0)
return(false);
m_data_total--;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Deleting range of elements |
//+------------------------------------------------------------------+
bool CArrayInt::DeleteRange(int from,int to)
{
//--- check
if(from<0 || to<0)
return(false);
if(from>to || from>=m_data_total)
return(false);
//--- delete
if(to>=m_data_total-1)
to=m_data_total-1;
if(MemMove(from,to+1,m_data_total-to-1)<0)
return(false);
m_data_total-=to-from+1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Equality comparison of two arrays |
//+------------------------------------------------------------------+
bool CArrayInt::CompareArray(const int &array[]) const
{
//--- compare
if(m_data_total!=ArraySize(array))
return(false);
for(int i=0;i<m_data_total;i++)
if(m_data[i]!=array[i])
return(false);
//--- equal
return(true);
}
//+------------------------------------------------------------------+
//| Equality comparison of two arrays |
//+------------------------------------------------------------------+
bool CArrayInt::CompareArray(const CArrayInt *array) const
{
//--- check
if(!CheckPointer(array))
return(false);
//--- compare
if(m_data_total!=array.m_data_total)
return(false);
for(int i=0;i<m_data_total;i++)
if(m_data[i]!=array.m_data[i])
return(false);
//--- equal
return(true);
}
//+------------------------------------------------------------------+
//| Method QuickSort |
//+------------------------------------------------------------------+
void CArrayInt::QuickSort(int beg,int end,const int mode)
{
int i,j;
int p_int,t_int;
//--- check
if(beg<0 || end<0)
return;
//--- sort
i=beg;
j=end;
while(i<end)
{
//--- ">>1" is quick division by 2
p_int=m_data[(beg+end)>>1];
while(i<j)
{
while(m_data[i]<p_int)
{
//--- control the output of the array bounds
if(i==m_data_total-1)
break;
i++;
}
while(m_data[j]>p_int)
{
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
if(i<=j)
{
t_int=m_data[i];
m_data[i++]=m_data[j];
m_data[j]=t_int;
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
}
if(beg<j)
QuickSort(beg,j);
beg=i;
j=end;
}
}
//+------------------------------------------------------------------+
//| Inserting element in a sorted array |
//+------------------------------------------------------------------+
bool CArrayInt::InsertSort(const int element)
{
int pos;
//--- check
if(!IsSorted())
return(false);
//--- check/reserve elements of array
if(!Reserve(1))
return(false);
//--- if the array is empty, add an element
if(m_data_total==0)
{
m_data[m_data_total++]=element;
return(true);
}
//--- find position and insert
pos=QuickSearch(element);
if(m_data[pos]>element)
Insert(element,pos);
else
Insert(element,pos+1);
//--- restore the sorting flag after Insert(...)
m_sort_mode=0;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Search of position of element in a array |
//+------------------------------------------------------------------+
int CArrayInt::SearchLinear(const int element) const
{
//--- check
if(m_data_total==0)
return(-1);
//---
for(int i=0;i<m_data_total;i++)
if(m_data[i]==element)
return(i);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Quick search of position of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayInt::QuickSearch(const int element) const
{
int i,j,m=-1;
int t_int;
//--- search
i=0;
j=m_data_total-1;
while(j>=i)
{
//--- ">>1" is quick division by 2
m=(j+i)>>1;
if(m<0 || m>=m_data_total)
break;
t_int=m_data[m];
if(t_int==element)
break;
if(t_int>element)
j=m-1;
else
i=m+1;
}
//--- position
return(m);
}
//+------------------------------------------------------------------+
//| Search of position of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayInt::Search(const int element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is greater than |
//| specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayInt::SearchGreat(const int element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
while(m_data[pos]<=element)
if(++pos==m_data_total)
return(-1);
//--- position
return(pos);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is less than |
//| specified in the sorted array |
//+------------------------------------------------------------------+
int CArrayInt::SearchLess(const int element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
while(m_data[pos]>=element)
if(pos--==0)
return(-1);
//--- position
return(pos);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is greater than or |
//| equal to the specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayInt::SearchGreatOrEqual(const int element) const
{
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
for(int pos=QuickSearch(element);pos<m_data_total;pos++)
if(m_data[pos]>=element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is less than or equal |
//| to the specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayInt::SearchLessOrEqual(const int element) const
{
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
for(int pos=QuickSearch(element);pos>=0;pos--)
if(m_data[pos]<=element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Find position of first appearance of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayInt::SearchFirst(const int element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
{
while(m_data[pos]==element)
if(pos--==0)
break;
return(pos+1);
}
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Find position of last appearance of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayInt::SearchLast(const int element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
{
while(m_data[pos]==element)
if(++pos==m_data_total)
break;
return(pos-1);
}
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Writing array to file |
//+------------------------------------------------------------------+
bool CArrayInt::Save(const int file_handle)
{
int i=0;
//--- check
if(!CArray::Save(file_handle))
return(false);
//--- write array length
if(FileWriteInteger(file_handle,m_data_total,INT_VALUE)!=INT_VALUE)
return(false);
//--- write array
for(i=0;i<m_data_total;i++)
if(FileWriteInteger(file_handle,m_data[i],INT_VALUE)!=INT_VALUE)
break;
//--- result
return(i==m_data_total);
}
//+------------------------------------------------------------------+
//| Reading array from file |
//+------------------------------------------------------------------+
bool CArrayInt::Load(const int file_handle)
{
int i=0,num;
//--- check
if(!CArray::Load(file_handle))
return(false);
//--- read array length
num=FileReadInteger(file_handle,INT_VALUE);
//--- read array
Clear();
if(num!=0)
{
if(!Reserve(num))
return(false);
for(i=0;i<num;i++)
{
m_data[i]=FileReadInteger(file_handle,INT_VALUE);
m_data_total++;
if(FileIsEnding(file_handle))
break;
}
}
m_sort_mode=-1;
//--- result
return(m_data_total==num);
}
//+------------------------------------------------------------------+
+770
View File
@@ -0,0 +1,770 @@
//+------------------------------------------------------------------+
//| ArrayLong.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "Array.mqh"
//+------------------------------------------------------------------+
//| Class CArrayLong. |
//| Purpose: Class of dynamic array of variables |
//| of long or ulong type. |
//| Derives from class CArray. |
//+------------------------------------------------------------------+
class CArrayLong : public CArray
{
protected:
long m_data[]; // data array
public:
CArrayLong(void);
~CArrayLong(void);
//--- method of identifying the object
virtual int Type(void) const { return(TYPE_LONG); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
//--- methods of managing dynamic memory
bool Reserve(const int size);
bool Resize(const int size);
bool Shutdown(void);
//--- methods of filling the array
bool Add(const long element);
bool AddArray(const long &src[]);
bool AddArray(const CArrayLong *src);
bool Insert(const long element,const int pos);
bool InsertArray(const long &src[],const int pos);
bool InsertArray(const CArrayLong *src,const int pos);
bool AssignArray(const long &src[]);
bool AssignArray(const CArrayLong *src);
//--- method of access to the array
long At(const int index) const;
long operator[](const int index) const { return(At(index)); }
//--- methods of searching for minimum and maximum
int Minimum(const int start,const int count) const { return(Minimum(m_data,start,count)); }
int Maximum(const int start,const int count) const { return(Maximum(m_data,start,count)); }
//--- methods change
bool Update(const int index,const long element);
bool Shift(const int index,const int shift);
//--- methods for deleting
bool Delete(const int index);
bool DeleteRange(int from,int to);
//--- methods for compare arrays
bool CompareArray(const long &array[]) const;
bool CompareArray(const CArrayLong *array) const;
//--- methods for working with the sorted array
bool InsertSort(const long element);
int Search(const long element) const;
int SearchGreat(const long element) const;
int SearchLess(const long element) const;
int SearchGreatOrEqual(const long element) const;
int SearchLessOrEqual(const long element) const;
int SearchFirst(const long element) const;
int SearchLast(const long element) const;
int SearchLinear(const long element) const;
protected:
virtual void QuickSort(int beg,int end,const int mode=0);
int QuickSearch(const long element) const;
int MemMove(const int dest,const int src,int count);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CArrayLong::CArrayLong(void)
{
//--- initialize protected data
m_data_max=ArraySize(m_data);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CArrayLong::~CArrayLong(void)
{
if(m_data_max!=0)
Shutdown();
}
//+------------------------------------------------------------------+
//| Moving the memory within a single array |
//+------------------------------------------------------------------+
int CArrayLong::MemMove(const int dest,const int src,int count)
{
int i;
//--- check parameters
if(dest<0 || src<0 || count<0)
return(-1);
//--- check count
if(src+count>m_data_total)
count=m_data_total-src;
if(count<0)
return(-1);
//--- no need to copy
if(dest==src || count==0)
return(dest);
//--- check data total
if(dest+count>m_data_total)
{
if(m_data_max<dest+count)
return(-1);
m_data_total=dest+count;
}
//--- copy
if(dest<src)
{
//--- copy from left to right
for(i=0;i<count;i++)
m_data[dest+i]=m_data[src+i];
}
else
{
//--- copy from right to left
for(i=count-1;i>=0;i--)
m_data[dest+i]=m_data[src+i];
}
//--- successful
return(dest);
}
//+------------------------------------------------------------------+
//| Request for more memory in an array. Checks if the requested |
//| number of free elements already exists; allocates additional |
//| memory with a given step |
//+------------------------------------------------------------------+
bool CArrayLong::Reserve(const int size)
{
int new_size;
//--- check
if(size<=0)
return(false);
//--- resize array
if(Available()<size)
{
new_size=m_data_max+m_step_resize*(1+(size-Available())/m_step_resize);
if(new_size<0)
//--- overflow occurred when calculating new_size
return(false);
if((m_data_max=ArrayResize(m_data,new_size))==-1)
m_data_max=ArraySize(m_data);
}
//--- result
return(Available()>=size);
}
//+------------------------------------------------------------------+
//| Resizing (with removal of elements on the right) |
//+------------------------------------------------------------------+
bool CArrayLong::Resize(const int size)
{
int new_size;
//--- check
if(size<0)
return(false);
//--- resize array
new_size=m_step_resize*(1+size/m_step_resize);
if(m_data_max!=new_size)
{
if((m_data_max=ArrayResize(m_data,new_size))==-1)
{
m_data_max=ArraySize(m_data);
return(false);
}
}
if(m_data_total>size)
m_data_total=size;
//--- result
return(m_data_max==new_size);
}
//+------------------------------------------------------------------+
//| Complete cleaning of the array with the release of memory |
//+------------------------------------------------------------------+
bool CArrayLong::Shutdown(void)
{
//--- check
if(m_data_max==0)
return(true);
//--- clean
if(ArrayResize(m_data,0)==-1)
return(false);
m_data_total=0;
m_data_max=0;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array |
//+------------------------------------------------------------------+
bool CArrayLong::Add(const long element)
{
//--- check/reserve elements of array
if(!Reserve(1))
return(false);
//--- add
m_data[m_data_total++]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array from another array |
//+------------------------------------------------------------------+
bool CArrayLong::AddArray(const long &src[])
{
int num=ArraySize(src);
//--- check/reserve elements of array
if(!Reserve(num))
return(false);
//--- add
for(int i=0;i<num;i++)
m_data[m_data_total++]=src[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array from another array |
//+------------------------------------------------------------------+
bool CArrayLong::AddArray(const CArrayLong *src)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.Total();
if(!Reserve(num))
return(false);
//--- add
for(int i=0;i<num;i++)
m_data[m_data_total++]=src.m_data[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting an element in the specified position |
//+------------------------------------------------------------------+
bool CArrayLong::Insert(const long element,const int pos)
{
//--- check/reserve elements of array
if(pos<0 || !Reserve(1))
return(false);
//--- insert
m_data_total++;
if(pos<m_data_total-1)
{
if(MemMove(pos+1,pos,m_data_total-pos-1)<0)
return(false);
m_data[pos]=element;
}
else
m_data[m_data_total-1]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting elements in the specified position |
//+------------------------------------------------------------------+
bool CArrayLong::InsertArray(const long &src[],const int pos)
{
int num=ArraySize(src);
//--- check/reserve elements of array
if(!Reserve(num))
return(false);
//--- insert
if(MemMove(num+pos,pos,m_data_total-pos)<0)
return(false);
for(int i=0;i<num;i++)
m_data[i+pos]=src[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting elements in the specified position |
//+------------------------------------------------------------------+
bool CArrayLong::InsertArray(const CArrayLong *src,const int pos)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.Total();
if(!Reserve(num))
return(false);
//--- insert
if(MemMove(num+pos,pos,m_data_total-pos)<0)
return(false);
for(int i=0;i<num;i++)
m_data[i+pos]=src.m_data[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Assignment (copying) of another array |
//+------------------------------------------------------------------+
bool CArrayLong::AssignArray(const long &src[])
{
int num=ArraySize(src);
//--- check/reserve elements of array
Clear();
if(m_data_max<num)
{
if(!Reserve(num))
return(false);
}
else
Resize(num);
//--- copy array
for(int i=0;i<num;i++)
{
m_data[i]=src[i];
m_data_total++;
}
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Assignment (copying) of another array |
//+------------------------------------------------------------------+
bool CArrayLong::AssignArray(const CArrayLong *src)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.m_data_total;
Clear();
if(m_data_max<num)
{
if(!Reserve(num))
return(false);
}
else
Resize(num);
//--- copy array
for(int i=0;i<num;i++)
{
m_data[i]=src.m_data[i];
m_data_total++;
}
m_sort_mode=src.SortMode();
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Access to data in the specified position |
//+------------------------------------------------------------------+
long CArrayLong::At(const int index) const
{
//--- check
if(index<0 || index>=m_data_total)
return(LONG_MAX);
//--- result
return(m_data[index]);
}
//+------------------------------------------------------------------+
//| Updating element in the specified position |
//+------------------------------------------------------------------+
bool CArrayLong::Update(const int index,const long element)
{
//--- check
if(index<0 || index>=m_data_total)
return(false);
//--- update
m_data[index]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Moving element from the specified position |
//| on the specified shift |
//+------------------------------------------------------------------+
bool CArrayLong::Shift(const int index,const int shift)
{
long tmp_long;
//--- check
if(index<0 || index+shift<0 || index+shift>=m_data_total)
return(false);
if(shift==0)
return(true);
//--- move
tmp_long=m_data[index];
if(shift>0)
{
if(MemMove(index,index+1,shift)<0)
return(false);
}
else
{
if(MemMove(index+shift+1,index+shift,-shift)<0)
return(false);
}
m_data[index+shift]=tmp_long;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Deleting element from the specified position |
//+------------------------------------------------------------------+
bool CArrayLong::Delete(const int index)
{
//--- check
if(index<0 || index>=m_data_total)
return(false);
//--- delete
if(index<m_data_total-1 && MemMove(index,index+1,m_data_total-index-1)<0)
return(false);
m_data_total--;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Deleting range of elements |
//+------------------------------------------------------------------+
bool CArrayLong::DeleteRange(int from,int to)
{
//--- check
if(from<0 || to<0)
return(false);
if(from>to || from>=m_data_total)
return(false);
//--- delete
if(to>=m_data_total-1)
to=m_data_total-1;
if(MemMove(from,to+1,m_data_total-to-1)<0)
return(false);
m_data_total-=to-from+1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Equality comparison of two arrays |
//+------------------------------------------------------------------+
bool CArrayLong::CompareArray(const long &array[]) const
{
//--- compare
if(m_data_total!=ArraySize(array))
return(false);
for(int i=0;i<m_data_total;i++)
if(m_data[i]!=array[i])
return(false);
//--- equal
return(true);
}
//+------------------------------------------------------------------+
//| Equality comparison of two arrays |
//+------------------------------------------------------------------+
bool CArrayLong::CompareArray(const CArrayLong *array) const
{
//--- check
if(!CheckPointer(array))
return(false);
//--- compare
if(m_data_total!=array.m_data_total)
return(false);
for(int i=0;i<m_data_total;i++)
if(m_data[i]!=array.m_data[i])
return(false);
//--- equal
return(true);
}
//+------------------------------------------------------------------+
//| Method QuickSort |
//+------------------------------------------------------------------+
void CArrayLong::QuickSort(int beg,int end,const int mode)
{
int i,j;
long p_long,t_long;
//--- check
if(beg<0 || end<0)
return;
//--- sort
i=beg;
j=end;
while(i<end)
{
//--- ">>1" is quick division by 2
p_long=m_data[(beg+end)>>1];
while(i<j)
{
while(m_data[i]<p_long)
{
//--- control the output of the array bounds
if(i==m_data_total-1)
break;
i++;
}
while(m_data[j]>p_long)
{
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
if(i<=j)
{
t_long=m_data[i];
m_data[i++]=m_data[j];
m_data[j]=t_long;
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
}
if(beg<j)
QuickSort(beg,j);
beg=i;
j=end;
}
}
//+------------------------------------------------------------------+
//| Inserting element in a sorted array |
//+------------------------------------------------------------------+
bool CArrayLong::InsertSort(const long element)
{
int pos;
//--- check
if(!IsSorted())
return(false);
//--- check/reserve elements of array
if(!Reserve(1))
return(false);
//--- if the array is empty, add an element
if(m_data_total==0)
{
m_data[m_data_total++]=element;
return(true);
}
//--- search position and insert
pos=QuickSearch(element);
if(m_data[pos]>element)
Insert(element,pos);
else
Insert(element,pos+1);
//--- restore the sorting flag after Insert(...)
m_sort_mode=0;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Search of position of element in a array |
//+------------------------------------------------------------------+
int CArrayLong::SearchLinear(const long element) const
{
//--- check
if(m_data_total==0)
return(-1);
//---
for(int i=0;i<m_data_total;i++)
if(m_data[i]==element)
return(i);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Quick search of position of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayLong::QuickSearch(const long element) const
{
int i,j,m=-1;
long t_long;
//--- search
i=0;
j=m_data_total-1;
while(j>=i)
{
//--- ">>1" is quick division by 2
m=(j+i)>>1;
if(m<0 || m>=m_data_total)
break;
t_long=m_data[m];
if(t_long==element)
break;
if(t_long>element)
j=m-1;
else
i=m+1;
}
//--- position
return(m);
}
//+------------------------------------------------------------------+
//| Search of position of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayLong::Search(const long element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is greater than |
//| specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayLong::SearchGreat(const long element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
while(m_data[pos]<=element)
if(++pos==m_data_total)
return(-1);
//--- position
return(pos);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is less than |
//| specified in the sorted array |
//+------------------------------------------------------------------+
int CArrayLong::SearchLess(const long element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
while(m_data[pos]>=element)
if(pos--==0)
return(-1);
//--- position
return(pos);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is greater than or |
//| equal to the specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayLong::SearchGreatOrEqual(const long element) const
{
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
for(int pos=QuickSearch(element);pos<m_data_total;pos++)
if(m_data[pos]>=element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is less than or equal |
//| to the specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayLong::SearchLessOrEqual(const long element) const
{
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
for(int pos=QuickSearch(element);pos>=0;pos--)
if(m_data[pos]<=element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Find position of first appearance of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayLong::SearchFirst(const long element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
{
while(m_data[pos]==element)
if(pos--==0)
break;
return(pos+1);
}
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Find position of last appearance of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayLong::SearchLast(const long element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
{
while(m_data[pos]==element)
if(++pos==m_data_total)
break;
return(pos-1);
}
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Writing array to file |
//+------------------------------------------------------------------+
bool CArrayLong::Save(const int file_handle)
{
int i=0;
//--- check
if(!CArray::Save(file_handle))
return(false);
//--- write array length
if(FileWriteInteger(file_handle,m_data_total,INT_VALUE)!=INT_VALUE)
return(false);
//--- write array
for(i=0;i<m_data_total;i++)
if(FileWriteLong(file_handle,m_data[i])!=sizeof(long))
break;
//--- result
return(i==m_data_total);
}
//+------------------------------------------------------------------+
//| Reading array from file |
//+------------------------------------------------------------------+
bool CArrayLong::Load(const int file_handle)
{
int i=0,num;
//--- check
if(!CArray::Load(file_handle))
return(false);
//--- read array length
num=FileReadInteger(file_handle,INT_VALUE);
//--- read array
Clear();
if(num!=0)
{
if(!Reserve(num))
return(false);
for(i=0;i<num;i++)
{
m_data[i]=FileReadLong(file_handle);
m_data_total++;
if(FileIsEnding(file_handle))
break;
}
}
m_sort_mode=-1;
//--- result
return(m_data_total==num);
}
//+------------------------------------------------------------------+
+759
View File
@@ -0,0 +1,759 @@
//+------------------------------------------------------------------+
//| ArrayObj.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "Array.mqh"
//+------------------------------------------------------------------+
//| Class CArrayObj. |
//| Puprose: Class of dynamic array of pointers to instances |
//| of the CObject class and its derivatives. |
//| Derives from class CArray. |
//+------------------------------------------------------------------+
class CArrayObj : public CArray
{
protected:
CObject *m_data[]; // data array
bool m_free_mode; // flag of necessity of "physical" deletion of object
public:
CArrayObj(void);
~CArrayObj(void);
//--- methods of access to protected data
bool FreeMode(void) const { return(m_free_mode); }
void FreeMode(const bool mode) { m_free_mode=mode; }
//--- method of identifying the object
virtual int Type(void) const { return(0x7778); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
//--- method of creating an element of array
virtual bool CreateElement(const int index) { return(false); }
//--- methods of managing dynamic memory
bool Reserve(const int size);
bool Resize(const int size);
bool Shutdown(void);
//--- methods of filling the array
bool Add(CObject *element);
bool AddArray(const CArrayObj *src);
bool Insert(CObject *element,const int pos);
bool InsertArray(const CArrayObj *src,const int pos);
bool AssignArray(const CArrayObj *src);
//--- method of access to thre array
CObject *At(const int index) const;
//--- methods of changing
bool Update(const int index,CObject *element);
bool Shift(const int index,const int shift);
//--- methods of deleting
CObject *Detach(const int index);
bool Delete(const int index);
bool DeleteRange(int from,int to);
void Clear(void);
//--- method for comparing arrays
bool CompareArray(const CArrayObj *array) const;
//--- methods for working with the sorted array
bool InsertSort(CObject *element);
int Search(const CObject *element) const;
int SearchGreat(const CObject *element) const;
int SearchLess(const CObject *element) const;
int SearchGreatOrEqual(const CObject *element) const;
int SearchLessOrEqual(const CObject *element) const;
int SearchFirst(const CObject *element) const;
int SearchLast(const CObject *element) const;
protected:
void QuickSort(int beg,int end,const int mode);
int QuickSearch(const CObject *element) const;
int MemMove(const int dest,const int src,int count);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CArrayObj::CArrayObj(void) : m_free_mode(true)
{
//--- initialize protected data
m_data_max=ArraySize(m_data);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CArrayObj::~CArrayObj(void)
{
if(m_data_max!=0)
Shutdown();
}
//+------------------------------------------------------------------+
//| Moving the memory within a single array |
//+------------------------------------------------------------------+
int CArrayObj::MemMove(const int dest,const int src,int count)
{
int i;
//--- check parameters
if(dest<0 || src<0 || count<0)
return(-1);
//--- check count
if(src+count>m_data_total)
count=m_data_total-src;
if(count<0)
return(-1);
//--- no need to copy
if(dest==src || count==0)
return(dest);
//--- check data total
if(dest+count>m_data_total)
{
if(m_data_max<dest+count)
return(-1);
m_data_total=dest+count;
}
//--- copy
if(dest<src)
{
//--- copy from left to right
for(i=0;i<count;i++)
{
//--- "physical" removal of the object (if necessary and possible)
if(m_free_mode && CheckPointer(m_data[dest+i])==POINTER_DYNAMIC)
delete m_data[dest+i];
//---
m_data[dest+i]=m_data[src+i];
m_data[src+i]=NULL;
}
}
else
{
//--- copy from right to left
for(i=count-1;i>=0;i--)
{
//--- "physical" removal of the object (if necessary and possible)
if(m_free_mode && CheckPointer(m_data[dest+i])==POINTER_DYNAMIC)
delete m_data[dest+i];
//---
m_data[dest+i]=m_data[src+i];
m_data[src+i]=NULL;
}
}
//--- successful
return(dest);
}
//+------------------------------------------------------------------+
//| Request for more memory in an array. Checks if the requested |
//| number of free elements already exists; allocates additional |
//| memory with a given step |
//+------------------------------------------------------------------+
bool CArrayObj::Reserve(const int size)
{
int new_size;
//--- check
if(size<=0)
return(false);
//--- resize array
if(Available()<size)
{
new_size=m_data_max+m_step_resize*(1+(size-Available())/m_step_resize);
if(new_size<0)
//--- overflow occurred when calculating new_size
return(false);
if((m_data_max=ArrayResize(m_data,new_size))==-1)
m_data_max=ArraySize(m_data);
//--- explicitly zeroize all the loose items in the array
for(int i=m_data_total;i<m_data_max;i++)
m_data[i]=NULL;
}
//--- result
return(Available()>=size);
}
//+------------------------------------------------------------------+
//| Resizing (with removal of elements on the right) |
//+------------------------------------------------------------------+
bool CArrayObj::Resize(const int size)
{
int new_size;
//--- check
if(size<0)
return(false);
//--- resize array
new_size=m_step_resize*(1+size/m_step_resize);
if(m_data_total>size)
{
//--- "physical" removal of the object (if necessary and possible)
if(m_free_mode)
for(int i=size;i<m_data_total;i++)
if(CheckPointer(m_data[i])==POINTER_DYNAMIC)
delete m_data[i];
m_data_total=size;
}
if(m_data_max!=new_size)
{
if((m_data_max=ArrayResize(m_data,new_size))==-1)
{
m_data_max=ArraySize(m_data);
return(false);
}
}
//--- result
return(m_data_max==new_size);
}
//+------------------------------------------------------------------+
//| Complete cleaning of the array with the release of memory |
//+------------------------------------------------------------------+
bool CArrayObj::Shutdown(void)
{
//--- check
if(m_data_max==0)
return(true);
//--- clean
Clear();
if(ArrayResize(m_data,0)==-1)
return(false);
m_data_max=0;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array |
//+------------------------------------------------------------------+
bool CArrayObj::Add(CObject *element)
{
//--- check
if(!CheckPointer(element))
return(false);
//--- check/reserve elements of array
if(!Reserve(1))
return(false);
//--- add
m_data[m_data_total++]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array from another array |
//+------------------------------------------------------------------+
bool CArrayObj::AddArray(const CArrayObj *src)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.Total();
if(!Reserve(num))
return(false);
//--- add
for(int i=0;i<num;i++)
m_data[m_data_total++]=src.m_data[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting an element in the specified position |
//+------------------------------------------------------------------+
bool CArrayObj::Insert(CObject *element,const int pos)
{
//--- check
if(pos<0 || !CheckPointer(element))
return(false);
//--- check/reserve elements of array
if(!Reserve(1))
return(false);
//--- insert
m_data_total++;
if(pos<m_data_total-1)
{
if(MemMove(pos+1,pos,m_data_total-pos-1)<0)
return(false);
m_data[pos]=element;
}
else
m_data[m_data_total-1]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting elements in the specified position |
//+------------------------------------------------------------------+
bool CArrayObj::InsertArray(const CArrayObj *src,const int pos)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.Total();
if(!Reserve(num)) return(false);
//--- insert
if(MemMove(num+pos,pos,m_data_total-pos)<0)
return(false);
for(int i=0;i<num;i++)
m_data[i+pos]=src.m_data[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Assignment (copying) of another array |
//+------------------------------------------------------------------+
bool CArrayObj::AssignArray(const CArrayObj *src)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.m_data_total;
Clear();
if(m_data_max<num)
{
if(!Reserve(num))
return(false);
}
else
Resize(num);
//--- copy array
for(int i=0;i<num;i++)
{
m_data[i]=src.m_data[i];
m_data_total++;
}
m_sort_mode=src.SortMode();
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Access to data in the specified position |
//+------------------------------------------------------------------+
CObject *CArrayObj::At(const int index) const
{
//--- check
if(index<0 || index>=m_data_total)
return(NULL);
//--- result
return(m_data[index]);
}
//+------------------------------------------------------------------+
//| Updating element in the specified position |
//+------------------------------------------------------------------+
bool CArrayObj::Update(const int index,CObject *element)
{
//--- check
if(index<0 || !CheckPointer(element) || index>=m_data_total)
return(false);
//--- "physical" removal of the object (if necessary and possible)
if(m_free_mode && CheckPointer(m_data[index])==POINTER_DYNAMIC)
delete m_data[index];
//--- update
m_data[index]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Moving element from the specified position |
//| on the specified shift |
//+------------------------------------------------------------------+
bool CArrayObj::Shift(const int index,const int shift)
{
CObject *tmp_node;
//--- check
if(index<0 || index+shift<0 || index+shift>=m_data_total)
return(false);
if(shift==0)
return(true);
//--- move
tmp_node=m_data[index];
m_data[index]=NULL;
if(shift>0)
{
if(MemMove(index,index+1,shift)<0)
return(false);
}
else
{
if(MemMove(index+shift+1,index+shift,-shift)<0)
return(false);
}
m_data[index+shift]=tmp_node;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Deleting element from the specified position |
//+------------------------------------------------------------------+
bool CArrayObj::Delete(const int index)
{
//--- check
if(index>=m_data_total)
return(false);
//--- delete
if(index<m_data_total-1)
{
if(index>=0 && MemMove(index,index+1,m_data_total-index-1)<0)
return(false);
}
else
if(m_free_mode && CheckPointer(m_data[index])==POINTER_DYNAMIC)
delete m_data[index];
m_data_total--;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Detach element from the specified position |
//+------------------------------------------------------------------+
CObject *CArrayObj::Detach(const int index)
{
CObject *result;
//--- check
if(index>=m_data_total)
return(NULL);
//--- detach
result=m_data[index];
//--- reset the array element, so as not remove the method MemMove
m_data[index]=NULL;
if(index<m_data_total-1 && MemMove(index,index+1,m_data_total-index-1)<0)
return(NULL);
m_data_total--;
//--- successful
return(result);
}
//+------------------------------------------------------------------+
//| Deleting range of elements |
//+------------------------------------------------------------------+
bool CArrayObj::DeleteRange(int from,int to)
{
//--- check
if(from<0 || to<0)
return(false);
if(from>to || from>=m_data_total)
return(false);
//--- delete
if(to>=m_data_total-1)
to=m_data_total-1;
if(MemMove(from,to+1,m_data_total-to-1)<0)
return(false);
for(int i=to-from+1;i>0;i--,m_data_total--)
if(m_free_mode && CheckPointer(m_data[m_data_total-1])==POINTER_DYNAMIC)
delete m_data[m_data_total-1];
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Clearing of array without the release of memory |
//+------------------------------------------------------------------+
void CArrayObj::Clear(void)
{
//--- "physical" removal of the object (if necessary and possible)
if(m_free_mode)
{
for(int i=0;i<m_data_total;i++)
{
if(CheckPointer(m_data[i])==POINTER_DYNAMIC)
delete m_data[i];
m_data[i]=NULL;
}
}
m_data_total=0;
}
//+------------------------------------------------------------------+
//| Equality comparison of two arrays |
//+------------------------------------------------------------------+
bool CArrayObj::CompareArray(const CArrayObj *array) const
{
//--- check
if(!CheckPointer(array))
return(false);
//--- compare
if(m_data_total!=array.m_data_total)
return(false);
for(int i=0;i<m_data_total;i++)
if(m_data[i].Compare(array.m_data[i],0)!=0)
return(false);
//--- equal
return(true);
}
//+------------------------------------------------------------------+
//| Method QuickSort |
//+------------------------------------------------------------------+
void CArrayObj::QuickSort(int beg,int end,const int mode)
{
int i,j;
CObject *p_node;
CObject *t_node;
//--- sort
i=beg;
j=end;
while(i<end)
{
//--- ">>1" is quick division by 2
p_node=m_data[(beg+end)>>1];
while(i<j)
{
while(m_data[i].Compare(p_node,mode)<0)
{
//--- control the output of the array bounds
if(i==m_data_total-1)
break;
i++;
}
while(m_data[j].Compare(p_node,mode)>0)
{
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
if(i<=j)
{
t_node=m_data[i];
m_data[i++]=m_data[j];
m_data[j]=t_node;
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
}
if(beg<j)
QuickSort(beg,j,mode);
beg=i;
j=end;
}
}
//+------------------------------------------------------------------+
//| Inserting element in a sorted array |
//+------------------------------------------------------------------+
bool CArrayObj::InsertSort(CObject *element)
{
int pos;
//--- check
if(!CheckPointer(element) || m_sort_mode==-1)
return(false);
//--- check/reserve elements of array
if(!Reserve(1))
return(false);
//--- if the array is empty, add an element
if(m_data_total==0)
{
m_data[m_data_total++]=element;
return(true);
}
//--- find position and insert
int mode=m_sort_mode;
pos=QuickSearch(element);
if(m_data[pos].Compare(element,m_sort_mode)>0)
Insert(element,pos);
else
Insert(element,pos+1);
//--- restore the sorting flag after Insert(...)
m_sort_mode=mode;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Quick search of position of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayObj::QuickSearch(const CObject *element) const
{
int i,j,m=-1;
CObject *t_node;
//--- search
i=0;
j=m_data_total-1;
while(j>=i)
{
//--- ">>1" is quick division by 2
m=(j+i)>>1;
if(m<0 || m==m_data_total-1)
break;
t_node=m_data[m];
if(t_node.Compare(element,m_sort_mode)==0)
break;
if(t_node.Compare(element,m_sort_mode)>0)
j=m-1;
else
i=m+1;
}
//--- position
return(m);
}
//+------------------------------------------------------------------+
//| Search of position of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayObj::Search(const CObject *element) const
{
int pos;
//--- check
if(m_data_total==0 || !CheckPointer(element) || m_sort_mode==-1)
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos].Compare(element,m_sort_mode)==0)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is greater than |
//| specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayObj::SearchGreat(const CObject *element) const
{
int pos;
//--- check
if(m_data_total==0 || !CheckPointer(element) || m_sort_mode==-1)
return(-1);
//--- search
pos=QuickSearch(element);
while(m_data[pos].Compare(element,m_sort_mode)<=0)
if(++pos==m_data_total)
return(-1);
//--- position
return(pos);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is less than |
//| specified in the sorted array |
//+------------------------------------------------------------------+
int CArrayObj::SearchLess(const CObject *element) const
{
int pos;
//--- check
if(m_data_total==0 || !CheckPointer(element) || m_sort_mode==-1)
return(-1);
//--- search
pos=QuickSearch(element);
while(m_data[pos].Compare(element,m_sort_mode)>=0)
if(pos--==0)
return(-1);
//--- position
return(pos);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is greater than or |
//| equal to the specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayObj::SearchGreatOrEqual(const CObject *element) const
{
//--- check
if(m_data_total==0 || !CheckPointer(element) || m_sort_mode==-1)
return(-1);
//--- search
for(int pos=QuickSearch(element);pos<m_data_total;pos++)
if(m_data[pos].Compare(element,m_sort_mode)>=0)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is less than or equal |
//| to the specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayObj::SearchLessOrEqual(const CObject *element) const
{
//--- check
if(m_data_total==0 || !CheckPointer(element) || m_sort_mode==-1)
return(-1);
//--- search
for(int pos=QuickSearch(element);pos>=0;pos--)
if(m_data[pos].Compare(element,m_sort_mode)<=0)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Find position of first appearance of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayObj::SearchFirst(const CObject *element) const
{
int pos;
//--- check
if(m_data_total==0 || !CheckPointer(element) || m_sort_mode==-1)
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos].Compare(element,m_sort_mode)==0)
{
while(m_data[pos].Compare(element,m_sort_mode)==0)
if(pos--==0)
break;
return(pos+1);
}
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Find position of last appearance of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayObj::SearchLast(const CObject *element) const
{
int pos;
//--- check
if(m_data_total==0 || !CheckPointer(element) || m_sort_mode==-1)
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos].Compare(element,m_sort_mode)==0)
{
while(m_data[pos].Compare(element,m_sort_mode)==0)
if(++pos==m_data_total)
break;
return(pos-1);
}
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Writing array to file |
//+------------------------------------------------------------------+
bool CArrayObj::Save(const int file_handle)
{
int i=0;
//--- check
if(!CArray::Save(file_handle))
return(false);
//--- write array length
if(FileWriteInteger(file_handle,m_data_total,INT_VALUE)!=INT_VALUE)
return(false);
//--- write array
for(i=0;i<m_data_total;i++)
if(m_data[i].Save(file_handle)!=true)
break;
//--- result
return(i==m_data_total);
}
//+------------------------------------------------------------------+
//| Reading array from file |
//+------------------------------------------------------------------+
bool CArrayObj::Load(const int file_handle)
{
int i=0,num;
//--- check
if(!CArray::Load(file_handle))
return(false);
//--- read array length
num=FileReadInteger(file_handle,INT_VALUE);
//--- read array
Clear();
if(num!=0)
{
if(!Reserve(num))
return(false);
for(i=0;i<num;i++)
{
//--- create new element
if(!CreateElement(i))
break;
if(m_data[i].Load(file_handle)!=true)
break;
m_data_total++;
}
}
m_sort_mode=-1;
//--- result
return(m_data_total==num);
}
//+------------------------------------------------------------------+
+770
View File
@@ -0,0 +1,770 @@
//+------------------------------------------------------------------+
//| ArrayShort.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "Array.mqh"
//+------------------------------------------------------------------+
//| Class CArrayShort. |
//| Pupose: Class of dynamic array of variables |
//| of short or ushort type. |
//| Derives from class CArray. |
//+------------------------------------------------------------------+
class CArrayShort : public CArray
{
protected:
short m_data[]; // data array
public:
CArrayShort(void);
~CArrayShort(void);
//--- method of identifying the object
virtual int Type(void) const { return(TYPE_SHORT); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
//--- methods of managing dynamic memory
bool Reserve(const int size);
bool Resize(const int size);
bool Shutdown(void);
//--- methods of filling the array
bool Add(const short element);
bool AddArray(const short &src[]);
bool AddArray(const CArrayShort *src);
bool Insert(const short element,const int pos);
bool InsertArray(const short &src[],const int pos);
bool InsertArray(const CArrayShort *src,const int pos);
bool AssignArray(const short &src[]);
bool AssignArray(const CArrayShort *src);
//--- method of access to the array
short At(const int index) const;
short operator[](const int index) const { return(At(index)); }
//--- methods of searching for minimum and maximum
int Minimum(const int start,const int count) const { return(Minimum(m_data,start,count)); }
int Maximum(const int start,const int count) const { return(Maximum(m_data,start,count)); }
//--- methods of changing
bool Update(const int index,const short element);
bool Shift(const int index,const int shift);
//--- methods of deleting
bool Delete(const int index);
bool DeleteRange(int from,int to);
//--- methods for comparing arrays
bool CompareArray(const short &array[]) const;
bool CompareArray(const CArrayShort *array) const;
//--- methods for working with the sorted array
bool InsertSort(const short element);
int Search(const short element) const;
int SearchGreat(const short element) const;
int SearchLess(const short element) const;
int SearchGreatOrEqual(const short element) const;
int SearchLessOrEqual(const short element) const;
int SearchFirst(const short element) const;
int SearchLast(const short element) const;
int SearchLinear(const short element) const;
protected:
virtual void QuickSort(int beg,int end,const int mode=0);
int QuickSearch(const short element) const;
int MemMove(const int dest,const int src,int count);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CArrayShort::CArrayShort(void)
{
//--- initialize protected data
m_data_max=ArraySize(m_data);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CArrayShort::~CArrayShort(void)
{
if(m_data_max!=0)
Shutdown();
}
//+------------------------------------------------------------------+
//| Moving the memory within a single array |
//+------------------------------------------------------------------+
int CArrayShort::MemMove(const int dest,const int src,int count)
{
int i;
//--- check parameters
if(dest<0 || src<0 || count<0)
return(-1);
//--- check count
if(src+count>m_data_total)
count=m_data_total-src;
if(count<0)
return(-1);
//--- no need to copy
if(dest==src || count==0)
return(dest);
//--- check data total
if(dest+count>m_data_total)
{
if(m_data_max<dest+count)
return(-1);
m_data_total=dest+count;
}
//--- copy
if(dest<src)
{
//--- copy from left to right
for(i=0;i<count;i++)
m_data[dest+i]=m_data[src+i];
}
else
{
//--- copy from right to left
for(i=count-1;i>=0;i--)
m_data[dest+i]=m_data[src+i];
}
//--- successful
return(dest);
}
//+------------------------------------------------------------------+
//| Request for more memory in an array. Checks if the requested |
//| number of free elements already exists; allocates additional |
//| memory with a given step |
//+------------------------------------------------------------------+
bool CArrayShort::Reserve(const int size)
{
int new_size;
//--- check
if(size<=0)
return(false);
//--- resize array
if(Available()<size)
{
new_size=m_data_max+m_step_resize*(1+(size-Available())/m_step_resize);
if(new_size<0)
//--- overflow occurred when calculating new_size
return(false);
if((m_data_max=ArrayResize(m_data,new_size))==-1)
m_data_max=ArraySize(m_data);
}
//--- result
return(Available()>=size);
}
//+------------------------------------------------------------------+
//| Resizing (with removal of elements on the right) |
//+------------------------------------------------------------------+
bool CArrayShort::Resize(const int size)
{
int new_size;
//--- check
if(size<0)
return(false);
//--- resize array
new_size=m_step_resize*(1+size/m_step_resize);
if(m_data_max!=new_size)
{
if((m_data_max=ArrayResize(m_data,new_size))==-1)
{
m_data_max=ArraySize(m_data);
return(false);
}
}
if(m_data_total>size)
m_data_total=size;
//--- result
return(m_data_max==new_size);
}
//+------------------------------------------------------------------+
//| Complete cleaning of the array with the release of memory |
//+------------------------------------------------------------------+
bool CArrayShort::Shutdown(void)
{
//--- check
if(m_data_max==0)
return(true);
//--- clean
if(ArrayResize(m_data,0)==-1)
return(false);
m_data_total=0;
m_data_max=0;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array |
//+------------------------------------------------------------------+
bool CArrayShort::Add(const short element)
{
//--- check/reserve elements of array
if(!Reserve(1))
return(false);
//--- add
m_data[m_data_total++]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array from another array |
//+------------------------------------------------------------------+
bool CArrayShort::AddArray(const short &src[])
{
int num=ArraySize(src);
//--- check/reserve elements of array
if(!Reserve(num))
return(false);
//--- add
for(int i=0;i<num;i++)
m_data[m_data_total++]=src[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array from another array |
//+------------------------------------------------------------------+
bool CArrayShort::AddArray(const CArrayShort *src)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.Total();
if(!Reserve(num))
return(false);
//--- add
for(int i=0;i<num;i++)
m_data[m_data_total++]=src.m_data[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting an element in the specified position |
//+------------------------------------------------------------------+
bool CArrayShort::Insert(const short element,const int pos)
{
//--- check/reserve elements of array
if(pos<0 || !Reserve(1))
return(false);
//--- insert
m_data_total++;
if(pos<m_data_total-1)
{
if(MemMove(pos+1,pos,m_data_total-pos-1)<0)
return(false);
m_data[pos]=element;
}
else
m_data[m_data_total-1]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting elements in the specified position |
//+------------------------------------------------------------------+
bool CArrayShort::InsertArray(const short &src[],const int pos)
{
int num=ArraySize(src);
//--- check/reserve elements of array
if(!Reserve(num))
return(false);
//--- insert
if(MemMove(num+pos,pos,m_data_total-pos)<0)
return(false);
for(int i=0;i<num;i++)
m_data[i+pos]=src[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting elements in the specified position |
//+------------------------------------------------------------------+
bool CArrayShort::InsertArray(const CArrayShort *src,const int pos)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.Total();
if(!Reserve(num))
return(false);
//--- insert
if(MemMove(num+pos,pos,m_data_total-pos)<0)
return(false);
for(int i=0;i<num;i++)
m_data[i+pos]=src.m_data[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Assignment (copying) of another array |
//+------------------------------------------------------------------+
bool CArrayShort::AssignArray(const short &src[])
{
int num=ArraySize(src);
//--- check/reserve elements of array
Clear();
if(m_data_max<num)
{
if(!Reserve(num))
return(false);
}
else
Resize(num);
//--- copy array
for(int i=0;i<num;i++)
{
m_data[i]=src[i];
m_data_total++;
}
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Assignment (copying) of another array |
//+------------------------------------------------------------------+
bool CArrayShort::AssignArray(const CArrayShort *src)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.m_data_total;
Clear();
if(m_data_max<num)
{
if(!Reserve(num))
return(false);
}
else
Resize(num);
//--- copy array
for(int i=0;i<num;i++)
{
m_data[i]=src.m_data[i];
m_data_total++;
}
m_sort_mode=src.SortMode();
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Access to data in the specified position |
//+------------------------------------------------------------------+
short CArrayShort::At(const int index) const
{
//--- check
if(index<0 || index>=m_data_total)
return(SHORT_MAX);
//--- result
return(m_data[index]);
}
//+------------------------------------------------------------------+
//| Updating element in the specified position |
//+------------------------------------------------------------------+
bool CArrayShort::Update(const int index,const short element)
{
//--- check
if(index<0 || index>=m_data_total)
return(false);
//--- update
m_data[index]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Moving element from the specified position |
//| on the specified shift |
//+------------------------------------------------------------------+
bool CArrayShort::Shift(const int index,const int shift)
{
short tmp_short;
//--- check
if(index<0 || index+shift<0 || index+shift>=m_data_total)
return(false);
if(shift==0)
return(true);
//--- move
tmp_short=m_data[index];
if(shift>0)
{
if(MemMove(index,index+1,shift)<0)
return(false);
}
else
{
if(MemMove(index+shift+1,index+shift,-shift)<0)
return(false);
}
m_data[index+shift]=tmp_short;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Deleting element from the specified position |
//+------------------------------------------------------------------+
bool CArrayShort::Delete(const int index)
{
//--- check
if(index<0 || index>=m_data_total)
return(false);
//--- delete
if(index<m_data_total-1 && MemMove(index,index+1,m_data_total-index-1)<0)
return(false);
m_data_total--;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Deleting range of elements |
//+------------------------------------------------------------------+
bool CArrayShort::DeleteRange(int from,int to)
{
//--- check
if(from<0 || to<0)
return(false);
if(from>to || from>=m_data_total)
return(false);
//--- delete
if(to>=m_data_total-1)
to=m_data_total-1;
if(MemMove(from,to+1,m_data_total-to-1)<0)
return(false);
m_data_total-=to-from+1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Equality comparison of two arrays |
//+------------------------------------------------------------------+
bool CArrayShort::CompareArray(const short &array[]) const
{
//--- compare
if(m_data_total!=ArraySize(array))
return(false);
for(int i=0;i<m_data_total;i++)
if(m_data[i]!=array[i])
return(false);
//--- equal
return(true);
}
//+------------------------------------------------------------------+
//| Equality comparison of two arrays |
//+------------------------------------------------------------------+
bool CArrayShort::CompareArray(const CArrayShort *array) const
{
//--- check
if(!CheckPointer(array))
return(false);
//--- compare
if(m_data_total!=array.m_data_total)
return(false);
for(int i=0;i<m_data_total;i++)
if(m_data[i]!=array.m_data[i])
return(false);
//--- equal
return(true);
}
//+------------------------------------------------------------------+
//| Method QuickSort |
//+------------------------------------------------------------------+
void CArrayShort::QuickSort(int beg,int end,const int mode)
{
int i,j;
short p_short,t_short;
//--- check
if(beg<0 || end<0)
return;
//--- sort
i=beg;
j=end;
while(i<end)
{
//--- ">>1" is quick division by 2
p_short=m_data[(beg+end)>>1];
while(i<j)
{
while(m_data[i]<p_short)
{
//--- control the output of the array bounds
if(i==m_data_total-1)
break;
i++;
}
while(m_data[j]>p_short)
{
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
if(i<=j)
{
t_short=m_data[i];
m_data[i++]=m_data[j];
m_data[j]=t_short;
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
}
if(beg<j)
QuickSort(beg,j);
beg=i;
j=end;
}
}
//+------------------------------------------------------------------+
//| Inserting element in a sorted array |
//+------------------------------------------------------------------+
bool CArrayShort::InsertSort(const short element)
{
int pos;
//--- check
if(!IsSorted())
return(false);
//--- check/reserve elements of array
if(!Reserve(1))
return(false);
//--- if the array is empty, add an element
if(m_data_total==0)
{
m_data[m_data_total++]=element;
return(true);
}
//--- find position and insert
pos=QuickSearch(element);
if(m_data[pos]>element)
Insert(element,pos);
else
Insert(element,pos+1);
//--- restore the sorting flag after Insert(...)
m_sort_mode=0;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Search of position of element in a array |
//+------------------------------------------------------------------+
int CArrayShort::SearchLinear(const short element) const
{
//--- check
if(m_data_total==0)
return(-1);
//---
for(int i=0;i<m_data_total;i++)
if(m_data[i]==element)
return(i);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Quick search of position of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayShort::QuickSearch(const short element) const
{
int i,j,m=-1;
short t_short;
//--- search
i=0;
j=m_data_total-1;
while(j>=i)
{
//--- ">>1" is quick division by 2
m=(j+i)>>1;
if(m<0 || m>=m_data_total)
break;
t_short=m_data[m];
if(t_short==element)
break;
if(t_short>element)
j=m-1;
else
i=m+1;
}
//--- position
return(m);
}
//+------------------------------------------------------------------+
//| Search of position of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayShort::Search(const short element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is greater than |
//| specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayShort::SearchGreat(const short element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
while(m_data[pos]<=element)
if(++pos==m_data_total)
return(-1);
//--- position
return(pos);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is less than |
//| specified in the sorted array |
//+------------------------------------------------------------------+
int CArrayShort::SearchLess(const short element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
while(m_data[pos]>=element)
if(pos--==0)
return(-1);
//--- position
return(pos);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is greater than or |
//| equal to the specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayShort::SearchGreatOrEqual(const short element) const
{
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
for(int pos=QuickSearch(element);pos<m_data_total;pos++)
if(m_data[pos]>=element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is less than or equal |
//| to the specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayShort::SearchLessOrEqual(const short element) const
{
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
for(int pos=QuickSearch(element);pos>=0;pos--)
if(m_data[pos]<=element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Find position of first appearance of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayShort::SearchFirst(const short element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
{
while(m_data[pos]==element)
if(pos--==0)
break;
return(pos+1);
}
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Find position of last appearance of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayShort::SearchLast(const short element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
{
while(m_data[pos]==element)
if(++pos==m_data_total)
break;
return(pos-1);
}
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Writing array to file |
//+------------------------------------------------------------------+
bool CArrayShort::Save(const int file_handle)
{
int i=0;
//--- check
if(!CArray::Save(file_handle))
return(false);
//--- write array length
if(FileWriteInteger(file_handle,m_data_total,INT_VALUE)!=INT_VALUE)
return(false);
//--- write array
for(i=0;i<m_data_total;i++)
if(FileWriteInteger(file_handle,m_data[i],SHORT_VALUE)!=SHORT_VALUE)
break;
//--- result
return(i==m_data_total);
}
//+------------------------------------------------------------------+
//| Reading array from file |
//+------------------------------------------------------------------+
bool CArrayShort::Load(const int file_handle)
{
int i=0,num;
//--- check
if(!CArray::Load(file_handle))
return(false);
//--- read array length
num=FileReadInteger(file_handle,INT_VALUE);
//--- read array
Clear();
if(num!=0)
{
if(!Reserve(num))
return(false);
for(i=0;i<num;i++)
{
m_data[i]=(short)FileReadInteger(file_handle,SHORT_VALUE);
m_data_total++;
if(FileIsEnding(file_handle))
break;
}
}
m_sort_mode=-1;
//--- result
return(m_data_total==num);
}
//+------------------------------------------------------------------+
+780
View File
@@ -0,0 +1,780 @@
//+------------------------------------------------------------------+
//| ArrayString.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "Array.mqh"
//+------------------------------------------------------------------+
//| Class CArrayString. |
//| Purpose: Class of dynamic array of variables of string type. |
//| Derives from class CArray. |
//+------------------------------------------------------------------+
class CArrayString : public CArray
{
protected:
string m_data[]; // data array
public:
CArrayString(void);
~CArrayString(void);
//--- method of identifying the object
virtual int Type(void) const { return(TYPE_STRING); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
//--- methods of managing dynamic memory
bool Reserve(const int size);
bool Resize(const int size);
bool Shutdown(void);
//--- methods of filling the array
bool Add(const string element);
bool AddArray(const string &src[]);
bool AddArray(const CArrayString *src);
bool Insert(const string element,const int pos);
bool InsertArray(const string &src[],const int pos);
bool InsertArray(const CArrayString *src,const int pos);
bool AssignArray(const string &src[]);
bool AssignArray(const CArrayString *src);
//--- method of access to the array
string At(const int index) const;
string operator[](const int index) const { return(At(index)); }
//--- methods of changing
bool Update(const int index,const string element);
bool Shift(const int index,const int shift);
//--- methods of deleting
bool Delete(const int index);
bool DeleteRange(int from,int to);
//--- methods for comparing arrays
bool CompareArray(const string &array[]) const;
bool CompareArray(const CArrayString *array) const;
//--- methods for working with the sorted array
bool InsertSort(const string element);
int Search(const string element) const;
int SearchGreat(const string element) const;
int SearchLess(const string element) const;
int SearchGreatOrEqual(const string element) const;
int SearchLessOrEqual(const string element) const;
int SearchFirst(const string element) const;
int SearchLast(const string element) const;
int SearchLinear(const string element) const;
protected:
virtual void QuickSort(int beg,int end,const int mode=0);
int QuickSearch(const string element) const;
int MemMove(const int dest,const int src,int count);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CArrayString::CArrayString(void)
{
//--- initialize protected data
m_data_max=ArraySize(m_data);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CArrayString::~CArrayString(void)
{
if(m_data_max!=0)
Shutdown();
}
//+------------------------------------------------------------------+
//| Moving the memory within a single array |
//+------------------------------------------------------------------+
int CArrayString::MemMove(const int dest,const int src,int count)
{
int i;
//--- check parameters
if(dest<0 || src<0 || count<0)
return(-1);
//--- check count
if(src+count>m_data_total)
count=m_data_total-src;
if(count<0)
return(-1);
//--- no need to copy
if(dest==src || count==0)
return(dest);
//--- check data total
if(dest+count>m_data_total)
{
if(m_data_max<dest+count)
return(-1);
m_data_total=dest+count;
}
//--- copy
if(dest<src)
{
//--- copy from left to right
for(i=0;i<count;i++)
m_data[dest+i]=m_data[src+i];
}
else
{
//--- copy from right to left
for(i=count-1;i>=0;i--)
m_data[dest+i]=m_data[src+i];
}
//--- successful
return(dest);
}
//+------------------------------------------------------------------+
//| Request for more memory in an array. Checks if the requested |
//| number of free elements already exists; allocates additional |
//| memory with a given step |
//+------------------------------------------------------------------+
bool CArrayString::Reserve(const int size)
{
int new_size;
//--- check
if(size<=0)
return(false);
//--- resize array
if(Available()<size)
{
new_size=m_data_max+m_step_resize*(1+(size-Available())/m_step_resize);
if(new_size<0)
//--- overflow occurred when calculating new_size
return(false);
if((m_data_max=ArrayResize(m_data,new_size))==-1)
m_data_max=ArraySize(m_data);
}
//--- result
return(Available()>=size);
}
//+------------------------------------------------------------------+
//| Resizing (with removal of elements on the right) |
//+------------------------------------------------------------------+
bool CArrayString::Resize(const int size)
{
int new_size;
//--- check
if(size<0)
return(false);
//--- resize array
new_size=m_step_resize*(1+size/m_step_resize);
if(m_data_max!=new_size)
{
if((m_data_max=ArrayResize(m_data,new_size))==-1)
{
m_data_max=ArraySize(m_data);
return(false);
}
}
if(m_data_total>size)
m_data_total=size;
//--- result
return(m_data_max==new_size);
}
//+------------------------------------------------------------------+
//| Complete cleaning of the array with the release of memory |
//+------------------------------------------------------------------+
bool CArrayString::Shutdown(void)
{
//--- check
if(m_data_max==0)
return(true);
//--- clean
if(ArrayResize(m_data,0)==-1)
return(false);
m_data_total=0;
m_data_max=0;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array |
//+------------------------------------------------------------------+
bool CArrayString::Add(const string element)
{
//--- check/reserve elements of array
if(!Reserve(1))
return(false);
//--- add
m_data[m_data_total++]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array from another array |
//+------------------------------------------------------------------+
bool CArrayString::AddArray(const string &src[])
{
int num=ArraySize(src);
//--- check/reserve elements of array
if(!Reserve(num))
return(false);
//--- add
for(int i=0;i<num;i++)
m_data[m_data_total++]=src[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Adding an element to the end of the array from another array |
//+------------------------------------------------------------------+
bool CArrayString::AddArray(const CArrayString *src)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.Total();
if(!Reserve(num))
return(false);
//--- add
for(int i=0;i<num;i++)
m_data[m_data_total++]=src.m_data[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting an element in the specified position |
//+------------------------------------------------------------------+
bool CArrayString::Insert(const string element,const int pos)
{
//--- check/reserve elements of array
if(pos<0 || !Reserve(1))
return(false);
//--- insert
m_data_total++;
if(pos<m_data_total-1)
{
if(MemMove(pos+1,pos,m_data_total-pos-1)<0)
return(false);
m_data[pos]=element;
}
else
m_data[m_data_total-1]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting elements in the specified position |
//+------------------------------------------------------------------+
bool CArrayString::InsertArray(const string &src[],const int pos)
{
int num=ArraySize(src);
//--- check/reserve elements of array
if(!Reserve(num))
return(false);
//--- insert
if(MemMove(num+pos,pos,m_data_total-pos)<0)
return(false);
for(int i=0;i<num;i++)
m_data[i+pos]=src[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Inserting elements in the specified position |
//+------------------------------------------------------------------+
bool CArrayString::InsertArray(const CArrayString *src,const int pos)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.Total();
if(!Reserve(num))
return(false);
//--- insert
if(MemMove(num+pos,pos,m_data_total-pos)<0)
return(false);
for(int i=0;i<num;i++)
m_data[i+pos]=src.m_data[i];
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Assignment (copying) of another array |
//+------------------------------------------------------------------+
bool CArrayString::AssignArray(const string &src[])
{
int num=ArraySize(src);
//--- check/reserve elements of array
Clear();
if(m_data_max<num)
{
if(!Reserve(num))
return(false);
}
else
Resize(num);
//--- copy array
for(int i=0;i<num;i++)
{
m_data[i]=src[i];
m_data_total++;
}
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Assignment (copying) of another array |
//+------------------------------------------------------------------+
bool CArrayString::AssignArray(const CArrayString *src)
{
int num;
//--- check
if(!CheckPointer(src))
return(false);
//--- check/reserve elements of array
num=src.m_data_total;
Clear();
if(m_data_max<num)
{
if(!Reserve(num))
return(false);
}
else
Resize(num);
//--- copy array
for(int i=0;i<num;i++)
{
m_data[i]=src.m_data[i];
m_data_total++;
}
m_sort_mode=src.SortMode();
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Access to data in the specified position |
//+------------------------------------------------------------------+
string CArrayString::At(const int index) const
{
//--- check
if(index<0 || index>=m_data_total)
return("");
//--- result
return(m_data[index]);
}
//+------------------------------------------------------------------+
//| Updating element in the specified position |
//+------------------------------------------------------------------+
bool CArrayString::Update(const int index,const string element)
{
//--- check
if(index<0 || index>=m_data_total)
return(false);
//--- update
m_data[index]=element;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Moving element from the specified position |
//| on the specified shift |
//+------------------------------------------------------------------+
bool CArrayString::Shift(const int index,const int shift)
{
string tmp_string;
//--- check
if(index<0 || index+shift<0 || index+shift>=m_data_total)
return(false);
if(shift==0)
return(true);
//--- move
tmp_string=m_data[index];
if(shift>0)
{
if(MemMove(index,index+1,shift)<0)
return(false);
}
else
{
if(MemMove(index+shift+1,index+shift,-shift)<0)
return(false);
}
m_data[index+shift]=tmp_string;
m_sort_mode=-1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Deleting element from the specified position |
//+------------------------------------------------------------------+
bool CArrayString::Delete(const int index)
{
//--- check
if(index<0 || index>=m_data_total)
return(false);
//--- delete
if(index<m_data_total-1 && MemMove(index,index+1,m_data_total-index-1)<0)
return(false);
m_data_total--;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Deleting range of elements |
//+------------------------------------------------------------------+
bool CArrayString::DeleteRange(int from,int to)
{
//--- check
if(from<0 || to<0)
return(false);
if(from>to || from>=m_data_total)
return(false);
//--- delete
if(to>=m_data_total-1)
to=m_data_total-1;
if(MemMove(from,to+1,m_data_total-to-1)<0)
return(false);
m_data_total-=to-from+1;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Equality comparison of two arrays |
//+------------------------------------------------------------------+
bool CArrayString::CompareArray(const string &array[]) const
{
//--- compare
if(m_data_total!=ArraySize(array))
return(false);
for(int i=0;i<m_data_total;i++)
if(m_data[i]!=array[i])
return(false);
//--- equal
return(true);
}
//+------------------------------------------------------------------+
//| Equality comparison of two arrays |
//+------------------------------------------------------------------+
bool CArrayString::CompareArray(const CArrayString *array) const
{
//--- check
if(!CheckPointer(array))
return(false);
//--- compare
if(m_data_total!=array.m_data_total)
return(false);
for(int i=0;i<m_data_total;i++)
if(m_data[i]!=array.m_data[i])
return(false);
//--- equal
return(true);
}
//+------------------------------------------------------------------+
//| Method QuickSort |
//+------------------------------------------------------------------+
void CArrayString::QuickSort(int beg,int end,const int mode)
{
int i,j;
string p_string;
string t_string;
//--- check
if(beg<0 || end<0)
return;
//--- sort
i=beg;
j=end;
while(i<end)
{
//--- ">>1" is quick division by 2
p_string=m_data[(beg+end)>>1];
while(i<j)
{
while(m_data[i]<p_string)
{
//--- control the output of the array bounds
if(i==m_data_total-1)
break;
i++;
}
while(m_data[j]>p_string)
{
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
if(i<=j)
{
t_string=m_data[i];
m_data[i++]=m_data[j];
m_data[j]=t_string;
//--- control the output of the array bounds
if(j==0)
break;
j--;
}
}
if(beg<j)
QuickSort(beg,j);
beg=i;
j=end;
}
}
//+------------------------------------------------------------------+
//| Inserting element in a sorted array |
//+------------------------------------------------------------------+
bool CArrayString::InsertSort(const string element)
{
int pos;
//--- check
if(!IsSorted())
return(false);
//--- check/reserve elements of array
if(!Reserve(1))
return(false);
//--- if the array is empty, add an element
if(m_data_total==0)
{
m_data[m_data_total++]=element;
return(true);
}
//--- find position and insert
pos=QuickSearch(element);
if(m_data[pos]>element)
Insert(element,pos);
else
Insert(element,pos+1);
//--- restore the sorting flag after Insert(...)
m_sort_mode=0;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Search of position of element in a array |
//+------------------------------------------------------------------+
int CArrayString::SearchLinear(const string element) const
{
//--- check
if(m_data_total==0)
return(-1);
//---
for(int i=0;i<m_data_total;i++)
if(m_data[i]==element)
return(i);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Quick search of position of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayString::QuickSearch(const string element) const
{
int i,j,m=-1;
string t_string;
//--- search
i=0;
j=m_data_total-1;
while(j>=i)
{
//--- ">>1" is quick division by 2
m=(j+i)>>1;
if(m<0 || m>=m_data_total)
break;
t_string=m_data[m];
if(t_string==element)
break;
if(t_string>element)
j=m-1;
else
i=m+1;
}
//--- position
return(m);
}
//+------------------------------------------------------------------+
//| Search of position of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayString::Search(const string element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is greater than |
//| specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayString::SearchGreat(const string element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
while(m_data[pos]<=element)
if(++pos==m_data_total)
return(-1);
//--- position
return(pos);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is less than |
//| specified in the sorted array |
//+------------------------------------------------------------------+
int CArrayString::SearchLess(const string element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
while(m_data[pos]>=element)
if(pos--==0)
return(-1);
//--- position
return(pos);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is greater than or |
//| equal to the specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayString::SearchGreatOrEqual(const string element) const
{
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
for(int pos=QuickSearch(element);pos<m_data_total;pos++)
if(m_data[pos]>=element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Search position of the first element which is less than or equal |
//| to the specified in a sorted array |
//+------------------------------------------------------------------+
int CArrayString::SearchLessOrEqual(const string element) const
{
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
for(int pos=QuickSearch(element);pos>=0;pos--)
if(m_data[pos]<=element)
return(pos);
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Find position of first appearance of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayString::SearchFirst(const string element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
{
while(m_data[pos]==element)
if(pos--==0)
break;
return(pos+1);
}
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Find position of last appearance of element in a sorted array |
//+------------------------------------------------------------------+
int CArrayString::SearchLast(const string element) const
{
int pos;
//--- check
if(m_data_total==0 || !IsSorted())
return(-1);
//--- search
pos=QuickSearch(element);
if(m_data[pos]==element)
{
while(m_data[pos]==element)
if(++pos==m_data_total)
break;
return(pos-1);
}
//--- not found
return(-1);
}
//+------------------------------------------------------------------+
//| Writing array to file |
//+------------------------------------------------------------------+
bool CArrayString::Save(const int file_handle)
{
int i=0,len;
//--- check
if(!CArray::Save(file_handle))
return(false);
//--- write array length
if(FileWriteInteger(file_handle,m_data_total,INT_VALUE)!=INT_VALUE)
return(false);
//--- write array
for(i=0;i<m_data_total;i++)
{
len=StringLen(m_data[i]);
//--- write string length
if(FileWriteInteger(file_handle,len,INT_VALUE)!=INT_VALUE)
return(false);
//--- write string
if(len!=0) if(FileWriteString(file_handle,m_data[i],len)!=len)
break;
}
//--- result
return(i==m_data_total);
}
//+------------------------------------------------------------------+
//| Reading array from file |
//+------------------------------------------------------------------+
bool CArrayString::Load(const int file_handle)
{
int i=0,num,len;
//--- check
if(!CArray::Load(file_handle))
return(false);
//--- read array length
num=FileReadInteger(file_handle,INT_VALUE);
//--- read array
Clear();
if(num!=0)
{
if(!Reserve(num))
return(false);
for(i=0;i<num;i++)
{
//--- read string length
len=FileReadInteger(file_handle,INT_VALUE);
//--- read string
if(len!=0)
m_data[i]=FileReadString(file_handle,len);
else
m_data[i]="";
m_data_total++;
if(FileIsEnding(file_handle))
break;
}
}
m_sort_mode=-1;
//--- result
return(m_data_total==num);
}
//+------------------------------------------------------------------+
+657
View File
@@ -0,0 +1,657 @@
//+------------------------------------------------------------------+
//| List.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include <Object.mqh>
//+------------------------------------------------------------------+
//| Class CList. |
//| Purpose: Provides the possibility of working with the list of |
//| CObject instances and its dervivatives |
//| Derives from class CObject. |
//+------------------------------------------------------------------+
class CList : public CObject
{
protected:
CObject *m_first_node; // pointer to the first element of the list
CObject *m_last_node; // pointer to the last element of the list
CObject *m_curr_node; // pointer to the current element of the list
int m_curr_idx; // index of the current list item
int m_data_total; // number of elements
bool m_free_mode; // flag of the necessity of "physical" deletion of object
bool m_data_sort; // flag if the list is sorted or not
int m_sort_mode; // mode of sorting of array
public:
CList(void);
~CList(void);
//--- methods of access to protected data
bool FreeMode(void) const { return(m_free_mode); }
void FreeMode(bool mode) { m_free_mode=mode; }
int Total(void) const { return(m_data_total); }
bool IsSorted(void) const { return(m_data_sort); }
int SortMode(void) const { return(m_sort_mode); }
//--- method of identifying the object
virtual int Type(void) const { return(0x7779); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
//--- method of creating an element of the list
virtual CObject *CreateElement(void) { return(NULL); }
//--- methods of filling the list
int Add(CObject *new_node);
int Insert(CObject *new_node,int index);
//--- methods for navigating
int IndexOf(CObject *node);
CObject *GetNodeAtIndex(int index);
CObject *GetFirstNode(void);
CObject *GetPrevNode(void);
CObject *GetCurrentNode(void);
CObject *GetNextNode(void);
CObject *GetLastNode(void);
//--- methods for deleting
CObject *DetachCurrent(void);
bool DeleteCurrent(void);
bool Delete(int index);
void Clear(void);
//--- method for comparing lists
bool CompareList(CList *List);
//--- methods for changing
void Sort(int mode);
bool MoveToIndex(int index);
bool Exchange(CObject *node1,CObject *node2);
//--- method for searching
CObject *Search(CObject *element);
protected:
void QuickSort(int beg,int end,int mode);
CObject *QuickSearch(CObject *element);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CList::CList(void) : m_first_node(NULL),
m_last_node(NULL),
m_curr_node(NULL),
m_curr_idx(-1),
m_data_total(0),
m_free_mode(true),
m_data_sort(false),
m_sort_mode(0)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CList::~CList(void)
{
Clear();
}
//+------------------------------------------------------------------+
//| Method QuickSort |
//+------------------------------------------------------------------+
void CList::QuickSort(int beg,int end,int mode)
{
int i,j,k;
CObject *i_ptr,*j_ptr,*k_ptr;
//---
i_ptr=GetNodeAtIndex(i=beg);
j_ptr=GetNodeAtIndex(j=end);
while(i<end)
{
//--- ">>1" is quick division by 2
k_ptr=GetNodeAtIndex(k=(beg+end)>>1);
while(i<j)
{
while(i_ptr.Compare(k_ptr,mode)<0)
{
//--- control the output of the array bounds
if(i==m_data_total-1)
break;
i++;
i_ptr=i_ptr.Next();
}
while(j_ptr.Compare(k_ptr,mode)>0)
{
//--- control the output of the array bounds
if(j==0)
break;
j--;
j_ptr=j_ptr.Prev();
}
if(i<=j)
{
Exchange(i_ptr,j_ptr);
i++;
i_ptr=GetNodeAtIndex(i);
//--- control the output of the array bounds
if(j==0)
break;
else
{
j--;
j_ptr=GetNodeAtIndex(j);
}
}
}
if(beg<j)
QuickSort(beg,j,mode);
beg=i;
i_ptr=GetNodeAtIndex(i=beg);
j_ptr=GetNodeAtIndex(j=end);
}
}
//+------------------------------------------------------------------+
//| Index of element specified via the pointer to the list item |
//+------------------------------------------------------------------+
int CList::IndexOf(CObject *node)
{
//--- check
if(!CheckPointer(node) || !CheckPointer(m_curr_node))
return(-1);
//--- searching index
if(node==m_curr_node)
return(m_curr_idx);
if(GetFirstNode()==node)
return(0);
for(int i=1;i<m_data_total;i++)
if(GetNextNode()==node)
return(i);
//---
return(-1);
}
//+------------------------------------------------------------------+
//| Adding a new element to the end of the list |
//+------------------------------------------------------------------+
int CList::Add(CObject *new_node)
{
//--- check
if(!CheckPointer(new_node))
return(-1);
//--- add
if(m_first_node==NULL)
m_first_node=new_node;
else
{
m_last_node.Next(new_node);
new_node.Prev(m_last_node);
}
m_curr_node=new_node;
m_curr_idx=m_data_total;
m_last_node=new_node;
m_data_sort=false;
//--- result
return(m_data_total++);
}
//+------------------------------------------------------------------+
//| Inserting a new element to the specified position in the list. |
//| Inserting element to the current position of the list if index=-1|
//+------------------------------------------------------------------+
int CList::Insert(CObject *new_node,int index)
{
CObject *tmp_node;
//--- check
if(!CheckPointer(new_node))
return(-1);
if(index>m_data_total || index<0)
return(-1);
//--- adjust
if(index==-1)
{
if(m_curr_node==NULL)
return(Add(new_node));
}
else
{
if(GetNodeAtIndex(index)==NULL)
return(Add(new_node));
}
//--- no need to check m_curr_node
tmp_node=m_curr_node.Prev();
new_node.Prev(tmp_node);
if(tmp_node!=NULL)
tmp_node.Next(new_node);
else
m_first_node=new_node;
new_node.Next(m_curr_node);
m_curr_node.Prev(new_node);
m_data_total++;
m_data_sort=false;
m_curr_node=new_node;
//--- result
return(index);
}
//+------------------------------------------------------------------+
//| Get a pointer to the position of element in the list |
//+------------------------------------------------------------------+
CObject *CList::GetNodeAtIndex(int index)
{
int i;
bool revers;
CObject *result;
//--- check
if(index>=m_data_total)
return(NULL);
if(index==m_curr_idx)
return(m_curr_node);
//--- optimize bust list
if(index<m_curr_idx)
{
//--- index to the left of the current
if(m_curr_idx-index<index)
{
//--- closer to the current index
i=m_curr_idx;
revers=true;
result=m_curr_node;
}
else
{
//--- closer to the top of the list
i=0;
revers=false;
result=m_first_node;
}
}
else
{
//--- index to the right of the current
if(index-m_curr_idx<m_data_total-index-1)
{
//--- closer to the current index
i=m_curr_idx;
revers=false;
result=m_curr_node;
}
else
{
//--- closer to the end of the list
i=m_data_total-1;
revers=true;
result=m_last_node;
}
}
if(!CheckPointer(result))
return(NULL);
//---
if(revers)
{
//--- search from right to left
for(;i>index;i--)
{
result=result.Prev();
if(result==NULL)
return(NULL);
}
}
else
{
//--- search from left to right
for(;i<index;i++)
{
result=result.Next();
if(result==NULL)
return(NULL);
}
}
m_curr_idx=index;
//--- result
return(m_curr_node=result);
}
//+------------------------------------------------------------------+
//| Get a pointer to the first itme of the list |
//+------------------------------------------------------------------+
CObject *CList::GetFirstNode(void)
{
//--- check
if(!CheckPointer(m_first_node))
return(NULL);
//--- save
m_curr_idx=0;
//--- result
return(m_curr_node=m_first_node);
}
//+------------------------------------------------------------------+
//| Get a pointer to the previous itme of the list |
//+------------------------------------------------------------------+
CObject *CList::GetPrevNode(void)
{
//--- check
if(!CheckPointer(m_curr_node) || m_curr_node.Prev()==NULL)
return(NULL);
//--- decrement
m_curr_idx--;
//--- result
return(m_curr_node=m_curr_node.Prev());
}
//+------------------------------------------------------------------+
//| Get a pointer to the current item of the list |
//+------------------------------------------------------------------+
CObject *CList::GetCurrentNode(void)
{
return(m_curr_node);
}
//+------------------------------------------------------------------+
//| Get a pointer to the next item of the list |
//+------------------------------------------------------------------+
CObject *CList::GetNextNode(void)
{
//--- check
if(!CheckPointer(m_curr_node) || m_curr_node.Next()==NULL)
return(NULL);
//--- increment
m_curr_idx++;
//--- result
return(m_curr_node=m_curr_node.Next());
}
//+------------------------------------------------------------------+
//| Get a pointer to the last itme of the list |
//+------------------------------------------------------------------+
CObject *CList::GetLastNode(void)
{
//--- check
if(!CheckPointer(m_last_node))
return(NULL);
//---
m_curr_idx=m_data_total-1;
//--- result
return(m_curr_node=m_last_node);
}
//+------------------------------------------------------------------+
//| Detach current item in the list |
//+------------------------------------------------------------------+
CObject *CList::DetachCurrent(void)
{
CObject *tmp_node,*result=NULL;
//--- check
if(!CheckPointer(m_curr_node))
return(result);
//--- "explode" list
result=m_curr_node;
m_curr_node=NULL;
//--- if the deleted item was not the last one, pull up the "tail" of the list
if((tmp_node=result.Next())!=NULL)
{
tmp_node.Prev(result.Prev());
m_curr_node=tmp_node;
}
//--- if the deleted item was not the first one, pull up "head" list
if((tmp_node=result.Prev())!=NULL)
{
tmp_node.Next(result.Next());
//--- if "last_node" is removed, move the current pointer to the end of the list
if(m_curr_node==NULL)
{
m_curr_node=tmp_node;
m_curr_idx=m_data_total-2;
}
}
m_data_total--;
//--- if necessary, adjust the settings of the first and last elements
if(m_first_node==result)
m_first_node=result.Next();
if(m_last_node==result)
m_last_node=result.Prev();
//--- complete the processing of element removed from the list
//--- remove references to the list
result.Prev(NULL);
result.Next(NULL);
//--- result
return(result);
}
//+------------------------------------------------------------------+
//| Delete current item of list item |
//+------------------------------------------------------------------+
bool CList::DeleteCurrent(void)
{
CObject *result=DetachCurrent();
//--- check
if(result==NULL)
return(false);
//--- complete the processing of element removed from the list
if(m_free_mode)
{
//--- delete it "physically"
if(CheckPointer(result)==POINTER_DYNAMIC)
delete result;
}
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Delete an item from a given position in the list |
//+------------------------------------------------------------------+
bool CList::Delete(int index)
{
if(GetNodeAtIndex(index)==NULL)
return(false);
//--- result
return(DeleteCurrent());
}
//+------------------------------------------------------------------+
//| Remove all items from the list |
//+------------------------------------------------------------------+
void CList::Clear(void)
{
GetFirstNode();
while(m_data_total!=0)
if(!DeleteCurrent())
break;
}
//+------------------------------------------------------------------+
//| Equality comparing of two lists |
//+------------------------------------------------------------------+
bool CList::CompareList(CList *List)
{
CObject *node,*lnode;
//--- check
if(!CheckPointer(List))
return(false);
if((node=GetFirstNode())==NULL)
return(false);
if((lnode=List.GetFirstNode())==NULL)
return(false);
//--- compare
if(node.Compare(lnode)!=0)
return(false);
while((node=GetNextNode())!=NULL)
{
if((lnode=List.GetNextNode())==NULL)
return(false);
if(node.Compare(lnode)!=0)
return(false);
}
//--- equal
return(true);
}
//+------------------------------------------------------------------+
//| Sorting an array in ascending order |
//+------------------------------------------------------------------+
void CList::Sort(int mode)
{
//--- check
if(m_data_total==0)
return;
if(m_data_sort && m_sort_mode==mode)
return;
//--- sort
QuickSort(0,m_data_total-1,mode);
m_sort_mode=mode;
m_data_sort=true;
}
//+------------------------------------------------------------------+
//| Move the current item of list to the specified position |
//+------------------------------------------------------------------+
bool CList::MoveToIndex(int index)
{
//--- check
if(index>=m_data_total || !CheckPointer(m_curr_node))
return(false);
//--- tune
if(m_curr_idx==index)
return(true);
if(m_curr_idx<index)
index--;
//--- move
Insert(DetachCurrent(),index);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Move an item of the list from the specified position to the |
//| current one |
//+------------------------------------------------------------------+
bool CList::Exchange(CObject *node1,CObject *node2)
{
CObject *tmp_node,*node;
//--- check
if(!CheckPointer(node1) || !CheckPointer(node2))
return(false);
//---
tmp_node=node1.Prev();
node1.Prev(node2.Prev());
if(node1.Prev()!=NULL)
{
node=node1.Prev();
node.Next(node1);
}
else
m_first_node=node1;
node2.Prev(tmp_node);
if(node2.Prev()!=NULL)
{
node=node2.Prev();
node.Next(node2);
}
else
m_first_node=node2;
tmp_node=node1.Next();
node1.Next(node2.Next());
if(node1.Next()!=NULL)
{
node=node1.Next();
node.Prev(node1);
}
else
m_last_node=node1;
node2.Next(tmp_node);
if(node2.Next()!=NULL)
{
node=node2.Next();
node.Prev(node2);
}
else
m_last_node=node2;
//---
m_curr_idx=0;
m_curr_node=m_first_node;
m_data_sort=false;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Search position of an element in a sorted list |
//+------------------------------------------------------------------+
CObject *CList::QuickSearch(CObject *element)
{
int i,j,m;
CObject *t_node=NULL;
//--- check
if(m_data_total==0)
return(NULL);
//--- check the pointer is not needed
i=0;
j=m_data_total;
while(j>=i)
{
//--- ">>1" is quick division by 2
m=(j+i)>>1;
if(m<0 || m>=m_data_total)
break;
t_node=GetNodeAtIndex(m);
if(t_node.Compare(element,m_sort_mode)==0)
break;
if(t_node.Compare(element,m_sort_mode)>0)
j=m-1;
else
i=m+1;
t_node=NULL;
}
//--- result
return(t_node);
}
//+------------------------------------------------------------------+
//| Search position of an element in a sorted list |
//+------------------------------------------------------------------+
CObject *CList::Search(CObject *element)
{
CObject *result;
//--- check
if(!CheckPointer(element) || !m_data_sort)
return(NULL);
//--- search
result=QuickSearch(element);
//--- result
return(result);
}
//+------------------------------------------------------------------+
//| Writing list to file |
//+------------------------------------------------------------------+
bool CList::Save(const int file_handle)
{
CObject *node;
bool result=true;
//--- check
if(!CheckPointer(m_curr_node) || file_handle==INVALID_HANDLE)
return(false);
//--- write start marker - 0xFFFFFFFFFFFFFFFF
if(FileWriteLong(file_handle,-1)!=sizeof(long))
return(false);
//--- write type
if(FileWriteInteger(file_handle,Type(),INT_VALUE)!=INT_VALUE)
return(false);
//--- write list size
if(FileWriteInteger(file_handle,m_data_total,INT_VALUE)!=INT_VALUE)
return(false);
//--- sequential scannning of elements in the list using the call of method Save()
node=m_first_node;
while(node!=NULL)
{
result&=node.Save(file_handle);
node=node.Next();
}
//--- successful
return(result);
}
//+------------------------------------------------------------------+
//| Reading list from file |
//+------------------------------------------------------------------+
bool CList::Load(const int file_handle)
{
uint i,num;
CObject *node;
bool result=true;
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//--- read and checking begin marker - 0xFFFFFFFFFFFFFFFF
if(FileReadLong(file_handle)!=-1)
return(false);
//--- read and checking type
if(FileReadInteger(file_handle,INT_VALUE)!=Type())
return(false);
//--- read list size
num=FileReadInteger(file_handle,INT_VALUE);
//--- sequential creation of list items using the call of method Load()
Clear();
for(i=0;i<num;i++)
{
node=CreateElement();
if(node==NULL)
return(false);
Add(node);
result&=node.Load(file_handle);
}
//--- successful
return(result);
}
//+------------------------------------------------------------------+
+415
View File
@@ -0,0 +1,415 @@
//+------------------------------------------------------------------+
//| Tree.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "TreeNode.mqh"
//+------------------------------------------------------------------+
//| Class CTree. |
//| Purpose: Building a binary tree of instances of CTreeNode class |
//| and its derviatives. |
//| Derives from class CTreeNode. |
//+------------------------------------------------------------------+
class CTree : public CTreeNode
{
protected:
CTreeNode *m_root_node; // root node of the tree
public:
CTree(void);
~CTree(void);
//--- methods of access to protected data
CTreeNode *Root(void) const { return(m_root_node); }
//--- method of identifying the object
virtual int Type() const { return(0x9999); }
//--- method of filling the tree
CTreeNode *Insert(CTreeNode *new_node);
//--- methods of removing tree nodes
bool Detach(CTreeNode *node);
bool Delete(CTreeNode *node);
void Clear(void);
//--- method of searching data in the tree
CTreeNode *Find(const CTreeNode *node);
//--- method to create elements in the tree
virtual CTreeNode *CreateElement() { return(NULL); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
protected:
void Balance(CTreeNode *node);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CTree::CTree(void) : m_root_node(NULL)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CTree::~CTree(void)
{
Clear();
}
//+------------------------------------------------------------------+
//| Method of adding a node to the tree |
//+------------------------------------------------------------------+
CTreeNode *CTree::Insert(CTreeNode *new_node)
{
CTreeNode *p_node;
CTreeNode *result=m_root_node;
//--- check
if(!CheckPointer(new_node))
return(NULL);
//--- add
if(result!=NULL)
{
p_node=NULL;
result=m_root_node;
while(result!=NULL && result.Compare(new_node)!=0)
{
p_node=result;
result=result.GetNext(new_node);
}
if(result!=NULL)
return(result);
if(p_node.Compare(new_node)>0)
p_node.Left(new_node);
else
p_node.Right(new_node);
new_node.Parent(p_node);
Balance(p_node);
}
else
m_root_node=new_node;
//--- result
return(result);
}
//+------------------------------------------------------------------+
//| Method of removing a node from the tree |
//+------------------------------------------------------------------+
bool CTree::Delete(CTreeNode *node)
{
//--- check
if(!CheckPointer(node))
return(false);
//--- delete
if(Detach(node) && CheckPointer(node)==POINTER_DYNAMIC)
delete node;
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Method of detaching node from the tree |
//+------------------------------------------------------------------+
bool CTree::Detach(CTreeNode *node)
{
CTreeNode *curr_node,*tmp_node;
CTreeNode *nodeA,*nodeB;
//--- check
curr_node=node;
if(!CheckPointer(curr_node))
return(false);
//--- detach
if(curr_node.BalanceL()>curr_node.BalanceR())
{
nodeA=curr_node.Left();
while(nodeA.Right()!=NULL)
nodeA=nodeA.Right();
nodeB=nodeA.Parent();
if(nodeB!=curr_node)
{
nodeB.Right(nodeA.Left());
tmp_node=nodeB.Right();
if(tmp_node!=NULL)
tmp_node.Parent(nodeB);
tmp_node=curr_node.Left();
nodeA.Left(tmp_node);
tmp_node.Parent(nodeA);
}
//--- left link of curr_node is already installed as it should be
curr_node.Left(NULL);
//--- transferring the right link of curr_node to nodeA
nodeA.Right(curr_node.Right());
tmp_node=curr_node.Right();
if(tmp_node!=NULL)
tmp_node.Parent(nodeA);
curr_node.Right(NULL);
//--- transferring the root link of curr_node to nodeA
tmp_node=curr_node.Parent();
nodeA.Parent(tmp_node);
if(tmp_node!=NULL)
{
if(tmp_node.Left()==curr_node)
tmp_node.Left(nodeA);
else
tmp_node.Right(nodeA);
}
else
{
curr_node.Parent(NULL);
m_root_node=nodeA;
tmp_node=nodeA;
}
Balance(tmp_node);
}
else
{
if(curr_node.BalanceR()>0)
{
nodeA=curr_node.Right();
while(nodeA.Left()!=NULL)
nodeA=nodeA.Left();
nodeB=nodeA.Parent();
if(nodeB!=curr_node)
{
nodeB.Left(nodeA.Right());
tmp_node=nodeB.Left();
if(tmp_node!=NULL)
tmp_node.Parent(nodeB);
tmp_node=curr_node.Right();
nodeA.Right(tmp_node);
tmp_node.Parent(nodeA);
}
//--- right link of curr_node is already installed as it should be
curr_node.Right(NULL);
//--- transferring the left link of curr_node to nodeA
nodeA.Left(curr_node.Left());
tmp_node=curr_node.Left();
if(tmp_node!=NULL)
tmp_node.Parent(nodeA);
curr_node.Left(NULL);
//--- transferring the root link of curr_node to nodeA
tmp_node=curr_node.Parent();
nodeA.Parent(tmp_node);
if(tmp_node!=NULL)
{
if(tmp_node.Left()==curr_node)
tmp_node.Left(nodeA);
else
tmp_node.Right(nodeA);
}
else
{
curr_node.Parent(NULL);
m_root_node=nodeA;
tmp_node=nodeA;
}
Balance(tmp_node);
}
else
{
//--- node list
if(curr_node.Parent()==NULL)
m_root_node=NULL;
else
{
tmp_node=curr_node.Parent();
if(tmp_node.Left()==curr_node)
tmp_node.Left(NULL);
else
tmp_node.Right(NULL);
curr_node.Parent(NULL);
}
Balance(curr_node.Parent());
}
}
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Method of cleaning the tree |
//+------------------------------------------------------------------+
void CTree::Clear(void)
{
if(CheckPointer(m_root_node)==POINTER_DYNAMIC)
delete m_root_node;
m_root_node=NULL;
}
//+------------------------------------------------------------------+
//| Method of searching for a node in the tree |
//+------------------------------------------------------------------+
CTreeNode *CTree::Find(const CTreeNode *node)
{
CTreeNode *result=m_root_node;
//--- find
while(result!=NULL && result.Compare(node)!=0)
result=result.GetNext(node);
//--- result
return(result);
}
//+------------------------------------------------------------------+
//| Method of balancing the tree |
//+------------------------------------------------------------------+
void CTree::Balance(CTreeNode *node)
{
CTreeNode *nodeA,*nodeB,*nodeC,*curr_node,*tmp_node;
//---
curr_node=node;
while(curr_node!=NULL)
{
curr_node.RefreshBalance();
if(MathAbs(curr_node.BalanceL()-curr_node.BalanceR())<=1)
curr_node=curr_node.Parent();
else
{
if(curr_node.BalanceR()>curr_node.BalanceL())
{
//--- rotation to the right
tmp_node=curr_node.Right();
if(tmp_node.BalanceL()>tmp_node.BalanceR())
{
//--- great rotation to the right
nodeA=curr_node;
nodeB=nodeA.Right();
nodeC=nodeB.Left();
nodeC.Parent(nodeA.Parent());
tmp_node=nodeC.Parent();
if(tmp_node!=NULL)
{
if(tmp_node.Right()==nodeA)
tmp_node.Right(nodeC);
else
tmp_node.Left(nodeC);
}
else
m_root_node=nodeC;
nodeA.Parent(nodeC);
nodeB.Parent(nodeC);
nodeA.Right(nodeC.Left());
tmp_node=nodeA.Right();
if(tmp_node!=NULL)
tmp_node.Parent(nodeA);
nodeC.Left(nodeA);
nodeB.Left(nodeC.Right());
tmp_node=nodeB.Left();
if(tmp_node!=NULL)
tmp_node.Parent(nodeB);
nodeC.Right(nodeB);
if(m_root_node==nodeA)
m_root_node=nodeC;
curr_node=nodeC.Parent();
}
else
{
//--- slight rotation to the right
nodeA=curr_node;
nodeB=nodeA.Right();
nodeB.Parent(nodeA.Parent());
tmp_node=nodeB.Parent();
if(tmp_node!=NULL)
{
if(tmp_node.Right()==nodeA)
tmp_node.Right(nodeB);
else
tmp_node.Left(nodeB);
}
else
m_root_node=nodeB;
nodeA.Parent(nodeB);
nodeA.Right(nodeB.Left());
tmp_node=nodeA.Right();
if(tmp_node!=NULL)
tmp_node.Parent(nodeA);
nodeB.Left(nodeA);
if(m_root_node==nodeA)
m_root_node=nodeB;
curr_node=nodeB.Parent();
}
}
else
{
//--- rotation to the left
tmp_node=curr_node.Left();
if(tmp_node.BalanceR()>tmp_node.BalanceL())
{
//--- great rotation to the left
nodeA=curr_node;
nodeB=nodeA.Left();
nodeC=nodeB.Right();
nodeC.Parent(nodeA.Parent());
tmp_node=nodeC.Parent();
if(tmp_node!=NULL)
{
if(tmp_node.Right()==nodeA)
tmp_node.Right(nodeC);
else
tmp_node.Left(nodeC);
}
else
m_root_node=nodeC;
nodeA.Parent(nodeC);
nodeB.Parent(nodeC);
nodeA.Left(nodeC.Right());
tmp_node=nodeA.Left();
if(tmp_node!=NULL)
tmp_node.Parent(nodeA);
nodeC.Right(nodeA);
nodeB.Right(nodeC.Left());
tmp_node=nodeB.Right();
if(tmp_node!=NULL)
tmp_node.Parent(nodeB);
nodeC.Left(nodeB);
if(m_root_node==nodeA)
m_root_node=nodeC;
curr_node=nodeC.Parent();
}
else
{
//--- small rotation to the left
nodeA=curr_node;
nodeB=nodeA.Left();
nodeB.Parent(nodeA.Parent());
tmp_node=nodeB.Parent();
if(tmp_node!=NULL)
{
if(tmp_node.Right()==nodeA)
tmp_node.Right(nodeB);
else
tmp_node.Left(nodeB);
}
else
m_root_node=nodeB;
nodeA.Parent(nodeB);
nodeA.Left(nodeB.Right());
tmp_node=nodeA.Left();
if(tmp_node!=NULL)
tmp_node.Parent(nodeA);
nodeB.Right(nodeA);
if(m_root_node==nodeA)
m_root_node=nodeB;
curr_node=nodeB.Parent();
}
}
}
}
}
//+------------------------------------------------------------------+
//| Writing tree to file |
//+------------------------------------------------------------------+
bool CTree::Save(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
if(m_root_node==NULL)
return(true);
//--- result
return(m_root_node.SaveNode(file_handle));
}
//+------------------------------------------------------------------+
//| Reading tree from file |
//+------------------------------------------------------------------+
bool CTree::Load(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//--- create root node only
Clear();
Insert(CreateElement());
//--- result
return(m_root_node.LoadNode(file_handle,m_root_node));
}
//+------------------------------------------------------------------+
+174
View File
@@ -0,0 +1,174 @@
//+------------------------------------------------------------------+
//| TreeNode.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include <Object.mqh>
//+------------------------------------------------------------------+
//| Class CTreeNode. |
//| Purpose: Base class of node of binary tree CTree. |
//| Derives from class CObject. |
//+------------------------------------------------------------------+
class CTreeNode : public CObject
{
private:
CTreeNode *m_p_node; // link to node up
CTreeNode *m_l_node; // link to node left
CTreeNode *m_r_node; // link to node right
//--- variables
int m_balance; // balance of node
int m_l_balance; // balance of the left branch
int m_r_balance; // balance of the right branch
public:
CTreeNode(void);
~CTreeNode(void);
//--- methods of access to protected data
CTreeNode* Parent(void) const { return(m_p_node); }
void Parent(CTreeNode *node) { m_p_node=node; }
CTreeNode* Left(void) const { return(m_l_node); }
void Left(CTreeNode *node) { m_l_node=node; }
CTreeNode* Right(void) const { return(m_r_node); }
void Right(CTreeNode *node) { m_r_node=node; }
int Balance(void) const { return(m_balance); }
int BalanceL(void) const { return(m_l_balance); }
int BalanceR(void) const { return(m_r_balance); }
//--- method of identifying the object
virtual int Type(void) const { return(0x8888); }
//--- methods for controlling
int RefreshBalance(void);
CTreeNode *GetNext(const CTreeNode *node);
//--- methods for working with files
bool SaveNode(const int file_handle);
bool LoadNode(const int file_handle,CTreeNode *main);
protected:
//--- method for creating an instance of class
virtual CTreeNode *CreateSample(void) { return(NULL); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CTreeNode::CTreeNode(void) : m_p_node(NULL),
m_l_node(NULL),
m_r_node(NULL),
m_balance(0),
m_l_balance(0),
m_r_balance(0)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CTreeNode::~CTreeNode(void)
{
//--- delete nodes of the next level
if(m_l_node!=NULL)
delete m_l_node;
if(m_r_node!=NULL)
delete m_r_node;
}
//+------------------------------------------------------------------+
//| Calculating the balance of the node |
//+------------------------------------------------------------------+
int CTreeNode::RefreshBalance(void)
{
//--- calculate the balance of the left branch
if(m_l_node==NULL)
m_l_balance=0;
else
m_l_balance=m_l_node.RefreshBalance();
//--- calculate the balance of the right branch
if(m_r_node==NULL)
m_r_balance=0;
else
m_r_balance=m_r_node.RefreshBalance();
//--- calculate the balance of the node
if(m_r_balance>m_l_balance)
m_balance=m_r_balance+1;
else
m_balance=m_l_balance+1;
//--- result
return(m_balance);
}
//+------------------------------------------------------------------+
//| Selecting next node |
//+------------------------------------------------------------------+
CTreeNode *CTreeNode::GetNext(const CTreeNode *node)
{
if(Compare(node)>0)
return(m_l_node);
//--- result
return(m_r_node);
}
//+------------------------------------------------------------------+
//| Writing node data to file |
//+------------------------------------------------------------------+
bool CTreeNode::SaveNode(const int file_handle)
{
bool result=true;
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//--- write left node (if it is available)
if(m_l_node!=NULL)
{
FileWriteInteger(file_handle,'L',SHORT_VALUE);
result&=m_l_node.SaveNode(file_handle);
}
else
FileWriteInteger(file_handle,'X',SHORT_VALUE);
//--- write data of current node
result&=Save(file_handle);
//--- write right node (if it is available)
if(m_r_node!=NULL)
{
FileWriteInteger(file_handle,'R',SHORT_VALUE);
result&=m_r_node.SaveNode(file_handle);
}
else
FileWriteInteger(file_handle,'X',SHORT_VALUE);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Reading node data from file |
//+------------------------------------------------------------------+
bool CTreeNode::LoadNode(const int file_handle,CTreeNode *main)
{
bool result=true;
short s_val;
CTreeNode *node;
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//--- read directions
s_val=(short)FileReadInteger(file_handle,SHORT_VALUE);
if(s_val=='L')
{
//--- read left node (if there is data)
node=CreateSample();
if(node==NULL)
return(false);
m_l_node=node;
node.Parent(main);
result&=node.LoadNode(file_handle,node);
}
//--- read data of current node
result&=Load(file_handle);
//--- read directions
s_val=(short)FileReadInteger(file_handle,SHORT_VALUE);
if(s_val=='R')
{
//--- read right node (if there is data)
node=CreateSample();
if(node==NULL)
return(false);
m_r_node=node;
node.Parent(main);
result&=node.LoadNode(file_handle,node);
}
//--- result
return(result);
}
//+------------------------------------------------------------------+
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+347
View File
@@ -0,0 +1,347 @@
//+------------------------------------------------------------------+
//| HistogramChart.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "ChartCanvas.mqh"
#include <Arrays\ArrayObj.mqh>
//+------------------------------------------------------------------+
//| Class CHistogramChart |
//| Usage: generates histogram chart |
//+------------------------------------------------------------------+
class CHistogramChart : public CChartCanvas
{
private:
//--- colors
uint m_fill_brush[];
//--- adjusted parameters
bool m_gradient;
uint m_bar_gap;
uint m_bar_min_size;
uint m_bar_border;
//--- data
CArrayObj *m_values;
public:
CHistogramChart(void);
~CHistogramChart(void);
//--- create
virtual bool Create(const string name,const int width,const int height,ENUM_COLOR_FORMAT clrfmt=COLOR_FORMAT_ARGB_NORMALIZE);
//--- adjusted parameters
void Gradient(const bool flag=true) { m_gradient=flag; }
void BarGap(const uint value) { m_bar_gap=value; }
void BarMinSize(const uint value) { m_bar_min_size=value; }
void BarBorder(const uint value) { m_bar_border=value; }
//--- data
bool SeriesAdd(const double &value[],const string descr="",const uint clr=0);
bool SeriesInsert(const uint pos,const double &value[],const string descr="",const uint clr=0);
bool SeriesUpdate(const uint pos,const double &value[],const string descr=NULL,const uint clr=0);
bool SeriesDelete(const uint pos);
bool ValueUpdate(const uint series,const uint pos,double value);
protected:
virtual void DrawData(const uint idx);
void DrawBar(const int x,const int y,const int w,const int h,const uint clr);
void GradientBrush(const int size,const uint fill_clr);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CHistogramChart::CHistogramChart(void) : m_gradient(true),
m_bar_gap(3),
m_bar_min_size(5),
m_bar_border(0)
{
ShowFlags(FLAG_SHOW_LEGEND|FLAGS_SHOW_SCALES|FLAG_SHOW_GRID);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CHistogramChart::~CHistogramChart(void)
{
if(ArraySize(m_fill_brush)!=0)
ArrayFree(m_fill_brush);
}
//+------------------------------------------------------------------+
//| Create dynamic resource |
//+------------------------------------------------------------------+
bool CHistogramChart::Create(const string name,const int width,const int height,ENUM_COLOR_FORMAT clrfmt)
{
//--- create object to store data
if((m_values=new CArrayObj)==NULL)
return(false);
//--- pass responsibility for its destruction to the parent class
m_data=m_values;
//--- call method of parent class
if(!CChartCanvas::Create(name,width,height,clrfmt))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Adds data series |
//+------------------------------------------------------------------+
bool CHistogramChart::SeriesAdd(const double &value[],const string descr,const uint clr)
{
//--- check
if(m_data_total==m_max_data)
return(false);
//--- add
CArrayDouble *arr=new CArrayDouble;
if(!m_values.Add(arr))
return(false);
if(!arr.AssignArray(value))
return(false);
if(!m_colors.Add((clr==0) ? GetDefaultColor(m_data_total) : clr))
return(false);
if(!m_descriptors.Add(descr))
return(false);
m_data_total++;
//--- redraw
Redraw();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Inserts data series |
//+------------------------------------------------------------------+
bool CHistogramChart::SeriesInsert(const uint pos,const double &value[],const string descr,const uint clr)
{
//--- check
if(m_data_total==m_max_data)
return(false);
if(pos>=m_data_total)
return(false);
//--- insert
CArrayDouble *arr=new CArrayDouble;
if(!m_values.Insert(arr,pos))
return(false);
if(!arr.AssignArray(value))
return(false);
if(!m_colors.Insert((clr==0) ? GetDefaultColor(m_data_total) : clr,pos))
return(false);
if(!m_descriptors.Insert(descr,pos))
return(false);
m_data_total++;
//--- redraw
Redraw();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Updates data series |
//+------------------------------------------------------------------+
bool CHistogramChart::SeriesUpdate(const uint pos,const double &value[],const string descr,const uint clr)
{
//--- check
if(pos>=m_data_total)
return(false);
CArrayDouble *data=m_values.At(pos);
if(data==NULL)
return(false);
//--- update
if(!data.AssignArray(value))
return(false);
if(clr!=0 && !m_colors.Update(pos,clr))
return(false);
if(descr!=NULL && !m_descriptors.Update(pos,descr))
return(false);
//--- redraw
Redraw();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Deletes data series |
//+------------------------------------------------------------------+
bool CHistogramChart::SeriesDelete(const uint pos)
{
//--- check
if(pos>=m_data_total && m_data_total!=0)
return(false);
//--- delete
if(!m_values.Delete(pos))
return(false);
m_data_total--;
if(!m_colors.Delete(pos))
return(false);
if(!m_descriptors.Delete(pos))
return(false);
//--- redraw
Redraw();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Updates element in data series |
//+------------------------------------------------------------------+
bool CHistogramChart::ValueUpdate(const uint series,const uint pos,double value)
{
CArrayDouble *data=m_values.At(series);
//--- check
if(data==NULL)
return(false);
//--- update
if(!data.Update(pos,value))
return(false);
//--- redraw
Redraw();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Draws histogram |
//+------------------------------------------------------------------+
void CHistogramChart::DrawData(const uint idx)
{
double value=0.0;
//--- check
CArrayDouble *data=m_values.At(idx);
if(data==NULL)
return;
int total=data.Total();
if(total==0 || (int)idx>=total)
return;
//--- calculate
int x1=m_data_area.left;
int x2=m_data_area.right;
int dx=(x2-x1)/total;
uint clr=m_colors[idx];
uint w=dx/m_data_total;
if(w<m_bar_min_size)
w=m_bar_min_size;
int x=x1+(int)(m_bar_gap+w*idx);
//--- set font
string fontname;
int fontsize=0;
uint fontflags=0;
uint fontangle=0;
if(IS_SHOW_VALUE)
{
FontGet(fontname,fontsize,fontflags,fontangle);
FontSet(fontname,-10*(w-3),fontflags,900);
}
//--- prepare gradient fill
GradientBrush(w,clr);
//--- draw
for(int i=0;i<total;i++,x+=dx)
{
int y,h;
double val=data[i];
if(val==EMPTY_VALUE)
continue;
if(m_accumulative)
value+=val;
else
value=val;
// int val=(int)(value*m_scale_y);
if(value>0)
{
y=(m_y_0-(int)(value*m_scale_y));
h=m_y_0-y;
}
else
{
y=m_y_0;
h=-(int)(value*m_scale_y);
}
DrawBar(x,y,w,h,clr);
//--- draw text of value
if(IS_SHOW_VALUE)
{
string text =DoubleToString(value,2);
int width=(int)(TextWidth(text)+w);
if(value>0)
{
if(width>y-m_y_max)
TextOut(x+w/2,y+w,text,m_color_text,TA_RIGHT|TA_VCENTER);
else
TextOut(x+w/2,y-w,text,m_color_text,TA_LEFT|TA_VCENTER);
}
else
{
if(width>m_y_min-y-h)
TextOut(x+w/2,y+h-w,text,m_color_text,TA_LEFT|TA_VCENTER);
else
TextOut(x+w/2,y+h+w,text,m_color_text,TA_RIGHT|TA_VCENTER);
}
}
}
if(IS_SHOW_VALUE)
FontSet(fontname,fontsize,fontflags,fontangle);
}
//+------------------------------------------------------------------+
//| Draws bar |
//+------------------------------------------------------------------+
void CHistogramChart::DrawBar(const int x,const int y,const int w,const int h,const uint clr)
{
//--- draw bar
if(!m_gradient || ArraySize(m_fill_brush)<w)
FillRectangle(x+1,y+1,w-x-2,h-y-2,clr);
else
{
for(int i=1;i<h;i++)
ArrayCopy(m_pixels,m_fill_brush,(y+i)*m_width+x+1,0,w);
}
//--- draw bar border
if(m_bar_border!=0)
Rectangle(x,y,x+w-1,y+h-1,m_color_border);
}
//+------------------------------------------------------------------+
//| Creates brush for gradient fill |
//+------------------------------------------------------------------+
void CHistogramChart::GradientBrush(const int size,const uint fill_clr)
{
//--- to prepare gradient fill, we will use Bresenham's circle algorithm
//--- X coordinate - size of the fill,
//--- Y coordinate - color brightness
if(m_gradient)
{
//--- adjust gradient radius if necessary
int r=size;
//--- check
if(r<1)
return;
if(r!=ArrayResize(m_fill_brush,r))
return;
//--- initialize brush
ArrayInitialize(m_fill_brush,m_color_background);
//--- variables
int f =1-r;
int dd_x=1;
int dd_y=-2*r;
int dx =0;
int dy =r;
int i1,i2;
uint clr,dclr;
//---
i1=i2=r>>1;
if((r&1)==0)
i1--;
//--- calculate
while(dy>=dx)
{
clr=fill_clr;
dclr=GETRGB(XRGB((r-dy)*GETRGBR(clr)/r,(r-dy)*GETRGBG(clr)/r,(r-dy)*GETRGBB(clr)/r));
clr-=dclr;
m_fill_brush[i1]=clr;
m_fill_brush[i2]=clr;
//---
if(f>=0)
{
dy--;
dd_y+=2;
f+=dd_y;
}
dx++;
if(--i1<0)
break;
i2++;
dd_x+=2;
f+=dd_x;
}
}
else
ArrayFree(m_fill_brush);
}
//+------------------------------------------------------------------+
+383
View File
@@ -0,0 +1,383 @@
//+------------------------------------------------------------------+
//| LineChart.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "ChartCanvas.mqh"
#include <Arrays\ArrayObj.mqh>
//+------------------------------------------------------------------+
//| Class CLineChart |
//| Usage: generates line chart |
//+------------------------------------------------------------------+
class CLineChart : public CChartCanvas
{
private:
//--- data
CArrayObj *m_values;
//--- adjusted parameters
bool m_filled;
public:
CLineChart(void);
~CLineChart(void);
//--- create
virtual bool Create(const string name,const int width,const int height,ENUM_COLOR_FORMAT clrfmt=COLOR_FORMAT_ARGB_NORMALIZE);
//--- adjusted parameters
void Filled(const bool flag=true) { m_filled=flag; }
//--- set up
bool SeriesAdd(const double &value[],const string descr="",const uint clr=0);
bool SeriesInsert(const uint pos,const double &value[],const string descr="",const uint clr=0);
bool SeriesUpdate(const uint pos,const double &value[],const string descr=NULL,const uint clr=0);
bool SeriesDelete(const uint pos);
bool ValueUpdate(const uint series,const uint pos,double value);
protected:
virtual void DrawChart(void);
virtual void DrawData(const uint index=0);
private:
double CalcArea(const uint index);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CLineChart::CLineChart(void) : m_filled(false)
{
ShowFlags(FLAG_SHOW_LEGEND|FLAGS_SHOW_SCALES|FLAG_SHOW_GRID);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CLineChart::~CLineChart(void)
{
}
//+------------------------------------------------------------------+
//| Create dynamic resource |
//+------------------------------------------------------------------+
bool CLineChart::Create(const string name,const int width,const int height,ENUM_COLOR_FORMAT clrfmt)
{
//--- create object to store data
if((m_values=new CArrayObj)==NULL)
return(false);
//--- pass responsibility for its destruction to the parent class
m_data=m_values;
//--- call method of parent class
if(!CChartCanvas::Create(name,width,height,clrfmt))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Adds data series |
//+------------------------------------------------------------------+
bool CLineChart::SeriesAdd(const double &value[],const string descr,const uint clr)
{
//--- check
if(m_data_total==m_max_data)
return(false);
//--- add
CArrayDouble *arr=new CArrayDouble;
if(!m_values.Add(arr))
return(false);
if(!arr.AssignArray(value))
return(false);
if(!m_colors.Add((clr==0) ? GetDefaultColor(m_data_total) : clr))
return(false);
if(!m_descriptors.Add(descr))
return(false);
m_data_total++;
//--- redraw
Redraw();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Inserts data series |
//+------------------------------------------------------------------+
bool CLineChart::SeriesInsert(const uint pos,const double &value[],const string descr,const uint clr)
{
//--- check
if(m_data_total==m_max_data)
return(false);
if(pos>=m_data_total)
return(false);
//--- insert
CArrayDouble *arr=new CArrayDouble;
if(!m_values.Insert(arr,pos))
return(false);
if(!arr.AssignArray(value))
return(false);
if(!m_colors.Insert((clr==0) ? GetDefaultColor(m_data_total) : clr,pos))
return(false);
if(!m_descriptors.Insert(descr,pos))
return(false);
m_data_total++;
//--- redraw
Redraw();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Updates data series |
//+------------------------------------------------------------------+
bool CLineChart::SeriesUpdate(const uint pos,const double &value[],const string descr,const uint clr)
{
//--- check
if(pos>=m_data_total)
return(false);
CArrayDouble *data=m_values.At(pos);
if(data==NULL)
return(false);
//--- update
if(!data.AssignArray(value))
return(false);
if(clr!=0 && !m_colors.Update(pos,clr))
return(false);
if(descr!=NULL && !m_descriptors.Update(pos,descr))
return(false);
//--- redraw
Redraw();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Deletes data series |
//+------------------------------------------------------------------+
bool CLineChart::SeriesDelete(const uint pos)
{
//--- check
if(pos>=m_data_total && m_data_total!=0)
return(false);
//--- delete
if(!m_values.Delete(pos))
return(false);
m_data_total--;
if(!m_colors.Delete(pos))
return(false);
if(!m_descriptors.Delete(pos))
return(false);
//--- redraw
Redraw();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Updates element in data series |
//+------------------------------------------------------------------+
bool CLineChart::ValueUpdate(const uint series,const uint pos,double value)
{
CArrayDouble *data=m_values.At(series);
//--- check
if(data==NULL)
return(false);
//--- update
if(!data.Update(pos,value))
return(false);
//--- redraw
Redraw();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Redraws data |
//+------------------------------------------------------------------+
void CLineChart::DrawChart(void)
{
if(m_filled)
{
//--- calculate areas of filling
double s[];
ArrayResize(s,m_data_total);
ArrayInitialize(s,0);
for(uint i=0;i<m_data_total;i++)
{
CArrayDouble *data=m_values.At(i);
if(data==NULL)
continue;
int total=data.Total();
if(total<=1)
continue;
s[i]=CalcArea(i);
}
int index=ArrayMaximum(s);
while(index!=-1 && s[index]!=0.0)
{
//--- draw in area descending order
DrawData(index);
s[index]=0.0;
index=ArrayMaximum(s);
}
}
else
for(uint i=0;i<m_data_total;i++)
DrawData(i);
}
//+------------------------------------------------------------------+
//| Draws lines |
//+------------------------------------------------------------------+
void CLineChart::DrawData(const uint index)
{
double value=0.0;
//--- check
CArrayDouble *data=m_values.At(index);
if(data==NULL)
return;
int total=data.Total();
if(total<=1)
return;
//--- calculate
int dx=m_data_area.Width()/(total-1);
int x=m_data_area.left+1;
int y1=0;
int y2=(int)(m_y_0-data[0]*m_scale_y);
//--- draw
for(int i=1;i<total;i++,x+=dx)
{
y1=y2;
double val=data[i];
if(val==EMPTY_VALUE)
continue;
if(m_accumulative)
value+=val;
else
value=val;
y2=(int)(m_y_0-value*m_scale_y);
if(m_filled)
{
if((y1>m_y_0 && y2<m_y_0) || (y1<m_y_0 && y2>m_y_0))
{
//--- draw two triangles
int x3;
if(y1>y2)
{
x3=x+dx*(y1-m_y_0)/(y1-y2);
FillTriangle(x,y1,x3,m_y_0,x,m_y_0,(uint)m_colors[index]);
FillTriangle(x+dx,y2,x3,m_y_0,x+dx,m_y_0,(uint)m_colors[index]);
}
else
{
x3=x+dx*(m_y_0-y1)/(y2-y1);
FillTriangle(x,y1,x3,m_y_0,x,m_y_0,(uint)m_colors[index]);
FillTriangle(x+dx,y2,x3,m_y_0,x+dx,m_y_0,(uint)m_colors[index]);
}
continue;
}
if(y1<m_y_0 || y2<m_y_0)
{
if(y1>y2)
FillTriangle(x,y1,x+dx,y2,x+dx,y1,(uint)m_colors[index]);
if(y1<y2)
{
FillTriangle(x,y1,x+dx,y2,x,y2,(uint)m_colors[index]);
y1=y2;
}
}
if(y1>m_y_0 || y2>m_y_0)
{
if(y1<y2)
FillTriangle(x,y1,x+dx,y2,x+dx,y1,(uint)m_colors[index]);
if(y1>y2)
{
FillTriangle(x,y1,x+dx,y2,x,y2,(uint)m_colors[index]);
y1=y2;
}
}
FillRectangle(x,m_y_0,x+dx,y1,(uint)m_colors[index]);
}
else
LineAA(x,y1,x+dx,y2,(uint)m_colors[index],STYLE_SOLID);
}
}
//+------------------------------------------------------------------+
//| Area of filling |
//+------------------------------------------------------------------+
double CLineChart::CalcArea(const uint index)
{
double area =0;
double value=0;
int dx =100;
//---
CArrayDouble *data=m_values.At(index);
if(data==NULL)
return(0);
int total=data.Total();
if(total<=1)
return(0);
int y1=0;
int y2=(int)(m_y_0-data[0]*m_scale_y);
for(int i=0;i<total;i++)
{
y1=y2;
double val=data[i];
if(val==EMPTY_VALUE)
continue;
if(m_accumulative)
value+=val;
else
value=val;
y2=(int)(m_y_0-value*m_scale_y);
if((y1>m_y_0 && y2<m_y_0) || (y1<m_y_0 && y2>m_y_0))
{
//--- line of values crosses the Y axis
int x;
if(y1>y2)
{
//--- from the bottom up
x=dx*(y1-m_y_0)/(y1-y2);
//--- add area of lower triangle
area+=x*(y1-m_y_0)/2;
//--- add area of upper triangle
area+=(dx-x)*(m_y_0-y2)/2;
}
else
{
//--- from top down
x=dx*(m_y_0-y1)/(y2-y1);
//--- add area of upper triangle
area+=x*(m_y_0-y1)/2;
//--- add area of lower triangle
area+=(dx-x)*(y2-m_y_0)/2;
}
continue;
}
if(y1<m_y_0 || y2<m_y_0)
{
//--- both values are greater than zero
if(y1>y2)
{
//--- add area of triangle
area+=dx*(y1-y2)/2;
//--- add area of rectangle
area+=dx*(m_y_0-y2);
}
if(y1<y2)
{
//--- add area of triangle
area+=dx*(y2-y1)/2;
//--- add area of rectangle
area+=dx*(m_y_0-y1);
}
}
if(y1>m_y_0 || y2>m_y_0)
{
//--- both values are less than zero
if(y1<y2)
{
//--- add area of triangle
area+=dx*(y2-y1)/2;
//--- add area of rectangle
area+=dx*(y1-m_y_0);
}
if(y1>y2)
{
//--- add area of triangle
area+=dx*(y1-y2)/2;
//--- add area of rectangle
area+=dx*(y2-m_y_0);
}
}
}
//---
return(area);
}
//+------------------------------------------------------------------+
+414
View File
@@ -0,0 +1,414 @@
//+------------------------------------------------------------------+
//| PieChart.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "ChartCanvas.mqh"
//+------------------------------------------------------------------+
//| Class CPieChart |
//| Usage: generates pie chart |
//+------------------------------------------------------------------+
class CPieChart : public CChartCanvas
{
private:
//--- data
CArrayDouble *m_values;
//--- for draw
int m_x0;
int m_y0;
int m_r;
public:
CPieChart(void);
~CPieChart(void);
//--- create
virtual bool Create(const string name,const int width,const int height,ENUM_COLOR_FORMAT clrfmt=COLOR_FORMAT_XRGB_NOALPHA);
//--- data
bool SeriesSet(const double &value[],const string &text[],const uint &clr[]);
bool ValueAdd(const double value,const string descr="",const uint clr=0);
bool ValueInsert(const uint pos,const double value,const string descr="",const uint clr=0);
bool ValueUpdate(const uint pos,const double value,const string descr=NULL,const uint clr=0);
bool ValueDelete(const uint pos);
protected:
virtual void DrawChart(void);
void DrawPie(double fi3,double fi4,int idx,CPoint &p[],const uint clr);
string LabelMake(const string text,const double value,const bool to_left);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CPieChart::CPieChart(void)
{
uint flags=FLAG_SHOW_LEGEND|FLAG_SHOW_DESCRIPTORS|FLAG_SHOW_VALUE|FLAG_SHOW_PERCENT;
AllowedShowFlags(flags);
ShowFlags(flags);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CPieChart::~CPieChart(void)
{
}
//+------------------------------------------------------------------+
//| Create dynamic resource |
//+------------------------------------------------------------------+
bool CPieChart::Create(const string name,const int width,const int height,ENUM_COLOR_FORMAT clrfmt)
{
//--- create object to store data
if((m_values=new CArrayDouble)==NULL)
return(false);
//--- pass responsibility for its destruction to the parent class
m_data=m_values;
//--- call method of parent class
if(!CChartCanvas::Create(name,width,height,clrfmt))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Sets displayed parameters |
//+------------------------------------------------------------------+
bool CPieChart::SeriesSet(const double &value[],const string &text[],const uint &clr[])
{
//--- !!! user is responsible for correct filling of arrays !!!
//--- check
if(m_values==NULL)
return(false);
//--- set
if(!m_values.AssignArray(value))
return(false);
if(!m_descriptors.AssignArray(text))
return(false);
if(!m_colors.AssignArray(clr))
return(false);
m_data_total=m_values.Total();
//--- redraw
Redraw();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Adds displayed parameter (to the end) |
//+------------------------------------------------------------------+
bool CPieChart::ValueAdd(const double value,const string descr,const uint clr)
{
//--- check
if((value<=0))
return(false);
//--- add
if(!m_values.Add(value))
return(false);
if(!m_descriptors.Add(descr))
return(false);
if(!m_colors.Add((clr==0) ? GetDefaultColor(m_data_total) : clr))
return(false);
m_data_total++;
//--- redraw
Redraw();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Inserts displayed parameter (to specified position) |
//+------------------------------------------------------------------+
bool CPieChart::ValueInsert(const uint pos,const double value,const string descr,const uint clr)
{
//--- check
if((value<=0))
return(false);
//--- insert
if(!m_values.Insert(value,pos))
return(false);
if(!m_descriptors.Insert(descr,pos))
return(false);
if(!m_colors.Insert((clr==0) ? GetDefaultColor(m_data_total) : clr,pos))
return(false);
m_data_total++;
//--- redraw
Redraw();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Updates displayed parameter (in specified position) |
//+------------------------------------------------------------------+
bool CPieChart::ValueUpdate(const uint pos,const double value,const string descr,const uint clr)
{
//--- check
if((value<=0))
return(false);
//--- update
if(!m_values.Update(pos,value))
return(false);
if(descr!=NULL && !m_descriptors.Update(pos,descr))
return(false);
if(clr!=0 && !m_colors.Update(pos,clr))
return(false);
//--- redraw
Redraw();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Deletes displayed parameter (from specified position) |
//+------------------------------------------------------------------+
bool CPieChart::ValueDelete(const uint pos)
{
//--- delete
if(!m_values.Delete(pos))
return(false);
m_data_total--;
if(!m_descriptors.Delete(pos))
return(false);
if(!m_colors.Delete(pos))
return(false);
//--- redraw
Redraw();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Draws |
//+------------------------------------------------------------------+
void CPieChart::DrawChart(void)
{
//--- check
if(m_data_total==0)
return;
//--- variables
string text="";
double angle=M_PI*(m_data_offset%360)/180;
int width,height;
int dw=0;
int dh=0;
int index;
CPoint p0[];
CPoint p1[];
//--- calculate geometry
width =(m_data_area.Width()<<3)/10;
height=(m_data_area.Height()<<3)/10;
if(IS_SHOW_LEGEND || !IS_SHOW_DESCRIPTORS)
{
if(IS_SHOW_VALUE)
dw=(int)m_max_value_width;
else
{
if(IS_SHOW_PERCENT)
dw=TextWidth("100.00%");
}
}
else
{
if(IS_SHOW_DESCRIPTORS)
{
if(IS_SHOW_VALUE)
dw=(int)m_max_value_width+TextWidth(" ()");
else
{
if(IS_SHOW_PERCENT)
dw=TextWidth(" (100.00%)");
}
dw+=(int)m_max_descr_width;
}
}
//--- pie chart will always be round
width -=2*dw+10;
height-=20;
m_x0=m_data_area.left+(m_data_area.Width()>>1);
m_y0=m_data_area.top+(m_data_area.Height()>>1);
m_r =(((width>height) ? height : width)>>1);
//--- draw pie chart
if(ArrayResize(p0,m_data_total+1)==-1)
return;
if(m_data_total==1)
{
FillCircle(m_x0,m_y0,m_r,m_colors[0]);
Circle(m_x0,m_y0,m_r,m_color_border);
}
else
{
Circle(m_x0,m_y0,m_r,m_color_border);
for(uint i=0;i<m_index_size;i++)
{
index=m_index[i];
double val=m_values[index];
double d_a=2*M_PI*val/m_sum;
DrawPie(angle,angle+d_a,i,p0,m_colors[index]);
angle+=d_a;
angle=MathMod(angle,2*M_PI);
}
if(m_data_total!=m_index_size)
DrawPie(angle,angle+2*M_PI*m_others/m_sum,m_index_size,p0,COLOR2RGB(clrBlack));
for(uint i=0;i<=m_index_size;i++)
Line(m_x0,m_y0,p0[i].x,p0[i].y,m_color_border);
Circle(m_x0,m_y0,m_r,m_color_border);
}
//--- draw descriptors
angle=M_PI*(m_data_offset%360)/180;
int r1=(int)round(1.1*m_r);
if(ArrayResize(p1,m_data_total)==-1)
return;
//--- calculations
for(uint i=0;i<m_index_size;i++)
{
index=m_index[i];
angle+=M_PI*m_values[index]/m_sum;
//--- lines
p0[i].x=m_x0+(int)round(m_r*cos(angle));
p0[i].y=m_y0-(int)round(m_r*sin(angle));
p1[i].x=m_x0+(int)round(r1*cos(angle));
p1[i].y=m_y0-(int)round(r1*sin(angle));
angle+=M_PI*m_values[index]/m_sum;
}
if(m_data_total!=m_index_size)
{
index=(int)m_data_total-1;
angle+=M_PI*m_others/m_sum;
p0[index].x=m_x0+(int)round(m_r*cos(angle));
p0[index].y=m_y0-(int)round(m_r*sin(angle));
p1[index].x=m_x0+(int)round(r1*cos(angle));
p1[index].y=m_y0-(int)round(r1*sin(angle));
}
int x,y;
//--- draw descriptors to the left
for(uint i=0;i<m_index_size;i++)
if(p0[i].x<m_x0)
{
x=p1[i].x-10;
y=p1[i].y;
index=m_index[i];
text=LabelMake(m_descriptors[index],m_values[index],true);
if(text!="")
{
Line(p0[i].x,p0[i].y,p1[i].x,p1[i].y,m_color_border);
Line(p1[i].x,p1[i].y,x,y,m_color_border);
TextOut(x-5,y,text,m_color_text,TA_RIGHT|TA_VCENTER);
}
}
//--- draw descriptors to the right
for(uint i=0;i<m_index_size;i++)
if(p0[i].x>=m_x0)
{
x=p1[i].x+10;
y=p1[i].y;
index=m_index[i];
text=LabelMake(m_descriptors[index],m_values[index],false);
if(text!="")
{
Line(p0[i].x,p0[i].y,p1[i].x,p1[i].y,m_color_border);
Line(p1[i].x,p1[i].y,x,y,m_color_border);
TextOut(x+5,y,text,m_color_text,TA_LEFT|TA_VCENTER);
}
}
if(m_data_total!=m_index_size)
{
index=(int)m_data_total-1;
if(p0[index].x>=m_x0)
{
x=p1[index].x+10;
y=p1[index].y;
text=LabelMake("Others",m_others,true);
TextOut(x+5,y,text,m_color_text,TA_LEFT|TA_VCENTER);
}
else
{
x=p1[index].x-10;
y=p1[index].y;
text=LabelMake("Others",m_others,false);
TextOut(x-5,y,text,m_color_text,TA_RIGHT|TA_VCENTER);
}
if(text!="")
{
Line(p0[index].x,p0[index].y,p1[index].x,p1[index].y,m_color_border);
Line(p1[index].x,p1[index].y,x,y,m_color_border);
}
}
ArrayFree(p1);
ArrayFree(p0);
}
//+------------------------------------------------------------------+
//| Draw pie |
//+------------------------------------------------------------------+
void CPieChart::DrawPie(double fi3,double fi4,int idx,CPoint &p[],const uint clr)
{
//--- draw arc
Arc(m_x0,m_y0,m_r,m_r,fi3,fi4,p[idx].x,p[idx].y,p[idx+1].x,p[idx+1].y,clr);
//--- variables
int x3=p[idx].x;
int y3=p[idx].y;
int x4=p[idx+1].x;
int y4=p[idx+1].y;
//--- draw radii
if(idx==0)
Line(m_x0,m_y0,x3,y3,clr);
if(idx!=m_data_total-1)
Line(m_x0,m_y0,x4,y4,clr);
//--- fill
double fi=(fi3+fi4)/2;
int xf=m_x0+(int)(0.99*m_r*cos(fi));
int yf=m_y0-(int)(0.99*m_r*sin(fi));
Fill(xf,yf,clr);
//--- for small pie
if(fi4-fi3<=M_PI_4)
Line(m_x0,m_y0,xf,yf,clr);
}
//+------------------------------------------------------------------+
//| Make label for pie |
//+------------------------------------------------------------------+
string CPieChart::LabelMake(const string text,const double value,const bool to_left)
{
string label="";
//---
if(to_left)
{
if(IS_SHOW_LEGEND || !IS_SHOW_DESCRIPTORS)
{
if(IS_SHOW_VALUE)
label=DoubleToString(value,2);
else
{
if(IS_SHOW_PERCENT)
label=DoubleToString(100*value/m_sum,2)+"%";
}
}
else
{
label=text;
if(IS_SHOW_VALUE)
label+=" ("+DoubleToString(value,2)+")";
else
{
if(IS_SHOW_PERCENT)
label+=" ("+DoubleToString(100*value/m_sum,2)+"%)";
}
}
}
else
{
if(IS_SHOW_LEGEND || !IS_SHOW_DESCRIPTORS)
{
if(IS_SHOW_VALUE)
label=DoubleToString(value,2);
else
{
if(IS_SHOW_PERCENT)
label=DoubleToString(100*value/m_sum,2)+"%";
}
}
else
{
if(IS_SHOW_VALUE)
label="("+DoubleToString(value,2)+") ";
else
{
if(IS_SHOW_PERCENT)
label="("+DoubleToString(100*value/m_sum,2)+"%) ";
}
label+=text;
}
}
//---
return(label);
}
//+------------------------------------------------------------------+
+751
View File
@@ -0,0 +1,751 @@
//+------------------------------------------------------------------+
//| FlameCanvas.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "Canvas.mqh"
#include <Controls\Defines.mqh>
//+------------------------------------------------------------------+
//| Gradient descriptors |
//+------------------------------------------------------------------+
struct GRADIENT_COLOR
{
uint clr; // color in ARGB format
uint pos; // position of color in percentage of gradient range
};
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
struct GRADIENT_SIZE
{
uint size; // width of gradient fill in percentage of base fill
uint pos; // position of color in percentage of gradient length
};
//+------------------------------------------------------------------+
//| Class CFlameCanvas |
//| Usage: generates flame |
//+------------------------------------------------------------------+
class CFlameCanvas : public CCanvas
{
private:
//--- parameters
uint m_bar_gap;
uint m_bar_width;
uint m_chart_scale;
double m_chart_price_min;
double m_chart_price_max;
ENUM_TIMEFRAMES m_timeframe;
string m_symbol;
int m_future_bars;
int m_back_bars;
int m_rates_total;
uint m_palette[256]; // flame palette
uchar m_flame[]; // buffer for calculation of flame
uint m_time_redraw;
uint m_delay;
// bool m_resize_flag;
// int m_tick_cnt;
//--- flame parameters
datetime m_tb1;
double m_pb1;
datetime m_te1;
double m_pe1;
datetime m_tb2;
double m_pb2;
datetime m_te2;
double m_pe2;
//--- equation parameters for flame
int m_cloud_axis[100];
double m_a1;
double m_b1;
double m_a2;
double m_b2;
int m_xb1;
int m_yb1;
int m_xe1;
int m_ye1;
int m_xb2;
int m_yb2;
int m_xe2;
int m_ye2;
public:
CFlameCanvas(void);
~CFlameCanvas(void);
//--- create
bool FlameCreate(const string name,const datetime time,const int future_bars,const int back_bars=0);
void RatesTotal(const int value);
//--- setting
void PaletteSet(uint clr=0xFF0000);
//--- draw
void FlameDraw(const double &prices[],const int width,const int lenght);
void FlameSet(datetime xb1,double yb1,datetime xe1,double ye1,datetime xb2,double yb2,datetime xe2,double ye2);
//--- event handler
void ChartEventHandler(const int id,const long &lparam,const double &dparam,const string &sparam);
protected:
bool Resize(void);
void ChartScale(void);
void FlameSet(void);
void CloudDraw(const double &prices[],const int width,const int lenght,GRADIENT_SIZE &size[],GRADIENT_COLOR &gradient[],const uchar t_level=255,const bool custom_gradient=true);
void FlameDraw(const int width,const int lenght,GRADIENT_SIZE &size[],GRADIENT_COLOR &gradient[]);
void GradientVertical(const int xb,const int xe,const int yb1,const int ye1,const int yb2,const int ye2,const GRADIENT_COLOR &gradient[]);
void GradientVerticalLine(int x,int y1,int y2,const GRADIENT_COLOR &gradient[]);
void GradientVerticalLineMonochrome(int x,int y1,int y2,uint clr1,uint clr2);
void FlameCreate(void);
void FlameCalculate(void);
void Delay(const uint value);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CFlameCanvas::CFlameCanvas(void) : m_bar_gap(16),
m_bar_width(8),
m_chart_scale(1),
m_chart_price_min(0.0),
m_chart_price_max(0.0),
m_timeframe(PERIOD_CURRENT),
m_symbol(NULL),
m_future_bars(0),
m_back_bars(0),
m_rates_total(0),
m_time_redraw(0),
m_delay(50),
m_tb1(0),
m_pb1(0),
m_te1(0),
m_pe1(0),
m_tb2(0),
m_pb2(0),
m_te2(0),
m_pe2(0)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CFlameCanvas::~CFlameCanvas(void)
{
Destroy();
}
//+------------------------------------------------------------------+
//| Creates dynamic resource with object |
//+------------------------------------------------------------------+
bool CFlameCanvas::FlameCreate(const string name,const datetime time,const int future_bars,const int back_bars)
{
//--- get chart parameters
ChartScale();
//--- create
int width =(int)m_bar_gap*(future_bars+back_bars);
int height=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
if(!CreateBitmap(0,0,name,time-back_bars*PeriodSeconds(),m_chart_price_max,width,height,COLOR_FORMAT_ARGB_NORMALIZE))
return(false);
ArrayResize(m_flame,width*height);
//--- save parameters
m_future_bars=future_bars;
m_back_bars =back_bars;
//--- settings
PaletteSet();
m_timeframe =Period();
m_symbol =Symbol();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Resize |
//+------------------------------------------------------------------+
bool CFlameCanvas::Resize(void)
{
int x,y;
//--- get limits
double min=ChartGetDouble(0,CHART_PRICE_MIN);
double max=ChartGetDouble(0,CHART_PRICE_MAX);
if(m_chart_price_max!=max)
{
//--- move object
ObjectSetDouble(0,m_objname,OBJPROP_PRICE,0,max);
}
//--- check
if(m_chart_price_min==min && m_chart_price_max==max)
return(false);
m_chart_price_min=min;
m_chart_price_max=max;
//--- grt size
ChartTimePriceToXY(0,0,m_tb1,min,x,y);
int width =(int)ChartGetInteger(0,CHART_WIDTH_IN_PIXELS)-x;
int height=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS);
//--- resize
if(width<m_width)
width=m_width;
if(width<=0)
return(false);
Resize(width,height);
//--- resize flame buffer
ArrayResize(m_flame,width*height);
ArrayInitialize(m_flame,0);
ArrayInitialize(m_pixels,0);
//--- restore parameters
if(m_pb1!=0.0)
FlameSet(m_tb1,m_pb1,m_te1,m_pe1,m_tb2,m_pb2,m_te2,m_pe2);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CFlameCanvas::RatesTotal(const int value)
{
if(value==0)
return;
if(m_rates_total==0)
m_rates_total=value;
else
{
if(m_rates_total!=value)
{
//--- move object
ObjectSetInteger(0,m_objname,OBJPROP_TIME,0,
ObjectGetInteger(0,m_objname,OBJPROP_TIME)+(value-m_rates_total)*PeriodSeconds());
m_rates_total=value;
}
}
}
//+------------------------------------------------------------------+
//| Adjusts to the chart scale |
//+------------------------------------------------------------------+
void CFlameCanvas::ChartScale(void)
{
m_chart_scale=(uint)ChartGetInteger(0,CHART_SCALE);
//--- set params
switch(m_chart_scale)
{
case 0:
m_bar_gap =1;
m_bar_width=1;
break;
case 1:
m_bar_gap =2;
m_bar_width=1;
break;
case 2:
m_bar_gap =4;
m_bar_width=2;
break;
case 3:
m_bar_gap =8;
m_bar_width=4;
break;
case 4:
m_bar_gap =16;
m_bar_width=10;
break;
case 5:
m_bar_gap =32;
m_bar_width=22;
break;
default:
return;
}
}
//+------------------------------------------------------------------+
//| Sets palette |
//+------------------------------------------------------------------+
void CFlameCanvas::PaletteSet(uint clr)
{
//--- create palette
double g=0,b=0,dg=1.45,db=0.63;
//---
for(uint a,i=0;i<256;i++)
{
//--- the first 32 values ??of flame are completely transparent
a=uchar(i<32?0:i-32);
//--- generate color for the i value of flame
m_palette[i]=(a<<24)|(uint(255)<<16)|(uint(g+0.5)<<8)|uint(b+0.5);
//--- increment the color components
//--- the red color gets gradient due to transparency
if(i>80) g+=dg;
if(i>160) b+=db;
}
}
//+------------------------------------------------------------------+
//| Draws the flame |
//+------------------------------------------------------------------+
void CFlameCanvas::FlameDraw(const double &prices[],const int width,const int lenght)
{
static GRADIENT_SIZE sword[]={{100,0},{150,70},{0,100}};
static GRADIENT_COLOR flame[]={{0x00,0},{0x7F7F7F,12},{0xCCCCCC,30},{0xFFFFFF,45},{0xFFFFFF,55},{0xCCCCCC,70},{0x7F7F7F,88},{0x00,100}};
//--- draw
CloudDraw(prices,width,lenght,sword,flame);
//--- copy flame buffer
FlameCalculate();
//--- start timer
EventChartCustom(CONTROLS_SELF_MESSAGE,1302,0,0,NULL);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CFlameCanvas::FlameDraw(const int width,const int lenght,GRADIENT_SIZE &size[],GRADIENT_COLOR &gradient[])
{
//--- check
int total=ArraySize(m_cloud_axis);
if(total<2)
return;
if(total>lenght)
total=lenght;
//--- draw
int xb,xe; // coordinates of the segment
int ybm,yem; // coordinates of the center line
int yb1,ye1; // coordinates of the first line
int yb2,ye2; // coordinates of the second line
//--- for implementation of variable width
int w_total=ArraySize(size);
if(w_total<2)
return;
int w_i =0;
int w_is=(int)size[w_i].pos*total/100;
int w_ie=(int)size[w_i+1].pos*total/100;
double w =size[w_i].size*width/100;
double dw =(size[w_i+1].size*width/100-w)/(w_ie-w_is);
//--- draw from left to right
xb=0;
ybm=m_cloud_axis[0];
yb1=ybm-(int)(w/2);
yb2=ybm+(int)(w/2);
//--- draw
for(int i=1;i<total;i++)
{
xe=(int)(i*m_bar_gap);
if(m_cloud_axis[i]==DBL_MAX)
continue;
yem=m_cloud_axis[i];
w+=dw;
ye1=yem-(int)(w/2);
ye2=yem+(int)(w/2);
//--- draw the segment of 'cloud'
GradientVertical(xb,xe,yb1,ye1,yb2,ye2,gradient);
xb=xe;
if(xb>=m_width)
break;
yb1=ye1;
yb2=ye2;
while(i>=w_ie-1 && i!=total-1)
{
w_i++;
w_is=(int)size[w_i].pos*total/100;
w_ie=(int)size[w_i+1].pos*total/100;
w =size[w_i].size*width/100;
if(w_ie==w_is)
{
//--- for "instant" resize
dw=size[w_i+1].size*width/100-w;
w+=dw;
ye1=yem-(int)(w/2);
ye2=yem+(int)(w/2);
//--- draw the segment of 'cloud'
GradientVertical(xb,xe,yb1,ye1,yb2,ye2,gradient);
yb1=ye1;
yb2=ye2;
}
else
{
dw=(size[w_i+1].size*width/100-w)/(w_ie-w_is);
break;
}
}
}
//--- copy flame buffer
FlameCalculate();
}
//+------------------------------------------------------------------+
//| Sets parameters of the flame and starts to draw |
//+------------------------------------------------------------------+
void CFlameCanvas::FlameSet(void)
{
m_a1=m_bar_gap*((m_ye1-m_yb1)/((double)m_xe1-m_xb1));
m_a2=m_bar_gap*((m_ye2-m_yb2)/((double)m_xe2-m_xb2));
}
//+------------------------------------------------------------------+
//| Sets parameters of the flame and starts to draw |
//+------------------------------------------------------------------+
void CFlameCanvas::FlameSet(datetime tb1,double pb1,
datetime te1,double pe1,
datetime tb2,double pb2,
datetime te2,double pe2)
{
datetime obj_time =(datetime)ObjectGetInteger(0,m_objname,OBJPROP_TIME);
double obj_price=ObjectGetDouble(0,m_objname,OBJPROP_PRICE);
int dx,dy;
//--- save parameters
m_tb1=tb1;
m_pb1=pb1;
m_te1=te1;
m_pe1=pe1;
m_tb2=tb2;
m_pb2=pb2;
m_te2=te2;
m_pe2=pe2;
//--- resize
Resize();
//--- convert
if(ChartTimePriceToXY(0,0,obj_time,obj_price,dx,dy))
{
dy=m_yb1;
if(ChartTimePriceToXY(0,0,tb1,pb1,m_xb1,m_yb1))
if(ChartTimePriceToXY(0,0,te1,pe1,m_xe1,m_ye1))
if(ChartTimePriceToXY(0,0,tb2,pb2,m_xb2,m_yb2))
if(ChartTimePriceToXY(0,0,te2,pe2,m_xe2,m_ye2))
{
//--- convert to canvas coordinates
m_xb1-=dx;
m_xe1-=dx;
m_xb2-=dx;
m_xe2-=dx;
//---
FlameSet();
}
}
//--- start timer
EventChartCustom(CONTROLS_SELF_MESSAGE,1302,0,0,NULL);
}
//+------------------------------------------------------------------+
//| Generate array that describes the body of flame |
//+------------------------------------------------------------------+
void CFlameCanvas::FlameCreate(void)
{
static GRADIENT_SIZE sword[]={{100,0},{150,70},{0,100}};
static GRADIENT_COLOR flame[]={{0x00,0},{0x7F7F7F,12},{0xCCCCCC,30},{0xFFFFFF,45},{0xFFFFFF,55},{0xCCCCCC,70},{0x7F7F7F,88},{0x00,100}};
//---
double a=rand(); // parameter of line a*x+b
double b=rand(); // parameter of line a*x+b
double c=rand(); // parameter of sine c*Sin(d*x)
double d=rand(); // parameter of sine c*Sin(d*x)
int w=rand(); // width at the base
int l=rand(); // length
//--- normalize
a=fmod(a,(m_a2-m_a1))+m_a1;
b=(m_yb1+m_yb2)/2;
c=fmod(c,20);
d=fmod(d,3*M_PI)+M_PI;
//--- shape
w%=150;
if(w<10)
w=10; // but no less than 10
sword[1].size=w;
w=rand();
l%=50;
sword[1].pos=l+30;
l=rand();
//--- sizes
w=(m_yb2-m_yb1!=0) ? w%(m_yb2-m_yb1) : 10; // proportional to the starting width
if(w<10)
w=10; // but no less than 10
l=l%((m_xe1-m_xb1)/(int)m_bar_gap-20)+20; // proportional to length
//--- create
int total=ArraySize(m_cloud_axis);
for(int i=0;i<total;i++)
m_cloud_axis[i]=int(a*i+b+c*sin(i/d));
//--- draw
FlameDraw(w,l,sword,flame);
}
//+------------------------------------------------------------------+
//| Calculates and renders frame |
//+------------------------------------------------------------------+
void CFlameCanvas::FlameCalculate(void)
{
//--- calculate new frame
int c;
int idx;
//--- draw body of flame to the right
for(int x=0,x_tot=m_width-1;x<x_tot;x++)
{
//--- separately for y==0
c=m_flame[x]+m_flame[x+m_width];
c+=+m_flame[x]+m_flame[x+m_width];
m_flame[x]=uchar(c/4);
//---
for(int y=1,y_tot=m_height-1;y<y_tot;y++)
{
idx=y*m_width+x;
c=m_flame[idx-m_width]+m_flame[idx]+m_flame[idx+m_width];
idx++;
c+=m_flame[idx-m_width]+m_flame[idx]+m_flame[idx+m_width];
m_flame[idx]=uchar(c/6);
}
//--- separately for y==m_height-1
idx=(m_height-1)*m_width+x;
c=m_flame[idx-m_width]+m_flame[idx];
idx++;
c+=m_flame[idx-m_width]+m_flame[idx];
m_flame[idx]=uchar(c/4);
}
//--- move flame to the resource buffer
for(int y=0;y<m_height;y++)
{
for(int x=0;x<m_width;x++)
{
idx=y*m_width+x;
m_pixels[idx]=m_palette[m_flame[idx]];
}
}
//---
}
//+------------------------------------------------------------------+
//| Draws "cloud" |
//+------------------------------------------------------------------+
void CFlameCanvas::CloudDraw(const double &prices[],const int width,const int lenght,GRADIENT_SIZE &size[],GRADIENT_COLOR &gradient[],const uchar t_level,const bool custom_gradient)
{
//--- check
int total=ArraySize(prices);
if(total<2)
return;
if(total>lenght)
total=lenght;
//--- draw
int xb,xe; // coordinates of the segment
int ybm,yem; // coordinates of the center line
int yb1,ye1; // coordinates of the first line
int yb2,ye2; // coordinates of the second line
int xx;
//--- for implementation of variable width
int w_total=ArraySize(size);
if(w_total<2)
return;
int w_i =0;
int w_is=(int)size[w_i].pos*total/100;
int w_ie=(int)size[w_i+1].pos*total/100;
double w =size[w_i].size*width/100;
double dw =(size[w_i+1].size*width/100-w)/(w_ie-w_is);
//--- draw from left to right
xb=0;
ChartTimePriceToXY(0,0,0,prices[0],xx,ybm);
yb1=ybm-(int)(w/2);
yb2=ybm+(int)(w/2);
//--- draw
for(int i=1;i<total;i++)
{
xe=(int)(i*m_bar_gap);
if(prices[i]==DBL_MAX)
continue;
ChartTimePriceToXY(0,0,0,prices[i],xx,yem);
w+=dw;
ye1=yem-(int)(w/2);
ye2=yem+(int)(w/2);
//--- draw the segment of 'cloud'
GradientVertical(xb,xe,yb1,ye1,yb2,ye2,gradient);
xb=xe;
if(xb>=m_width)
break;
yb1=ye1;
yb2=ye2;
while(i>=w_ie-1 && i!=total-1)
{
w_i++;
w_is=(int)size[w_i].pos*total/100;
w_ie=(int)size[w_i+1].pos*total/100;
w =size[w_i].size*width/100;
if(w_ie==w_is)
{
//--- for "instant" resize
dw=size[w_i+1].size*width/100-w;
w+=dw;
ye1=yem-(int)(w/2);
ye2=yem+(int)(w/2);
//--- draw the segment of 'cloud'
GradientVertical(xb,xe,yb1,ye1,yb2,ye2,gradient);
yb1=ye1;
yb2=ye2;
}
else
{
dw=(size[w_i+1].size*width/100-w)/(w_ie-w_is);
break;
}
}
}
}
//+------------------------------------------------------------------+
//| Draws area with vertical fill using specified gradient |
//+------------------------------------------------------------------+
void CFlameCanvas::GradientVertical(const int xb,const int xe,const int yb1,const int ye1,const int yb2,const int ye2,const GRADIENT_COLOR &gradient[])
{
//--- it is assumed that the colors array has sufficient size and positions are already sorted in ascending order
//--- get length by X and Y
int x1 =xb;
int y1 =yb1;
int x2 =xb;
int y2 =yb2;
int dx =(xe>xb)? xe-xb : xb-xe;
int dy1=(ye1>yb1)? ye1-yb1 : yb1-ye1;
int dy2=(ye2>yb2)? ye2-yb2 : yb2-ye2;
//--- get direction by X and Y
int sx =(xb<xe)? 1 : -1;
int sy1=(yb1<ye1)? 1 : -1;
int sy2=(yb2<ye2)? 1 : -1;
int er1=dx-dy1;
int er2=dx-dy2;
//--- extreme colors
uint clr_first=gradient[0].clr;
uint clr_last =gradient[ArraySize(gradient)-1].clr;
//--- draw the first line
while(x1!=xe || y1!=ye1)
{
//--- calculate coordinates of next pixel of the first line
if((er1<<1)>-dy1)
{
//--- try to change X coordinate of the first line
//--- draw the second line
while(x2!=xe || y2!=ye2)
{
//--- calculate coordinates of next pixel of the second line
if((er2<<1)>-dy2)
{
//--- try to change X coordinate of the second line
//--- gradient fill
GradientVerticalLine(x1,y1,y2,gradient);
er2-=dy2;
if(x2!=xe)
x2+=sx;
}
if((er2<<1)<dx)
{
er2+=dx;
if(y2!=ye2)
y2+=sy2;
}
//--- draw the first line
if(x1!=x2)
break;
}
er1-=dy1;
if(x1!=xe)
x1+=sx;
}
if((er1<<1)<dx)
{
er1+=dx;
if(y1!=ye1)
y1+=sy1;
}
}
//--- gradient fill
GradientVerticalLine(x1,ye1,ye2,gradient);
}
//+------------------------------------------------------------------+
//| Draws gradient vertical line |
//+------------------------------------------------------------------+
void CFlameCanvas::GradientVerticalLineMonochrome(int x,int y1,int y2,uint clr1,uint clr2)
{
//---
double dc;
int dd,dy=y2-y1;
//--- check
if(dy==0)
return;
//--- extract components from the first color
uchar clr=(uchar)clr1;
//--- parameters of pixels iteration
if(dy>0)
{
dd=dy;
dy=1;
}
else
{
dd=-dy;
dy=-1;
}
//--- increments for the color components
dc=(double)((uchar)clr2-clr)/dd;
//--- draw
for(int i=0;y1!=y2;i++,y1+=dy)
{
int idx=y1*m_width+x;
//--- check range
if(idx<0 || idx>=ArraySize(m_flame))
continue;
if(x>=0 && x<m_width && y1>=0 && y1<m_height)
if(m_flame[idx]<(uchar)(clr+dc*i))
m_flame[idx]=(uchar)(clr+dc*i);
}
}
//+------------------------------------------------------------------+
//| Draws vertical line with specified gradient |
//+------------------------------------------------------------------+
void CFlameCanvas::GradientVerticalLine(int x,int y1,int y2,const GRADIENT_COLOR &gradient[])
{
//--- it is assumed that the colors array has sufficient size and positions are already sorted in ascending order
int total=ArraySize(gradient);
int dy=y2-y1;
//--- draw segments
for(int i=0;i<total-1;i++)
GradientVerticalLineMonochrome(x,y1+dy*gradient[i].pos/100,y1+dy*gradient[i+1].pos/100,gradient[i].clr,gradient[i+1].clr);
}
//+------------------------------------------------------------------+
//| Event handler |
//+------------------------------------------------------------------+
void CFlameCanvas::ChartEventHandler(const int id,const long &lparam,const double &dparam,const string &sparam)
{
//--- events filter
switch(id)
{
case CHARTEVENT_CHART_CHANGE:
//--- handle only chart modification events
if(m_chart_scale!=(uint)ChartGetInteger(0,CHART_SCALE))
{
Delay(20);
//--- changed horizontal scale
ChartScale();
if(m_pb1!=0.0)
FlameSet(m_tb1,m_pb1,m_te1,m_pe1,m_tb2,m_pb2,m_te2,m_pe2);
return;
}
if(m_height!=(int)ChartGetInteger(0,CHART_HEIGHT_IN_PIXELS))
{
//--- changed vertical size
Delay(20);
if(m_pb1!=0.0)
FlameSet(m_tb1,m_pb1,m_te1,m_pe1,m_tb2,m_pb2,m_te2,m_pe2);
return;
}
if(m_chart_price_min!=ChartGetDouble(0,CHART_PRICE_MIN) ||
m_chart_price_max!=ChartGetDouble(0,CHART_PRICE_MAX))
{
//--- changed vertical scale
Delay(20);
if(m_pb1!=0.0)
FlameSet(m_tb1,m_pb1,m_te1,m_pe1,m_tb2,m_pb2,m_te2,m_pe2);
return;
}
break;
//--- organize custom timer
case CHARTEVENT_CUSTOM+1302:
//--- time to draw the new frame?
if(GetTickCount()>m_time_redraw)
{
//--- add the body of flame
FlameCreate();
//--- draw frame
FlameCalculate();
Update();
//--- calculate time for the next frame
m_time_redraw=GetTickCount()+m_delay;
}
//--- generate next event for custom timer
EventChartCustom(CONTROLS_SELF_MESSAGE,1302,0,0,NULL);
break;
}
}
//+------------------------------------------------------------------+
//| Delay |
//+------------------------------------------------------------------+
void CFlameCanvas::Delay(const uint value)
{
//--- too small
if(value<10)
return;
//--- start delay
uint cnt=GetTickCount()+value;
//--- delay
while(cnt>=GetTickCount());
}
//+------------------------------------------------------------------+
File diff suppressed because it is too large Load Diff
+198
View File
@@ -0,0 +1,198 @@
//+------------------------------------------------------------------+
//| ChartObjectPanel.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include <ChartObjects\ChartObjectsTxtControls.mqh>
#include <Arrays\ArrayObj.mqh>
#include <Arrays\ArrayInt.mqh>
//+------------------------------------------------------------------+
//| Class CChartObjectPanel. |
//| Purpose: Class for grouping objects for managing a chart |
//+------------------------------------------------------------------+
class CChartObjectPanel : public CChartObjectButton
{
protected:
CArrayObj m_attachment; // array of attached objects
CArrayInt m_dX; // array of dX attached objects
CArrayInt m_dY; // array of dY attached objects
bool m_expanded; // collapsed/expanded flag
public:
CChartObjectPanel();
~CChartObjectPanel();
//--- method for attaching objects
bool Attach(CChartObjectLabel *chart_object);
bool X_Distance(const int X);
bool Y_Distance(const int Y);
int X_Size() const;
int Y_Size() const;
virtual bool Timeframes(const int timeframes);
bool State(const bool state);
bool CheckState();
protected:
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
void CChartObjectPanel::CChartObjectPanel(void) : m_expanded(true)
{
}
//+------------------------------------------------------------------+
//| Destructor. |
//+------------------------------------------------------------------+
void CChartObjectPanel::~CChartObjectPanel(void)
{
//--- All objects added by the method Add(), deleted automatically
}
//+------------------------------------------------------------------+
//| Method Attach |
//+------------------------------------------------------------------+
bool CChartObjectPanel::Attach(CChartObjectLabel *chart_object)
{
if(m_attachment.Add(chart_object))
{
int x,y;
x=chart_object.X_Distance();
m_dX.Add(chart_object.X_Distance());
x+=X_Distance();
chart_object.X_Distance(X_Distance()+chart_object.X_Distance());
y=CChartObjectButton::Y_Size();
y+=chart_object.Y_Distance();
m_dY.Add(chart_object.Y_Distance()+CChartObjectButton::Y_Size()+2);
chart_object.Y_Distance(Y_Distance()+chart_object.Y_Distance()+CChartObjectButton::Y_Size()+2);
return(true);
}
//---
return(false);
}
//+------------------------------------------------------------------+
//| Method X_Distance |
//+------------------------------------------------------------------+
bool CChartObjectPanel::X_Distance(const int X)
{
CChartObjectLabel *chart_object;
//---
for(int i=0;i<m_attachment.Total();i++)
{
chart_object=m_attachment.At(i);
chart_object.X_Distance(X+m_dX.At(i));
}
//---
return(CChartObjectButton::X_Distance(X));
}
//+------------------------------------------------------------------+
//| Method Y_Distance |
//+------------------------------------------------------------------+
bool CChartObjectPanel::Y_Distance(const int Y)
{
CChartObjectLabel *chart_object;
//---
for(int i=0;i<m_attachment.Total();i++)
{
chart_object=m_attachment.At(i);
chart_object.Y_Distance(Y+m_dY.At(i));
}
//---
return(CChartObjectButton::Y_Distance(Y));
}
//+------------------------------------------------------------------+
//| Method X_Size |
//+------------------------------------------------------------------+
int CChartObjectPanel::X_Size() const
{
int max_x=CChartObjectButton::X_Size()+X_Distance();
CChartObjectLabel *chart_object;
//---
if(m_expanded)
{
for(int i=0;i<m_attachment.Total();i++)
if((chart_object=m_attachment.At(i))!=NULL)
if(max_x<chart_object.X_Distance()+chart_object.X_Size())
max_x=chart_object.X_Distance()+chart_object.X_Size();
return(max_x-X_Distance()+2);
}
//---
return(CChartObjectButton::X_Size()+2);
}
//+------------------------------------------------------------------+
//| Method Y_Size |
//+------------------------------------------------------------------+
int CChartObjectPanel::Y_Size() const
{
int max_y=CChartObjectButton::Y_Size()+Y_Distance();
CChartObjectLabel *chart_object;
//---
if(m_expanded)
{
for(int i=0;i<m_attachment.Total();i++)
if((chart_object=m_attachment.At(i))!=NULL)
if(max_y<chart_object.Y_Distance()+chart_object.Y_Size())
max_y=chart_object.Y_Distance()+chart_object.Y_Size();
return(max_y-Y_Distance()+2);
}
//---
return(CChartObjectButton::Y_Size()+2);
}
//+------------------------------------------------------------------+
//| Method Timeframes |
//+------------------------------------------------------------------+
bool CChartObjectPanel::Timeframes(const int timeframes)
{
int i;
bool res=CChartObject::Timeframes(timeframes);
CChartObjectLabel *chart_object;
//---
if(m_expanded)
for(i=0;i<m_attachment.Total();i++)
{
chart_object=m_attachment.At(i);
res&=chart_object.Timeframes(timeframes);
}
//---
return(res);
}
//+------------------------------------------------------------------+
//| Method State |
//+------------------------------------------------------------------+
bool CChartObjectPanel::State(const bool state)
{
if(CChartObjectButton::State(state))
{
m_expanded=state;
return(true);
}
//---
return(false);
}
//+------------------------------------------------------------------+
//| Method CheckState |
//+------------------------------------------------------------------+
bool CChartObjectPanel::CheckState(void)
{
int i;
CChartObjectLabel *chart_object;
//---
if(m_expanded!=State())
{
if(m_expanded=State())
//--- make all objects visible
for(i=0;i<m_attachment.Total();i++)
{
chart_object=m_attachment.At(i);
chart_object.Timeframes(-1);
}
else
//--- make all objects invisible
for(i=0;i<m_attachment.Total();i++)
{
chart_object=m_attachment.At(i);
chart_object.Timeframes(0x100000);
}
return(true);
}
//---
return(false);
}
//+------------------------------------------------------------------+
@@ -0,0 +1,397 @@
//+------------------------------------------------------------------+
//| ChartObjectSubChart.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "ChartObject.mqh"
//+------------------------------------------------------------------+
//| Class CChartObjectSubChart. |
//| Purpose: Class of the "SubChart" object of chart. |
//| Derives from class CChartObject. |
//+------------------------------------------------------------------+
class CChartObjectSubChart : public CChartObject
{
public:
CChartObjectSubChart(void);
~CChartObjectSubChart(void);
//--- methods of access to properties of the object
int X_Distance(void) const;
bool X_Distance(const int X) const;
int Y_Distance(void) const;
bool Y_Distance(const int Y) const;
ENUM_BASE_CORNER Corner(void) const;
bool Corner(const ENUM_BASE_CORNER corner) const;
int X_Size(void) const;
bool X_Size(const int size) const;
int Y_Size(void) const;
bool Y_Size(const int size) const;
string Symbol(void) const;
bool Symbol(const string symbol) const;
int Period(void) const;
bool Period(const int period) const;
int Scale(void) const;
bool Scale(const int scale) const;
bool DateScale(void) const;
bool DateScale(const bool scale) const;
bool PriceScale(void) const;
bool PriceScale(const bool scale) const;
//--- change of time/price coordinates is blocked
bool Time(const datetime time) const { return(false); }
bool Price(const double price) const { return(false); }
//--- method of creating object
bool Create(long chart_id,const string name,const int window,
const int X,const int Y,const int sizeX,const int sizeY);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_CHART); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectSubChart::CChartObjectSubChart(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectSubChart::~CChartObjectSubChart(void)
{
}
//+------------------------------------------------------------------+
//| Create object "SubChart" |
//+------------------------------------------------------------------+
bool CChartObjectSubChart::Create(long chart_id,const string name,const int window,
const int X,const int Y,const int sizeX,const int sizeY)
{
if(!ObjectCreate(chart_id,name,OBJ_CHART,window,0,0,0))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
if(!X_Distance(X) || !Y_Distance(Y))
return(false);
if(!X_Size(sizeX) || !Y_Size(sizeY))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Get the X-distance |
//+------------------------------------------------------------------+
int CChartObjectSubChart::X_Distance(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_XDISTANCE));
}
//+------------------------------------------------------------------+
//| Set the X-distance |
//+------------------------------------------------------------------+
bool CChartObjectSubChart::X_Distance(const int X) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_XDISTANCE,X));
}
//+------------------------------------------------------------------+
//| Get the Y-distance |
//+------------------------------------------------------------------+
int CChartObjectSubChart::Y_Distance(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_YDISTANCE));
}
//+------------------------------------------------------------------+
//| Set the Y-distance |
//+------------------------------------------------------------------+
bool CChartObjectSubChart::Y_Distance(const int Y) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_YDISTANCE,Y));
}
//+------------------------------------------------------------------+
//| Get base corner |
//+------------------------------------------------------------------+
ENUM_BASE_CORNER CChartObjectSubChart::Corner(void) const
{
//--- check
if(m_chart_id==-1)
return(WRONG_VALUE);
//--- result
return((ENUM_BASE_CORNER)ObjectGetInteger(m_chart_id,m_name,OBJPROP_CORNER));
}
//+------------------------------------------------------------------+
//| Set base corner |
//+------------------------------------------------------------------+
bool CChartObjectSubChart::Corner(const ENUM_BASE_CORNER corner) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_CORNER,corner));
}
//+------------------------------------------------------------------+
//| Get the X-size |
//+------------------------------------------------------------------+
int CChartObjectSubChart::X_Size(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_XSIZE));
}
//+------------------------------------------------------------------+
//| Set X-size |
//+------------------------------------------------------------------+
bool CChartObjectSubChart::X_Size(const int size) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_XSIZE,size));
}
//+------------------------------------------------------------------+
//| Get the Y-size |
//+------------------------------------------------------------------+
int CChartObjectSubChart::Y_Size(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_YSIZE));
}
//+------------------------------------------------------------------+
//| Set the Y-size |
//+------------------------------------------------------------------+
bool CChartObjectSubChart::Y_Size(const int size) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_YSIZE,size));
}
//+------------------------------------------------------------------+
//| Get chart symbol |
//+------------------------------------------------------------------+
string CChartObjectSubChart::Symbol(void) const
{
//--- check
if(m_chart_id==-1)
return("");
//--- result
return(ObjectGetString(m_chart_id,m_name,OBJPROP_SYMBOL));
}
//+------------------------------------------------------------------+
//| Set chart symbol |
//+------------------------------------------------------------------+
bool CChartObjectSubChart::Symbol(const string symbol) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetString(m_chart_id,m_name,OBJPROP_SYMBOL,symbol));
}
//+------------------------------------------------------------------+
//| Get chart period |
//+------------------------------------------------------------------+
int CChartObjectSubChart::Period(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_PERIOD));
}
//+------------------------------------------------------------------+
//| Set chart period |
//+------------------------------------------------------------------+
bool CChartObjectSubChart::Period(const int period) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_PERIOD,period));
}
//+------------------------------------------------------------------+
//| Get chart scale |
//+------------------------------------------------------------------+
int CChartObjectSubChart::Scale(void) const
{
//--- check
if(m_chart_id==-1)
return(-1);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_CHART_SCALE));
}
//+------------------------------------------------------------------+
//| Set chart scale |
//+------------------------------------------------------------------+
bool CChartObjectSubChart::Scale(const int scale) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_CHART_SCALE,scale));
}
//+------------------------------------------------------------------+
//| Get the "time scale" flag |
//+------------------------------------------------------------------+
bool CChartObjectSubChart::DateScale(void) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectGetInteger(m_chart_id,m_name,OBJPROP_DATE_SCALE));
}
//+------------------------------------------------------------------+
//| Set the "time scale" flag |
//+------------------------------------------------------------------+
bool CChartObjectSubChart::DateScale(const bool scale) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_DATE_SCALE,scale));
}
//+------------------------------------------------------------------+
//| Get the "price scale" flag |
//+------------------------------------------------------------------+
bool CChartObjectSubChart::PriceScale(void) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectGetInteger(m_chart_id,m_name,OBJPROP_PRICE_SCALE));
}
//+------------------------------------------------------------------+
//| Set the "price scale" flag |
//+------------------------------------------------------------------+
bool CChartObjectSubChart::PriceScale(const bool scale) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_PRICE_SCALE,scale));
}
//+------------------------------------------------------------------+
//| Writing parameters of object to file |
//+------------------------------------------------------------------+
bool CChartObjectSubChart::Save(const int file_handle)
{
int len;
string str;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- write
if(!CChartObject::Save(file_handle))
return(false);
//--- write value of the "X-distance" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_XDISTANCE),INT_VALUE)!=sizeof(int))
return(false);
//--- write value of the "Y-distance" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_YDISTANCE),INT_VALUE)!=sizeof(int))
return(false);
//--- write value of the "corner" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_CORNER),INT_VALUE)!=sizeof(int))
return(false);
//--- write value of the "X-size" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_XSIZE),INT_VALUE)!=sizeof(int))
return(false);
//--- write value of the "Y-size" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_YSIZE),INT_VALUE)!=sizeof(int))
return(false);
//--- write value of the "symbol" property
str=ObjectGetString(m_chart_id,m_name,OBJPROP_SYMBOL);
len=StringLen(str);
if(FileWriteInteger(file_handle,len,INT_VALUE)!=INT_VALUE)
return(false);
if(len!=0 && FileWriteString(file_handle,str,len)!=len)
return(false);
//--- write value of the "period" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_PERIOD),INT_VALUE)!=sizeof(int))
return(false);
//--- write value of the "scale" property
if(FileWriteDouble(file_handle,ObjectGetDouble(m_chart_id,m_name,OBJPROP_SCALE))!=sizeof(double))
return(false);
//--- write value of the "time scale" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_DATE_SCALE),CHAR_VALUE)!=sizeof(char))
return(false);
//--- write value of the "price scale" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_PRICE_SCALE),CHAR_VALUE)!=sizeof(char))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Reading parameters of object from file |
//+------------------------------------------------------------------+
bool CChartObjectSubChart::Load(const int file_handle)
{
int len;
string str;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- read
if(!CChartObject::Load(file_handle))
return(false);
//--- read value of the "X-distance" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_XDISTANCE,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- read value of the "Y-distance" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_YDISTANCE,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- read value of the "corner" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_CORNER,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- read value of the "X-size" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_XSIZE,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- read value of the "Y-size" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_YSIZE,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- read value of the "symbol" property
len=FileReadInteger(file_handle,INT_VALUE);
str=(len!=0) ? FileReadString(file_handle,len) : "";
if(!ObjectSetString(m_chart_id,m_name,OBJPROP_SYMBOL,str))
return(false);
//--- read value of the "period" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_PERIOD,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- read value of the "scale" property
if(!ObjectSetDouble(m_chart_id,m_name,OBJPROP_SCALE,FileReadDatetime(file_handle)))
return(false);
//--- read value of the "time scale" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_DATE_SCALE,FileReadInteger(file_handle,CHAR_VALUE)))
return(false);
//--- read value of the "price scale" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_PRICE_SCALE,FileReadInteger(file_handle,CHAR_VALUE)))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
+486
View File
@@ -0,0 +1,486 @@
//+------------------------------------------------------------------+
//| ChartObjectsArrows.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
//| All arrows. |
//+------------------------------------------------------------------+
#include "ChartObject.mqh"
//+------------------------------------------------------------------+
//| Class CChartObjectArrow. |
//| Purpose: Class of the "Arrow" object of chart. |
//| Derives from class CChartObject. |
//+------------------------------------------------------------------+
class CChartObjectArrow : public CChartObject
{
public:
CChartObjectArrow(void);
~CChartObjectArrow(void);
//--- methods of access to properties of the object
char ArrowCode(void) const;
bool ArrowCode(const char code) const;
ENUM_ARROW_ANCHOR Anchor(void) const;
bool Anchor(const ENUM_ARROW_ANCHOR anchor) const;
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time,const double price,const char code);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_ARROW); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectArrow::CChartObjectArrow(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectArrow::~CChartObjectArrow(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Arrow" |
//+------------------------------------------------------------------+
bool CChartObjectArrow::Create(long chart_id,const string name,const int window,
const datetime time,const double price,const char code)
{
if(!ObjectCreate(chart_id,name,OBJ_ARROW,window,time,price))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
if(!ArrowCode(code))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Get code of "arrow" symbol |
//+------------------------------------------------------------------+
char CChartObjectArrow::ArrowCode(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((char)ObjectGetInteger(m_chart_id,m_name,OBJPROP_ARROWCODE));
}
//+------------------------------------------------------------------+
//| Set code of "arrow" symbol |
//+------------------------------------------------------------------+
bool CChartObjectArrow::ArrowCode(const char code) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_ARROWCODE,code));
}
//+------------------------------------------------------------------+
//| Get anchor type |
//+------------------------------------------------------------------+
ENUM_ARROW_ANCHOR CChartObjectArrow::Anchor(void) const
{
//--- result
return((ENUM_ARROW_ANCHOR)ObjectGetInteger(m_chart_id,m_name,OBJPROP_ANCHOR));
}
//+------------------------------------------------------------------+
//| Set anchor type |
//+------------------------------------------------------------------+
bool CChartObjectArrow::Anchor(const ENUM_ARROW_ANCHOR anchor) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_ANCHOR,anchor));
}
//+------------------------------------------------------------------+
//| Writing parameters of object to file |
//+------------------------------------------------------------------+
bool CChartObjectArrow::Save(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- writing
if(!CObject::Save(file_handle))
return(false);
//--- write code of "arrow" symbol
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_ARROWCODE),CHAR_VALUE)!=sizeof(char))
return(false);
//--- write anchor type
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_ANCHOR),INT_VALUE)!=sizeof(int))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Reading parameters of object from file |
//+------------------------------------------------------------------+
bool CChartObjectArrow::Load(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- reading
if(!CObject::Load(file_handle))
return(false);
//--- read code of "arrow" symbol
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_ARROWCODE,FileReadInteger(file_handle,CHAR_VALUE)))
return(false);
//--- read anchor type
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_ANCHOR,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectArrowThumbUp. |
//| Purpose: Class of the "Thumbs Up" object of chart. |
//| Derives from class CChartObjectArrow. |
//+------------------------------------------------------------------+
class CChartObjectArrowThumbUp : public CChartObjectArrow
{
public:
CChartObjectArrowThumbUp(void);
~CChartObjectArrowThumbUp(void);
//--- change of arrow code is blocked
bool ArrowCode(const char code) const { return(false); }
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time,const double price);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_ARROW_THUMB_UP); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectArrowThumbUp::CChartObjectArrowThumbUp(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectArrowThumbUp::~CChartObjectArrowThumbUp(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Thumbs Up" |
//+------------------------------------------------------------------+
bool CChartObjectArrowThumbUp::Create(long chart_id,const string name,const int window,
const datetime time,const double price)
{
if(!ObjectCreate(chart_id,name,OBJ_ARROW_THUMB_UP,window,time,price))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectArrowThumbDown. |
//| Purpose: Class of the "Thumbs Down" object of chart. |
//| Derives from class CChartObjectArrow. |
//+------------------------------------------------------------------+
class CChartObjectArrowThumbDown : public CChartObjectArrow
{
public:
CChartObjectArrowThumbDown(void);
~CChartObjectArrowThumbDown(void);
//--- change of arrow code is blocked
bool ArrowCode(const char code) const { return(false); }
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time,const double price);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_ARROW_THUMB_DOWN); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectArrowThumbDown::CChartObjectArrowThumbDown(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectArrowThumbDown::~CChartObjectArrowThumbDown(void)
{
}
//+------------------------------------------------------------------+
//| Create object "ThumbsDown" |
//+------------------------------------------------------------------+
bool CChartObjectArrowThumbDown::Create(long chart_id,const string name,const int window,
const datetime time,const double price)
{
if(!ObjectCreate(chart_id,name,OBJ_ARROW_THUMB_DOWN,window,time,price))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectArrowUp. |
//| Purpose: Class of the "Arrow Up" object of chart. |
//| Derives from class CChartObjectArrow. |
//+------------------------------------------------------------------+
class CChartObjectArrowUp : public CChartObjectArrow
{
public:
CChartObjectArrowUp(void);
~CChartObjectArrowUp(void);
//--- change of arrow code is blocked
bool ArrowCode(const char code) const { return(false); }
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time,const double price);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_ARROW_UP); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectArrowUp::CChartObjectArrowUp(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectArrowUp::~CChartObjectArrowUp(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Arrow Up" |
//+------------------------------------------------------------------+
bool CChartObjectArrowUp::Create(long chart_id,const string name,const int window,
const datetime time,const double price)
{
if(!ObjectCreate(chart_id,name,OBJ_ARROW_UP,window,time,price))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectArrowDown. |
//| Purpose: Class of the "Arrow Down" object of chart. |
//| Derives from class CChartObjectArrow. |
//+------------------------------------------------------------------+
class CChartObjectArrowDown : public CChartObjectArrow
{
public:
CChartObjectArrowDown(void);
~CChartObjectArrowDown(void);
//--- change of arrow code is blocked
bool ArrowCode(const char code) const { return(false); }
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time,const double price);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_ARROW_DOWN); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectArrowDown::CChartObjectArrowDown(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectArrowDown::~CChartObjectArrowDown(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Arrow Down" |
//+------------------------------------------------------------------+
bool CChartObjectArrowDown::Create(long chart_id,const string name,const int window,
const datetime time,const double price)
{
if(!ObjectCreate(chart_id,name,OBJ_ARROW_DOWN,window,time,price))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectArrowStop. |
//| Purpose: Class of the "Stop Sign" object of chart. |
//| Derives from class CChartObjectArrow. |
//+------------------------------------------------------------------+
class CChartObjectArrowStop : public CChartObjectArrow
{
public:
CChartObjectArrowStop(void);
~CChartObjectArrowStop(void);
//--- change of arrow code is blocked
bool ArrowCode(const char code) const { return(false); }
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time,const double price);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_ARROW_STOP); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectArrowStop::CChartObjectArrowStop(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectArrowStop::~CChartObjectArrowStop(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Stop Sign" |
//+------------------------------------------------------------------+
bool CChartObjectArrowStop::Create(long chart_id,const string name,const int window,
const datetime time,const double price)
{
if(!ObjectCreate(chart_id,name,OBJ_ARROW_STOP,window,time,price))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectArrowCheck. |
//| Purpose: Class of the "Check Sign" object of chart. |
//| Derives from class CChartObjectArrow. |
//+------------------------------------------------------------------+
class CChartObjectArrowCheck : public CChartObjectArrow
{
public:
CChartObjectArrowCheck(void);
~CChartObjectArrowCheck(void);
//--- change of arrow code is blocked
bool ArrowCode(const char code) const { return(false); }
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time,const double price);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_ARROW_CHECK); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectArrowCheck::CChartObjectArrowCheck(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectArrowCheck::~CChartObjectArrowCheck(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Check Sign" |
//+------------------------------------------------------------------+
bool CChartObjectArrowCheck::Create(long chart_id,const string name,const int window,
const datetime time,const double price)
{
if(!ObjectCreate(chart_id,name,OBJ_ARROW_CHECK,window,time,price))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectArrowLeftPrice. |
//| Purpose: Class of the "Left Price Label" object of chart. |
//| Derives from class CChartObjectArrow. |
//+------------------------------------------------------------------+
class CChartObjectArrowLeftPrice : public CChartObjectArrow
{
public:
CChartObjectArrowLeftPrice(void);
~CChartObjectArrowLeftPrice(void);
//--- change of arrow code and anchor point is blocked
bool ArrowCode(const char code) const { return(false); }
bool Anchor(const ENUM_ANCHOR_POINT anchor) const { return(false); }
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time,const double price);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_ARROW_LEFT_PRICE); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectArrowLeftPrice::CChartObjectArrowLeftPrice(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectArrowLeftPrice::~CChartObjectArrowLeftPrice(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Left Price Label" |
//+------------------------------------------------------------------+
bool CChartObjectArrowLeftPrice::Create(long chart_id,const string name,const int window,const datetime time,const double price)
{
if(!ObjectCreate(chart_id,name,OBJ_ARROW_LEFT_PRICE,window,time,price))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectArrowRightPrice. |
//| Purpose: Class of the "Right Price Label" object of chart. |
//| Derives from class CChartObjectArrow. |
//+------------------------------------------------------------------+
class CChartObjectArrowRightPrice : public CChartObjectArrow
{
public:
CChartObjectArrowRightPrice(void);
~CChartObjectArrowRightPrice(void);
//--- change of arrow code and anchor point is blocked
bool ArrowCode(const char code) const { return(false); }
bool Anchor(const ENUM_ANCHOR_POINT anchor) const { return(false); }
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time,const double price);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_ARROW_RIGHT_PRICE); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectArrowRightPrice::CChartObjectArrowRightPrice(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectArrowRightPrice::~CChartObjectArrowRightPrice(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Right Price Label" |
//+------------------------------------------------------------------+
bool CChartObjectArrowRightPrice::Create(long chart_id,const string name,const int window,
const datetime time,const double price)
{
if(!ObjectCreate(chart_id,name,OBJ_ARROW_RIGHT_PRICE,window,time,price))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
@@ -0,0 +1,512 @@
//+------------------------------------------------------------------+
//| ChartObjectsBmpControls.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
//| All objects with "bmp" pictures. |
//+------------------------------------------------------------------+
#include "ChartObject.mqh"
//+------------------------------------------------------------------+
//| Class CChartObjectBitmap. |
//| Purpose: Class of the "Bitmap" object of chart. |
//| Derives from class CChartObject. |
//+------------------------------------------------------------------+
class CChartObjectBitmap : public CChartObject
{
public:
CChartObjectBitmap(void);
~CChartObjectBitmap(void);
//--- methods of access to properties of the object
string BmpFile(void) const;
bool BmpFile(const string name) const;
int X_Offset(void) const;
bool X_Offset(const int X) const;
int Y_Offset(void) const;
bool Y_Offset(const int Y) const;
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,const datetime time,const double price);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_BITMAP); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectBitmap::CChartObjectBitmap(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectBitmap::~CChartObjectBitmap(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Bitmapp" |
//+------------------------------------------------------------------+
bool CChartObjectBitmap::Create(long chart_id,const string name,const int window,const datetime time,const double price)
{
if(!ObjectCreate(chart_id,name,OBJ_BITMAP,window,time,price))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Get name of bmp-file |
//+------------------------------------------------------------------+
string CChartObjectBitmap::BmpFile(void) const
{
//--- check
if(m_chart_id==-1)
return("");
//--- result
return(ObjectGetString(m_chart_id,m_name,OBJPROP_BMPFILE));
}
//+------------------------------------------------------------------+
//| Set name of bmp-file |
//+------------------------------------------------------------------+
bool CChartObjectBitmap::BmpFile(const string name) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetString(m_chart_id,m_name,OBJPROP_BMPFILE,name));
}
//+------------------------------------------------------------------+
//| Get the XOffset property |
//+------------------------------------------------------------------+
int CChartObjectBitmap::X_Offset(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_XOFFSET));
}
//+------------------------------------------------------------------+
//| Set the XOffset property |
//+------------------------------------------------------------------+
bool CChartObjectBitmap::X_Offset(const int X) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_XOFFSET,X));
}
//+------------------------------------------------------------------+
//| Get the YOffset property |
//+------------------------------------------------------------------+
int CChartObjectBitmap::Y_Offset(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_YOFFSET));
}
//+------------------------------------------------------------------+
//| Set the YOffset property |
//+------------------------------------------------------------------+
bool CChartObjectBitmap::Y_Offset(const int Y) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_YOFFSET,Y));
}
//+------------------------------------------------------------------+
//| Writing parameters of object to file |
//+------------------------------------------------------------------+
bool CChartObjectBitmap::Save(const int file_handle)
{
int len;
string str;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- write
if(!CChartObject::Save(file_handle))
return(false);
//--- write value of the "name of bmp-file" property
str=ObjectGetString(m_chart_id,m_name,OBJPROP_BMPFILE);
len=StringLen(str);
if(FileWriteInteger(file_handle,len,INT_VALUE)!=INT_VALUE)
return(false);
if(len!=0 && FileWriteString(file_handle,str,len)!=len)
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Reading parameters of object from file |
//+------------------------------------------------------------------+
bool CChartObjectBitmap::Load(const int file_handle)
{
int len;
string str;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- read
if(!CChartObject::Load(file_handle))
return(false);
//--- read value of the "name of bmp-file" property
len=FileReadInteger(file_handle,INT_VALUE);
str=(len!=0) ? FileReadString(file_handle,len) : "";
if(!ObjectSetString(m_chart_id,m_name,OBJPROP_BMPFILE,str))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectBmpLabel. |
//| Purpose: Class of the "Bitmap label" object of chart. |
//| Derives from class CChartObject. |
//+------------------------------------------------------------------+
class CChartObjectBmpLabel : public CChartObject
{
public:
CChartObjectBmpLabel(void);
~CChartObjectBmpLabel(void);
//--- methods of access to properties of the object
int X_Distance(void) const;
bool X_Distance(const int X) const;
int Y_Distance(void) const;
bool Y_Distance(const int Y) const;
int X_Size(void) const;
int Y_Size(void) const;
ENUM_BASE_CORNER Corner(void) const;
bool Corner(const ENUM_BASE_CORNER corner) const;
string BmpFileOn(void) const;
bool BmpFileOn(const string name) const;
string BmpFileOff(void) const;
bool BmpFileOff(const string name) const;
bool State(void) const;
bool State(const bool state) const;
int X_Offset(void) const;
bool X_Offset(const int X) const;
int Y_Offset(void) const;
bool Y_Offset(const int Y) const;
//--- change of time/price coordinates is blocked
bool Time(const datetime time) const { return(false); }
bool Price(const double price) const { return(false); }
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,const int X,const int Y);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_BITMAP_LABEL); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectBmpLabel::CChartObjectBmpLabel(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectBmpLabel::~CChartObjectBmpLabel(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Bitmap label" |
//+------------------------------------------------------------------+
bool CChartObjectBmpLabel::Create(long chart_id,const string name,const int window,const int X,const int Y)
{
if(!ObjectCreate(chart_id,name,OBJ_BITMAP_LABEL,window,0,0.0))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
if(!X_Distance(X) || !Y_Distance(Y))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Get the X-distance property |
//+------------------------------------------------------------------+
int CChartObjectBmpLabel::X_Distance(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_XDISTANCE));
}
//+------------------------------------------------------------------+
//| Set the X-distance property |
//+------------------------------------------------------------------+
bool CChartObjectBmpLabel::X_Distance(const int X) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_XDISTANCE,X));
}
//+------------------------------------------------------------------+
//| Get the Y-distance property |
//+------------------------------------------------------------------+
int CChartObjectBmpLabel::Y_Distance(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_YDISTANCE));
}
//+------------------------------------------------------------------+
//| Set the Y-distance property |
//+------------------------------------------------------------------+
bool CChartObjectBmpLabel::Y_Distance(const int Y) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_YDISTANCE,Y));
}
//+------------------------------------------------------------------+
//| Get the X-size |
//+------------------------------------------------------------------+
int CChartObjectBmpLabel::X_Size(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_XSIZE));
}
//+------------------------------------------------------------------+
//| Get the Y-size |
//+------------------------------------------------------------------+
int CChartObjectBmpLabel::Y_Size(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_YSIZE));
}
//+------------------------------------------------------------------+
//| Get the Corner property |
//+------------------------------------------------------------------+
ENUM_BASE_CORNER CChartObjectBmpLabel::Corner(void) const
{
//--- check
if(m_chart_id==-1)
return(WRONG_VALUE);
//--- result
return((ENUM_BASE_CORNER)ObjectGetInteger(m_chart_id,m_name,OBJPROP_CORNER));
}
//+------------------------------------------------------------------+
//| Set the Corner property |
//+------------------------------------------------------------------+
bool CChartObjectBmpLabel::Corner(const ENUM_BASE_CORNER corner) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_CORNER,corner));
}
//+------------------------------------------------------------------+
//| Get filename of the "bmp-ON" property |
//+------------------------------------------------------------------+
string CChartObjectBmpLabel::BmpFileOn(void) const
{
//--- check
if(m_chart_id==-1)
return("");
//--- result
return(ObjectGetString(m_chart_id,m_name,OBJPROP_BMPFILE,0));
}
//+------------------------------------------------------------------+
//| Set filename for the "bmp-ON" property |
//+------------------------------------------------------------------+
bool CChartObjectBmpLabel::BmpFileOn(const string name) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetString(m_chart_id,m_name,OBJPROP_BMPFILE,0,name));
}
//+------------------------------------------------------------------+
//| Get filename of the "bmp-OFF" property |
//+------------------------------------------------------------------+
string CChartObjectBmpLabel::BmpFileOff(void) const
{
//--- check
if(m_chart_id==-1)
return("");
//--- result
return(ObjectGetString(m_chart_id,m_name,OBJPROP_BMPFILE,1));
}
//+------------------------------------------------------------------+
//| Set filename for the "bmp-OFF" property |
//+------------------------------------------------------------------+
bool CChartObjectBmpLabel::BmpFileOff(const string name) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetString(m_chart_id,m_name,OBJPROP_BMPFILE,1,name));
}
//+------------------------------------------------------------------+
//| Get the State property |
//+------------------------------------------------------------------+
bool CChartObjectBmpLabel::State(void) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_STATE));
}
//+------------------------------------------------------------------+
//| Set the State property |
//+------------------------------------------------------------------+
bool CChartObjectBmpLabel::State(const bool state) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_STATE,state));
}
//+------------------------------------------------------------------+
//| Get the XOffset property |
//+------------------------------------------------------------------+
int CChartObjectBmpLabel::X_Offset(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_XOFFSET));
}
//+------------------------------------------------------------------+
//| Set the XOffset property |
//+------------------------------------------------------------------+
bool CChartObjectBmpLabel::X_Offset(const int X) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_XOFFSET,X));
}
//+------------------------------------------------------------------+
//| Get the YOffset property |
//+------------------------------------------------------------------+
int CChartObjectBmpLabel::Y_Offset(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_YOFFSET));
}
//+------------------------------------------------------------------+
//| Set the YOffset property |
//+------------------------------------------------------------------+
bool CChartObjectBmpLabel::Y_Offset(const int Y) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_YOFFSET,Y));
}
//+------------------------------------------------------------------+
//| Writing parameters of object to file |
//+------------------------------------------------------------------+
bool CChartObjectBmpLabel::Save(const int file_handle)
{
int len;
string str;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- write
if(!CChartObject::Save(file_handle))
return(false);
//--- write value of the "X-distance" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_XDISTANCE),INT_VALUE)!=sizeof(int))
return(false);
//--- write value of the "Y-distance" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_YDISTANCE),INT_VALUE)!=sizeof(int))
return(false);
//--- write value of the "Corner" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_CORNER),INT_VALUE)!=sizeof(int))
return(false);
//--- write value of the "filename bmp-ON" property
str=ObjectGetString(m_chart_id,m_name,OBJPROP_BMPFILE,0);
len=StringLen(str);
if(FileWriteInteger(file_handle,len,INT_VALUE)!=INT_VALUE)
return(false);
if(len!=0 && FileWriteString(file_handle,str,len)!=len)
return(false);
//--- write value of the "filename bmp-OFF" property
str=ObjectGetString(m_chart_id,m_name,OBJPROP_BMPFILE,1);
len=StringLen(str);
if(FileWriteInteger(file_handle,len,INT_VALUE)!=INT_VALUE)
return(false);
if(len!=0 && FileWriteString(file_handle,str,len)!=len)
return(false);
//--- write state
if(FileWriteLong(file_handle,ObjectGetInteger(m_chart_id,m_name,OBJPROP_STATE))!=sizeof(long))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Reading object parameters from file |
//+------------------------------------------------------------------+
bool CChartObjectBmpLabel::Load(const int file_handle)
{
int len;
string str;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- read
if(!CChartObject::Load(file_handle))
return(false);
//--- read value of the "X-distance" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_XDISTANCE,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- read value of the "Y-distance" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_YDISTANCE,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- read value of "Corner" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_CORNER,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- read value of the "filename bmp-ON" property
len=FileReadInteger(file_handle,INT_VALUE);
str=(len!=0) ? FileReadString(file_handle,len) : "";
if(!ObjectSetString(m_chart_id,m_name,OBJPROP_BMPFILE,0,str))
return(false);
//--- read value of the "filename bmp-OFF" property
len=FileReadInteger(file_handle,INT_VALUE);
str=(len!=0) ? FileReadString(file_handle,len) : "";
if(!ObjectSetString(m_chart_id,m_name,OBJPROP_BMPFILE,1,str))
return(false);
//--- read state
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_STATE,FileReadLong(file_handle)))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
@@ -0,0 +1,246 @@
//+------------------------------------------------------------------+
//| ChartObjectsChannels.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
//| All channels. |
//+------------------------------------------------------------------+
#include "ChartObjectsLines.mqh"
//+------------------------------------------------------------------+
//| Class CChartObjectChannel. |
//| Purpose: Class of the "Equidistant channel" object of chart. |
//| Derives from class CChartObjectTrend. |
//+------------------------------------------------------------------+
class CChartObjectChannel : public CChartObjectTrend
{
public:
CChartObjectChannel(void);
~CChartObjectChannel(void);
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,
const datetime time3,const double price3);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_CHANNEL); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectChannel::CChartObjectChannel(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectChannel::~CChartObjectChannel(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Equidistant channel" |
//+------------------------------------------------------------------+
bool CChartObjectChannel::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,
const datetime time3,const double price3)
{
if(!ObjectCreate(chart_id,name,OBJ_CHANNEL,window,time1,price1,time2,price2,time3,price3))
return(false);
if(!Attach(chart_id,name,window,3))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectStdDevChannel. |
//| Purpose: Class of the "Standrad deviation channel" |
//| object of chart. |
//| Derives from class CChartObjectTrend. |
//+------------------------------------------------------------------+
class CChartObjectStdDevChannel : public CChartObjectTrend
{
public:
CChartObjectStdDevChannel(void);
~CChartObjectStdDevChannel(void);
//--- methods of access to properties of the object
double Deviations(void) const;
bool Deviations(const double deviation) const;
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const datetime time2,const double deviation);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_STDDEVCHANNEL); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectStdDevChannel::CChartObjectStdDevChannel(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectStdDevChannel::~CChartObjectStdDevChannel(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Standard deviation channel" |
//+------------------------------------------------------------------+
bool CChartObjectStdDevChannel::Create(long chart_id,const string name,const int window,
const datetime time1,const datetime time2,const double deviation)
{
if(!ObjectCreate(chart_id,name,OBJ_STDDEVCHANNEL,window,time1,0.0,time2,0.0))
return(false);
if(!Attach(chart_id,name,window,2))
return(false);
if(!Deviations(deviation))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Get value of the "Deviations" property |
//+------------------------------------------------------------------+
double CChartObjectStdDevChannel::Deviations(void) const
{
//--- check
if(m_chart_id==-1)
return(EMPTY_VALUE);
//--- result
return(ObjectGetDouble(m_chart_id,m_name,OBJPROP_DEVIATION));
}
//+------------------------------------------------------------------+
//| Set value for the "Deviations" property |
//+------------------------------------------------------------------+
bool CChartObjectStdDevChannel::Deviations(const double deviation) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetDouble(m_chart_id,m_name,OBJPROP_DEVIATION,deviation));
}
//+------------------------------------------------------------------+
//| Writing parameters of object to file |
//+------------------------------------------------------------------+
bool CChartObjectStdDevChannel::Save(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- write
if(!CChartObjectTrend::Save(file_handle))
return(false);
//--- write value of the "Deviations" property
if(FileWriteDouble(file_handle,ObjectGetDouble(m_chart_id,m_name,OBJPROP_DEVIATION))!=sizeof(double))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Reading parameters of object from file |
//+------------------------------------------------------------------+
bool CChartObjectStdDevChannel::Load(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- read
if(!CChartObjectTrend::Load(file_handle))
return(false);
//--- read value of the "Deviations" property
if(!ObjectSetDouble(m_chart_id,m_name,OBJPROP_DEVIATION,FileReadDouble(file_handle)))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectRegression. |
//| Purpose: Class of the "Regression channel" object of chart. |
//| Derives from class CChartObjectTrend. |
//+------------------------------------------------------------------+
class CChartObjectRegression : public CChartObjectTrend
{
public:
CChartObjectRegression(void);
~CChartObjectRegression(void);
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const datetime time2);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_REGRESSION); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectRegression::CChartObjectRegression(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectRegression::~CChartObjectRegression(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Regression channel" |
//+------------------------------------------------------------------+
bool CChartObjectRegression::Create(long chart_id,const string name,const int window,
const datetime time1,const datetime time2)
{
if(!ObjectCreate(chart_id,name,OBJ_REGRESSION,window,time1,0.0,time2,0.0))
return(false);
if(!Attach(chart_id,name,window,2))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectPitchfork. |
//| Purpose: Class of the "Andrews pitchfork" object of chart |
//| Derives from class CChartObjectTrend. |
//+------------------------------------------------------------------+
class CChartObjectPitchfork : public CChartObjectTrend
{
public:
CChartObjectPitchfork(void);
~CChartObjectPitchfork(void);
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,
const datetime time3,const double price3);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_CHANNEL); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectPitchfork::CChartObjectPitchfork(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectPitchfork::~CChartObjectPitchfork(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Andrews pitchfork" |
//+------------------------------------------------------------------+
bool CChartObjectPitchfork::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,
const datetime time3,const double price3)
{
if(!ObjectCreate(chart_id,name,OBJ_PITCHFORK,window,time1,price1,time2,price2,time3,price3))
return(false);
if(!Attach(chart_id,name,window,3))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
@@ -0,0 +1,201 @@
//+------------------------------------------------------------------+
//| ChartObjectsElliott.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
//| All Elliott tools. |
//+------------------------------------------------------------------+
#include "ChartObject.mqh"
//+------------------------------------------------------------------+
//| Class CChartObjectElliottWave3. |
//| Purpose: Class of the "ElliottCorrectiveWave" object of chart. |
//| Derives from class CChartObject. |
//+------------------------------------------------------------------+
class CChartObjectElliottWave3 : public CChartObject
{
public:
CChartObjectElliottWave3(void);
~CChartObjectElliottWave3(void);
//--- methods of access to properties of the object
ENUM_ELLIOT_WAVE_DEGREE Degree(void) const;
bool Degree(const ENUM_ELLIOT_WAVE_DEGREE degree) const;
bool Lines(void) const;
bool Lines(const bool lines) const;
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,
const datetime time3,const double price3);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_ELLIOTWAVE3); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectElliottWave3::CChartObjectElliottWave3(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectElliottWave3::~CChartObjectElliottWave3(void)
{
}
//+------------------------------------------------------------------+
//| Create object "ElliottCorrectiveWave" |
//+------------------------------------------------------------------+
bool CChartObjectElliottWave3::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,
const datetime time3,const double price3)
{
if(!ObjectCreate(chart_id,name,OBJ_ELLIOTWAVE3,window,time1,price1,time2,price2,time3,price3))
return(false);
if(!Attach(chart_id,name,window,3))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Get value of the "Degree" property |
//+------------------------------------------------------------------+
ENUM_ELLIOT_WAVE_DEGREE CChartObjectElliottWave3::Degree(void) const
{
//--- check
if(m_chart_id==-1)
return(WRONG_VALUE);
//--- result
return((ENUM_ELLIOT_WAVE_DEGREE)ObjectGetInteger(m_chart_id,m_name,OBJPROP_DEGREE));
}
//+------------------------------------------------------------------+
//| Set value for the "Degree" property |
//+------------------------------------------------------------------+
bool CChartObjectElliottWave3::Degree(const ENUM_ELLIOT_WAVE_DEGREE degree) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_DEGREE,degree));
}
//+------------------------------------------------------------------+
//| Get value of the "Lines" property |
//+------------------------------------------------------------------+
bool CChartObjectElliottWave3::Lines(void) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectGetInteger(m_chart_id,m_name,OBJPROP_DRAWLINES));
}
//+------------------------------------------------------------------+
//| Set value for the "Lines" property |
//+------------------------------------------------------------------+
bool CChartObjectElliottWave3::Lines(const bool lines) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_DRAWLINES,lines));
}
//+------------------------------------------------------------------+
//| Writing parameters of object to file |
//+------------------------------------------------------------------+
bool CChartObjectElliottWave3::Save(const int file_handle)
{
bool result;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- write
result=CChartObject::Save(file_handle);
if(result)
{
//--- write value of the "Degree" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_DEGREE),INT_VALUE)!=sizeof(int))
return(false);
//--- write value of the "Lines" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_DRAWLINES),INT_VALUE)!=sizeof(int))
return(false);
}
//--- result
return(result);
}
//+------------------------------------------------------------------+
//| Reading parameters of object from file |
//+------------------------------------------------------------------+
bool CChartObjectElliottWave3::Load(const int file_handle)
{
bool result;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- read
result=CChartObject::Load(file_handle);
if(result)
{
//--- read value of the "Degree" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_DEGREE,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- read value of the "Lines" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_DRAWLINES,FileReadInteger(file_handle,INT_VALUE)))
return(false);
}
//--- result
return(result);
}
//+------------------------------------------------------------------+
//| Class CChartObjectElliottWave5. |
//| Purpose: Class of the "ElliottMotiveWave" object of chart. |
//| Derives from class CChartObjectElliottWave3. |
//+------------------------------------------------------------------+
class CChartObjectElliottWave5 : public CChartObjectElliottWave3
{
public:
CChartObjectElliottWave5(void);
~CChartObjectElliottWave5(void);
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,
const datetime time3,const double price3,
const datetime time4,const double price4,
const datetime time5,const double price5);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_ELLIOTWAVE5); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectElliottWave5::CChartObjectElliottWave5(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectElliottWave5::~CChartObjectElliottWave5(void)
{
}
//+------------------------------------------------------------------+
//| Create object "ElliottMotiveWave" |
//+------------------------------------------------------------------+
bool CChartObjectElliottWave5::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,
const datetime time3,const double price3,
const datetime time4,const double price4,
const datetime time5,const double price5)
{
if(!ObjectCreate(chart_id,name,OBJ_ELLIOTWAVE5,window,time1,price1,time2,price2,time3,price3,time4,price4,time5,price5))
return(false);
if(!Attach(chart_id,name,window,5))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
+365
View File
@@ -0,0 +1,365 @@
//+------------------------------------------------------------------+
//| ChartObjectsFibo.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
//| All Fibonacci tools. |
//+------------------------------------------------------------------+
#include "ChartObjectsLines.mqh"
//+------------------------------------------------------------------+
//| Class CChartObjectFibo. |
//| Purpose: Class of the "Fibonacci Lines" object. |
//| Derives from class CChartObjectTrend. |
//+------------------------------------------------------------------+
class CChartObjectFibo : public CChartObjectTrend
{
public:
CChartObjectFibo(void);
~CChartObjectFibo(void);
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_FIBO); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectFibo::CChartObjectFibo(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectFibo::~CChartObjectFibo(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Fibonacci Lines" |
//+------------------------------------------------------------------+
bool CChartObjectFibo::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2)
{
if(!ObjectCreate(chart_id,name,OBJ_FIBO,window,time1,price1,time2,price2))
return(false);
if(!Attach(chart_id,name,window,2))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectFiboTimes. |
//| Purpose: Class of the "Fibonacci Time Zones" object of chart |
//| Derives from class CChartObject. |
//+------------------------------------------------------------------+
class CChartObjectFiboTimes : public CChartObject
{
public:
CChartObjectFiboTimes(void);
~CChartObjectFiboTimes(void);
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_FIBOTIMES); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectFiboTimes::CChartObjectFiboTimes(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectFiboTimes::~CChartObjectFiboTimes(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Fibonacci Time Zones" |
//+------------------------------------------------------------------+
bool CChartObjectFiboTimes::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2)
{
if(!ObjectCreate(chart_id,name,OBJ_FIBOTIMES,window,time1,price1,time2,price2))
return(false);
if(!Attach(chart_id,name,window,2))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectFiboFan. |
//| Purpose: Class of the "Fibonacci Fan" object of chart. |
//| Derives from class CChartObject. |
//+------------------------------------------------------------------+
class CChartObjectFiboFan : public CChartObject
{
public:
CChartObjectFiboFan(void);
~CChartObjectFiboFan(void);
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_FIBOFAN); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectFiboFan::CChartObjectFiboFan(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectFiboFan::~CChartObjectFiboFan(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Fibonacci Fan" |
//+------------------------------------------------------------------+
bool CChartObjectFiboFan::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2)
{
if(!ObjectCreate(chart_id,name,OBJ_FIBOFAN,window,time1,price1,time2,price2))
return(false);
if(!Attach(chart_id,name,window,2))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectFiboArc. |
//| Purpose: Class of the "Fibonacci Arcs" object of chart. |
//| Derives from class CChartObject. |
//+------------------------------------------------------------------+
class CChartObjectFiboArc : public CChartObject
{
public:
CChartObjectFiboArc(void);
~CChartObjectFiboArc(void);
//--- methods of access to properties of the object
double Scale(void) const;
bool Scale(const double scale) const;
bool Ellipse(void) const;
bool Ellipse(const bool ellipse) const;
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,const double scale);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_FIBOARC); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectFiboArc::CChartObjectFiboArc(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectFiboArc::~CChartObjectFiboArc(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Fibonacci Arcs" |
//+------------------------------------------------------------------+
bool CChartObjectFiboArc::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,const double scale)
{
if(!ObjectCreate(chart_id,name,OBJ_FIBOARC,window,time1,price1,time2,price2))
return(false);
if(!Attach(chart_id,name,window,2))
return(false);
if(!Scale(scale))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Get value of the "Scale" property |
//+------------------------------------------------------------------+
double CChartObjectFiboArc::Scale(void) const
{
//--- check
if(m_chart_id==-1)
return(EMPTY_VALUE);
//--- result
return(ObjectGetDouble(m_chart_id,m_name,OBJPROP_SCALE));
}
//+------------------------------------------------------------------+
//| Set value for the "Scale" property |
//+------------------------------------------------------------------+
bool CChartObjectFiboArc::Scale(const double scale) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetDouble(m_chart_id,m_name,OBJPROP_SCALE,scale));
}
//+------------------------------------------------------------------+
//| Get value of the "Ellipse" property |
//+------------------------------------------------------------------+
bool CChartObjectFiboArc::Ellipse(void) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectGetInteger(m_chart_id,m_name,OBJPROP_ELLIPSE));
}
//+------------------------------------------------------------------+
//| Set value for the "Ellipse" property |
//+------------------------------------------------------------------+
bool CChartObjectFiboArc::Ellipse(const bool ellipse) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_ELLIPSE,ellipse));
}
//+------------------------------------------------------------------+
//| Writing parameter of object to file |
//+------------------------------------------------------------------+
bool CChartObjectFiboArc::Save(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- write
if(!CChartObject::Save(file_handle))
return(false);
//--- write value of the "Scale" property
if(FileWriteDouble(file_handle,ObjectGetDouble(m_chart_id,m_name,OBJPROP_SCALE))!=sizeof(double))
return(false);
//--- write value of the "Ellipse" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_ELLIPSE),CHAR_VALUE)!=sizeof(char))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Reading parameters of object from file |
//+------------------------------------------------------------------+
bool CChartObjectFiboArc::Load(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- read
if(!CChartObject::Load(file_handle))
return(false);
//--- read value of the "Scale" property
if(!ObjectSetDouble(m_chart_id,m_name,OBJPROP_SCALE,FileReadDouble(file_handle)))
return(false);
//--- read value of the "Ellipse" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_ELLIPSE,FileReadInteger(file_handle,CHAR_VALUE)))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectFiboChannel. |
//| Purpose: Class of the "Fibonacci Channel" object of chart. |
//| Derives from class CChartObjectTrend. |
//+------------------------------------------------------------------+
class CChartObjectFiboChannel : public CChartObjectTrend
{
public:
CChartObjectFiboChannel(void);
~CChartObjectFiboChannel(void);
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,
const datetime time3,const double price3);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_FIBOCHANNEL); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectFiboChannel::CChartObjectFiboChannel(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectFiboChannel::~CChartObjectFiboChannel(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Fibonacci Channel" |
//+------------------------------------------------------------------+
bool CChartObjectFiboChannel::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,
const datetime time3,const double price3)
{
if(!ObjectCreate(chart_id,name,OBJ_FIBOCHANNEL,window,time1,price1,time2,price2,time3,price3))
return(false);
if(!Attach(chart_id,name,window,3))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectFiboExpansion. |
//| Purpose: Class of the "Fibonacci Expansion" object. |
//| Derives from class CChartObjectTrend. |
//+------------------------------------------------------------------+
class CChartObjectFiboExpansion : public CChartObjectTrend
{
public:
CChartObjectFiboExpansion(void);
~CChartObjectFiboExpansion(void);
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,
const datetime time3,const double price3);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_EXPANSION); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectFiboExpansion::CChartObjectFiboExpansion(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectFiboExpansion::~CChartObjectFiboExpansion(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Fibonacci Expansion" |
//+------------------------------------------------------------------+
bool CChartObjectFiboExpansion::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,
const datetime time3,const double price3)
{
if(!ObjectCreate(chart_id,name,OBJ_EXPANSION,window,time1,price1,time2,price2,time3,price3))
return(false);
if(!Attach(chart_id,name,window,3))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
+390
View File
@@ -0,0 +1,390 @@
//+------------------------------------------------------------------+
//| ChartObjectsGann.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
//| All Gann tools. |
//+------------------------------------------------------------------+
#include "ChartObjectsLines.mqh"
//+------------------------------------------------------------------+
//| Class CChartObjectGannLine. |
//| Purpose: Class of the "Gann Line" object of chart. |
//| Derives from class CChartObjectTrendByAngle. |
//+------------------------------------------------------------------+
class CChartObjectGannLine : public CChartObjectTrendByAngle
{
public:
CChartObjectGannLine(void);
~CChartObjectGannLine(void);
//--- methods of access to properties of the object
double PipsPerBar(void) const;
bool PipsPerBar(const double ppb) const;
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double ppb);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_GANNLINE); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectGannLine::CChartObjectGannLine(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectGannLine::~CChartObjectGannLine(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Gann Line" |
//+------------------------------------------------------------------+
bool CChartObjectGannLine::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double ppb)
{
if(!ObjectCreate(chart_id,name,OBJ_GANNLINE,window,time1,price1,time2,0.0))
return(false);
if(!Attach(chart_id,name,window,2))
return(false);
if(!PipsPerBar(ppb))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Get value of the "PipsPerBar" property |
//+------------------------------------------------------------------+
double CChartObjectGannLine::PipsPerBar(void) const
{
//--- check
if(m_chart_id==-1)
return(EMPTY_VALUE);
//--- result
return(ObjectGetDouble(m_chart_id,m_name,OBJPROP_SCALE));
}
//+------------------------------------------------------------------+
//| Set value for the "PipsPerBar" property |
//+------------------------------------------------------------------+
bool CChartObjectGannLine::PipsPerBar(const double ppb) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetDouble(m_chart_id,m_name,OBJPROP_SCALE,ppb));
}
//+------------------------------------------------------------------+
//| Writing parameters of object to file |
//+------------------------------------------------------------------+
bool CChartObjectGannLine::Save(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- write
if(!CChartObjectTrend::Save(file_handle))
return(false);
//--- write value of the "PipsPerBar"
if(FileWriteDouble(file_handle,ObjectGetDouble(m_chart_id,m_name,OBJPROP_SCALE))!=sizeof(double))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Reading parameters of object from file |
//+------------------------------------------------------------------+
bool CChartObjectGannLine::Load(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- read
if(!CChartObjectTrend::Load(file_handle))
return(false);
//--- read value of the "PipsPerBar" property
if(!ObjectSetDouble(m_chart_id,m_name,OBJPROP_SCALE,FileReadDouble(file_handle)))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectGannFan. |
//| Purpose: Class of the "Gann Fan" object of chart. |
//| Derives from class CChartObjectTrend. |
//+------------------------------------------------------------------+
class CChartObjectGannFan : public CChartObjectTrend
{
public:
CChartObjectGannFan(void);
~CChartObjectGannFan(void);
//--- methods of access to properties of the object
double PipsPerBar(void) const;
bool PipsPerBar(const double ppb) const;
bool Downtrend(void) const;
bool Downtrend(const bool downtrend) const;
//--- method of create the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double ppb);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_GANNFAN); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectGannFan::CChartObjectGannFan(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectGannFan::~CChartObjectGannFan(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Gann Fan" |
//+------------------------------------------------------------------+
bool CChartObjectGannFan::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double ppb)
{
if(!ObjectCreate(chart_id,name,OBJ_GANNFAN,window,time1,price1,time2,0.0))
return(false);
if(!Attach(chart_id,name,window,2))
return(false);
if(!PipsPerBar(ppb))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Get value of the "PipsPerBar" property |
//+------------------------------------------------------------------+
double CChartObjectGannFan::PipsPerBar(void) const
{
//--- check
if(m_chart_id==-1)
return(EMPTY_VALUE);
//--- result
return(ObjectGetDouble(m_chart_id,m_name,OBJPROP_SCALE));
}
//+------------------------------------------------------------------+
//| Set value for the "PipsPerBar" property |
//+------------------------------------------------------------------+
bool CChartObjectGannFan::PipsPerBar(const double ppb) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetDouble(m_chart_id,m_name,OBJPROP_SCALE,ppb));
}
//+------------------------------------------------------------------+
//| Get value of the "Downtrend" property |
//+------------------------------------------------------------------+
bool CChartObjectGannFan::Downtrend(void) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectGetInteger(m_chart_id,m_name,OBJPROP_DIRECTION));
}
//+------------------------------------------------------------------+
//| Set value for the "Downtrend" property |
//+------------------------------------------------------------------+
bool CChartObjectGannFan::Downtrend(const bool downtrend) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_DIRECTION,downtrend));
}
//+------------------------------------------------------------------+
//| Writing parameters of object to file |
//+------------------------------------------------------------------+
bool CChartObjectGannFan::Save(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- write
if(!CChartObjectTrend::Save(file_handle))
return(false);
//--- write value of the "PipsPerBar" property
if(FileWriteDouble(file_handle,ObjectGetDouble(m_chart_id,m_name,OBJPROP_SCALE))!=sizeof(double))
return(false);
//--- write value of the "Downtrend" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_DIRECTION),CHAR_VALUE)!=sizeof(char))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Reading object parameters from file |
//+------------------------------------------------------------------+
bool CChartObjectGannFan::Load(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- read
if(!CChartObjectTrend::Load(file_handle))
return(false);
//--- read value of the "PipsPerBar" property
if(!ObjectSetDouble(m_chart_id,m_name,OBJPROP_SCALE,FileReadDouble(file_handle)))
return(false);
//--- read value of the "Downtrend" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_DIRECTION,FileReadInteger(file_handle,CHAR_VALUE)))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectGannGrid. |
//| Purpose: Class of the "Gann Grid" object of chart. |
//| Derives from class CChartObjectTrend. |
//+------------------------------------------------------------------+
class CChartObjectGannGrid : public CChartObjectTrend
{
public:
CChartObjectGannGrid(void);
~CChartObjectGannGrid(void);
//--- methods of access to properties of the object
double PipsPerBar(void) const;
bool PipsPerBar(const double ppb) const;
bool Downtrend(void) const;
bool Downtrend(const bool downtrend) const;
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double ppb);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_GANNGRID); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectGannGrid::CChartObjectGannGrid(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectGannGrid::~CChartObjectGannGrid(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Gann Grid" |
//+------------------------------------------------------------------+
bool CChartObjectGannGrid::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double ppb)
{
if(!ObjectCreate(chart_id,name,OBJ_GANNGRID,window,time1,price1,time2,0.0))
return(false);
if(!Attach(chart_id,name,window,2))
return(false);
if(!PipsPerBar(ppb))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Get value of the"PipsPerBar" property |
//+------------------------------------------------------------------+
double CChartObjectGannGrid::PipsPerBar(void) const
{
//--- check
if(m_chart_id==-1)
return(EMPTY_VALUE);
//--- result
return(ObjectGetDouble(m_chart_id,m_name,OBJPROP_SCALE));
}
//+------------------------------------------------------------------+
//| Set value for the "PipsPerBar" property |
//+------------------------------------------------------------------+
bool CChartObjectGannGrid::PipsPerBar(const double ppb) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetDouble(m_chart_id,m_name,OBJPROP_SCALE,ppb));
}
//+------------------------------------------------------------------+
//| Get the property value "Downtrend" |
//+------------------------------------------------------------------+
bool CChartObjectGannGrid::Downtrend(void) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectGetInteger(m_chart_id,m_name,OBJPROP_DIRECTION));
}
//+------------------------------------------------------------------+
//| Set the property value "Downtrend" |
//+------------------------------------------------------------------+
bool CChartObjectGannGrid::Downtrend(const bool downtrend) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_DIRECTION,downtrend));
}
//+------------------------------------------------------------------+
//| Writing parameters of object to file |
//+------------------------------------------------------------------+
bool CChartObjectGannGrid::Save(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- write
if(!CChartObjectTrend::Save(file_handle))
return(false);
//--- write value of the "PipsPerBar" property
if(FileWriteDouble(file_handle,ObjectGetDouble(m_chart_id,m_name,OBJPROP_SCALE))!=sizeof(double))
return(false);
//--- write value of the "Downtrend" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_DIRECTION),CHAR_VALUE)!=sizeof(char))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Reading paprameters of object from file |
//+------------------------------------------------------------------+
bool CChartObjectGannGrid::Load(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- read
if(!CChartObjectTrend::Load(file_handle))
return(false);
//--- read value of the "PipsPerBar" property
if(!ObjectSetDouble(m_chart_id,m_name,OBJPROP_SCALE,FileReadDouble(file_handle)))
return(false);
//--- read value of the "Downtrend" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_DIRECTION,FileReadInteger(file_handle,CHAR_VALUE)))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
+335
View File
@@ -0,0 +1,335 @@
//+------------------------------------------------------------------+
//| ChartObjectsLines.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
//| All lines. |
//+------------------------------------------------------------------+
#include "ChartObject.mqh"
//+------------------------------------------------------------------+
//| Class CChartObjectVLine. |
//| Purpose: Class of the "Vertical line" object of chart. |
//| Derives from class CChartObject. |
//+------------------------------------------------------------------+
class CChartObjectVLine : public CChartObject
{
public:
CChartObjectVLine(void);
~CChartObjectVLine(void);
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,const datetime time);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_VLINE); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectVLine::CChartObjectVLine(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectVLine::~CChartObjectVLine(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Vertical line" |
//+------------------------------------------------------------------+
bool CChartObjectVLine::Create(long chart_id,const string name,const int window,const datetime time)
{
if(!ObjectCreate(chart_id,name,OBJ_VLINE,window,time,0.0))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectHLine. |
//| Purpose: Class of the "Horizontal line" object of chart. |
//| Derives from class CChartObject. |
//+------------------------------------------------------------------+
class CChartObjectHLine : public CChartObject
{
public:
CChartObjectHLine(void);
~CChartObjectHLine(void);
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,const double price);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_HLINE); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectHLine::CChartObjectHLine(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectHLine::~CChartObjectHLine(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Horizontal line" |
//+------------------------------------------------------------------+
bool CChartObjectHLine::Create(long chart_id,const string name,const int window,const double price)
{
if(!ObjectCreate(chart_id,name,OBJ_HLINE,window,0,price))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectTrend. |
//| Purpose: Class of the "Trendline" object of chart. |
//| Derives from class CChartObject. |
//| It is the parent class for all objects that have properties |
//| RAY_LEFT and RAY_RIGHT. |
//+------------------------------------------------------------------+
class CChartObjectTrend : public CChartObject
{
public:
CChartObjectTrend(void);
~CChartObjectTrend(void);
//--- methods of access to properties of the object
bool RayLeft(void) const;
bool RayLeft(const bool new_sel) const;
bool RayRight(void) const;
bool RayRight(const bool new_sel) const;
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_TREND); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectTrend::CChartObjectTrend(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectTrend::~CChartObjectTrend(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Trendline" |
//+------------------------------------------------------------------+
bool CChartObjectTrend::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2)
{
if(!ObjectCreate(chart_id,name,OBJ_TREND,window,time1,price1,time2,price2))
return(false);
if(!Attach(chart_id,name,window,2))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Get the "Ray left" flag |
//+------------------------------------------------------------------+
bool CChartObjectTrend::RayLeft(void) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectGetInteger(m_chart_id,m_name,OBJPROP_RAY_LEFT));
}
//+------------------------------------------------------------------+
//| Set the "Ray left" flag |
//+------------------------------------------------------------------+
bool CChartObjectTrend::RayLeft(const bool new_ray) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_RAY_LEFT,new_ray));
}
//+------------------------------------------------------------------+
//| Get the "Ray right" flag |
//+------------------------------------------------------------------+
bool CChartObjectTrend::RayRight(void) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectGetInteger(m_chart_id,m_name,OBJPROP_RAY_RIGHT));
}
//+------------------------------------------------------------------+
//| Set the "Ray right" flag |
//+------------------------------------------------------------------+
bool CChartObjectTrend::RayRight(const bool new_ray) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_RAY_RIGHT,new_ray));
}
//+------------------------------------------------------------------+
//| Writing parameters of objject to file |
//+------------------------------------------------------------------+
bool CChartObjectTrend::Save(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- write
if(!CChartObject::Save(file_handle))
return(false);
//--- write value of the "Ray left" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_RAY_LEFT),CHAR_VALUE)!=sizeof(char))
return(false);
//--- write value of the "Ray right" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_RAY_RIGHT),CHAR_VALUE)!=sizeof(char))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Reading parameters of object from file |
//+------------------------------------------------------------------+
bool CChartObjectTrend::Load(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- read
if(!CChartObject::Load(file_handle))
return(false);
//--- read value of the "Ray left" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_RAY_LEFT,FileReadInteger(file_handle,CHAR_VALUE)))
return(false);
//--- read value of the "Ray right" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_RAY_RIGHT,FileReadInteger(file_handle,CHAR_VALUE)))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectTrendByAngle. |
//| Puprose: Class of the "Trendline by angle" object of chart. |
//| Derives from class CChartObjectTrend. |
//+------------------------------------------------------------------+
class CChartObjectTrendByAngle : public CChartObjectTrend
{
public:
CChartObjectTrendByAngle(void);
~CChartObjectTrendByAngle(void);
//--- methods of access to properties of the object
double Angle(void) const;
bool Angle(const double angle) const;
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_TRENDBYANGLE); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectTrendByAngle::CChartObjectTrendByAngle(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectTrendByAngle::~CChartObjectTrendByAngle(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Trendline by angle" |
//+------------------------------------------------------------------+
bool CChartObjectTrendByAngle::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2)
{
if(!ObjectCreate(chart_id,name,OBJ_TRENDBYANGLE,window,time1,price1,time2,price2))
return(false);
if(!Attach(chart_id,name,window,2))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Get the "Angle" property |
//+------------------------------------------------------------------+
double CChartObjectTrendByAngle::Angle(void) const
{
//--- check
if(m_chart_id==-1)
return(EMPTY_VALUE);
//---
return(ObjectGetDouble(m_chart_id,m_name,OBJPROP_ANGLE));
}
//+------------------------------------------------------------------+
//| Set the "Angle" property |
//+------------------------------------------------------------------+
bool CChartObjectTrendByAngle::Angle(const double angle) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetDouble(m_chart_id,m_name,OBJPROP_ANGLE,angle));
}
//+------------------------------------------------------------------+
//| Class CChartObjectCycles. |
//| Purpose: Class of the "Cycle lines" object of chart. |
//| Derives from class CChartObject. |
//+------------------------------------------------------------------+
class CChartObjectCycles : public CChartObject
{
public:
CChartObjectCycles(void);
~CChartObjectCycles(void);
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_TREND); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectCycles::CChartObjectCycles(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectCycles::~CChartObjectCycles(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Cycle lines" |
//+------------------------------------------------------------------+
bool CChartObjectCycles::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2)
{
if(!ObjectCreate(chart_id,name,OBJ_CYCLES,window,time1,price1,time2,price2))
return(false);
if(!Attach(chart_id,name,window,2))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
+142
View File
@@ -0,0 +1,142 @@
//+------------------------------------------------------------------+
//| ChartObjectsShapes.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
//| All shapes. |
//+------------------------------------------------------------------+
#include "ChartObject.mqh"
//+------------------------------------------------------------------+
//| Class CChartObjectRectangle. |
//| Purpose: Class of the "Rectangle" object of chart. |
//| Derives from class CChartObject. |
//+------------------------------------------------------------------+
class CChartObjectRectangle : public CChartObject
{
public:
CChartObjectRectangle(void);
~CChartObjectRectangle(void);
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_RECTANGLE); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectRectangle::CChartObjectRectangle(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectRectangle::~CChartObjectRectangle(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Rectangle" |
//+------------------------------------------------------------------+
bool CChartObjectRectangle::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2)
{
if(!ObjectCreate(chart_id,name,OBJ_RECTANGLE,window,time1,price1,time2,price2))
return(false);
if(!Attach(chart_id,name,window,2))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectTriangle. |
//| Purpose: Class of the "Triangle" object of chart. |
//| Derives from class CChartObject. |
//+------------------------------------------------------------------+
class CChartObjectTriangle : public CChartObject
{
public:
CChartObjectTriangle(void);
~CChartObjectTriangle(void);
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,
const datetime time3,const double price3);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_TRIANGLE); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectTriangle::CChartObjectTriangle(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectTriangle::~CChartObjectTriangle(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Triangle" |
//+------------------------------------------------------------------+
bool CChartObjectTriangle::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,
const datetime time3,const double price3)
{
if(!ObjectCreate(chart_id,name,OBJ_TRIANGLE,window,time1,price1,time2,price2,time3,price3))
return(false);
if(!Attach(chart_id,name,window,3))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectEllipse. |
//| Purpose: Class of the "Ellipse" object of chart. |
//| Derives from class CChartObject. |
//+------------------------------------------------------------------+
class CChartObjectEllipse : public CChartObject
{
public:
CChartObjectEllipse(void);
~CChartObjectEllipse(void);
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,
const datetime time3,const double price3);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_ELLIPSE); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectEllipse::CChartObjectEllipse(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectEllipse::~CChartObjectEllipse(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Ellipse" |
//+------------------------------------------------------------------+
bool CChartObjectEllipse::Create(long chart_id,const string name,const int window,
const datetime time1,const double price1,
const datetime time2,const double price2,
const datetime time3,const double price3)
{
if(!ObjectCreate(chart_id,name,OBJ_ELLIPSE,window,time1,price1,time2,price2,time3,price3))
return(false);
if(!Attach(chart_id,name,window,3))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
@@ -0,0 +1,887 @@
//+------------------------------------------------------------------+
//| ChartObjectsTxtControls.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
//| All text objects. |
//+------------------------------------------------------------------+
#include "ChartObject.mqh"
//+------------------------------------------------------------------+
//| Class CChartObjectText. |
//| Purpose: Class of the "Text" object of chart. |
//| Derives from class CChartObject. |
//+------------------------------------------------------------------+
class CChartObjectText : public CChartObject
{
public:
CChartObjectText(void);
~CChartObjectText(void);
//--- methods of access to properties of the object
double Angle(void) const;
bool Angle(const double angle) const;
string Font(void) const;
bool Font(const string font) const;
int FontSize(void) const;
bool FontSize(const int size) const;
ENUM_ANCHOR_POINT Anchor(void) const;
bool Anchor(const ENUM_ANCHOR_POINT anchor) const;
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,
const datetime time,const double price);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_TEXT); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectText::CChartObjectText(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectText::~CChartObjectText(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Text" |
//+------------------------------------------------------------------+
bool CChartObjectText::Create(long chart_id,const string name,const int window,
const datetime time,const double price)
{
if(!ObjectCreate(chart_id,name,OBJ_TEXT,window,time,price))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Get value of the "Angle" property |
//+------------------------------------------------------------------+
double CChartObjectText::Angle(void) const
{
//--- check
if(m_chart_id==-1)
return(EMPTY_VALUE);
//--- result
return(ObjectGetDouble(m_chart_id,m_name,OBJPROP_ANGLE));
}
//+------------------------------------------------------------------+
//| Set value of the "Angle" property |
//+------------------------------------------------------------------+
bool CChartObjectText::Angle(const double angle) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetDouble(m_chart_id,m_name,OBJPROP_ANGLE,angle));
}
//+------------------------------------------------------------------+
//| Get font name |
//+------------------------------------------------------------------+
string CChartObjectText::Font(void) const
{
//--- check
if(m_chart_id==-1)
return("");
//--- result
return(ObjectGetString(m_chart_id,m_name,OBJPROP_FONT));
}
//+------------------------------------------------------------------+
//| Set font name |
//+------------------------------------------------------------------+
bool CChartObjectText::Font(const string font) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetString(m_chart_id,m_name,OBJPROP_FONT,font));
}
//+------------------------------------------------------------------+
//| Get font size |
//+------------------------------------------------------------------+
int CChartObjectText::FontSize(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_FONTSIZE));
}
//+------------------------------------------------------------------+
//| Set font size |
//+------------------------------------------------------------------+
bool CChartObjectText::FontSize(const int size) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_FONTSIZE,size));
}
//+------------------------------------------------------------------+
//| Get anchor point |
//+------------------------------------------------------------------+
ENUM_ANCHOR_POINT CChartObjectText::Anchor(void) const
{
//--- check
if(m_chart_id==-1)
return(WRONG_VALUE);
//--- result
return((ENUM_ANCHOR_POINT)ObjectGetInteger(m_chart_id,m_name,OBJPROP_ANCHOR));
}
//+------------------------------------------------------------------+
//| Set anchor point |
//+------------------------------------------------------------------+
bool CChartObjectText::Anchor(const ENUM_ANCHOR_POINT anchor) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_ANCHOR,anchor));
}
//+------------------------------------------------------------------+
//| Writing parameters of object to file |
//+------------------------------------------------------------------+
bool CChartObjectText::Save(const int file_handle)
{
int len;
string str;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- write
if(!CChartObject::Save(file_handle))
return(false);
//--- write value of the "Angle" property
if(FileWriteDouble(file_handle,ObjectGetDouble(m_chart_id,m_name,OBJPROP_ANGLE))!=sizeof(double))
return(false);
//--- write value of the "Font Name" property
str=ObjectGetString(m_chart_id,m_name,OBJPROP_FONT);
len=StringLen(str);
if(FileWriteInteger(file_handle,len,INT_VALUE)!=INT_VALUE)
return(false);
if(len!=0 && FileWriteString(file_handle,str,len)!=len)
return(false);
//--- write value of the "Font Size" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_FONTSIZE),INT_VALUE)!=sizeof(int))
return(false);
//--- write value of the "Anchor Point" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_ANCHOR),INT_VALUE)!=sizeof(int))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Reading parameters of object from file |
//+------------------------------------------------------------------+
bool CChartObjectText::Load(const int file_handle)
{
int len;
string str;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- read
if(!CChartObject::Load(file_handle))
return(false);
//--- reading value of the "Angle" property
if(!ObjectSetDouble(m_chart_id,m_name,OBJPROP_ANGLE,0,FileReadDouble(file_handle)))
return(false);
//--- read value of the "Font Name" property
len=FileReadInteger(file_handle,INT_VALUE);
str=(len!=0) ? FileReadString(file_handle,len) : "";
if(!ObjectSetString(m_chart_id,m_name,OBJPROP_FONT,str))
return(false);
//--- read value of the "Font Size" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_FONTSIZE,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- read value of the "Anchor Point" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_ANCHOR,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectLabel. |
//| Purpose: Class of the "Label" object of chart. |
//| Derives from class CChartObjectText. |
//+------------------------------------------------------------------+
class CChartObjectLabel : public CChartObjectText
{
public:
CChartObjectLabel(void);
~CChartObjectLabel(void);
//--- methods of access to properties of the object
int X_Distance(void) const;
bool X_Distance(const int X) const;
int Y_Distance(void) const;
bool Y_Distance(const int Y) const;
int X_Size(void) const;
int Y_Size(void) const;
ENUM_BASE_CORNER Corner(void) const;
bool Corner(const ENUM_BASE_CORNER corner) const;
//--- change of time/price coordinates is blocked
bool Time(const datetime time) const { return(false); }
bool Price(const double price) const { return(false); }
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,const int X,const int Y);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_LABEL); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectLabel::CChartObjectLabel(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectLabel::~CChartObjectLabel(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Label" |
//+------------------------------------------------------------------+
bool CChartObjectLabel::Create(long chart_id,const string name,const int window,const int X,const int Y)
{
if(!ObjectCreate(chart_id,name,OBJ_LABEL,window,0,0.0))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
if(!Description(name))
return(false);
if(!X_Distance(X) || !Y_Distance(Y))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Get the X-distance |
//+------------------------------------------------------------------+
int CChartObjectLabel::X_Distance(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_XDISTANCE));
}
//+------------------------------------------------------------------+
//| Set the X-distance |
//+------------------------------------------------------------------+
bool CChartObjectLabel::X_Distance(const int X) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_XDISTANCE,X));
}
//+------------------------------------------------------------------+
//| Get the Y-distance |
//+------------------------------------------------------------------+
int CChartObjectLabel::Y_Distance(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_YDISTANCE));
}
//+------------------------------------------------------------------+
//| Set the Y-distance |
//+------------------------------------------------------------------+
bool CChartObjectLabel::Y_Distance(const int Y) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_YDISTANCE,Y));
}
//+------------------------------------------------------------------+
//| Get the X-size |
//+------------------------------------------------------------------+
int CChartObjectLabel::X_Size(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_XSIZE));
}
//+------------------------------------------------------------------+
//| Get the Y-size |
//+------------------------------------------------------------------+
int CChartObjectLabel::Y_Size(void) const
{
//--- check
if(m_chart_id==-1)
return(0);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_YSIZE));
}
//+------------------------------------------------------------------+
//| Get base corner |
//+------------------------------------------------------------------+
ENUM_BASE_CORNER CChartObjectLabel::Corner(void) const
{
//--- check
if(m_chart_id==-1)
return(WRONG_VALUE);
//--- result
return((ENUM_BASE_CORNER)ObjectGetInteger(m_chart_id,m_name,OBJPROP_CORNER));
}
//+------------------------------------------------------------------+
//| Set base corner |
//+------------------------------------------------------------------+
bool CChartObjectLabel::Corner(const ENUM_BASE_CORNER corner) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_CORNER,corner));
}
//+------------------------------------------------------------------+
//| Writing parameters of object to file |
//+------------------------------------------------------------------+
bool CChartObjectLabel::Save(const int file_handle)
{
string str;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- write
if(!CChartObjectText::Save(file_handle))
return(false);
//--- write value of the "X-distance" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_XDISTANCE),INT_VALUE)!=sizeof(int))
return(false);
//--- write value of the "Y-distance" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_YDISTANCE),INT_VALUE)!=sizeof(int))
return(false);
//--- write value of the "Corner" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_CORNER),INT_VALUE)!=sizeof(int))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Reading parameters of object from file |
//+------------------------------------------------------------------+
bool CChartObjectLabel::Load(const int file_handle)
{
string str;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- read
if(!CChartObjectText::Load(file_handle))
return(false);
//--- reading value of the "X-distance" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_XDISTANCE,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- read value of the "Y-distance" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_YDISTANCE,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- read value of the "Corner" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_CORNER,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectEdit. |
//| Purpose: Class of the "Edit" object of chart. |
//| Derives from class CChartObjectLabel. |
//+------------------------------------------------------------------+
class CChartObjectEdit : public CChartObjectLabel
{
public:
CChartObjectEdit(void);
~CChartObjectEdit(void);
//--- methods of access to properties of the object
bool X_Size(const int X) const;
bool Y_Size(const int Y) const;
color BackColor(void) const;
bool BackColor(const color new_color) const;
color BorderColor(void) const;
bool BorderColor(const color new_color) const;
bool ReadOnly(void) const;
bool ReadOnly(const bool flag) const;
ENUM_ALIGN_MODE TextAlign(void) const;
bool TextAlign(const ENUM_ALIGN_MODE align) const;
//--- change of angle is blocked
bool Angle(const double angle) const { return(false); }
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,const int X,const int Y,const int sizeX,const int sizeY);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_EDIT); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectEdit::CChartObjectEdit(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectEdit::~CChartObjectEdit(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Edit" |
//+------------------------------------------------------------------+
bool CChartObjectEdit::Create(long chart_id,const string name,const int window,const int X,const int Y,const int sizeX,const int sizeY)
{
if(!ObjectCreate(chart_id,name,(ENUM_OBJECT)Type(),window,0,0,0))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
if(!X_Distance(X) || !Y_Distance(Y))
return(false);
if(!X_Size(sizeX) || !Y_Size(sizeY))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Set X-size |
//+------------------------------------------------------------------+
bool CChartObjectEdit::X_Size(const int X) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_XSIZE,X));
}
//+------------------------------------------------------------------+
//| Set Y-size |
//+------------------------------------------------------------------+
bool CChartObjectEdit::Y_Size(const int Y) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_YSIZE,Y));
}
//+------------------------------------------------------------------+
//| Get background color |
//+------------------------------------------------------------------+
color CChartObjectEdit::BackColor(void) const
{
//--- check
if(m_chart_id==-1)
return(CLR_NONE);
//--- result
return((color)ObjectGetInteger(m_chart_id,m_name,OBJPROP_BGCOLOR));
}
//+------------------------------------------------------------------+
//| Set background color |
//+------------------------------------------------------------------+
bool CChartObjectEdit::BackColor(const color new_color) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_BGCOLOR,new_color));
}
//+------------------------------------------------------------------+
//| Get border color |
//+------------------------------------------------------------------+
color CChartObjectEdit::BorderColor(void) const
{
//--- check
if(m_chart_id==-1)
return(CLR_NONE);
//--- result
return((color)ObjectGetInteger(m_chart_id,m_name,OBJPROP_BORDER_COLOR));
}
//+------------------------------------------------------------------+
//| Set border color |
//+------------------------------------------------------------------+
bool CChartObjectEdit::BorderColor(const color new_color) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_BORDER_COLOR,new_color));
}
//+------------------------------------------------------------------+
//| Get the "Read only" property |
//+------------------------------------------------------------------+
bool CChartObjectEdit::ReadOnly(void) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return((int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_READONLY));
}
//+------------------------------------------------------------------+
//| Set the "Read only" property |
//+------------------------------------------------------------------+
bool CChartObjectEdit::ReadOnly(const bool flag) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_READONLY,flag));
}
//+------------------------------------------------------------------+
//| Get the "Align" property |
//+------------------------------------------------------------------+
ENUM_ALIGN_MODE CChartObjectEdit::TextAlign(void) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return((ENUM_ALIGN_MODE)ObjectGetInteger(m_chart_id,m_name,OBJPROP_ALIGN));
}
//+------------------------------------------------------------------+
//| Set the "Align" property |
//+------------------------------------------------------------------+
bool CChartObjectEdit::TextAlign(const ENUM_ALIGN_MODE align) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_ALIGN,align));
}
//+------------------------------------------------------------------+
//| Writing parameters of object to file |
//+------------------------------------------------------------------+
bool CChartObjectEdit::Save(const int file_handle)
{
string str;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- write
if(!CChartObjectLabel::Save(file_handle))
return(false);
//--- write value of the "X-size" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_XSIZE),INT_VALUE)!=sizeof(int))
return(false);
//--- write value of the "Y-size" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_YSIZE),INT_VALUE)!=sizeof(int))
return(false);
//--- write background color
if(FileWriteLong(file_handle,ObjectGetInteger(m_chart_id,m_name,OBJPROP_BGCOLOR))!=sizeof(long))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Reading parameters of object from file |
//+------------------------------------------------------------------+
bool CChartObjectEdit::Load(const int file_handle)
{
string str;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- read
if(!CChartObjectLabel::Load(file_handle))
return(false);
//--- read value of the "X-size" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_XSIZE,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- read value of the "Y-size" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_YSIZE,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- read background color
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_BGCOLOR,FileReadLong(file_handle)))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectButton. |
//| Purpose: Class of the "Button" object of chart. |
//| Derives from class CChartObjectEdit. |
//+------------------------------------------------------------------+
class CChartObjectButton : public CChartObjectEdit
{
public:
CChartObjectButton(void);
~CChartObjectButton(void);
//--- methods of access to properties of the object
bool State(void) const;
bool State(const bool state) const;
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_BUTTON); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectButton::CChartObjectButton(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectButton::~CChartObjectButton(void)
{
}
//+------------------------------------------------------------------+
//| Get state |
//+------------------------------------------------------------------+
bool CChartObjectButton::State(void) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectGetInteger(m_chart_id,m_name,OBJPROP_STATE));
}
//+------------------------------------------------------------------+
//| Set state |
//+------------------------------------------------------------------+
bool CChartObjectButton::State(const bool state) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_STATE,state));
}
//+------------------------------------------------------------------+
//| Writing parameters of object to file |
//+------------------------------------------------------------------+
bool CChartObjectButton::Save(const int file_handle)
{
string str;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- write
if(!CChartObjectEdit::Save(file_handle))
return(false);
//--- write state
if(FileWriteLong(file_handle,ObjectGetInteger(m_chart_id,m_name,OBJPROP_STATE))!=sizeof(long))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Reading parameters of object from file |
//+------------------------------------------------------------------+
bool CChartObjectButton::Load(const int file_handle)
{
string str;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- read
if(!CChartObjectEdit::Load(file_handle))
return(false);
//--- read state
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_STATE,FileReadLong(file_handle)))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Class CChartObjectRectLabel. |
//| Purpose: Class of the "Rectangle Label" object of chart. |
//| Derives from class CChartObjectLabel. |
//+------------------------------------------------------------------+
class CChartObjectRectLabel : public CChartObjectLabel
{
public:
CChartObjectRectLabel(void);
~CChartObjectRectLabel(void);
//--- methods of access to properties of the object
bool X_Size(const int X) const;
bool Y_Size(const int Y) const;
color BackColor(void) const;
bool BackColor(const color new_color) const;
ENUM_BORDER_TYPE BorderType(void) const;
bool BorderType(const ENUM_BORDER_TYPE flag) const;
//--- change of angle is blocked
bool Angle(const double angle) const { return(false); }
//--- method of creating the object
bool Create(long chart_id,const string name,const int window,const int X,const int Y,const int sizeX,const int sizeY);
//--- method of identifying the object
virtual int Type(void) const { return(OBJ_RECTANGLE_LABEL); }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CChartObjectRectLabel::CChartObjectRectLabel(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CChartObjectRectLabel::~CChartObjectRectLabel(void)
{
}
//+------------------------------------------------------------------+
//| Create object "Ractangle Label" |
//+------------------------------------------------------------------+
bool CChartObjectRectLabel::Create(long chart_id,const string name,const int window,const int X,const int Y,const int sizeX,const int sizeY)
{
if(!ObjectCreate(chart_id,name,(ENUM_OBJECT)Type(),window,0,0,0))
return(false);
if(!Attach(chart_id,name,window,1))
return(false);
if(!X_Distance(X) || !Y_Distance(Y))
return(false);
if(!X_Size(sizeX) || !Y_Size(sizeY))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Set X-size |
//+------------------------------------------------------------------+
bool CChartObjectRectLabel::X_Size(const int X) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_XSIZE,X));
}
//+------------------------------------------------------------------+
//| Set Y-size |
//+------------------------------------------------------------------+
bool CChartObjectRectLabel::Y_Size(const int Y) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_YSIZE,Y));
}
//+------------------------------------------------------------------+
//| Get background color |
//+------------------------------------------------------------------+
color CChartObjectRectLabel::BackColor(void) const
{
//--- check
if(m_chart_id==-1)
return(CLR_NONE);
//--- result
return((color)ObjectGetInteger(m_chart_id,m_name,OBJPROP_BGCOLOR));
}
//+------------------------------------------------------------------+
//| Set background color |
//+------------------------------------------------------------------+
bool CChartObjectRectLabel::BackColor(const color new_color) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_BGCOLOR,new_color));
}
//+------------------------------------------------------------------+
//| Get the "Border type" property |
//+------------------------------------------------------------------+
ENUM_BORDER_TYPE CChartObjectRectLabel::BorderType(void) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return((ENUM_BORDER_TYPE)ObjectGetInteger(m_chart_id,m_name,OBJPROP_BORDER_TYPE));
}
//+------------------------------------------------------------------+
//| Set the "Border type" property |
//+------------------------------------------------------------------+
bool CChartObjectRectLabel::BorderType(const ENUM_BORDER_TYPE type) const
{
//--- check
if(m_chart_id==-1)
return(false);
//--- result
return(ObjectSetInteger(m_chart_id,m_name,OBJPROP_BORDER_TYPE,type));
}
//+------------------------------------------------------------------+
//| Writing parameters of object to file |
//+------------------------------------------------------------------+
bool CChartObjectRectLabel::Save(const int file_handle)
{
string str;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- write
if(!CChartObjectLabel::Save(file_handle))
return(false);
//--- write value of the "X-size" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_XSIZE),INT_VALUE)!=sizeof(int))
return(false);
//--- write value of the "Y-size" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_YSIZE),INT_VALUE)!=sizeof(int))
return(false);
//--- write background color
if(FileWriteLong(file_handle,ObjectGetInteger(m_chart_id,m_name,OBJPROP_BGCOLOR))!=sizeof(long))
return(false);
//--- write value of the "Border type" property
if(FileWriteInteger(file_handle,(int)ObjectGetInteger(m_chart_id,m_name,OBJPROP_BORDER_TYPE),INT_VALUE)!=sizeof(int))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
//| Reading parameters of object from file |
//+------------------------------------------------------------------+
bool CChartObjectRectLabel::Load(const int file_handle)
{
string str;
//--- check
if(file_handle==INVALID_HANDLE || m_chart_id==-1)
return(false);
//--- read
if(!CChartObjectLabel::Load(file_handle))
return(false);
//--- read value of the "X-size" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_XSIZE,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- read value of the "Y-size" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_YSIZE,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- read background color
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_BGCOLOR,FileReadLong(file_handle)))
return(false);
//--- read value of the "Border type" property
if(!ObjectSetInteger(m_chart_id,m_name,OBJPROP_BORDER_TYPE,FileReadInteger(file_handle,INT_VALUE)))
return(false);
//--- successful
return(true);
}
//+------------------------------------------------------------------+
File diff suppressed because it is too large Load Diff
+268
View File
@@ -0,0 +1,268 @@
//+------------------------------------------------------------------+
//| BmpButton.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndObj.mqh"
#include <ChartObjects\ChartObjectsBmpControls.mqh>
//+------------------------------------------------------------------+
//| Class CBmpButton |
//| Usage: control that is displayed by |
//| the CChartObjectBmpLabel object |
//+------------------------------------------------------------------+
class CBmpButton : public CWndObj
{
private:
CChartObjectBmpLabel m_button; // chart object
//--- parameters of the chart object
int m_border; // border width
string m_bmp_off_name; // name of BMP file for the "OFF" state (default state)
string m_bmp_on_name; // name of BMP file for the "ON" state
string m_bmp_passive_name;
string m_bmp_active_name;
public:
CBmpButton(void);
~CBmpButton(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
//--- parameters of the chart object
int Border(void) const { return(m_border); }
bool Border(const int value);
bool BmpNames(const string off="",const string on="");
string BmpOffName(void) const { return(m_bmp_off_name); }
bool BmpOffName(const string name);
string BmpOnName(void) const { return(m_bmp_on_name); }
bool BmpOnName(const string name);
string BmpPassiveName(void) const { return(m_bmp_passive_name); }
bool BmpPassiveName(const string name);
string BmpActiveName(void) const { return(m_bmp_active_name); }
bool BmpActiveName(const string name);
//--- state
bool Pressed(void) const { return(m_button.State()); }
bool Pressed(const bool pressed) { return(m_button.State(pressed)); }
//--- properties
bool Locking(void) const { return(IS_CAN_LOCK); }
void Locking(const bool locking);
protected:
//--- handlers of object settings
virtual bool OnSetZOrder(void) { return(m_button.Z_Order(m_zorder)); }
//--- internal event handlers
virtual bool OnCreate(void);
virtual bool OnShow(void);
virtual bool OnHide(void);
virtual bool OnMove(void);
virtual bool OnChange(void);
//--- íîâûå îáðàáîò÷èêè
virtual bool OnActivate(void);
virtual bool OnDeactivate(void);
virtual bool OnMouseDown(void);
virtual bool OnMouseUp(void);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CBmpButton::CBmpButton(void) : m_border(0),
m_bmp_off_name(NULL),
m_bmp_on_name(NULL),
m_bmp_passive_name(NULL),
m_bmp_active_name(NULL)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CBmpButton::~CBmpButton(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CBmpButton::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- call method of the parent class
if(!CWndObj::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- create the chart object
if(!m_button.Create(chart,name,subwin,x1,y1))
return(false);
//--- call the settings handler
return(OnChange());
}
//+------------------------------------------------------------------+
//| Set border width |
//+------------------------------------------------------------------+
bool CBmpButton::Border(const int value)
{
//--- save new value of parameter
m_border=value;
//--- set up the chart object
return(m_button.Width(value));
}
//+------------------------------------------------------------------+
//| Set two images at once |
//+------------------------------------------------------------------+
bool CBmpButton::BmpNames(const string off,const string on)
{
//--- save new values of parameters
m_bmp_off_name=off;
m_bmp_on_name =on;
//--- set up the chart object
if(!m_button.BmpFileOff(off))
return(false);
if(!m_button.BmpFileOn(on))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Set image for the "OFF" state |
//+------------------------------------------------------------------+
bool CBmpButton::BmpOffName(const string name)
{
//--- save new value of parameter
m_bmp_off_name=name;
//--- set up the chart object
if(!m_button.BmpFileOff(name))
return(false);
//--- set size by image dimensions
Width(m_button.X_Size());
Height(m_button.Y_Size());
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Set image for the "ON" state |
//+------------------------------------------------------------------+
bool CBmpButton::BmpOnName(const string name)
{
//--- save new value of parameter
m_bmp_on_name=name;
//--- set up the chart object
if(!m_button.BmpFileOn(name))
return(false);
//--- set size by image dimensions
Width(m_button.X_Size());
Height(m_button.Y_Size());
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Set image for the "OFF" state (passive) |
//+------------------------------------------------------------------+
bool CBmpButton::BmpPassiveName(const string name)
{
//--- save new value of parameter
m_bmp_passive_name=name;
//--- set up the chart object
if(!IS_ACTIVE)
return(BmpOffName(name));
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Set image for the "OFF" state (active) |
//+------------------------------------------------------------------+
bool CBmpButton::BmpActiveName(const string name)
{
//--- save new value of parameter
m_bmp_active_name=name;
//--- set up the chart object
if(IS_ACTIVE)
return(BmpOffName(name));
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Locking flag |
//+------------------------------------------------------------------+
void CBmpButton::Locking(const bool flag)
{
if(flag)
PropFlagsSet(WND_PROP_FLAG_CAN_LOCK);
else
PropFlagsReset(WND_PROP_FLAG_CAN_LOCK);
}
//+------------------------------------------------------------------+
//| Create object on chart |
//+------------------------------------------------------------------+
bool CBmpButton::OnCreate(void)
{
//--- create the chart object by previously set parameters
return(m_button.Create(m_chart_id,m_name,m_subwin,m_rect.left,m_rect.top));
}
//+------------------------------------------------------------------+
//| Display object on chart |
//+------------------------------------------------------------------+
bool CBmpButton::OnShow(void)
{
return(m_button.Timeframes(OBJ_ALL_PERIODS));
}
//+------------------------------------------------------------------+
//| Hide object from chart |
//+------------------------------------------------------------------+
bool CBmpButton::OnHide(void)
{
return(m_button.Timeframes(OBJ_NO_PERIODS));
}
//+------------------------------------------------------------------+
//| Absolute movement of the chart object |
//+------------------------------------------------------------------+
bool CBmpButton::OnMove(void)
{
//--- position the chart object
return(m_button.X_Distance(m_rect.left) && m_button.Y_Distance(m_rect.top));
}
//+------------------------------------------------------------------+
//| Set up the chart object |
//+------------------------------------------------------------------+
bool CBmpButton::OnChange(void)
{
//--- set up the chart object
return(m_button.Width(m_border) && m_button.BmpFileOff(m_bmp_off_name) && m_button.BmpFileOn(m_bmp_on_name));
}
//+------------------------------------------------------------------+
//| Handler of activating the group of controls |
//+------------------------------------------------------------------+
bool CBmpButton::OnActivate(void)
{
if(m_bmp_active_name!=NULL)
BmpOffName(m_bmp_active_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of deactivating the group of controls |
//+------------------------------------------------------------------+
bool CBmpButton::OnDeactivate(void)
{
if(m_bmp_passive_name!=NULL)
BmpOffName(m_bmp_passive_name);
if(!IS_CAN_LOCK)
Pressed(false);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of click on the left mouse button |
//+------------------------------------------------------------------+
bool CBmpButton::OnMouseDown(void)
{
if(!IS_CAN_LOCK)
Pressed(!Pressed());
//--- call of the method of the parent class
return(CWnd::OnMouseDown());
}
//+------------------------------------------------------------------+
//| Handler of click on the left mouse button |
//+------------------------------------------------------------------+
bool CBmpButton::OnMouseUp(void)
{
//--- depress the button if it is not fixed
if(m_button.State() && !IS_CAN_LOCK)
m_button.State(false);
//--- call of the method of the parent class
return(CWnd::OnMouseUp());
}
//+------------------------------------------------------------------+
+146
View File
@@ -0,0 +1,146 @@
//+------------------------------------------------------------------+
//| Button.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndObj.mqh"
#include <ChartObjects\ChartObjectsTxtControls.mqh>
//+------------------------------------------------------------------+
//| Class CButton |
//| Usage: control that is displayed by |
//| the CChartObjectButton object |
//+------------------------------------------------------------------+
class CButton : public CWndObj
{
private:
CChartObjectButton m_button; // chart object
public:
CButton(void);
~CButton(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
//--- state
bool Pressed(void) const { return(m_button.State()); }
bool Pressed(const bool pressed) { return(m_button.State(pressed)); }
//--- properties
bool Locking(void) const { return(IS_CAN_LOCK); }
void Locking(const bool flag);
protected:
//--- handlers of object settings
virtual bool OnSetText(void) { return(m_button.Description(m_text)); }
virtual bool OnSetColor(void) { return(m_button.Color(m_color)); }
virtual bool OnSetColorBackground(void) { return(m_button.BackColor(m_color_background)); }
virtual bool OnSetColorBorder(void) { return(m_button.BorderColor(m_color_border)); }
virtual bool OnSetFont(void) { return(m_button.Font(m_font)); }
virtual bool OnSetFontSize(void) { return(m_button.FontSize(m_font_size)); }
//--- internal event handlers
virtual bool OnCreate(void);
virtual bool OnShow(void);
virtual bool OnHide(void);
virtual bool OnMove(void);
virtual bool OnResize(void);
//--- íîâûå îáðàáîò÷èêè
virtual bool OnMouseDown(void);
virtual bool OnMouseUp(void);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CButton::CButton(void)
{
m_color =CONTROLS_BUTTON_COLOR;
m_color_background=CONTROLS_BUTTON_COLOR_BG;
m_color_border =CONTROLS_BUTTON_COLOR_BORDER;
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CButton::~CButton(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CButton::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- call method of the parent class
if(!CWndObj::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- create the chart object
if(!m_button.Create(chart,name,subwin,x1,y1,Width(),Height()))
return(false);
//--- call the settings handler
return(OnChange());
}
//+------------------------------------------------------------------+
//| Locking flag |
//+------------------------------------------------------------------+
void CButton::Locking(const bool flag)
{
if(flag)
PropFlagsSet(WND_PROP_FLAG_CAN_LOCK);
else
PropFlagsReset(WND_PROP_FLAG_CAN_LOCK);
}
//+------------------------------------------------------------------+
//| Create object on chart |
//+------------------------------------------------------------------+
bool CButton::OnCreate(void)
{
//--- create the chart object by previously set parameters
return(m_button.Create(m_chart_id,m_name,m_subwin,m_rect.left,m_rect.top,m_rect.Width(),m_rect.Height()));
}
//+------------------------------------------------------------------+
//| Display object on chart |
//+------------------------------------------------------------------+
bool CButton::OnShow(void)
{
return(m_button.Timeframes(OBJ_ALL_PERIODS));
}
//+------------------------------------------------------------------+
//| Hide object from chart |
//+------------------------------------------------------------------+
bool CButton::OnHide(void)
{
return(m_button.Timeframes(OBJ_NO_PERIODS));
}
//+------------------------------------------------------------------+
//| Absolute movement of the chart object |
//+------------------------------------------------------------------+
bool CButton::OnMove(void)
{
//--- position the chart object
return(m_button.X_Distance(m_rect.left) && m_button.Y_Distance(m_rect.top));
}
//+------------------------------------------------------------------+
//| Resize the chart object |
//+------------------------------------------------------------------+
bool CButton::OnResize(void)
{
//--- resize the chart object
return(m_button.X_Size(m_rect.Width()) && m_button.Y_Size(m_rect.Height()));
}
//+------------------------------------------------------------------+
//| Handler of click on the left mouse button |
//+------------------------------------------------------------------+
bool CButton::OnMouseDown(void)
{
if(!IS_CAN_LOCK)
Pressed(!Pressed());
//--- call of the method of the parent class
return(CWnd::OnMouseDown());
}
//+------------------------------------------------------------------+
//| Handler of click on the left mouse button |
//+------------------------------------------------------------------+
bool CButton::OnMouseUp(void)
{
//--- depress the button if it is not fixed
if(m_button.State() && !IS_CAN_LOCK)
m_button.State(false);
//--- call of the method of the parent class
return(CWnd::OnMouseUp());
}
//+------------------------------------------------------------------+
+183
View File
@@ -0,0 +1,183 @@
//+------------------------------------------------------------------+
//| CheckBox.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndContainer.mqh"
#include "BmpButton.mqh"
#include "Edit.mqh"
//+------------------------------------------------------------------+
//| Resources |
//+------------------------------------------------------------------+
#resource "res\\CheckBoxOn.bmp"
#resource "res\\CheckBoxOff.bmp"
//+------------------------------------------------------------------+
//| Class CCheckBox |
//| Usage: class that implements the "CheckBox" control |
//+------------------------------------------------------------------+
class CCheckBox : public CWndContainer
{
private:
//--- dependent controls
CBmpButton m_button; // button object
CEdit m_label; // label object
//--- data
int m_value; // value
public:
CCheckBox(void);
~CCheckBox(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- settings
string Text(void) const { return(m_label.Text()); }
bool Text(const string value) { return(m_label.Text(value)); }
color Color(void) const { return(m_label.Color()); }
bool Color(const color value) { return(m_label.Color(value)); }
//--- state
bool Checked(void) const { return(m_button.Pressed()); }
bool Checked(const bool flag) { return(m_button.Pressed(flag)); }
//--- data
int Value(void) const { return(m_value); }
void Value(const int value) { m_value=value; }
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
protected:
//--- create dependent controls
virtual bool CreateButton(void);
virtual bool CreateLabel(void);
//--- handlers of the dependent controls events
virtual bool OnClickButton(void);
virtual bool OnClickLabel(void);
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CCheckBox)
ON_EVENT(ON_CLICK,m_button,OnClickButton)
ON_EVENT(ON_CLICK,m_label,OnClickLabel)
EVENT_MAP_END(CWndContainer)
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CCheckBox::CCheckBox(void) : m_value(0)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CCheckBox::~CCheckBox(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CCheckBox::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- call method of the parent class
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- create dependent controls
if(!CreateButton())
return(false);
if(!CreateLabel())
return(false);
//--- succeeded
return(true);
}
//+------------------------------------------------------------------+
//| Create button |
//+------------------------------------------------------------------+
bool CCheckBox::CreateButton(void)
{
//--- calculate coordinates
int x1=CONTROLS_CHECK_BUTTON_X_OFF;
int y1=CONTROLS_CHECK_BUTTON_Y_OFF;
int x2=x1+CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_BUTTON_SIZE-CONTROLS_BORDER_WIDTH;
//--- create
if(!m_button.Create(m_chart_id,m_name+"Button",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_button.BmpNames("::res\\CheckBoxOff.bmp","::res\\CheckBoxOn.bmp"))
return(false);
if(!Add(m_button))
return(false);
m_button.Locking(true);
//--- succeeded
return(true);
}
//+------------------------------------------------------------------+
//| Create label |
//+------------------------------------------------------------------+
bool CCheckBox::CreateLabel(void)
{
//--- calculate coordinates
int x1=CONTROLS_CHECK_LABEL_X_OFF;
int y1=CONTROLS_CHECK_LABEL_Y_OFF;
int x2=Width();
int y2=Height();
//--- create
if(!m_label.Create(m_chart_id,m_name+"Label",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_label.Text(m_name))
return(false);
if(!Add(m_label))
return(false);
m_label.ReadOnly(true);
m_label.ColorBackground(CONTROLS_CHECKGROUP_COLOR_BG);
m_label.ColorBorder(CONTROLS_CHECKGROUP_COLOR_BG);
//--- succeeded
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CCheckBox::Save(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//---
FileWriteInteger(file_handle,Checked());
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CCheckBox::Load(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//---
if(!FileIsEnding(file_handle))
Checked(FileReadInteger(file_handle));
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Handler of click on button |
//+------------------------------------------------------------------+
bool CCheckBox::OnClickButton(void)
{
//--- send the "changed state" event
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of click on label |
//+------------------------------------------------------------------+
bool CCheckBox::OnClickLabel(void)
{
//--- change button state
m_button.Pressed(!m_button.Pressed());
//--- return the result of the button click handler
return(OnClickButton());
}
//+------------------------------------------------------------------+
+377
View File
@@ -0,0 +1,377 @@
//+------------------------------------------------------------------+
//| CheckGroup.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndClient.mqh"
#include "CheckBox.mqh"
#include <Arrays\ArrayString.mqh>
#include <Arrays\ArrayLong.mqh>
#include <Arrays\ArrayInt.mqh>
//+------------------------------------------------------------------+
//| Class CCheckGroup |
//| Usage: view and edit group of flags |
//+------------------------------------------------------------------+
class CCheckGroup : public CWndClient
{
private:
//--- dependent controls
CCheckBox m_rows[]; // array of the row objects
//--- set up
int m_offset; // index of first visible row in array of rows
int m_total_view; // number of visible rows
int m_item_height; // height of visible row
//--- data
CArrayString m_strings; // array of rows
CArrayLong m_values; // array of values
CArrayInt m_states; // array of states
long m_value; // current value
int m_current; // index of current row in array of rows
public:
CCheckGroup(void);
~CCheckGroup(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
virtual void Destroy(const int reason=0);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- fill
virtual bool AddItem(const string item,const long value=0);
//--- data
long Value(void) const;
bool Value(const long value);
int Check(const int idx) const;
bool Check(const int idx,const int value);
//--- state
virtual bool Show(void);
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
protected:
//--- create dependent controls
bool CreateButton(int index);
//--- handlers of the dependent controls events
virtual bool OnVScrollShow(void);
virtual bool OnVScrollHide(void);
virtual bool OnScrollLineDown(void);
virtual bool OnScrollLineUp(void);
virtual bool OnChangeItem(const int row_index);
//--- redraw
bool Redraw(void);
bool RowState(const int index,const bool select);
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CCheckGroup)
ON_INDEXED_EVENT(ON_CHANGE,m_rows,OnChangeItem)
EVENT_MAP_END(CWndClient)
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CCheckGroup::CCheckGroup(void) : m_offset(0),
m_total_view(0),
m_item_height(CONTROLS_LIST_ITEM_HEIGHT),
m_current(CONTROLS_INVALID_INDEX),
m_value(0)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CCheckGroup::~CCheckGroup(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CCheckGroup::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- determine the number of visible rows
m_total_view=(y2-y1)/m_item_height;
//--- check the number of visible rows
if(m_total_view<1)
return(false);
//--- call method of the parent class
if(!CWndClient::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- set up
if(!m_background.ColorBackground(CONTROLS_CHECKGROUP_COLOR_BG))
return(false);
if(!m_background.ColorBorder(CONTROLS_CHECKGROUP_COLOR_BORDER))
return(false);
//--- create dependent controls
ArrayResize(m_rows,m_total_view);
for(int i=0;i<m_total_view;i++)
if(!CreateButton(i))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Delete group of controls |
//+------------------------------------------------------------------+
void CCheckGroup::Destroy(const int reason)
{
//--- call of the method of the parent class
CWndClient::Destroy(reason);
//--- clear items
m_strings.Clear();
m_values.Clear();
m_states.Clear();
}
//+------------------------------------------------------------------+
//| Create "row" |
//+------------------------------------------------------------------+
bool CCheckGroup::CreateButton(int index)
{
//--- calculate coordinates
int x1=CONTROLS_BORDER_WIDTH;
int y1=CONTROLS_BORDER_WIDTH+m_item_height*index;
int x2=Width()-CONTROLS_BORDER_WIDTH;
int y2=y1+m_item_height;
//--- create
if(!m_rows[index].Create(m_chart_id,m_name+"Item"+IntegerToString(index),m_subwin,x1,y1,x2,y2))
return(false);
if(!m_rows[index].Text(""))
return(false);
if(!Add(m_rows[index]))
return(false);
m_rows[index].Hide();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Add item (row) |
//+------------------------------------------------------------------+
bool CCheckGroup::AddItem(const string item,const long value)
{
//--- add
if(!m_strings.Add(item))
return(false);
if(!m_values.Add(value))
return(false);
if(!m_states.Add(0))
return(false);
//--- number of items
int total=m_strings.Total();
//--- exit if number of items does not exceed the size of visible area
if(total<m_total_view+1)
{
if(IS_VISIBLE && total!=0)
m_rows[total-1].Show();
return(Redraw());
}
//--- if number of items exceeded the size of visible area
if(total==m_total_view+1)
{
//--- enable vertical scrollbar
if(!VScrolled(true))
return(false);
//--- and immediately make it invisible (if needed)
if(!IS_VISIBLE)
m_scroll_v.Visible(false);
}
//--- set up the scrollbar
m_scroll_v.MaxPos(m_strings.Total()-m_total_view);
//--- redraw
return(Redraw());
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
long CCheckGroup::Value(void) const
{
return(m_value);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CCheckGroup::Value(const long value)
{
m_value=value;
//---
return(Redraw());
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
int CCheckGroup::Check(const int idx) const
{
//--- check
if(idx>=m_values.Total())
return(0);
//---
return(m_states[idx]);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CCheckGroup::Check(const int idx,const int value)
{
//--- check
if(idx>=m_values.Total())
return(false);
//---
bool res=(m_states.Update(idx,value) && Redraw());
//--- change value
if(res && idx<64)
{
if(m_rows[idx].Checked())
Value(m_value|m_values.At(idx));
else
Value(m_value&(~m_values.At(idx)));
}
//---
return(res);
}
//+------------------------------------------------------------------+
//| Makes the group visible |
//+------------------------------------------------------------------+
bool CCheckGroup::Show(void)
{
//--- call of the method of the parent class
if(!CWndClient::Show())
return(false);
//--- loop by rows
int total=m_values.Total();
for(int i=total;i<m_total_view;i++)
m_rows[i].Hide();
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CCheckGroup::Save(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//---
FileWriteLong(file_handle,Value());
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CCheckGroup::Load(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//---
if(!FileIsEnding(file_handle))
Value(FileReadLong(file_handle));
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Redraw |
//+------------------------------------------------------------------+
bool CCheckGroup::Redraw(void)
{
//--- loop by "rows"
for(int i=0;i<m_total_view;i++)
{
//--- copy text
if(!m_rows[i].Text(m_strings[i+m_offset]))
return(false);
//--- select
if(!RowState(i,m_states[i+m_offset]!=0))
return(false);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Change state |
//+------------------------------------------------------------------+
bool CCheckGroup::RowState(const int index,const bool select)
{
//--- check index
if(index<0 || index>=ArraySize(m_rows))
return(true);
//--- change state
return(m_rows[index].Checked(select));
}
//+------------------------------------------------------------------+
//| Handler of the "Show vertical scrollbar" event |
//+------------------------------------------------------------------+
bool CCheckGroup::OnVScrollShow(void)
{
//--- loop by "rows"
for(int i=0;i<m_total_view;i++)
{
//--- resize "rows" according to shown vertical scrollbar
m_rows[i].Width(Width()-(CONTROLS_SCROLL_SIZE+CONTROLS_BORDER_WIDTH));
}
//--- check visibility
if(!IS_VISIBLE)
{
m_scroll_v.Visible(false);
return(true);
}
//--- event is handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of the "Hide vertical scrollbar" event |
//+------------------------------------------------------------------+
bool CCheckGroup::OnVScrollHide(void)
{
//--- check visibility
if(!IS_VISIBLE)
return(true);
//--- loop by "rows"
for(int i=0;i<m_total_view;i++)
{
//--- resize "rows" according to hidden vertical scroll bar
m_rows[i].Width(Width()-CONTROLS_BORDER_WIDTH);
}
//--- event is handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of the "Scroll up for one row" event |
//+------------------------------------------------------------------+
bool CCheckGroup::OnScrollLineUp(void)
{
//--- get new offset
m_offset=m_scroll_v.CurrPos();
//--- redraw
return(Redraw());
}
//+------------------------------------------------------------------+
//| Handler of the "Scroll down for one row" event |
//+------------------------------------------------------------------+
bool CCheckGroup::OnScrollLineDown(void)
{
//--- get new offset
m_offset=m_scroll_v.CurrPos();
//--- redraw
return(Redraw());
}
//+------------------------------------------------------------------+
//| Handler of changing a "row" state |
//+------------------------------------------------------------------+
bool CCheckGroup::OnChangeItem(const int row_index)
{
//--- change value
m_states.Update(row_index+m_offset,m_rows[row_index].Checked());
if(row_index+m_offset<64)
{
if(m_rows[row_index].Checked())
Value(m_value|m_values.At(row_index+m_offset));
else
Value(m_value&(~m_values.At(row_index+m_offset)));
}
//--- send notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
+324
View File
@@ -0,0 +1,324 @@
//+------------------------------------------------------------------+
//| ComboBox.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndContainer.mqh"
#include "Edit.mqh"
#include "BmpButton.mqh"
#include "ListView.mqh"
//+------------------------------------------------------------------+
//| Resources |
//+------------------------------------------------------------------+
//--- Can not place the same file into resource twice
#resource "res\\DropOn.bmp" // image file
#resource "res\\DropOff.bmp" // image file
//+------------------------------------------------------------------+
//| Class CComboBox |
//| Usage: drop-down list |
//+------------------------------------------------------------------+
class CComboBox : public CWndContainer
{
private:
//--- dependent controls
CEdit m_edit; // the entry field object
CBmpButton m_drop; // the button object
CListView m_list; // the drop-down list object
//--- set up
int m_item_height; // height of visible row
int m_view_items; // number of visible rows in the drop-down list
public:
CComboBox(void);
~CComboBox(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- fill
bool AddItem(const string item,const long value=0);
//--- set up
void ListViewItems(const int value) { m_view_items=value; }
//--- data
virtual bool ItemAdd(const string item,const long value=0) { return(m_list.ItemAdd(item,value)); }
virtual bool ItemInsert(const int index,const string item,const long value=0) { return(m_list.ItemInsert(index,item,value)); }
virtual bool ItemUpdate(const int index,const string item,const long value=0) { return(m_list.ItemUpdate(index,item,value)); }
virtual bool ItemDelete(const int index) { return(m_list.ItemDelete(index)); }
virtual bool ItemsClear(void) { return(m_list.ItemsClear()); }
//--- data
string Select(void) { return(m_edit.Text()); }
bool Select(const int index);
bool SelectByText(const string text);
bool SelectByValue(const long value);
//--- data (read only)
long Value(void) { return(m_list.Value()); }
//--- state
virtual bool Show(void);
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
protected:
//--- create dependent controls
virtual bool CreateEdit(void);
virtual bool CreateButton(void);
virtual bool CreateList(void);
//--- handlers of the dependent controls events
virtual bool OnClickEdit(void);
virtual bool OnClickButton(void);
virtual bool OnChangeList(void);
//--- show drop-down list
bool ListShow(void);
bool ListHide(void);
void CheckListHide(const int id,int x,int y);
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CComboBox)
ON_EVENT(ON_CLICK,m_edit,OnClickEdit)
ON_EVENT(ON_CLICK,m_drop,OnClickButton)
ON_EVENT(ON_CHANGE,m_list,OnChangeList)
CheckListHide(id,(int)lparam,(int)dparam);
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
EVENT_MAP_END(CWndContainer)
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CComboBox::CComboBox(void) : m_item_height(CONTROLS_COMBO_ITEM_HEIGHT),
m_view_items(CONTROLS_COMBO_ITEMS_VIEW)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CComboBox::~CComboBox(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CComboBox::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- check height
if(y2-y1<CONTROLS_COMBO_MIN_HEIGHT)
return(false);
//--- call method of the parent class
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- create dependent controls
if(!CreateEdit())
return(false);
if(!CreateButton())
return(false);
if(!CreateList())
return(false);
//--- succeeded
return(true);
}
//+------------------------------------------------------------------+
//| Create main entry field |
//+------------------------------------------------------------------+
bool CComboBox::CreateEdit(void)
{
//--- create
if(!m_edit.Create(m_chart_id,m_name+"Edit",m_subwin,0,0,Width(),Height()))
return(false);
if(!m_edit.Text(""))
return(false);
if(!m_edit.ReadOnly(true))
return(false);
if(!Add(m_edit))
return(false);
//--- succeeded
return(true);
}
//+------------------------------------------------------------------+
//| Create button |
//+------------------------------------------------------------------+
bool CComboBox::CreateButton(void)
{
//--- right align button (try to make equal offsets from top and bottom)
int x1=Width()-(CONTROLS_BUTTON_SIZE+CONTROLS_COMBO_BUTTON_X_OFF);
int y1=(Height()-CONTROLS_BUTTON_SIZE)/2;
int x2=x1+CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_BUTTON_SIZE;
//--- create
if(!m_drop.Create(m_chart_id,m_name+"Drop",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_drop.BmpNames("::res\\DropOff.bmp","::res\\DropOn.bmp"))
return(false);
if(!Add(m_drop))
return(false);
m_drop.Locking(true);
//--- succeeded
return(true);
}
//+------------------------------------------------------------------+
//| Create drop-down list |
//+------------------------------------------------------------------+
bool CComboBox::CreateList(void)
{
//--- create
if(m_list.TotalView(m_view_items))
{
if(!m_list.Create(m_chart_id,m_name+"List",m_subwin,0,Height(),Width(),0))
return(false);
if(!Add(m_list))
return(false);
m_list.Hide();
}
//--- succeeded
return(true);
}
//+------------------------------------------------------------------+
//| Add item (row) |
//+------------------------------------------------------------------+
bool CComboBox::AddItem(const string item,const long value)
{
//--- add item to list
return(m_list.AddItem(item,value));
}
//+------------------------------------------------------------------+
//| Select item |
//+------------------------------------------------------------------+
bool CComboBox::Select(const int index)
{
if(!m_list.Select(index))
return(false);
//--- call the handler
return(OnChangeList());
}
//+------------------------------------------------------------------+
//| Select item (by text) |
//+------------------------------------------------------------------+
bool CComboBox::SelectByText(const string text)
{
if(!m_list.SelectByText(text))
return(false);
//--- call the handler
return(OnChangeList());
}
//+------------------------------------------------------------------+
//| Select item (by value) |
//+------------------------------------------------------------------+
bool CComboBox::SelectByValue(const long value)
{
if(!m_list.SelectByValue(value))
return(false);
//--- call the handler
return(OnChangeList());
}
//+------------------------------------------------------------------+
//| Makes the control visible |
//+------------------------------------------------------------------+
bool CComboBox::Show(void)
{
m_edit.Show();
m_drop.Show();
m_list.Hide();
//--- call of the method of the parent class
return(CWnd::Show());
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CComboBox::Save(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//---
FileWriteLong(file_handle,Value());
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CComboBox::Load(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//---
if(!FileIsEnding(file_handle))
SelectByValue(FileReadLong(file_handle));
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Handler of click on main entry field |
//+------------------------------------------------------------------+
bool CComboBox::OnClickEdit(void)
{
//--- change button state
if(!m_drop.Pressed(!m_drop.Pressed()))
return(false);
//--- call the click on button handler
return(OnClickButton());
}
//+------------------------------------------------------------------+
//| Handler of click on button |
//+------------------------------------------------------------------+
bool CComboBox::OnClickButton(void)
{
//--- show or hide the drop-down list depending on the button state
return((m_drop.Pressed()) ? ListShow() : ListHide());
}
//+------------------------------------------------------------------+
//| Handler of click on drop-down list |
//+------------------------------------------------------------------+
bool CComboBox::OnChangeList(void)
{
string text=m_list.Select();
//--- hide the list, depress the button
ListHide();
m_drop.Pressed(false);
//--- set text in the main entry field
m_edit.Text(text);
//--- send notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Show the drop-down list |
//+------------------------------------------------------------------+
bool CComboBox::ListShow(void)
{
BringToTop();
//--- show the list
return(m_list.Show());
}
//+------------------------------------------------------------------+
//| Hide drop-down list |
//+------------------------------------------------------------------+
bool CComboBox::ListHide(void)
{
//--- hide the list
return(m_list.Hide());
}
//+------------------------------------------------------------------+
//| Hide the drop-down element if necessary |
//+------------------------------------------------------------------+
void CComboBox::CheckListHide(const int id,int x,int y)
{
//--- check event ID
if(id!=CHARTEVENT_CLICK)
return;
//--- check visibility of the drop-down element
if(!m_list.IsVisible())
return;
//--- check mouse cursor's position
y-=(int)ChartGetInteger(m_chart_id,CHART_WINDOW_YDISTANCE,m_subwin);
if(!m_edit.Contains(x,y) && !m_list.Contains(x,y))
{
m_drop.Pressed(false);
m_list.Hide();
}
}
//+------------------------------------------------------------------+
+413
View File
@@ -0,0 +1,413 @@
//+------------------------------------------------------------------+
//| DateDropList.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndContainer.mqh"
#include "BmpButton.mqh"
#include "Picture.mqh"
#include <Canvas\Canvas.mqh>
#include <Tools\DateTime.mqh>
//+------------------------------------------------------------------+
//| Enumerations |
//+------------------------------------------------------------------+
//--- date modes
enum ENUM_DATE_MODES
{
DATE_MODE_MON, // month mode
DATE_MODE_YEAR // year mode
};
//+------------------------------------------------------------------+
//| Resources |
//+------------------------------------------------------------------+
//--- Can not place the same file into resource twice
#resource "res\\LeftTransp.bmp"
#resource "res\\RightTransp.bmp"
//+------------------------------------------------------------------+
//| Class CDateDropList |
//| Usage: drop-down list |
//+------------------------------------------------------------------+
class CDateDropList : public CWndContainer
{
private:
//--- dependent controls
CBmpButton m_dec; // the button object
CBmpButton m_inc; // the button object
CPicture m_list; // the drop-down list object
CCanvas m_canvas; // and its canvas
//--- data
CDateTime m_value; // current value
//--- variable
ENUM_DATE_MODES m_mode; // operation mode
CRect m_click_rect[32]; // array of click sensibility areas on canvas
public:
CDateDropList(void);
~CDateDropList(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- data
datetime Value(void) { return(StructToTime(m_value)); }
void Value(datetime value) { m_value.Date(value); }
void Value(MqlDateTime& value) { m_value=value; }
//--- state
virtual bool Show(void);
protected:
//--- internal event handlers
virtual bool OnClick(void);
//--- create dependent controls
virtual bool CreateButtons(void);
virtual bool CreateList(void);
//--- draw
void DrawCanvas(void);
void DrawClickRect(const int idx,int x,int y,string text,const uint clr,uint alignment=0);
//--- handlers of the dependent controls events
virtual bool OnClickDec(void);
virtual bool OnClickInc(void);
virtual bool OnClickList(void);
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CDateDropList)
ON_EVENT(ON_CLICK,m_dec,OnClickDec)
ON_EVENT(ON_CLICK,m_inc,OnClickInc)
ON_EVENT(ON_CLICK,m_list,OnClickList)
EVENT_MAP_END(CWndContainer)
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CDateDropList::CDateDropList(void) : m_mode(DATE_MODE_MON)
{
ZeroMemory(m_value);
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CDateDropList::~CDateDropList(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CDateDropList::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- need to find dimensions depending on font size
//--- width 7 columns + 2 offsets
int w=7*(2*CONTROLS_FONT_SIZE)+2*CONTROLS_FONT_SIZE;
//--- header height + 7 rows
int h=(CONTROLS_BUTTON_SIZE+4*CONTROLS_BORDER_WIDTH)+7*(2*CONTROLS_FONT_SIZE);
//--- call method of the parent class
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x1+w,y1+h))
return(false);
//--- create dependent controls
if(!CreateList())
return(false);
if(!CreateButtons())
return(false);
//--- succeeded
return(true);
}
//+------------------------------------------------------------------+
//| Create drop-down list |
//+------------------------------------------------------------------+
bool CDateDropList::CreateList(void)
{
//--- create object
if(!m_list.Create(m_chart_id,m_name+"List",m_subwin,0,0,Width(),Height()))
return(false);
if(!Add(m_list))
return(false);
//--- create canvas
if(!m_canvas.Create(m_name,Width(),Height()))
return(false);
m_canvas.FontSet(CONTROLS_FONT_NAME,CONTROLS_FONT_SIZE*(-10));
m_list.BmpName(m_canvas.ResourceName());
//--- succeeded
return(true);
}
//+------------------------------------------------------------------+
//| Create buttons |
//+------------------------------------------------------------------+
bool CDateDropList::CreateButtons(void)
{
//--- right align button (try to make equal offsets from top and bottom)
int x1=2*CONTROLS_BORDER_WIDTH;
int y1=2*CONTROLS_BORDER_WIDTH;
int x2=x1+CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_BUTTON_SIZE;
//--- create "Dec" button
if(!m_dec.Create(m_chart_id,m_name+"Dec",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_dec.BmpNames("::res\\LeftTransp.bmp"))
return(false);
if(!Add(m_dec))
return(false);
//---
x2=Width()-2*CONTROLS_BORDER_WIDTH;
x1=x2-CONTROLS_BUTTON_SIZE;
//--- create "Inc" button
if(!m_inc.Create(m_chart_id,m_name+"Inc",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_inc.BmpNames("::res\\RightTransp.bmp"))
return(false);
if(!Add(m_inc))
return(false);
//--- succeeded
return(true);
}
//+------------------------------------------------------------------+
//| Makes the control visible |
//+------------------------------------------------------------------+
bool CDateDropList::Show(void)
{
//--- draw canvas
DrawCanvas();
//--- call method of the parent class
return(CWndContainer::Show());
}
//+------------------------------------------------------------------+
//| Handler of click on button |
//+------------------------------------------------------------------+
bool CDateDropList::OnClickDec(void)
{
switch(m_mode)
{
//--- within the month
case DATE_MODE_MON:
m_value.MonDec();
break;
//--- within the year
case DATE_MODE_YEAR:
m_value.YearDec();
break;
}
DrawCanvas();
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of click on button |
//+------------------------------------------------------------------+
bool CDateDropList::OnClickInc(void)
{
switch(m_mode)
{
//--- within the month
case DATE_MODE_MON:
m_value.MonInc();
break;
//--- within the year
case DATE_MODE_YEAR:
m_value.YearInc();
break;
}
DrawCanvas();
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of click on picture |
//+------------------------------------------------------------------+
bool CDateDropList::OnClickList(void)
{
m_mouse_x=m_list.MouseX();
m_mouse_y=m_list.MouseY();
//---
OnClick();
//---
m_mouse_x=0;
m_mouse_y=0;
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of the "click" event |
//+------------------------------------------------------------------+
bool CDateDropList::OnClick(void)
{
for(int i=0;i<32;i++)
{
if(m_click_rect[i].Contains(m_mouse_x,m_mouse_y))
{
if(i==0)
{
//--- clicked on the header
switch(m_mode)
{
//--- within the month
case DATE_MODE_MON:
//--- switch to the "within the year" mode
m_mode=DATE_MODE_YEAR;
DrawCanvas();
break;
//--- within the year
case DATE_MODE_YEAR:
//--- do nothing for now
break;
}
}
else
{
//--- selected
switch(m_mode)
{
//--- within the month
case DATE_MODE_MON:
m_value.Day(i);
Hide();
//--- send notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
break;
//--- within the year
case DATE_MODE_YEAR:
m_value.Mon(i);
m_mode=DATE_MODE_MON;
DrawCanvas();
break;
default:
break;
}
}
break;
}
}
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Draw canvas |
//+------------------------------------------------------------------+
void CDateDropList::DrawCanvas(void)
{
int x,y;
int dx,dy;
string text;
uint text_al=TA_CENTER|TA_VCENTER;
CDateTime tmp_date;
int rows,cols;
int idx;
//--- zero out array of areas
for(int i=0;i<32;i++)
ZeroMemory(m_click_rect[i]);
//---
m_canvas.Erase(COLOR2RGB(CONTROLS_EDIT_COLOR_BG));
m_canvas.Rectangle(0,0,Width()-1,Height()-1,COLOR2RGB(CONTROLS_EDIT_COLOR_BORDER));
x=Width()/2;
y=CONTROLS_BUTTON_SIZE/2+2*CONTROLS_BORDER_WIDTH;
switch(m_mode)
{
//--- within the month
case DATE_MODE_MON:
text=m_value.MonthName()+" "+IntegerToString(m_value.year);
DrawClickRect(0,x,y,text,COLOR2RGB(CONTROLS_EDIT_COLOR),text_al);
rows=6;
cols=7;
x=dx=Width()/(cols+1);
y+=y;
dy=(Height()-y-2*CONTROLS_BORDER_WIDTH)/(rows+1);
y+=dy/2;
for(int i=0;i<cols;i++,x+=dx)
m_canvas.TextOut(x,y,m_value.ShortDayName(i),COLOR2RGB(CONTROLS_EDIT_COLOR),text_al);
//--- backup data
tmp_date=m_value;
//--- find the beginning of the first displayed week
tmp_date.DayDec(tmp_date.day_of_week);
while(tmp_date.mon==m_value.mon && tmp_date.day!=1)
tmp_date.DayDec(cols);
//--- draw
idx=1;
y+=dy;
for(int i=0;i<rows;i++,y+=dy)
{
x=dx;
for(int j=0;j<cols;j++,x+=dx)
{
text=IntegerToString(tmp_date.day);
if(tmp_date.mon==m_value.mon)
{
if(tmp_date.day==m_value.day)
m_canvas.FillRectangle(x-dx/2,y-dy/2,x+dx/2,y+dy/2,COLOR2RGB(CONTROLS_COLOR_BG_SEL));
DrawClickRect(idx++,x,y,text,COLOR2RGB(CONTROLS_EDIT_COLOR),text_al);
}
else
m_canvas.TextOut(x,y,text,COLOR2RGB(CONTROLS_BUTTON_COLOR_BORDER),text_al);
tmp_date.DayInc();
}
}
break;
//--- within the year
case DATE_MODE_YEAR:
text=IntegerToString(m_value.year);
DrawClickRect(0,x,y,text,COLOR2RGB(CONTROLS_EDIT_COLOR),text_al);
rows=3;
cols=4;
x=dx=Width()/(cols+1);
y+=y;
dy=(Height()-y)/rows;
y+=dy/2;
for(int i=0;i<rows*cols;i++)
{
if(i+1==m_value.mon)
m_canvas.FillRectangle(x-dx/2,y-dy/4,x+dx/2,y+dy/4,COLOR2RGB(CONTROLS_COLOR_BG_SEL));
DrawClickRect(i+1,x,y,m_value.ShortMonthName(i+1),COLOR2RGB(CONTROLS_EDIT_COLOR),text_al);
if(i%cols==cols-1)
{
x=dx;
y+=dy;
}
else
x+=dx;
}
break;
default:
break;
}
m_canvas.Update();
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
void CDateDropList::DrawClickRect(const int idx,int x,int y,string text,const uint clr,uint alignment)
{
int text_w,text_h;
//--- display the text
m_canvas.TextOut(x,y,text,clr,alignment);
//--- determine area occupied by text
m_canvas.TextSize(text,text_w,text_h);
//--- convert relative coordinated to absolute ones
x+=Left();
y+=Top();
//--- check flags of horizontal alignment
switch(alignment&(TA_LEFT|TA_CENTER|TA_RIGHT))
{
case TA_LEFT:
m_click_rect[idx].left=x;
break;
case TA_CENTER:
m_click_rect[idx].left=x-text_w/2;
break;
case TA_RIGHT:
m_click_rect[idx].left=x-text_w;
break;
}
m_click_rect[idx].Width(text_w);
//--- check flags of vertical alignment
switch(alignment&(TA_TOP|TA_VCENTER|TA_BOTTOM))
{
case TA_TOP:
m_click_rect[idx].top=y;
break;
case TA_VCENTER:
m_click_rect[idx].top=y-text_h/2;
break;
case TA_BOTTOM:
m_click_rect[idx].top=y-text_h;
break;
}
m_click_rect[idx].Height(text_h);
}
//+------------------------------------------------------------------+
+264
View File
@@ -0,0 +1,264 @@
//+------------------------------------------------------------------+
//| DatePicker.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndContainer.mqh"
#include "Edit.mqh"
#include "BmpButton.mqh"
#include "DateDropList.mqh"
//+------------------------------------------------------------------+
//| Resources |
//+------------------------------------------------------------------+
//--- Can not place the same file into resource twice
#resource "res\\DateDropOn.bmp" // image file
#resource "res\\DateDropOff.bmp" // image file
//+------------------------------------------------------------------+
//| Class CDatePicker |
//| Usage: date picker |
//+------------------------------------------------------------------+
class CDatePicker : public CWndContainer
{
private:
//--- dependent controls
CEdit m_edit; // the entry field object
CBmpButton m_drop; // the button object
CDateDropList m_list; // the drop-down list object
//--- data
datetime m_value; // current value
public:
CDatePicker(void);
~CDatePicker(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- data
datetime Value(void) const { return(m_value); }
void Value(datetime value) { m_edit.Text(TimeToString(m_value=value,TIME_DATE)); }
//--- state
virtual bool Show(void);
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
protected:
//--- create dependent controls
virtual bool CreateEdit(void);
virtual bool CreateButton(void);
virtual bool CreateList(void);
//--- handlers of the dependent controls events
virtual bool OnClickEdit(void);
virtual bool OnClickButton(void);
virtual bool OnChangeList(void);
//--- show drop-down list
bool ListShow(void);
bool ListHide(void);
void CheckListHide(const int id,int x,int y);
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CDatePicker)
ON_EVENT(ON_CLICK,m_edit,OnClickEdit)
ON_EVENT(ON_CLICK,m_drop,OnClickButton)
ON_EVENT(ON_CHANGE,m_list,OnChangeList)
CheckListHide(id,(int)lparam,(int)dparam);
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
EVENT_MAP_END(CWndContainer)
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CDatePicker::CDatePicker(void) : m_value(0)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CDatePicker::~CDatePicker(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CDatePicker::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- call method of the parent class
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- create dependent controls
if(!CreateEdit())
return(false);
if(!CreateButton())
return(false);
if(!CreateList())
return(false);
//--- succeeded
return(true);
}
//+------------------------------------------------------------------+
//| Create main entry field |
//+------------------------------------------------------------------+
bool CDatePicker::CreateEdit(void)
{
//--- create
if(!m_edit.Create(m_chart_id,m_name+"Edit",m_subwin,0,0,Width(),Height()))
return(false);
if(!m_edit.Text(""))
return(false);
if(!m_edit.ReadOnly(true))
return(false);
if(!Add(m_edit))
return(false);
//--- succeeded
return(true);
}
//+------------------------------------------------------------------+
//| Create button |
//+------------------------------------------------------------------+
bool CDatePicker::CreateButton(void)
{
//--- right align button (try to make equal offsets from top and bottom)
int x1=Width()-(2*CONTROLS_BUTTON_SIZE+CONTROLS_COMBO_BUTTON_X_OFF);
int y1=(Height()-CONTROLS_BUTTON_SIZE)/2;
int x2=x1+2*CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_BUTTON_SIZE;
//--- create
if(!m_drop.Create(m_chart_id,m_name+"Drop",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_drop.BmpNames("::res\\DateDropOff.bmp","::res\\DateDropOn.bmp"))
return(false);
if(!Add(m_drop))
return(false);
m_drop.Locking(true);
//--- succeeded
return(true);
}
//+------------------------------------------------------------------+
//| Create drop-down list |
//+------------------------------------------------------------------+
bool CDatePicker::CreateList(void)
{
//--- create
if(!m_list.Create(m_chart_id,m_name+"List",m_subwin,0,Height()-1,Width(),0))
return(false);
if(!Add(m_list))
return(false);
m_list.Hide();
//--- succeeded
return(true);
}
//+------------------------------------------------------------------+
//| Makes the control visible |
//+------------------------------------------------------------------+
bool CDatePicker::Show(void)
{
m_edit.Show();
m_drop.Show();
m_list.Hide();
//--- call method of the parent class
return(CWnd::Show());
}
//+------------------------------------------------------------------+
//| save |
//+------------------------------------------------------------------+
bool CDatePicker::Save(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//--- write
FileWriteLong(file_handle,Value());
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| load |
//+------------------------------------------------------------------+
bool CDatePicker::Load(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//--- load
if(!FileIsEnding(file_handle))
Value(FileReadLong(file_handle));
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Handler of click on main entry field |
//+------------------------------------------------------------------+
bool CDatePicker::OnClickEdit(void)
{
//--- change button state
if(!m_drop.Pressed(!m_drop.Pressed()))
return(false);
//--- call the click on button handler
return(OnClickButton());
}
//+------------------------------------------------------------------+
//| Handler of click on button |
//+------------------------------------------------------------------+
bool CDatePicker::OnClickButton(void)
{
//--- show or hide the drop-down list depending on the button state
return((m_drop.Pressed()) ? ListShow():ListHide());
}
//+------------------------------------------------------------------+
//| Handler of change on drop-down list |
//+------------------------------------------------------------------+
bool CDatePicker::OnChangeList(void)
{
string text=TimeToString(m_value=m_list.Value(),TIME_DATE);
//--- hide the list, depress the button
ListHide();
m_drop.Pressed(false);
//--- set text in the main entry field
m_edit.Text(text);
//--- send notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Show the drop-down list |
//+------------------------------------------------------------------+
bool CDatePicker::ListShow(void)
{
//--- set value
m_list.Value(m_value);
//--- show the list
return(m_list.Show());
}
//+------------------------------------------------------------------+
//| Hide drop-down list |
//+------------------------------------------------------------------+
bool CDatePicker::ListHide(void)
{
//--- hide the list
return(m_list.Hide());
}
//+------------------------------------------------------------------+
//| Hide the drop-down element if necessary |
//+------------------------------------------------------------------+
void CDatePicker::CheckListHide(const int id,int x,int y)
{
//--- check event ID
if(id!=CHARTEVENT_CLICK)
return;
//--- check visibility of the drop-down element
if(!m_list.IsVisible())
return;
//--- check mouse cursor's position
y-=(int)ChartGetInteger(m_chart_id,CHART_WINDOW_YDISTANCE,m_subwin);
if(!m_edit.Contains(x,y) && !m_list.Contains(x,y))
{
m_drop.Pressed(false);
m_list.Hide();
}
}
//+------------------------------------------------------------------+
+190
View File
@@ -0,0 +1,190 @@
//+------------------------------------------------------------------+
//| Defines.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Enumerations |
//+------------------------------------------------------------------+
//--- properties flags
enum ENUM_WND_PROP_FLAGS
{
WND_PROP_FLAG_CAN_DBL_CLICK = 1, // can be double clicked by mouse
WND_PROP_FLAG_CAN_DRAG = 2, // can be dragged by mouse
WND_PROP_FLAG_CLICKS_BY_PRESS= 4, // generates the "click" event series on pressing left mouse button
WND_PROP_FLAG_CAN_LOCK = 8, // control with fixed state (usually it is a button)
WND_PROP_FLAG_READ_ONLY =16 // read only (usually it is a edit)
};
//--- state flags
enum ENUM_WND_STATE_FLAGS
{
WND_STATE_FLAG_ENABLE = 1, // "object is enabled" flag
WND_STATE_FLAG_VISIBLE = 2, // "object is visible" flag
WND_STATE_FLAG_ACTIVE = 4, // "object is active" flag
};
//--- mouse flags
enum ENUM_MOUSE_FLAGS
{
MOUSE_INVALID_FLAGS =-1, // no buttons state
MOUSE_EMPTY = 0, // buttons are not pressed
MOUSE_LEFT = 1, // left button pressed
MOUSE_RIGHT = 2 // right button pressed
};
//--- alignment flags
enum ENUM_WND_ALIGN_FLAGS
{
WND_ALIGN_NONE = 0, // no alignment
WND_ALIGN_LEFT = 1, // align by left border
WND_ALIGN_TOP = 2, // align by top border
WND_ALIGN_RIGHT = 4, // align by right border
WND_ALIGN_BOTTOM = 8, // align by bottom border
WND_ALIGN_WIDTH = WND_ALIGN_LEFT|WND_ALIGN_RIGHT, // justify
WND_ALIGN_HEIGHT = WND_ALIGN_TOP|WND_ALIGN_BOTTOM, // align by top and bottom border
WND_ALIGN_CLIENT = WND_ALIGN_WIDTH|WND_ALIGN_HEIGHT // align by all sides
};
//+------------------------------------------------------------------+
//| Drawing styles and colors |
//+------------------------------------------------------------------+
//--- common
#define CONTROLS_FONT_NAME "Trebuchet MS"
#define CONTROLS_FONT_SIZE (10)
//--- Text
#define CONTROLS_COLOR_TEXT C'0x3B,0x29,0x28'
#define CONTROLS_COLOR_TEXT_SEL White
#define CONTROLS_COLOR_BG White
#define CONTROLS_COLOR_BG_SEL C'0x33,0x99,0xFF'
//--- Button
#define CONTROLS_BUTTON_COLOR C'0x3B,0x29,0x28'
#define CONTROLS_BUTTON_COLOR_BG C'0xDD,0xE2,0xEB'
#define CONTROLS_BUTTON_COLOR_BORDER C'0xB2,0xC3,0xCF'
//--- Label
#define CONTROLS_LABEL_COLOR C'0x3B,0x29,0x28'
//--- Edit
#define CONTROLS_EDIT_COLOR C'0x3B,0x29,0x28'
#define CONTROLS_EDIT_COLOR_BG White
#define CONTROLS_EDIT_COLOR_BORDER C'0xB2,0xC3,0xCF'
//--- Scrolls
#define CONTROLS_SCROLL_COLOR_BG C'0xEC,0xEC,0xEC'
#define CONTROLS_SCROLL_COLOR_BORDER C'0xD3,0xD3,0xD3'
//--- Client
#define CONTROLS_CLIENT_COLOR_BG C'0xDE,0xDE,0xDE'
#define CONTROLS_CLIENT_COLOR_BORDER C'0x2C,0x2C,0x2C'
//--- ListView
#define CONTROLS_LISTITEM_COLOR_TEXT C'0x3B,0x29,0x28'
#define CONTROLS_LISTITEM_COLOR_TEXT_SEL White
#define CONTROLS_LISTITEM_COLOR_BG White
#define CONTROLS_LISTITEM_COLOR_BG_SEL C'0x33,0x99,0xFF'
#define CONTROLS_LIST_COLOR_BG White
#define CONTROLS_LIST_COLOR_BORDER C'0xB2,0xC3,0xCF'
//--- CheckGroup
#define CONTROLS_CHECKGROUP_COLOR_BG C'0xF7,0xF7,0xF7'
#define CONTROLS_CHECKGROUP_COLOR_BORDER C'0xB2,0xC3,0xCF'
//--- RadioGroup
#define CONTROLS_RADIOGROUP_COLOR_BG C'0xF7,0xF7,0xF7'
#define CONTROLS_RADIOGROUP_COLOR_BORDER C'0xB2,0xC3,0xCF'
//--- Dialog
#define CONTROLS_DIALOG_COLOR_BORDER_LIGHT White
#define CONTROLS_DIALOG_COLOR_BORDER_DARK C'0xB6,0xB6,0xB6'
#define CONTROLS_DIALOG_COLOR_BG C'0xF0,0xF0,0xF0'
#define CONTROLS_DIALOG_COLOR_CAPTION_TEXT C'0x28,0x29,0x3B'
#define CONTROLS_DIALOG_COLOR_CLIENT_BG C'0xF7,0xF7,0xF7'
#define CONTROLS_DIALOG_COLOR_CLIENT_BORDER C'0xC8,0xC8,0xC8'
//+------------------------------------------------------------------+
//| Constants for the controls |
//+------------------------------------------------------------------+
//--- common
#define CONTROLS_INVALID_ID (-1) // invalid ID
#define CONTROLS_INVALID_INDEX (-1) // invalid index of array
#define CONTROLS_SELF_MESSAGE (-1) // message to oneself
#define CONTROLS_MAXIMUM_ID (10000) // maximum number of IDs in application
#define CONTROLS_BORDER_WIDTH (1) // border width
#define CONTROLS_SUBWINDOW_GAP (3) // gap between sub-windows along the Y axis
#define CONTROLS_DRAG_SPACING (50) // sensitivity threshold for dragging
#define CONTROLS_DBL_CLICK_TIME (100) // double click interval
//--- BmpButton
#define CONTROLS_BUTTON_SIZE (16) // default size of button (16 x 16)
//--- Scrolls
#define CONTROLS_SCROLL_SIZE (18) // default lateral size of scrollbar
#define CONTROLS_SCROLL_THUMB_SIZE (22) // default length of scroll box
//--- RadioButton
#define CONTROLS_RADIO_BUTTON_X_OFF (3) // X offset of radio button (for RadioButton)
#define CONTROLS_RADIO_BUTTON_Y_OFF (3) // Y offset of radio button (for RadioButton)
#define CONTROLS_RADIO_LABEL_X_OFF (20) // X offset of label (for RadioButton)
#define CONTROLS_RADIO_LABEL_Y_OFF (0) // Y offset of label (for RadioButton)
//--- CheckBox
#define CONTROLS_CHECK_BUTTON_X_OFF (3) // X offset of check button (for CheckBox)
#define CONTROLS_CHECK_BUTTON_Y_OFF (3) // Y offset of check button (for CheckBox)
#define CONTROLS_CHECK_LABEL_X_OFF (20) // X offset of label (for CheckBox)
#define CONTROLS_CHECK_LABEL_Y_OFF (0) // Y offset of label (for CheckBox)
//--- Spin
#define CONTROLS_SPIN_BUTTON_X_OFF (2) // X offset of button from right (for SpinEdit)
#define CONTROLS_SPIN_MIN_HEIGHT (18) // minimal height (for SpinEdit)
#define CONTROLS_SPIN_BUTTON_SIZE (8) // default size of button (16 x 8) (for SpinEdit)
//--- Combo
#define CONTROLS_COMBO_BUTTON_X_OFF (2) // X offset of button from right (for ComboBox)
#define CONTROLS_COMBO_MIN_HEIGHT (18) // minimal height (for ComboBox)
#define CONTROLS_COMBO_ITEM_HEIGHT (18) // height of combo box item (for ComboBox)
#define CONTROLS_COMBO_ITEMS_VIEW (8) // number of items in combo box (for ComboBox)
//--- ListView
#define CONTROLS_LIST_ITEM_HEIGHT (18) // height of list item (for ListView)
//--- Dialog
#define CONTROLS_DIALOG_CAPTION_HEIGHT (22) // height of dialog header
#define CONTROLS_DIALOG_BUTTON_OFF (3) // offset of dialog buttons
#define CONTROLS_DIALOG_CLIENT_OFF (2) // offset of dialog client area
#define CONTROLS_DIALOG_MINIMIZE_LEFT (10) // left coordinate of dialog in minimized state
#define CONTROLS_DIALOG_MINIMIZE_TOP (10) // top coordinate of dialog in minimized state
#define CONTROLS_DIALOG_MINIMIZE_WIDTH (100) // width of dialog in minimized state
#define CONTROLS_DIALOG_MINIMIZE_HEIGHT (4*CONTROLS_BORDER_WIDTH+CONTROLS_DIALOG_CAPTION_HEIGHT) // height of dialog in minimized state
//+------------------------------------------------------------------+
//| Macro |
//+------------------------------------------------------------------+
//--- check properties
#define IS_CAN_DBL_CLICK ((m_prop_flags&WND_PROP_FLAG_CAN_DBL_CLICK)!=0)
#define IS_CAN_DRAG ((m_prop_flags&WND_PROP_FLAG_CAN_DRAG)!=0)
#define IS_CLICKS_BY_PRESS ((m_prop_flags&WND_PROP_FLAG_CLICKS_BY_PRESS)!=0)
#define IS_CAN_LOCK ((m_prop_flags&WND_PROP_FLAG_CAN_LOCK)!=0)
#define IS_READ_ONLY ((m_prop_flags&WND_PROP_FLAG_READ_ONLY)!=0)
//--- check state
#define IS_ENABLED ((m_state_flags&WND_STATE_FLAG_ENABLE)!=0)
#define IS_VISIBLE ((m_state_flags&WND_STATE_FLAG_VISIBLE)!=0)
#define IS_ACTIVE ((m_state_flags&WND_STATE_FLAG_ACTIVE)!=0)
//+------------------------------------------------------------------+
//| Macro of event handling map |
//+------------------------------------------------------------------+
#define INTERNAL_EVENT (-1)
//--- beginning of map
#define EVENT_MAP_BEGIN(class_name) bool class_name::OnEvent(const int id,const long& lparam,const double& dparam,const string& sparam) {
//--- end of map
#define EVENT_MAP_END(parent_class_name) return(parent_class_name::OnEvent(id,lparam,dparam,sparam)); }
//--- event handling by numeric ID
#define ON_EVENT(event,control,handler) if(id==(event+CHARTEVENT_CUSTOM) && lparam==control.Id()) { handler(); return(true); }
//--- event handling by numeric ID by pointer of control
#define ON_EVENT_PTR(event,control,handler) if(control!=NULL && id==(event+CHARTEVENT_CUSTOM) && lparam==control.Id()) { handler(); return(true); }
//--- event handling without ID analysis
#define ON_NO_ID_EVENT(event,handler) if(id==(event+CHARTEVENT_CUSTOM)) { return(handler()); }
//--- event handling by row ID
#define ON_NAMED_EVENT(event,control,handler) if(id==(event+CHARTEVENT_CUSTOM) && sparam==control.Name()) { handler(); return(true); }
//--- handling of indexed event
#define ON_INDEXED_EVENT(event,controls,handler) { int total=ArraySize(controls); for(int i=0;i<total;i++) if(id==(event+CHARTEVENT_CUSTOM) && lparam==controls[i].Id()) return(handler(i)); }
//--- handling of external event
#define ON_EXTERNAL_EVENT(event,handler) if(id==(event+CHARTEVENT_CUSTOM)) { handler(lparam,dparam,sparam); return(true); }
//+------------------------------------------------------------------+
//| Events |
//+------------------------------------------------------------------+
#define ON_CLICK (0) // clicking on control event
#define ON_DBL_CLICK (1) // double clicking on control event
#define ON_SHOW (2) // showing control event
#define ON_HIDE (3) // hiding control event
#define ON_CHANGE (4) // changing control event
#define ON_START_EDIT (5) // start of editing event
#define ON_END_EDIT (6) // end of editing event
#define ON_SCROLL_INC (7) // increment of scrollbar event
#define ON_SCROLL_DEC (8) // decrement of scrollbar event
#define ON_MOUSE_FOCUS_SET (9) // the "mouse cursor entered the control" event
#define ON_MOUSE_FOCUS_KILL (10) // the "mouse cursor exited the control" event
#define ON_DRAG_START (11) // the "control dragging start" event
#define ON_DRAG_PROCESS (12) // the "control is being dragged" event
#define ON_DRAG_END (13) // the "control dragging end" event
#define ON_BRING_TO_TOP (14) // the "mouse events priority increase" event
#define ON_APP_CLOSE (100) // "closing the application" event
//+------------------------------------------------------------------+
+971
View File
@@ -0,0 +1,971 @@
//+------------------------------------------------------------------+
//| Dialog.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndContainer.mqh"
#include "WndClient.mqh"
#include "Panel.mqh"
#include "Edit.mqh"
#include "BmpButton.mqh"
#include <Charts\Chart.mqh>
//+------------------------------------------------------------------+
//| Resources |
//+------------------------------------------------------------------+
#resource "res\\Close.bmp"
#resource "res\\Restore.bmp"
#resource "res\\Turn.bmp"
//+------------------------------------------------------------------+
//| Class CDialog |
//| Usage: base class to create dialog boxes |
//| and indicator panels |
//+------------------------------------------------------------------+
class CDialog : public CWndContainer
{
private:
//--- dependent controls
CPanel m_white_border; // the "white border" object
CPanel m_background; // the background object
CEdit m_caption; // the window title object
CBmpButton m_button_close; // the "Close" button object
CWndClient m_client_area; // the client area object
protected:
//--- flags
bool m_panel_flag; // the "panel in a separate window" flag
//--- flags
bool m_minimized; // "create in minimized state" flag
//--- additional areas
CRect m_min_rect; // minimal area coordinates
CRect m_norm_rect; // normal area coordinates
public:
CDialog(void);
~CDialog(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- set up
string Caption(void) const { return(m_caption.Text()); }
bool Caption(const string text) { return(m_caption.Text(text)); }
//--- fill
bool Add(CWnd *control);
bool Add(CWnd &control);
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
protected:
//--- create dependent controls
virtual bool CreateWhiteBorder(void);
virtual bool CreateBackground(void);
virtual bool CreateCaption(void);
virtual bool CreateButtonClose(void);
virtual bool CreateClientArea(void);
//--- handlers of the dependent controls events
virtual void OnClickCaption(void);
virtual void OnClickButtonClose(void);
//--- access properties of caption
void CaptionAlignment(const int flags,const int left,const int top,const int right,const int bottom)
{ m_caption.Alignment(flags,left,top,right,bottom); }
//--- access properties of client area
bool ClientAreaVisible(const bool visible) { return(m_client_area.Visible(visible)); }
int ClientAreaLeft(void) const { return(m_client_area.Left()); }
int ClientAreaTop(void) const { return(m_client_area.Top()); }
int ClientAreaRight(void) const { return(m_client_area.Right()); }
int ClientAreaBottom(void) const { return(m_client_area.Bottom()); }
int ClientAreaWidth(void) const { return(m_client_area.Width()); }
int ClientAreaHeight(void) const { return(m_client_area.Height()); }
//--- handlers of drag
virtual bool OnDialogDragStart(void);
virtual bool OnDialogDragProcess(void);
virtual bool OnDialogDragEnd(void);
};
//+------------------------------------------------------------------+
//| Common handler of events |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CDialog)
ON_EVENT(ON_CLICK,m_button_close,OnClickButtonClose)
ON_EVENT(ON_CLICK,m_caption,OnClickCaption)
ON_EVENT(ON_DRAG_START,m_caption,OnDialogDragStart)
ON_EVENT_PTR(ON_DRAG_PROCESS,m_drag_object,OnDialogDragProcess)
ON_EVENT_PTR(ON_DRAG_END,m_drag_object,OnDialogDragEnd)
EVENT_MAP_END(CWndContainer)
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CDialog::CDialog(void) : m_panel_flag(false),
m_minimized(false)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CDialog::~CDialog(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- call method of parent class
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- create dependent controls
if(!m_panel_flag && !CreateWhiteBorder())
return(false);
if(!CreateBackground())
return(false);
if(!CreateCaption())
return(false);
if(!CreateButtonClose())
return(false);
if(!CreateClientArea())
return(false);
//--- set up additional areas
m_norm_rect.SetBound(m_rect);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Add control to the client area (by pointer) |
//+------------------------------------------------------------------+
bool CDialog::Add(CWnd *control)
{
return(m_client_area.Add(control));
}
//+------------------------------------------------------------------+
//| Add control to the client area (by reference) |
//+------------------------------------------------------------------+
bool CDialog::Add(CWnd &control)
{
return(m_client_area.Add(control));
}
//+------------------------------------------------------------------+
//| Save |
//+------------------------------------------------------------------+
bool CDialog::Save(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//--- save
FileWriteStruct(file_handle,m_norm_rect);
FileWriteInteger(file_handle,m_min_rect.left);
FileWriteInteger(file_handle,m_min_rect.top);
FileWriteInteger(file_handle,m_minimized);
//--- result
return(CWndContainer::Save(file_handle));
}
//+------------------------------------------------------------------+
//| Load |
//+------------------------------------------------------------------+
bool CDialog::Load(const int file_handle)
{
if(file_handle==INVALID_HANDLE)
return(false);
//--- load
if(!FileIsEnding(file_handle))
{
FileReadStruct(file_handle,m_norm_rect);
int left=FileReadInteger(file_handle);
int top=FileReadInteger(file_handle);
m_min_rect.Move(left,top);
m_minimized=FileReadInteger(file_handle);
}
//--- result
return(CWndContainer::Load(file_handle));
}
//+------------------------------------------------------------------+
//| Create "white border" |
//+------------------------------------------------------------------+
bool CDialog::CreateWhiteBorder(void)
{
//--- coordinates
int x1=0;
int y1=0;
int x2=Width();
int y2=Height();
//--- create
if(!m_white_border.Create(m_chart_id,m_name+"Border",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_white_border.ColorBackground(CONTROLS_DIALOG_COLOR_BG))
return(false);
if(!m_white_border.ColorBorder(CONTROLS_DIALOG_COLOR_BORDER_LIGHT))
return(false);
if(!CWndContainer::Add(m_white_border))
return(false);
m_white_border.Alignment(WND_ALIGN_CLIENT,0,0,0,0);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create background |
//+------------------------------------------------------------------+
bool CDialog::CreateBackground(void)
{
int off=(m_panel_flag) ? 0:CONTROLS_BORDER_WIDTH;
//--- coordinates
int x1=off;
int y1=off;
int x2=Width()-off;
int y2=Height()-off;
//--- create
if(!m_background.Create(m_chart_id,m_name+"Back",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_background.ColorBackground(CONTROLS_DIALOG_COLOR_BG))
return(false);
color border=(m_panel_flag) ? CONTROLS_DIALOG_COLOR_BG : CONTROLS_DIALOG_COLOR_BORDER_DARK;
if(!m_background.ColorBorder(border))
return(false);
if(!CWndContainer::Add(m_background))
return(false);
m_background.Alignment(WND_ALIGN_CLIENT,off,off,off,off);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create window title |
//+------------------------------------------------------------------+
bool CDialog::CreateCaption(void)
{
int off=(m_panel_flag) ? 0:2*CONTROLS_BORDER_WIDTH;
//--- coordinates
int x1=off;
int y1=off;
int x2=Width()-off;
int y2=y1+CONTROLS_DIALOG_CAPTION_HEIGHT;
//--- create
if(!m_caption.Create(m_chart_id,m_name+"Caption",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_caption.Color(CONTROLS_DIALOG_COLOR_CAPTION_TEXT))
return(false);
if(!m_caption.ColorBackground(CONTROLS_DIALOG_COLOR_BG))
return(false);
if(!m_caption.ColorBorder(CONTROLS_DIALOG_COLOR_BG))
return(false);
if(!m_caption.ReadOnly(true))
return(false);
if(!m_caption.Text(m_name))
return(false);
if(!CWndContainer::Add(m_caption))
return(false);
m_caption.Alignment(WND_ALIGN_WIDTH,off,0,off,0);
if(!m_panel_flag)
m_caption.PropFlags(WND_PROP_FLAG_CAN_DRAG);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "Close" button |
//+------------------------------------------------------------------+
bool CDialog::CreateButtonClose(void)
{
int off=(m_panel_flag) ? 0 : 2*CONTROLS_BORDER_WIDTH;
//--- coordinates
int x1=Width()-off-(CONTROLS_BUTTON_SIZE+CONTROLS_DIALOG_BUTTON_OFF);
int y1=off+CONTROLS_DIALOG_BUTTON_OFF;
int x2=x1+CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_BUTTON_SIZE;
//--- create
if(!m_button_close.Create(m_chart_id,m_name+"Close",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_button_close.BmpNames("::res\\Close.bmp"))
return(false);
if(!CWndContainer::Add(m_button_close))
return(false);
m_button_close.Alignment(WND_ALIGN_RIGHT,0,0,off+CONTROLS_DIALOG_BUTTON_OFF,0);
//--- change caption
CaptionAlignment(WND_ALIGN_WIDTH,off,0,off+(CONTROLS_BUTTON_SIZE+CONTROLS_DIALOG_BUTTON_OFF),0);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create client area |
//+------------------------------------------------------------------+
bool CDialog::CreateClientArea(void)
{
int off=(m_panel_flag) ? 0:2*CONTROLS_BORDER_WIDTH;
//--- coordinates
int x1=off+CONTROLS_DIALOG_CLIENT_OFF;
int y1=off+CONTROLS_DIALOG_CAPTION_HEIGHT;
int x2=Width()-(off+CONTROLS_DIALOG_CLIENT_OFF);
int y2=Height()-(off+CONTROLS_DIALOG_CLIENT_OFF);
//--- create
if(!m_client_area.Create(m_chart_id,m_name+"Client",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_client_area.ColorBackground(CONTROLS_DIALOG_COLOR_CLIENT_BG))
return(false);
if(!m_client_area.ColorBorder(CONTROLS_DIALOG_COLOR_CLIENT_BORDER))
return(false);
CWndContainer::Add(m_client_area);
m_client_area.Alignment(WND_ALIGN_CLIENT,x1,y1,x1,x1);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Handler of click on the window title |
//+------------------------------------------------------------------+
void CDialog::OnClickCaption(void)
{
}
//+------------------------------------------------------------------+
//| Handler of click on the "Close" button |
//+------------------------------------------------------------------+
void CDialog::OnClickButtonClose(void)
{
Visible(false);
}
//+------------------------------------------------------------------+
//| Start dragging the dialog box |
//+------------------------------------------------------------------+
bool CDialog::OnDialogDragStart(void)
{
if(m_drag_object==NULL)
{
m_drag_object=new CDragWnd;
if(m_drag_object==NULL)
return(false);
}
//--- calculate coordinates
int x1=Left()-CONTROLS_DRAG_SPACING;
int y1=Top()-CONTROLS_DRAG_SPACING;
int x2=Right()+CONTROLS_DRAG_SPACING;
int y2=Bottom()+CONTROLS_DRAG_SPACING;
//--- create
m_drag_object.Create(m_chart_id,"",m_subwin,x1,y1,x2,y2);
m_drag_object.PropFlags(WND_PROP_FLAG_CAN_DRAG);
//--- constraints
CChart chart;
chart.Attach(m_chart_id);
m_drag_object.Limits(-CONTROLS_DRAG_SPACING,-CONTROLS_DRAG_SPACING,
chart.WidthInPixels()+CONTROLS_DRAG_SPACING,
chart.HeightInPixels(m_subwin)+CONTROLS_DRAG_SPACING);
chart.Detach();
//--- set mouse params
m_drag_object.MouseX(m_caption.MouseX());
m_drag_object.MouseY(m_caption.MouseY());
m_drag_object.MouseFlags(m_caption.MouseFlags());
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Continue dragging the dialog box |
//+------------------------------------------------------------------+
bool CDialog::OnDialogDragProcess(void)
{
//--- checking
if(m_drag_object==NULL)
return(false);
//--- calculate coordinates
int x=m_drag_object.Left()+50;
int y=m_drag_object.Top()+50;
//--- move dialog
Move(x,y);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| End dragging the dialog box |
//+------------------------------------------------------------------+
bool CDialog::OnDialogDragEnd(void)
{
if(m_drag_object!=NULL)
{
m_caption.MouseFlags(m_drag_object.MouseFlags());
delete m_drag_object;
m_drag_object=NULL;
}
//--- set up additional areas
if(m_minimized)
m_min_rect.SetBound(m_rect);
else
m_norm_rect.SetBound(m_rect);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Class CAppDialog |
//| Usage: main dialog box of MQL5 application |
//+------------------------------------------------------------------+
class CAppDialog : public CDialog
{
private:
//--- dependent controls
CBmpButton m_button_minmax; // the "Minimize/Maximize" button object
//--- variables
string m_program_name; // name of program
string m_instance_id; // unique string ID
ENUM_PROGRAM_TYPE m_program_type; // type of program
string m_indicator_name;
int m_deinit_reason;
//--- for mouse
int m_subwin_Yoff; // subwindow Y offset
CWnd* m_focused_wnd; // pointer to object that has mouse focus
CWnd* m_top_wnd; // pointer to object that has priority over mouse events handling
protected:
CChart m_chart; // object to access chart
public:
CAppDialog(void);
~CAppDialog(void);
//--- main application dialog creation and destroy
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
virtual void Destroy(const int reason=REASON_PROGRAM);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- dialog run
bool Run(void);
//--- chart events processing
void ChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- set up
void Minimized(const bool flag) { m_minimized=flag; }
//--- to save/restore state
void IniFileSave(void);
void IniFileLoad(void);
virtual string IniFileName(void) const;
virtual string IniFileExt(void) const { return(".dat"); }
virtual bool Load(const int file_handle);
virtual bool Save(const int file_handle);
private:
bool CreateCommon(const long chart,const string name,const int subwin);
bool CreateExpert(const int x1,const int y1,const int x2,const int y2);
bool CreateIndicator(const int x1,const int y1,const int x2,const int y2);
protected:
//--- create dependent controls
virtual bool CreateButtonMinMax(void);
//--- handlers of the dependent controls events
virtual void OnClickButtonClose(void);
virtual void OnClickButtonMinMax(void);
//--- external event handlers
virtual void OnAnotherApplicationClose(const long &lparam,const double &dparam,const string &sparam);
//--- methods
virtual bool Rebound(const CRect &rect);
virtual void Minimize(void);
virtual void Maximize(void);
string CreateInstanceId(void);
string ProgramName(void) const { return(m_program_name); }
void SubwinOff(void);
};
//+------------------------------------------------------------------+
//| Common handler of events |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CAppDialog)
ON_EVENT(ON_CLICK,m_button_minmax,OnClickButtonMinMax)
ON_EXTERNAL_EVENT(ON_APP_CLOSE,OnAnotherApplicationClose)
EVENT_MAP_END(CDialog)
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CAppDialog::CAppDialog(void) : m_program_type(WRONG_VALUE),
m_deinit_reason(WRONG_VALUE),
m_subwin_Yoff(0),
m_focused_wnd(NULL),
m_top_wnd(NULL)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CAppDialog::~CAppDialog(void)
{
}
//+------------------------------------------------------------------+
//| Application dialog initialization function |
//+------------------------------------------------------------------+
bool CAppDialog::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
if(!CreateCommon(chart,name,subwin))
return(false);
//---
switch(m_program_type)
{
case PROGRAM_EXPERT:
if(!CreateExpert(x1,y1,x2,y2))
return(false);
break;
case PROGRAM_INDICATOR:
if(!CreateIndicator(x1,y1,x2,y2))
return(false);
break;
default:
Print("CAppDialog: invalid program type");
return(false);
}
//--- Title of dialog window
if(!Caption(m_program_name))
return(false);
//--- create dependent controls
if(!CreateButtonMinMax())
return(false);
//--- get subwindow offset
SubwinOff();
//--- if flag is set, minimize the dialog
if(m_minimized)
Minimize();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Initialize common area |
//+------------------------------------------------------------------+
bool CAppDialog::CreateCommon(const long chart,const string name,const int subwin)
{
//--- save parameters
m_chart_id =chart;
m_name =name;
m_subwin =subwin;
m_program_name =name;
m_deinit_reason=WRONG_VALUE;
//--- get unique ID
m_instance_id=CreateInstanceId();
//--- initialize chart object
m_chart.Attach(chart);
//--- determine type of program
m_program_type=(ENUM_PROGRAM_TYPE)MQL5InfoInteger(MQL5_PROGRAM_TYPE);
//--- specify object and mouse events
if(!m_chart.EventObjectCreate() || !m_chart.EventObjectDelete() || !m_chart.EventMouseMove())
{
Print("CAppDialog: object events specify error");
m_chart.Detach();
return(false);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Initialize in Expert Advisor |
//+------------------------------------------------------------------+
bool CAppDialog::CreateExpert(const int x1,const int y1,const int x2,const int y2)
{
//--- EA works only in main window
m_subwin=0;
//--- geometry for the minimized state
m_min_rect.SetBound(CONTROLS_DIALOG_MINIMIZE_LEFT,
CONTROLS_DIALOG_MINIMIZE_TOP,
CONTROLS_DIALOG_MINIMIZE_LEFT+CONTROLS_DIALOG_MINIMIZE_WIDTH,
CONTROLS_DIALOG_MINIMIZE_TOP+CONTROLS_DIALOG_MINIMIZE_HEIGHT);
//--- call method of the parent class
if(!CDialog::Create(m_chart.ChartId(),m_instance_id,m_subwin,x1,y1,x2,y2))
{
Print("CAppDialog: expert dialog create error");
m_chart.Detach();
return(false);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Initialize in Indicator |
//+------------------------------------------------------------------+
bool CAppDialog::CreateIndicator(const int x1,const int y1,const int x2,const int y2)
{
int width=m_chart.WidthInPixels();
//--- geometry for the minimized state
m_min_rect.LeftTop(0,0);
m_min_rect.Width(width);
m_min_rect.Height(CONTROLS_DIALOG_MINIMIZE_HEIGHT-2*CONTROLS_BORDER_WIDTH);
//--- determine subwindow
m_subwin=ChartWindowFind();
if(m_subwin==-1)
{
Print("CAppDialog: find subwindow error");
m_chart.Detach();
return(false);
}
//---
int total=ChartIndicatorsTotal(m_chart.ChartId(),m_subwin);
m_indicator_name=ChartIndicatorName(m_chart.ChartId(),m_subwin,total-1);
//--- if subwindow number is 0 (main window), then our program is
//--- not an indicator panel, but is an indicator with built-in settings dialog
//--- dialog of such an indicator should behave as an Expert Advisor dialog
if(m_subwin==0)
return(CreateExpert(x1,y1,x2,y2));
//--- if subwindow number is not 0, then our program is an indicator panel
//--- check if subwindow is not occupied by other indicators
if(total!=1)
{
Print("CAppDialog: subwindow busy");
ChartIndicatorDelete(m_chart.ChartId(),m_subwin,ChartIndicatorName(m_chart.ChartId(),m_subwin,total-1));
m_chart.Detach();
return(false);
}
//--- resize subwindow by dialog height
if(!IndicatorSetInteger(INDICATOR_HEIGHT,(y2-y1)+1))
{
Print("CAppDialog: subwindow resize error");
ChartIndicatorDelete(m_chart.ChartId(),m_subwin,ChartIndicatorName(m_chart.ChartId(),m_subwin,total-1));
m_chart.Detach();
return(false);
}
//--- indicator short name
m_indicator_name=m_program_name+IntegerToString(m_subwin);
if(!IndicatorSetString(INDICATOR_SHORTNAME,m_indicator_name))
{
Print("CAppDialog: shortname error");
ChartIndicatorDelete(m_chart.ChartId(),m_subwin,ChartIndicatorName(m_chart.ChartId(),m_subwin,total-1));
m_chart.Detach();
return(false);
}
//--- set flag
m_panel_flag=true;
//--- call method of the parent class
if(!CDialog::Create(m_chart.ChartId(),m_instance_id,m_subwin,0,0,width,y2-y1))
{
Print("CAppDialog: indicator dialog create error");
ChartIndicatorDelete(m_chart.ChartId(),m_subwin,ChartIndicatorName(m_chart.ChartId(),m_subwin,total-1));
m_chart.Detach();
return(false);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Application dialog deinitialization function |
//+------------------------------------------------------------------+
void CAppDialog::Destroy(const int reason)
{
//--- destroyed already?
if(m_deinit_reason!=WRONG_VALUE)
return;
//---
m_deinit_reason=reason;
IniFileSave();
//--- detach chart object from chart
m_chart.Detach();
//--- call parent destroy
CDialog::Destroy();
//---
if(reason==REASON_PROGRAM)
{
if(m_program_type==PROGRAM_EXPERT)
ExpertRemove();
if(m_program_type==PROGRAM_INDICATOR)
ChartIndicatorDelete(m_chart_id,m_subwin,m_indicator_name);
}
//--- send message
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_APP_CLOSE,m_subwin,0.0,m_program_name);
}
//+------------------------------------------------------------------+
//| Calculate subwindow offset |
//+------------------------------------------------------------------+
void CAppDialog::SubwinOff(void)
{
m_subwin_Yoff=m_chart.SubwindowY(m_subwin);
}
//+------------------------------------------------------------------+
//| Create the "Minimize/Maximize" button |
//+------------------------------------------------------------------+
bool CAppDialog::CreateButtonMinMax(void)
{
int off=(m_panel_flag) ? 0:2*CONTROLS_BORDER_WIDTH;
//--- coordinates
int x1=Width()-off-2*(CONTROLS_BUTTON_SIZE+CONTROLS_DIALOG_BUTTON_OFF);
int y1=off+CONTROLS_DIALOG_BUTTON_OFF;
int x2=x1+CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_BUTTON_SIZE;
//--- create
if(!m_button_minmax.Create(m_chart_id,m_name+"MinMax",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_button_minmax.BmpNames("::res\\Turn.bmp","::res\\Restore.bmp"))
return(false);
if(!CWndContainer::Add(m_button_minmax))
return(false);
m_button_minmax.Locking(true);
m_button_minmax.Alignment(WND_ALIGN_RIGHT,0,0,off+CONTROLS_BUTTON_SIZE+2*CONTROLS_DIALOG_BUTTON_OFF,0);
//--- change caption
CaptionAlignment(WND_ALIGN_WIDTH,off,0,off+2*(CONTROLS_BUTTON_SIZE+CONTROLS_DIALOG_BUTTON_OFF),0);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Charts event processing |
//+------------------------------------------------------------------+
void CAppDialog::ChartEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
int mouse_x=(int)lparam;
int mouse_y=(int)dparam-m_subwin_Yoff;
//--- separate mouse events from others
switch(id)
{
case CHARTEVENT_CHART_CHANGE:
//--- assumed that the CHARTEVENT_CHART_CHANGE event can handle only the application dialog
break;
case CHARTEVENT_OBJECT_CLICK:
//--- we won't handle the CHARTEVENT_OBJECT_CLICK event, as we are working with the CHARTEVENT_MOUSE_MOVE events
return;
case CHARTEVENT_CUSTOM+ON_MOUSE_FOCUS_SET:
//--- the CHARTEVENT_CUSTOM + ON_MOUSE_FOCUS_SET event
if(CheckPointer(m_focused_wnd)!=POINTER_INVALID)
{
//--- if there is an element with focus, try to take its focus away
if(!m_focused_wnd.MouseFocusKill(lparam))
return;
}
m_focused_wnd=ControlFind(lparam);
return;
case CHARTEVENT_CUSTOM+ON_BRING_TO_TOP:
m_top_wnd=ControlFind(lparam);
return;
case CHARTEVENT_MOUSE_MOVE:
//--- the CHARTEVENT_MOUSE_MOVE event
if(CheckPointer(m_top_wnd)!=POINTER_INVALID)
{
//--- if a priority element already exists, pass control to it
if(m_top_wnd.OnMouseEvent(mouse_x,mouse_y,(int)StringToInteger(sparam)))
{
//--- event handled
m_chart.Redraw();
return;
}
}
if(OnMouseEvent(mouse_x,mouse_y,(int)StringToInteger(sparam)))
m_chart.Redraw();
return;
default:
//--- call event processing and redraw chart if event handled
if(OnEvent(id,lparam,dparam,sparam))
m_chart.Redraw();
return;
}
//--- if event was not handled, try to handle the CHARTEVENT_CHART_CHANGE event
if(id==CHARTEVENT_CHART_CHANGE)
{
//--- if subwindow number is not 0, and dialog subwindow has changed its number, then restart
if(m_subwin!=0 && m_subwin!=ChartWindowFind())
{
long fiction=1;
OnAnotherApplicationClose(fiction,dparam,sparam);
}
//--- if subwindow height is less that dialog height, minimize application window (always)
if(m_chart.HeightInPixels(m_subwin)<Height()+CONTROLS_BORDER_WIDTH)
{
m_button_minmax.Pressed(true);
Minimize();
m_chart.Redraw();
}
//--- if chart width is less that dialog width, and subwindow number is not 0, try to modify dialog width
if(m_chart.WidthInPixels()!=Width() && m_subwin!=0)
{
Width(m_chart.WidthInPixels());
m_chart.Redraw();
}
//--- get subwindow offset
SubwinOff();
return;
}
}
//+------------------------------------------------------------------+
//| Run application |
//+------------------------------------------------------------------+
bool CAppDialog::Run(void)
{
//--- redraw chart for dialog invalidate
m_chart.Redraw();
//--- here we begin to assign IDs to controls
if(Id(m_subwin*CONTROLS_MAXIMUM_ID)>CONTROLS_MAXIMUM_ID)
{
Print("CAppDialog: too many objects");
return(false);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Stop application |
//+------------------------------------------------------------------+
void CAppDialog::OnClickButtonClose(void)
{
//--- destroy application
Destroy();
}
//+------------------------------------------------------------------+
//| Handler of click on the "Minimize/Maximize" button |
//+------------------------------------------------------------------+
void CAppDialog::OnClickButtonMinMax(void)
{
if(m_button_minmax.Pressed())
Minimize();
else
Maximize();
//--- get subwindow offset
SubwinOff();
}
//+------------------------------------------------------------------+
//| Resize |
//+------------------------------------------------------------------+
bool CAppDialog::Rebound(const CRect &rect)
{
if(!Move(rect.LeftTop()))
return(false);
if(!Size(rect.Size()))
return(false);
//--- resize subwindow
if(m_program_type==PROGRAM_INDICATOR && !IndicatorSetInteger(INDICATOR_HEIGHT,rect.Height()+1))
{
Print("CAppDialog: subwindow resize error");
return(false);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Minimize dialog window |
//+------------------------------------------------------------------+
void CAppDialog::Minimize(void)
{
//--- set flag
m_minimized=true;
//--- resize
Rebound(m_min_rect);
//--- hide client area
ClientAreaVisible(false);
}
//+------------------------------------------------------------------+
//| Restore dialog window |
//+------------------------------------------------------------------+
void CAppDialog::Maximize(void)
{
//--- reset flag
m_minimized=false;
//--- resize
Rebound(m_norm_rect);
//--- show client area
ClientAreaVisible(true);
}
//+------------------------------------------------------------------+
//| Create unique prefix for object names |
//+------------------------------------------------------------------+
string CAppDialog::CreateInstanceId(void)
{
return(IntegerToString(rand(),5,'0'));
}
//+------------------------------------------------------------------+
//| Handler of the ON_APP_CLOSE external event |
//+------------------------------------------------------------------+
void CAppDialog::OnAnotherApplicationClose(const long &lparam,const double &dparam,const string &sparam)
{
//--- exit if we are in the main window
if(m_subwin==0)
return;
//--- exit if external program was closed in main window
if(lparam==0)
return;
//--- get subwindow offset
SubwinOff();
//--- exit if external program was closed in subwindow with greater number
if(lparam>=m_subwin)
return;
//--- after all the checks we must change the subwindow
//--- get the new number of subwindow
m_subwin=ChartWindowFind();
//--- change short name
m_indicator_name=m_program_name+IntegerToString(m_subwin);
IndicatorSetString(INDICATOR_SHORTNAME,m_indicator_name);
//--- change dialog title
Caption(m_program_name);
//--- reassign IDs
Run();
}
//+------------------------------------------------------------------+
//| Save the current state of the program |
//+------------------------------------------------------------------+
void CAppDialog::IniFileSave(void)
{
string filename=IniFileName()+IniFileExt();
int handle=FileOpen(filename,FILE_WRITE|FILE_BIN|FILE_ANSI);
//---
if(handle!=INVALID_HANDLE)
{
Save(handle);
FileClose(handle);
}
}
//+------------------------------------------------------------------+
//| Read the previous state of the program |
//+------------------------------------------------------------------+
void CAppDialog::IniFileLoad(void)
{
string filename=IniFileName()+IniFileExt();
int handle=FileOpen(filename,FILE_READ|FILE_BIN|FILE_ANSI);
//---
if(handle!=INVALID_HANDLE)
{
Load(handle);
FileClose(handle);
}
}
//+------------------------------------------------------------------+
//| Generate the filename |
//+------------------------------------------------------------------+
string CAppDialog::IniFileName(void) const
{
string name;
//---
name=(m_indicator_name!=NULL) ? m_indicator_name : m_program_name;
//---
name+="_"+Symbol();
name+="_Ini";
//---
return(name);
}
//+------------------------------------------------------------------+
//| Load data |
//+------------------------------------------------------------------+
bool CAppDialog::Load(const int file_handle)
{
if(CDialog::Load(file_handle))
{
if(m_minimized)
{
m_button_minmax.Pressed(true);
Minimize();
}
else
{
m_button_minmax.Pressed(false);
Maximize();
}
int prev_deinit_reason=FileReadInteger(file_handle);
if(prev_deinit_reason==REASON_CHARTCLOSE || prev_deinit_reason==REASON_CLOSE)
{
//--- if the previous time program ended after closing the chart window,
//--- delete object left since the last start of the program
string prev_instance_id=IntegerToString(FileReadInteger(file_handle),5,'0');
if(prev_instance_id!=m_instance_id)
{
long chart_id=m_chart.ChartId();
int total=ObjectsTotal(chart_id,m_subwin);
for(int i=total-1;i>=0;i--)
{
string obj_name=ObjectName(chart_id,i,m_subwin);
if(StringFind(obj_name,prev_instance_id)==0)
ObjectDelete(chart_id,obj_name);
}
}
}
return(true);
}
//--- failure
return(false);
}
//+------------------------------------------------------------------+
//| Save data |
//+------------------------------------------------------------------+
bool CAppDialog::Save(const int file_handle)
{
if(CDialog::Save(file_handle))
{
FileWriteInteger(file_handle,m_deinit_reason);
FileWriteInteger(file_handle,(int)StringToInteger(m_instance_id));
return(true);
}
//--- failure
return(false);
}
//+------------------------------------------------------------------+
+187
View File
@@ -0,0 +1,187 @@
//+------------------------------------------------------------------+
//| Edit.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndObj.mqh"
#include <ChartObjects\ChartObjectsTxtControls.mqh>
//+------------------------------------------------------------------+
//| Class CEdit |
//| Usage: control that is displayed by |
//| the CChartObjectEdit object |
//+------------------------------------------------------------------+
class CEdit : public CWndObj
{
private:
CChartObjectEdit m_edit; // chart object
//--- parameters of the chart object
bool m_read_only; // "read-only" mode flag
ENUM_ALIGN_MODE m_align_mode; // align mode
public:
CEdit(void);
~CEdit(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- parameters of the chart object
bool ReadOnly(void) const { return(m_read_only); }
bool ReadOnly(const bool flag);
ENUM_ALIGN_MODE TextAlign(void) const { return(m_align_mode); }
bool TextAlign(const ENUM_ALIGN_MODE align);
//--- data access
string Text(void) const { return(m_edit.Description()); }
protected:
//--- handlers of object events
virtual bool OnObjectEndEdit(void);
//--- handlers of object settings
virtual bool OnSetText(void) { return(m_edit.Description(m_text)); }
virtual bool OnSetColor(void) { return(m_edit.Color(m_color)); }
virtual bool OnSetColorBackground(void) { return(m_edit.BackColor(m_color_background)); }
virtual bool OnSetColorBorder(void) { return(m_edit.BorderColor(m_color_border)); }
virtual bool OnSetFont(void) { return(m_edit.Font(m_font)); }
virtual bool OnSetFontSize(void) { return(m_edit.FontSize(m_font_size)); }
virtual bool OnSetZOrder(void) { return(m_edit.Z_Order(m_zorder)); }
//--- internal event handlers
virtual bool OnCreate(void);
virtual bool OnShow(void);
virtual bool OnHide(void);
virtual bool OnMove(void);
virtual bool OnResize(void);
virtual bool OnChange(void);
virtual bool OnClick(void);
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
bool CEdit::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
if(m_name==sparam && id==CHARTEVENT_OBJECT_ENDEDIT)
return(OnObjectEndEdit());
//--- event was not handled
return(CWndObj::OnEvent(id,lparam,dparam,sparam));
}
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CEdit::CEdit(void) : m_read_only(false),
m_align_mode(ALIGN_LEFT)
{
m_color =CONTROLS_EDIT_COLOR;
m_color_background=CONTROLS_EDIT_COLOR_BG;
m_color_border =CONTROLS_EDIT_COLOR_BORDER;
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CEdit::~CEdit(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CEdit::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- call method of the parent class
if(!CWndObj::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- create the chart object
if(!m_edit.Create(chart,name,subwin,x1,y1,Width(),Height()))
return(false);
//--- call the settings handler
return(OnChange());
}
//+------------------------------------------------------------------+
//| Set parameter |
//+------------------------------------------------------------------+
bool CEdit::ReadOnly(const bool flag)
{
//--- save new value of parameter
m_read_only=flag;
//--- set up the chart object
return(m_edit.ReadOnly(flag));
}
//+------------------------------------------------------------------+
//| Set parameter |
//+------------------------------------------------------------------+
bool CEdit::TextAlign(const ENUM_ALIGN_MODE align)
{
//--- save new value of parameter
m_align_mode=align;
//--- set up the chart object
return(m_edit.TextAlign(align));
}
//+------------------------------------------------------------------+
//| Create object on chart |
//+------------------------------------------------------------------+
bool CEdit::OnCreate(void)
{
//--- create the chart object by previously set parameters
return(m_edit.Create(m_chart_id,m_name,m_subwin,m_rect.left,m_rect.top,m_rect.Width(),m_rect.Height()));
}
//+------------------------------------------------------------------+
//| Display object on chart |
//+------------------------------------------------------------------+
bool CEdit::OnShow(void)
{
return(m_edit.Timeframes(OBJ_ALL_PERIODS));
}
//+------------------------------------------------------------------+
//| Hide object from chart |
//+------------------------------------------------------------------+
bool CEdit::OnHide(void)
{
return(m_edit.Timeframes(OBJ_NO_PERIODS));
}
//+------------------------------------------------------------------+
//| Absolute movement of the chart object |
//+------------------------------------------------------------------+
bool CEdit::OnMove(void)
{
//--- position the chart object
return(m_edit.X_Distance(m_rect.left) && m_edit.Y_Distance(m_rect.top));
}
//+------------------------------------------------------------------+
//| Resize the chart object |
//+------------------------------------------------------------------+
bool CEdit::OnResize(void)
{
//--- resize the chart object
return(m_edit.X_Size(m_rect.Width()) && m_edit.Y_Size(m_rect.Height()));
}
//+------------------------------------------------------------------+
//| Set up the chart object |
//+------------------------------------------------------------------+
bool CEdit::OnChange(void)
{
//--- set up the chart object
return(CWndObj::OnChange() && ReadOnly(m_read_only) && TextAlign(m_align_mode));
}
//+------------------------------------------------------------------+
//| Handler of the "End of editing" event |
//+------------------------------------------------------------------+
bool CEdit::OnObjectEndEdit(void)
{
//--- send the ON_END_EDIT notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_END_EDIT,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of the "click" event |
//+------------------------------------------------------------------+
bool CEdit::OnClick(void)
{
//--- if editing is enabled, send the ON_START_EDIT notification
if(!m_read_only)
{
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_START_EDIT,m_id,0.0,m_name);
//--- handled
return(true);
}
//--- else send the ON_CLICK notification
return(CWnd::OnClick());
}
//+------------------------------------------------------------------+
+93
View File
@@ -0,0 +1,93 @@
//+------------------------------------------------------------------+
//| Label.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndObj.mqh"
#include <ChartObjects\ChartObjectsTxtControls.mqh>
//+------------------------------------------------------------------+
//| Class CLabel |
//| Usage: control that is displayed by |
//| the CChartObjectLabel object |
//+------------------------------------------------------------------+
class CLabel : public CWndObj
{
private:
CChartObjectLabel m_label; // chart object
public:
CLabel(void);
~CLabel(void);
//--- create
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:
//--- handlers of object settings
virtual bool OnSetText(void) { return(m_label.Description(m_text)); }
virtual bool OnSetColor(void) { return(m_label.Color(m_color)); }
virtual bool OnSetFont(void) { return(m_label.Font(m_font)); }
virtual bool OnSetFontSize(void) { return(m_label.FontSize(m_font_size)); }
//--- internal event handlers
virtual bool OnCreate(void);
virtual bool OnShow(void);
virtual bool OnHide(void);
virtual bool OnMove(void);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CLabel::CLabel(void)
{
m_color=CONTROLS_LABEL_COLOR;
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CLabel::~CLabel(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CLabel::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- call method of the parent class
if(!CWndObj::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- create the chart object
if(!m_label.Create(chart,name,subwin,x1,y1))
return(false);
//--- call the settings handler
return(OnChange());
}
//+------------------------------------------------------------------+
//| Create object on chart |
//+------------------------------------------------------------------+
bool CLabel::OnCreate(void)
{
//--- create the chart object by previously set parameters
return(m_label.Create(m_chart_id,m_name,m_subwin,m_rect.left,m_rect.top));
}
//+------------------------------------------------------------------+
//| Display object on chart |
//+------------------------------------------------------------------+
bool CLabel::OnShow(void)
{
return(m_label.Timeframes(OBJ_ALL_PERIODS));
}
//+------------------------------------------------------------------+
//| Hide object from chart |
//+------------------------------------------------------------------+
bool CLabel::OnHide(void)
{
return(m_label.Timeframes(OBJ_NO_PERIODS));
}
//+------------------------------------------------------------------+
//| Absolute movement of the chart object |
//+------------------------------------------------------------------+
bool CLabel::OnMove(void)
{
//--- position the chart object
return(m_label.X_Distance(m_rect.left) && m_label.Y_Distance(m_rect.top));
}
//+------------------------------------------------------------------+
+544
View File
@@ -0,0 +1,544 @@
//+------------------------------------------------------------------+
//| ListView.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndClient.mqh"
#include "Edit.mqh"
#include <Arrays\ArrayString.mqh>
#include <Arrays\ArrayLong.mqh>
//+------------------------------------------------------------------+
//| Class CListView |
//| Usage: display lists |
//+------------------------------------------------------------------+
class CListView : public CWndClient
{
private:
//--- dependent controls
CEdit m_rows[]; // array of the row objects
//--- set up
int m_offset; // index of first visible row in array of rows
int m_total_view; // number of visible rows
int m_item_height; // height of visible row
bool m_height_variable; // ïðèçíàê ïåðåìåííîé âûñîòû ñïèñêà
//--- data
CArrayString m_strings; // array of rows
CArrayLong m_values; // array of values
int m_current; // index of current row in array of rows
public:
CListView(void);
~CListView(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
virtual void Destroy(const int reason=0);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- set up
bool TotalView(const int value);
//--- fill
virtual bool AddItem(const string item,const long value=0);
//--- data
virtual bool ItemAdd(const string item,const long value=0);
virtual bool ItemInsert(const int index,const string item,const long value=0);
virtual bool ItemUpdate(const int index,const string item,const long value=0);
virtual bool ItemDelete(const int index);
virtual bool ItemsClear(void);
//--- data
int Current(void) { return(m_current); }
string Select(void) { return(m_strings.At(m_current)); }
bool Select(const int index);
bool SelectByText(const string text);
bool SelectByValue(const long value);
//--- data (read only)
long Value(void) { return(m_values.At(m_current)); }
//--- state
virtual bool Show(void);
protected:
//--- create dependent controls
bool CreateRow(const int index);
//--- event handlers
virtual bool OnResize(void);
//--- handlers of the dependent controls events
virtual bool OnVScrollShow(void);
virtual bool OnVScrollHide(void);
virtual bool OnScrollLineDown(void);
virtual bool OnScrollLineUp(void);
virtual bool OnItemClick(const int index);
//--- redraw
bool Redraw(void);
bool RowState(const int index,const bool select);
bool CheckView(void);
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CListView)
ON_INDEXED_EVENT(ON_CLICK,m_rows,OnItemClick)
EVENT_MAP_END(CWndClient)
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CListView::CListView(void) : m_offset(0),
m_total_view(0),
m_item_height(CONTROLS_LIST_ITEM_HEIGHT),
m_current(CONTROLS_INVALID_INDEX),
m_height_variable(false)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CListView::~CListView(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CListView::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
int y=y2;
//--- if the number of visible rows is previously determined, adjust the vertical size
if(!TotalView((y2-y1)/m_item_height))
y=m_item_height+y1+2*CONTROLS_BORDER_WIDTH;
//--- check the number of visible rows
if(m_total_view<1)
return(false);
//--- call method of the parent class
if(!CWndClient::Create(chart,name,subwin,x1,y1,x2,y))
return(false);
//--- set up
if(!m_background.ColorBackground(CONTROLS_LIST_COLOR_BG))
return(false);
if(!m_background.ColorBorder(CONTROLS_LIST_COLOR_BORDER))
return(false);
//--- create dependent controls
ArrayResize(m_rows,m_total_view);
for(int i=0;i<m_total_view;i++)
{
if(!CreateRow(i))
return(false);
if(m_height_variable && i>0)
m_rows[i].Hide();
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Delete group of controls |
//+------------------------------------------------------------------+
void CListView::Destroy(const int reason)
{
//--- call of the method of the parent class
CWndClient::Destroy(reason);
//--- clear items
m_strings.Clear();
m_values.Clear();
//---
m_offset =0;
m_total_view=0;
}
//+------------------------------------------------------------------+
//| Set parameter |
//+------------------------------------------------------------------+
bool CListView::TotalView(const int value)
{
//--- if parameter is not equal to 0, modifications are not possible
if(m_total_view!=0)
{
m_height_variable=true;
return(false);
}
//--- save value
m_total_view=value;
//--- parameter has been changed
return(true);
}
//+------------------------------------------------------------------+
//| Makes the control visible |
//+------------------------------------------------------------------+
bool CListView::Show(void)
{
//--- call of the method of the parent class
CWndClient::Show();
//--- number of items
int total=m_strings.Total();
//---
if(total==0)
total=1;
//---
if(m_height_variable && total<m_total_view)
for(int i=total;i<m_total_view;i++)
m_rows[i].Hide();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create "row" |
//+------------------------------------------------------------------+
bool CListView::CreateRow(const int index)
{
//--- calculate coordinates
int x1=CONTROLS_BORDER_WIDTH;
int y1=CONTROLS_BORDER_WIDTH+m_item_height*index;
int x2=Width()-2*CONTROLS_BORDER_WIDTH;
int y2=y1+m_item_height;
//--- create
if(!m_rows[index].Create(m_chart_id,m_name+"Item"+IntegerToString(index),m_subwin,x1,y1,x2,y2))
return(false);
if(!m_rows[index].Text(""))
return(false);
if(!m_rows[index].ReadOnly(true))
return(false);
if(!RowState(index,false))
return(false);
if(!Add(m_rows[index]))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Add item (row) |
//+------------------------------------------------------------------+
bool CListView::AddItem(const string item,const long value)
{
//--- method left for compatibility with previous version
return(ItemAdd(item,value));
}
//+------------------------------------------------------------------+
//| Add item (row) |
//+------------------------------------------------------------------+
bool CListView::ItemAdd(const string item,const long value)
{
//--- add
if(!m_strings.Add(item))
return(false);
if(!m_values.Add((value)?value:m_values.Total()))
return(false);
//--- number of items
int total=m_strings.Total();
//--- exit if number of items does not exceed the size of visible area
if(total<m_total_view+1)
{
if(m_height_variable && total!=1)
{
Height(total*m_item_height+2*CONTROLS_BORDER_WIDTH);
if(IS_VISIBLE)
m_rows[total-1].Show();
}
return(Redraw());
}
//--- if number of items exceeded the size of visible area
if(total==m_total_view+1)
{
//--- enable vertical scrollbar
if(!VScrolled(true))
return(false);
//--- and immediately make it invisible (if needed)
if(IS_VISIBLE && !OnVScrollShow())
return(false);
}
//--- set up the scrollbar
m_scroll_v.MaxPos(m_strings.Total()-m_total_view);
//--- redraw
return(Redraw());
}
//+------------------------------------------------------------------+
//| Insert item (row) |
//+------------------------------------------------------------------+
bool CListView::ItemInsert(const int index,const string item,const long value)
{
//--- insert
if(!m_strings.Insert(item,index))
return(false);
if(!m_values.Insert(value,index))
return(false);
//--- number of items
int total=m_strings.Total();
//--- exit if number of items does not exceed the size of visible area
if(total<m_total_view+1)
{
if(m_height_variable && total!=1)
{
Height(total*m_item_height+2*CONTROLS_BORDER_WIDTH);
if(IS_VISIBLE)
m_rows[total-1].Show();
}
return(Redraw());
}
//--- if number of items exceeded the size of visible area
if(total==m_total_view+1)
{
//--- enable vertical scrollbar
if(!VScrolled(true))
return(false);
//--- and immediately make it invisible (if needed)
if(IS_VISIBLE && !OnVScrollShow())
return(false);
}
//--- set up the scrollbar
m_scroll_v.MaxPos(m_strings.Total()-m_total_view);
//--- redraw
return(Redraw());
}
//+------------------------------------------------------------------+
//| Update item (row) |
//+------------------------------------------------------------------+
bool CListView::ItemUpdate(const int index,const string item,const long value)
{
//--- update
if(!m_strings.Update(index,item))
return(false);
if(!m_values.Update(index,value))
return(false);
//--- redraw
return(Redraw());
}
//+------------------------------------------------------------------+
//| Delete item (row) |
//+------------------------------------------------------------------+
bool CListView::ItemDelete(const int index)
{
//--- delete
if(!m_strings.Delete(index))
return(false);
if(!m_values.Delete(index))
return(false);
//--- number of items
int total=m_strings.Total();
//--- exit if number of items does not exceed the size of visible area
if(total<m_total_view)
{
if(m_height_variable && total!=0)
{
Height(total*m_item_height+2*CONTROLS_BORDER_WIDTH);
m_rows[total].Hide();
}
return(Redraw());
}
//--- if number of items exceeded the size of visible area
if(total==m_total_view)
{
//--- disable vertical scrollbar
if(!VScrolled(false))
return(false);
//--- and immediately make it unvisible
if(!OnVScrollHide())
return(false);
}
//--- set up the scrollbar
m_scroll_v.MaxPos(m_strings.Total()-m_total_view);
//--- redraw
return(Redraw());
}
//+------------------------------------------------------------------+
//| Delete all items |
//+------------------------------------------------------------------+
bool CListView::ItemsClear(void)
{
m_offset=0;
//--- clear
if(!m_strings.Shutdown())
return(false);
if(!m_values.Shutdown())
return(false);
//---
if(m_height_variable)
{
Height(m_item_height+2*CONTROLS_BORDER_WIDTH);
for(int i=1;i<m_total_view;i++)
m_rows[i].Hide();
}
//--- disable vertical scrollbar
if(!VScrolled(false))
return(false);
//--- and immediately make it unvisible (if needed)
if(!OnVScrollHide())
return(false);
//--- redraw
return(Redraw());
}
//+------------------------------------------------------------------+
//| Sett current item |
//+------------------------------------------------------------------+
bool CListView::Select(const int index)
{
//--- check index
if(index>=m_strings.Total())
return(false);
if(index<0 && index!=CONTROLS_INVALID_INDEX)
return(false);
//--- unselect
if(m_current!=CONTROLS_INVALID_INDEX)
RowState(m_current-m_offset,false);
//--- select
if(index!=CONTROLS_INVALID_INDEX)
RowState(index-m_offset,true);
//--- save value
m_current=index;
//--- succeed
return(CheckView());
}
//+------------------------------------------------------------------+
//| Set current item (by text) |
//+------------------------------------------------------------------+
bool CListView::SelectByText(const string text)
{
//--- find text
int index=m_strings.SearchLinear(text);
//--- if text is not found, exit without changing the selection
if(index==CONTROLS_INVALID_INDEX)
return(false);
//--- change selection
return(Select(index));
}
//+------------------------------------------------------------------+
//| Set current item (by value) |
//+------------------------------------------------------------------+
bool CListView::SelectByValue(const long value)
{
//--- find value
int index=m_values.SearchLinear(value);
//--- if value is not found, exit without changing the selection
if(index==CONTROLS_INVALID_INDEX)
return(false);
//--- change selection
return(Select(index));
}
//+------------------------------------------------------------------+
//| Redraw |
//+------------------------------------------------------------------+
bool CListView::Redraw(void)
{
//--- loop by "rows"
for(int i=0;i<m_total_view;i++)
{
//--- copy text
if(!m_rows[i].Text(m_strings.At(i+m_offset)))
return(false);
//--- select
if(!RowState(i,(m_current==i+m_offset)))
return(false);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Change state |
//+------------------------------------------------------------------+
bool CListView::RowState(const int index,const bool select)
{
//--- check index
if(index<0 || index>=ArraySize(m_rows))
return(true);
//--- determine colors
color text_color=(select) ? CONTROLS_LISTITEM_COLOR_TEXT_SEL : CONTROLS_LISTITEM_COLOR_TEXT;
color back_color=(select) ? CONTROLS_LISTITEM_COLOR_BG_SEL : CONTROLS_LISTITEM_COLOR_BG;
//--- get pointer
CEdit *item=GetPointer(m_rows[index]);
//--- recolor the "row"
return(item.Color(text_color) && item.ColorBackground(back_color) && item.ColorBorder(back_color));
}
//+------------------------------------------------------------------+
//| Check visibility of selected row |
//+------------------------------------------------------------------+
bool CListView::CheckView(void)
{
//--- check visibility
if(m_current>=m_offset && m_current<m_offset+m_total_view)
return(true);
//--- selected row is not visible
int total=m_strings.Total();
m_offset=(total-m_current>m_total_view) ? m_current : total-m_total_view;
//--- adjust the scrollbar
m_scroll_v.CurrPos(m_offset);
//--- redraw
return(Redraw());
}
//+------------------------------------------------------------------+
//| Handler of resizing |
//+------------------------------------------------------------------+
bool CListView::OnResize(void)
{
//--- call of the method of the parent class
if(!CWndClient::OnResize())
return(false);
//--- set up the size of "row"
if(VScrolled())
OnVScrollShow();
else
OnVScrollHide();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Handler of the "Show vertical scrollbar" event |
//+------------------------------------------------------------------+
bool CListView::OnVScrollShow(void)
{
//--- loop by "rows"
for(int i=0;i<m_total_view;i++)
{
//--- resize "rows" according to shown vertical scrollbar
m_rows[i].Width(Width()-(CONTROLS_SCROLL_SIZE+CONTROLS_BORDER_WIDTH));
}
//--- check visibility
if(!IS_VISIBLE)
{
m_scroll_v.Visible(false);
return(true);
}
//--- event is handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of the "Hide vertical scrollbar" event |
//+------------------------------------------------------------------+
bool CListView::OnVScrollHide(void)
{
//--- check visibility
if(!IS_VISIBLE)
return(true);
//--- loop by "rows"
for(int i=0;i<m_total_view;i++)
{
//--- resize "rows" according to hidden vertical scroll bar
m_rows[i].Width(Width()-2*CONTROLS_BORDER_WIDTH);
}
//--- event is handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of the "Scroll up for one row" event |
//+------------------------------------------------------------------+
bool CListView::OnScrollLineUp(void)
{
//--- get new offset
m_offset=m_scroll_v.CurrPos();
//--- redraw
return(Redraw());
}
//+------------------------------------------------------------------+
//| Handler of the "Scroll down for one row" event |
//+------------------------------------------------------------------+
bool CListView::OnScrollLineDown(void)
{
//--- get new offset
m_offset=m_scroll_v.CurrPos();
//--- redraw
return(Redraw());
}
//+------------------------------------------------------------------+
//| Handler of click on row |
//+------------------------------------------------------------------+
bool CListView::OnItemClick(const int index)
{
//--- select "row"
Select(index+m_offset);
//--- send notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
+124
View File
@@ -0,0 +1,124 @@
//+------------------------------------------------------------------+
//| Panel.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndObj.mqh"
#include <ChartObjects\ChartObjectsTxtControls.mqh>
//+------------------------------------------------------------------+
//| Class CPanel |
//| Usage: control that is displayed by |
//| the CChartObjectRectLabel object |
//+------------------------------------------------------------------+
class CPanel : public CWndObj
{
private:
CChartObjectRectLabel m_rectangle; // chart object
//--- parameters of the chart object
ENUM_BORDER_TYPE m_border; // border type
public:
CPanel(void);
~CPanel(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
//--- parameters of the chart object
ENUM_BORDER_TYPE BorderType(void) const { return(m_border); }
bool BorderType(const ENUM_BORDER_TYPE type);
protected:
//--- handlers of object settings
virtual bool OnSetText(void) { return(m_rectangle.Description(m_text)); }
virtual bool OnSetColorBackground(void) { return(m_rectangle.BackColor(m_color_background)); }
virtual bool OnSetColorBorder(void) { return(m_rectangle.Color(m_color_border)); }
//--- internal event handlers
virtual bool OnCreate(void);
virtual bool OnShow(void);
virtual bool OnHide(void);
virtual bool OnMove(void);
virtual bool OnResize(void);
virtual bool OnChange(void);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CPanel::CPanel(void) : m_border(BORDER_FLAT)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CPanel::~CPanel(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CPanel::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- call method of the parent class
if(!CWndObj::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- create the chart object
if(!m_rectangle.Create(chart,name,subwin,x1,y1,Width(),Height()))
return(false);
//--- call the settings handler
return(OnChange());
}
//+------------------------------------------------------------------+
//| Set border type |
//+------------------------------------------------------------------+
bool CPanel::BorderType(const ENUM_BORDER_TYPE type)
{
//--- save new value of parameter
m_border=type;
//--- set up the chart object
return(m_rectangle.BorderType(type));
}
//+------------------------------------------------------------------+
//| Create object on chart |
//+------------------------------------------------------------------+
bool CPanel::OnCreate(void)
{
//--- create the chart object by previously set parameters
return(m_rectangle.Create(m_chart_id,m_name,m_subwin,m_rect.left,m_rect.top,m_rect.Width(),m_rect.Height()));
}
//+------------------------------------------------------------------+
//| Display object on chart |
//+------------------------------------------------------------------+
bool CPanel::OnShow(void)
{
return(m_rectangle.Timeframes(OBJ_ALL_PERIODS));
}
//+------------------------------------------------------------------+
//| Hide object from chart |
//+------------------------------------------------------------------+
bool CPanel::OnHide(void)
{
return(m_rectangle.Timeframes(OBJ_NO_PERIODS));
}
//+------------------------------------------------------------------+
//| Absolute movement of the chart object |
//+------------------------------------------------------------------+
bool CPanel::OnMove(void)
{
//--- position the chart object
return(m_rectangle.X_Distance(m_rect.left) && m_rectangle.Y_Distance(m_rect.top));
}
//+------------------------------------------------------------------+
//| Resize the chart object |
//+------------------------------------------------------------------+
bool CPanel::OnResize(void)
{
//--- resize the chart object
return(m_rectangle.X_Size(m_rect.Width()) && m_rectangle.Y_Size(m_rect.Height()));
}
//+------------------------------------------------------------------+
//| Set up the chart object |
//+------------------------------------------------------------------+
bool CPanel::OnChange(void)
{
//--- set up the chart object
return(CWndObj::OnChange() && m_rectangle.BorderType(m_border));
}
//+------------------------------------------------------------------+
+125
View File
@@ -0,0 +1,125 @@
//+------------------------------------------------------------------+
//| Picture.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndObj.mqh"
#include <ChartObjects\ChartObjectsBmpControls.mqh>
//+------------------------------------------------------------------+
//| Class CPicture |
//| Note: image displayed by |
//| the CChartObjectBmpLabel object |
//+------------------------------------------------------------------+
class CPicture : public CWndObj
{
private:
CChartObjectBmpLabel m_picture; // chart object
//--- parameters of the chart object
int m_border; // border width
string m_bmp_name; // filename
public:
CPicture(void);
~CPicture(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
//--- parameters of the chart object
int Border(void) const { return(m_border); }
bool Border(const int value);
string BmpName(void) const { return(m_bmp_name); }
bool BmpName(const string name);
protected:
//--- internal event handlers
virtual bool OnCreate(void);
virtual bool OnShow(void);
virtual bool OnHide(void);
virtual bool OnMove(void);
virtual bool OnChange(void);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CPicture::CPicture(void) : m_border(0),
m_bmp_name(NULL)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CPicture::~CPicture(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CPicture::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- call method of the parent class
if(!CWndObj::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- create the chart object
if(!m_picture.Create(chart,name,subwin,x1,y1))
return(false);
//--- call the settings handler
return(OnChange());
}
//+------------------------------------------------------------------+
//| Set border width |
//+------------------------------------------------------------------+
bool CPicture::Border(const int value)
{
//--- save new value of parameter
m_border=value;
//--- set up the chart object
return(m_picture.Width(value));
}
//+------------------------------------------------------------------+
//| Set image |
//+------------------------------------------------------------------+
bool CPicture::BmpName(const string name)
{
//--- save new value of parameter
m_bmp_name=name;
//--- set up the chart object
return(m_picture.BmpFileOn(name));
}
//+------------------------------------------------------------------+
//| Create object on chart |
//+------------------------------------------------------------------+
bool CPicture::OnCreate(void)
{
//--- create the chart object by previously set parameters
return(m_picture.Create(m_chart_id,m_name,m_subwin,m_rect.left,m_rect.top));
}
//+------------------------------------------------------------------+
//| Display object on chart |
//+------------------------------------------------------------------+
bool CPicture::OnShow(void)
{
return(m_picture.Timeframes(OBJ_ALL_PERIODS));
}
//+------------------------------------------------------------------+
//| Hide object from chart |
//+------------------------------------------------------------------+
bool CPicture::OnHide(void)
{
return(m_picture.Timeframes(OBJ_NO_PERIODS));
}
//+------------------------------------------------------------------+
//| Absolute movement of the chart object |
//+------------------------------------------------------------------+
bool CPicture::OnMove(void)
{
//--- position the chart object
return(m_picture.X_Distance(m_rect.left) && m_picture.Y_Distance(m_rect.top));
}
//+------------------------------------------------------------------+
//| Set up the chart object |
//+------------------------------------------------------------------+
bool CPicture::OnChange(void)
{
//--- set up the chart object
return(m_picture.Width(m_border) && m_picture.BmpFileOn(m_bmp_name));
}
//+------------------------------------------------------------------+
+160
View File
@@ -0,0 +1,160 @@
//+------------------------------------------------------------------+
//| RadioButton.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndContainer.mqh"
#include "BmpButton.mqh"
#include "Edit.mqh"
//+------------------------------------------------------------------+
//| Resources |
//+------------------------------------------------------------------+
#resource "res\\RadioButtonOn.bmp"
#resource "res\\RadioButtonOff.bmp"
//+------------------------------------------------------------------+
//| Class CRadioButton |
//| Usage: class that implements the "RadioButton" control |
//+------------------------------------------------------------------+
class CRadioButton : public CWndContainer
{
private:
//--- dependent controls
CBmpButton m_button; // button object
CEdit m_label; // label object
public:
CRadioButton(void);
~CRadioButton(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- settings
string Text(void) const { return(m_label.Text()); }
bool Text(const string value) { return(m_label.Text(value)); }
color Color(void) const { return(m_label.Color()); }
bool Color(const color value) { return(m_label.Color(value)); }
//--- state
bool State(void) const { return(m_button.Pressed()); }
bool State(const bool flag) { return(m_button.Pressed(flag)); }
protected:
//--- create dependent controls
virtual bool CreateButton(void);
virtual bool CreateLabel(void);
//--- handlers of the dependent controls events
virtual bool OnClickButton(void);
virtual bool OnClickLabel(void);
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CRadioButton)
ON_EVENT(ON_CLICK,m_button,OnClickButton)
ON_EVENT(ON_CLICK,m_label,OnClickLabel)
EVENT_MAP_END(CWndContainer)
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CRadioButton::CRadioButton(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CRadioButton::~CRadioButton(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CRadioButton::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- call method of the parent class
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- create dependent controls
if(!CreateButton())
return(false);
if(!CreateLabel())
return(false);
//--- succeeded
return(true);
}
//+------------------------------------------------------------------+
//| Create button |
//+------------------------------------------------------------------+
bool CRadioButton::CreateButton(void)
{
//--- calculate coordinates
int x1=CONTROLS_RADIO_BUTTON_X_OFF;
int y1=CONTROLS_RADIO_BUTTON_Y_OFF;
int x2=x1+CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_BUTTON_SIZE-CONTROLS_BORDER_WIDTH;
//--- create
if(!m_button.Create(m_chart_id,m_name+"Button",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_button.BmpNames("::res\\RadioButtonOff.bmp","::res\\RadioButtonOn.bmp"))
return(false);
if(!Add(m_button))
return(false);
m_button.Locking(true);
//--- succeeded
return(true);
}
//+------------------------------------------------------------------+
//| Create label |
//+------------------------------------------------------------------+
bool CRadioButton::CreateLabel(void)
{
//--- calculate coordinates
int x1=CONTROLS_RADIO_LABEL_X_OFF;
int y1=CONTROLS_RADIO_LABEL_Y_OFF;
int x2=Width();
int y2=Height();
//--- create
if(!m_label.Create(m_chart_id,m_name+"Label",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_label.Text(m_name))
return(false);
if(!Add(m_label))
return(false);
m_label.ReadOnly(true);
m_label.ColorBackground(CONTROLS_CHECKGROUP_COLOR_BG);
m_label.ColorBorder(CONTROLS_CHECKGROUP_COLOR_BG);
//--- succeeded
return(true);
}
//+------------------------------------------------------------------+
//| Handler of click on button |
//+------------------------------------------------------------------+
bool CRadioButton::OnClickButton(void)
{
//--- if button is in the "turned off" state, turn it on again and complete the handling
//--- this is due to that radio button can not be turned off by clicking on it (it can be only turned on)
if(!m_button.Pressed())
{
//--- turn on the radio button
if(!m_button.Pressed(true))
return(false);
}
//--- send the "changed state" event
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of click on label |
//+------------------------------------------------------------------+
bool CRadioButton::OnClickLabel(void)
{
//--- if button is in the "turned on" state, simply complete the handling
//--- this is due to that radio button can not be turned off by clicking on it (it can be only turned on)
if(m_button.Pressed())
return(true);
//--- turn on the radio button
m_button.Pressed(true);
//--- return the result of the button click handler
return(OnClickButton());
}
//+------------------------------------------------------------------+
+361
View File
@@ -0,0 +1,361 @@
//+------------------------------------------------------------------+
//| RadioGroup.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndClient.mqh"
#include "RadioButton.mqh"
#include <Arrays\ArrayString.mqh>
#include <Arrays\ArrayLong.mqh>
//+------------------------------------------------------------------+
//| Class CRadioGroup |
//| Usage: view and edit radio buttons |
//+------------------------------------------------------------------+
class CRadioGroup : public CWndClient
{
private:
//--- dependent controls
CRadioButton m_rows[]; // array of the row objects
//--- set up
int m_offset; // index of first visible row in array of rows
int m_total_view; // number of visible rows
int m_item_height; // height of visible row
//--- data
CArrayString m_strings; // array of rows
CArrayLong m_values; // array of values
int m_current; // index of current row in array of rows
public:
CRadioGroup(void);
~CRadioGroup(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
virtual void Destroy(const int reason=0);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- fill
virtual bool AddItem(const string item,const long value=0);
//--- data
long Value(void) const { return(m_values.At(m_current)); }
bool Value(const long value);
bool ValueCheck(long value) const;
//--- state
virtual bool Show(void);
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
protected:
//--- create dependent controls
bool CreateButton(const int index);
//--- handlers of the dependent controls events
virtual bool OnVScrollShow(void);
virtual bool OnVScrollHide(void);
virtual bool OnScrollLineDown(void);
virtual bool OnScrollLineUp(void);
virtual bool OnChangeItem(const int row_index);
//--- redraw
bool Redraw(void);
bool RowState(const int index,const bool select);
void Select(const int index);
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CRadioGroup)
ON_INDEXED_EVENT(ON_CHANGE,m_rows,OnChangeItem)
EVENT_MAP_END(CWndClient)
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CRadioGroup::CRadioGroup(void) : m_offset(0),
m_total_view(0),
m_item_height(CONTROLS_LIST_ITEM_HEIGHT),
m_current(CONTROLS_INVALID_INDEX)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CRadioGroup::~CRadioGroup(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CRadioGroup::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- determine the number of visible rows
m_total_view=(y2-y1)/m_item_height;
//--- check the number of visible rows
if(m_total_view<1)
return(false);
//--- call method of the parent class
if(!CWndClient::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- set up
if(!m_background.ColorBackground(CONTROLS_RADIOGROUP_COLOR_BG))
return(false);
if(!m_background.ColorBorder(CONTROLS_RADIOGROUP_COLOR_BORDER))
return(false);
//--- create dependent controls
ArrayResize(m_rows,m_total_view);
for(int i=0;i<m_total_view;i++)
if(!CreateButton(i))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Delete group of controls |
//+------------------------------------------------------------------+
void CRadioGroup::Destroy(const int reason)
{
//--- call of the method of the parent class
CWndClient::Destroy(reason);
//--- clear items
m_strings.Clear();
m_values.Clear();
}
//+------------------------------------------------------------------+
//| Create "row" |
//+------------------------------------------------------------------+
bool CRadioGroup::CreateButton(const int index)
{
//--- calculate coordinates
int x1=CONTROLS_BORDER_WIDTH;
int y1=CONTROLS_BORDER_WIDTH+m_item_height*index;
int x2=Width()-CONTROLS_BORDER_WIDTH;
int y2=y1+m_item_height;
//--- create
if(!m_rows[index].Create(m_chart_id,m_name+"Item"+IntegerToString(index),m_subwin,x1,y1,x2,y2))
return(false);
if(!m_rows[index].Text(""))
return(false);
if(!Add(m_rows[index]))
return(false);
m_rows[index].Hide();
//---
return(true);
}
//+------------------------------------------------------------------+
//| Add item (row) |
//+------------------------------------------------------------------+
bool CRadioGroup::AddItem(const string item,const long value)
{
//--- check value
if(value!=0 && !ValueCheck(value))
return(false);
//--- add
if(!m_strings.Add(item))
return(false);
if(!m_values.Add(value))
return(false);
//--- number of items
int total=m_strings.Total();
//--- exit if number of items does not exceed the size of visible area
if(total<m_total_view+1)
{
if(IS_VISIBLE && total!=0)
m_rows[total-1].Show();
return(Redraw());
}
//--- if number of items exceeded the size of visible area
if(total==m_total_view+1)
{
//--- enable vertical scrollbar
if(!VScrolled(true))
return(false);
//--- and immediately make it invisible (if needed)
if(!IS_VISIBLE)
m_scroll_v.Visible(false);
}
//--- set up the scrollbar
m_scroll_v.MaxPos(m_strings.Total()-m_total_view);
//--- redraw
return(Redraw());
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CRadioGroup::Value(const long value)
{
//--- çíà÷åíèå äîëæíî ïðèñóòñòâîâàòü â íàáîðå
int total=m_values.Total();
//---
for(int i=0;i<total;i++)
if(m_values.At(i)==value)
Select(i+m_offset);
//---
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CRadioGroup::ValueCheck(long value) const
{
//--- ïðîâåðÿåìîå çíà÷åíèå íå äîëæíî äóáëèðîâàòü óæå ñóùåñòâóþùåå
int total=m_values.Total();
//---
for(int i=0;i<total;i++)
if(m_values.At(i)==value)
return(false);
//---
return(true);
}
//+------------------------------------------------------------------+
//| Makes the group visible |
//+------------------------------------------------------------------+
bool CRadioGroup::Show(void)
{
//--- call of the method of the parent class
if(!CWndClient::Show())
return(false);
//--- loop by rows
int total=m_values.Total();
for(int i=total;i<m_total_view;i++)
m_rows[i].Hide();
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CRadioGroup::Save(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//---
FileWriteLong(file_handle,Value());
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CRadioGroup::Load(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//---
if(!FileIsEnding(file_handle))
Value(FileReadLong(file_handle));
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Sett current item |
//+------------------------------------------------------------------+
void CRadioGroup::Select(const int index)
{
//--- disable the "ON" state
if(m_current!=-1)
RowState(m_current-m_offset,false);
//--- enable the "ON" state
if(index!=-1)
RowState(index-m_offset,true);
//--- save value
m_current=index;
}
//+------------------------------------------------------------------+
//| Redraw |
//+------------------------------------------------------------------+
bool CRadioGroup::Redraw(void)
{
//--- loop by "rows"
for(int i=0;i<m_total_view;i++)
{
//--- copy text
if(!m_rows[i].Text(m_strings.At(i+m_offset)))
return(false);
//--- select
if(!RowState(i,(m_current==i+m_offset)))
return(false);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Change state |
//+------------------------------------------------------------------+
bool CRadioGroup::RowState(const int index,const bool select)
{
//--- check index
if(index<0 || index>=ArraySize(m_rows))
return(true);
//--- change state
return(m_rows[index].State(select));
}
//+------------------------------------------------------------------+
//| Handler of the "Show vertical scrollbar" event |
//+------------------------------------------------------------------+
bool CRadioGroup::OnVScrollShow(void)
{
//--- loop by "rows"
for(int i=0;i<m_total_view;i++)
{
//--- resize "rows" according to shown vertical scrollbar
m_rows[i].Width(Width()-(CONTROLS_SCROLL_SIZE+CONTROLS_BORDER_WIDTH));
}
//--- check visibility
if(!IS_VISIBLE)
{
m_scroll_v.Visible(false);
return(true);
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| Handler of the "Hide vertical scrollbar" event |
//+------------------------------------------------------------------+
bool CRadioGroup::OnVScrollHide(void)
{
//--- check visibility
if(!IS_VISIBLE)
return(true);
//--- loop by "rows"
for(int i=0;i<m_total_view;i++)
{
//--- resize "rows" according to hidden vertical scroll bar
m_rows[i].Width(Width()-CONTROLS_BORDER_WIDTH);
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| Handler of the "Scroll up for one row" event |
//+------------------------------------------------------------------+
bool CRadioGroup::OnScrollLineUp(void)
{
//--- get new offset
m_offset=m_scroll_v.CurrPos();
//--- redraw
return(Redraw());
}
//+------------------------------------------------------------------+
//| Handler of the "Scroll down for one row" event |
//+------------------------------------------------------------------+
bool CRadioGroup::OnScrollLineDown(void)
{
//--- get new offset
m_offset=m_scroll_v.CurrPos();
//--- redraw
return(Redraw());
}
//+------------------------------------------------------------------+
//| Handler of changing a "row" state |
//+------------------------------------------------------------------+
bool CRadioGroup::OnChangeItem(const int row_index)
{
//--- select "row"
Select(row_index+m_offset);
//--- send notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
+279
View File
@@ -0,0 +1,279 @@
//+------------------------------------------------------------------+
//| Rect.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Structure CPoint |
//| Usage: point of chart in Cartesian coordinates |
//+------------------------------------------------------------------+
struct CPoint
{
int x; // horizontal coordinate
int y; // vertical coordinate
};
//+------------------------------------------------------------------+
//| Structure CSize |
//| Usage: size of area of chart in Cartesian coordinates |
//+------------------------------------------------------------------+
struct CSize
{
int cx; // horizontal size
int cy; // vertical size
};
//+------------------------------------------------------------------+
//| Structure CRect |
//| Usage: area of chart in Cartesian coordinates |
//+------------------------------------------------------------------+
struct CRect
{
int left; // left coordinate
int top; // top coordinate
int right; // right coordinate
int bottom; // bottom coordinate
//--- methods
CPoint LeftTop(void) const;
void LeftTop(const int x,const int y);
void LeftTop(const CPoint& point);
CPoint RightBottom(void) const;
void RightBottom(const int x,const int y);
void RightBottom(const CPoint& point);
CPoint CenterPoint(void) const;
int Width(void) const { return(right-left); }
void Width(const int w) { right=left+w; }
int Height(void) const { return(bottom-top); }
void Height(const int h) { bottom=top+h; }
CSize Size(void) const;
void Size(const int cx,const int cy);
void Size(const CSize& size);
void SetBound(const int l,const int t,const int r,const int b);
void SetBound(const CRect& rect);
void SetBound(const CPoint& point,const CSize& size);
void SetBound(const CPoint& left_top,const CPoint& right_bottom);
void Move(const int x,const int y);
void Move(const CPoint& point);
void Shift(const int dx,const int dy);
void Shift(const CPoint& point);
void Shift(const CSize& size);
bool Contains(const int x,const int y) const;
bool Contains(const CPoint& point) const;
void Normalize(void);
};
//+------------------------------------------------------------------+
//| Get parameters of area |
//+------------------------------------------------------------------+
CPoint CRect::LeftTop(void) const
{
CPoint point;
//--- action
point.x=left;
point.y=top;
//--- result
return(point);
}
//+------------------------------------------------------------------+
//| Set parameters of area |
//+------------------------------------------------------------------+
void CRect::LeftTop(const int x,const int y)
{
left=x;
top =y;
}
//+------------------------------------------------------------------+
//| Set parameters of area |
//+------------------------------------------------------------------+
void CRect::LeftTop(const CPoint& point)
{
left=point.x;
top =point.y;
}
//+------------------------------------------------------------------+
//| Get parameters of area |
//+------------------------------------------------------------------+
CPoint CRect::RightBottom(void) const
{
CPoint point;
//--- action
point.x=right;
point.y=bottom;
//--- result
return(point);
}
//+------------------------------------------------------------------+
//| Set parameters of area |
//+------------------------------------------------------------------+
void CRect::RightBottom(const int x,const int y)
{
right =x;
bottom=y;
}
//+------------------------------------------------------------------+
//| Set parameters of area |
//+------------------------------------------------------------------+
void CRect::RightBottom(const CPoint& point)
{
right =point.x;
bottom=point.y;
}
//+------------------------------------------------------------------+
//| Get parameters of area |
//+------------------------------------------------------------------+
CPoint CRect::CenterPoint(void) const
{
CPoint point;
//--- action
point.x=left+Width()/2;
point.y=top+Height()/2;
//--- result
return(point);
}
//+------------------------------------------------------------------+
//| Get parameters of area |
//+------------------------------------------------------------------+
CSize CRect::Size(void) const
{
CSize size;
//--- action
size.cx=right-left;
size.cy=bottom-top;
//--- result
return(size);
}
//+------------------------------------------------------------------+
//| Set parameters of area |
//+------------------------------------------------------------------+
void CRect::Size(const int cx,const int cy)
{
right =left+cx;
bottom=top+cy;
}
//+------------------------------------------------------------------+
//| Set parameters of area |
//+------------------------------------------------------------------+
void CRect::Size(const CSize& size)
{
right =left+size.cx;
bottom=top+size.cy;
}
//+------------------------------------------------------------------+
//| Set parameters of area |
//+------------------------------------------------------------------+
void CRect::SetBound(const int l,const int t,const int r,const int b)
{
left =l;
top =t;
right =r;
bottom=b;
}
//+------------------------------------------------------------------+
//| Set parameters of area |
//+------------------------------------------------------------------+
void CRect::SetBound(const CRect& rect)
{
left =rect.left;
top =rect.top;
right =rect.right;
bottom=rect.bottom;
}
//+------------------------------------------------------------------+
//| Set parameters of area |
//+------------------------------------------------------------------+
void CRect::SetBound(const CPoint& point,const CSize& size)
{
LeftTop(point);
Size(size);
}
//+------------------------------------------------------------------+
//| Set parameters of area |
//+------------------------------------------------------------------+
void CRect::SetBound(const CPoint& left_top,const CPoint& right_bottom)
{
LeftTop(left_top);
RightBottom(right_bottom);
}
//+------------------------------------------------------------------+
//| Absolute movement of area |
//+------------------------------------------------------------------+
void CRect::Move(const int x,const int y)
{
right +=x-left;
bottom+=y-top;
left =x;
top =y;
}
//+------------------------------------------------------------------+
//| Absolute movement of area |
//+------------------------------------------------------------------+
void CRect::Move(const CPoint& point)
{
right +=point.x-left;
bottom+=point.y-top;
left =point.x;
top =point.y;
}
//+------------------------------------------------------------------+
//| Relative movement of area |
//+------------------------------------------------------------------+
void CRect::Shift(const int dx,const int dy)
{
left +=dx;
top +=dy;
right +=dx;
bottom+=dy;
}
//+------------------------------------------------------------------+
//| Relative movement of area |
//+------------------------------------------------------------------+
void CRect::Shift(const CPoint& point)
{
left +=point.x;
top +=point.y;
right +=point.x;
bottom+=point.y;
}
//+------------------------------------------------------------------+
//| Relative movement of area |
//+------------------------------------------------------------------+
void CRect::Shift(const CSize& size)
{
left +=size.cx;
top +=size.cy;
right +=size.cx;
bottom+=size.cy;
}
//+------------------------------------------------------------------+
//| Check if a point is within the area |
//+------------------------------------------------------------------+
bool CRect::Contains(const int x,const int y) const
{
//--- check and return the result
return(x>=left && x<=right && y>=top && y<=bottom);
}
//+------------------------------------------------------------------+
//| Check if a point is within the area |
//+------------------------------------------------------------------+
bool CRect::Contains(const CPoint& point) const
{
//--- check and return the result
return(point.x>=left && point.x<=right && point.y>=top && point.y<=bottom);
}
//+------------------------------------------------------------------+
//| Standardizes the height and width |
//+------------------------------------------------------------------+
void CRect::Normalize(void)
{
if(left>right)
{
int tmp=left;
left=right;
right=tmp;
}
if(top>bottom)
{
int tmp=top;
top=bottom;
bottom=tmp;
}
}
//+------------------------------------------------------------------+
+675
View File
@@ -0,0 +1,675 @@
//+------------------------------------------------------------------+
//| Scrolls.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndContainer.mqh"
#include "Panel.mqh"
#include "BmpButton.mqh"
//+------------------------------------------------------------------+
//| Resources |
//+------------------------------------------------------------------+
#resource "res\\Up.bmp"
#resource "res\\ThumbVert.bmp"
#resource "res\\Down.bmp"
#resource "res\\Left.bmp"
#resource "res\\ThumbHor.bmp"
#resource "res\\Right.bmp"
//+------------------------------------------------------------------+
//| Class CScroll |
//| Usage: base class for scrollbars |
//+------------------------------------------------------------------+
class CScroll : public CWndContainer
{
protected:
//--- dependent controls
CPanel m_back; // the "scrollbar background" object
CBmpButton m_inc; // the "increment button" object ("down" for vertical scrollbar, "right" for horizontal scrollbar)
CBmpButton m_dec; // the "decrement button" object ("up" for vertical scrollbar, "left" for horizontal scrollbar)
CBmpButton m_thumb; // the "scroll box" object
//--- set up
int m_min_pos; // minimum value
int m_max_pos; // maximum value
//--- state
int m_curr_pos; // current value
public:
CScroll(void);
~CScroll(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- set up
int MinPos(void) const { return(m_min_pos); }
void MinPos(const int value);
int MaxPos(void) const { return(m_max_pos); }
void MaxPos(const int value);
//--- state
int CurrPos(void) const { return(m_curr_pos); }
bool CurrPos(int value);
protected:
//--- create dependent controls
virtual bool CreateBack(void);
virtual bool CreateInc(void) { return(true); }
virtual bool CreateDec(void) { return(true); }
virtual bool CreateThumb(void) { return(true); }
//--- handlers of the dependent controls events
virtual bool OnClickInc(void);
virtual bool OnClickDec(void);
//--- internal event handlers
virtual bool OnShow(void);
virtual bool OnHide(void);
virtual bool OnChangePos(void) { return(true); }
//--- handlers of dragging
virtual bool OnThumbDragStart(void) { return(true); }
virtual bool OnThumbDragProcess(void) { return(true); }
virtual bool OnThumbDragEnd(void) { return(true); }
//--- calculate position by coordinate
virtual int CalcPos(const int coord) { return(0); }
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CScroll)
ON_EVENT(ON_CLICK,m_inc,OnClickInc)
ON_EVENT(ON_CLICK,m_dec,OnClickDec)
ON_EVENT(ON_DRAG_START,m_thumb,OnThumbDragStart)
ON_EVENT_PTR(ON_DRAG_PROCESS,m_drag_object,OnThumbDragProcess)
ON_EVENT_PTR(ON_DRAG_END,m_drag_object,OnThumbDragEnd)
EVENT_MAP_END(CWndContainer)
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CScroll::CScroll(void) : m_curr_pos(0),
m_min_pos(0),
m_max_pos(0)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CScroll::~CScroll(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CScroll::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- call method of the parent class
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- create dependent controls
if(!CreateBack())
return(false);
if(!CreateInc())
return(false);
if(!CreateDec())
return(false);
if(!CreateThumb())
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create scrollbar background |
//+------------------------------------------------------------------+
bool CScroll::CreateBack(void)
{
//--- create
if(!m_back.Create(m_chart_id,m_name+"Back",m_subwin,0,0,Width(),Height()))
return(false);
if(!m_back.ColorBackground(CONTROLS_SCROLL_COLOR_BG))
return(false);
if(!m_back.ColorBorder(CONTROLS_SCROLL_COLOR_BORDER))
return(false);
if(!Add(m_back))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Set current value |
//+------------------------------------------------------------------+
bool CScroll::CurrPos(int value)
{
//--- check value
if(value<m_min_pos)
value=m_min_pos;
if(value>m_max_pos)
value=m_max_pos;
//--- if value was changed
if(m_curr_pos!=value)
{
m_curr_pos=value;
//--- call virtual handler
return(OnChangePos());
}
//--- value has not been changed
return(false);
}
//+------------------------------------------------------------------+
//| Set minimum value |
//+------------------------------------------------------------------+
void CScroll::MinPos(const int value)
{
//--- if value was changed
if(m_min_pos!=value)
{
m_min_pos=value;
//--- adjust the scroll box position
CurrPos(m_curr_pos);
}
}
//+------------------------------------------------------------------+
//| Set maximum value |
//+------------------------------------------------------------------+
void CScroll::MaxPos(const int value)
{
//--- if value was changed
if(m_max_pos!=value)
{
m_max_pos=value;
//--- adjust the scroll box position
CurrPos(m_curr_pos);
}
}
//+------------------------------------------------------------------+
//| Handler of the "Show scrollbar" event |
//+------------------------------------------------------------------+
bool CScroll::OnShow(void)
{
if(m_id==CONTROLS_INVALID_ID)
return(true);
//--- send notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_SHOW,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of the "Hide scrollbar" event |
//+------------------------------------------------------------------+
bool CScroll::OnHide(void)
{
if(m_id==CONTROLS_INVALID_ID)
return(true);
//--- send notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_HIDE,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of click on the "increment" button |
//+------------------------------------------------------------------+
bool CScroll::OnClickInc(void)
{
//--- try to increment current value
if(!CurrPos(m_curr_pos+1))
return(true);
//--- if value was changed, send notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_SCROLL_INC,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of click on the "decrement" button |
//+------------------------------------------------------------------+
bool CScroll::OnClickDec(void)
{
//--- try to decrement current value
if(!CurrPos(m_curr_pos-1))
return(true);
//--- if value was changed, send notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_SCROLL_DEC,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Class CScrollV |
//| Usage: class of vertical scrollbar |
//+------------------------------------------------------------------+
class CScrollV : public CScroll
{
public:
CScrollV(void);
~CScrollV(void);
protected:
//--- create dependent controls
virtual bool CreateInc(void);
virtual bool CreateDec(void);
virtual bool CreateThumb(void);
//--- internal event handlers
virtual bool OnResize(void);
virtual bool OnChangePos(void);
//--- handlers of dragging
virtual bool OnThumbDragStart(void);
virtual bool OnThumbDragProcess(void);
virtual bool OnThumbDragEnd(void);
//--- calculate position by coordinate
virtual int CalcPos(const int coord);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CScrollV::CScrollV(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CScrollV::~CScrollV(void)
{
}
//+------------------------------------------------------------------+
//| Create the "Increment" button |
//+------------------------------------------------------------------+
bool CScrollV::CreateInc(void)
{
//--- calculate coordinates
int x1=CONTROLS_BORDER_WIDTH;
int y1=Height()-CONTROLS_SCROLL_SIZE+CONTROLS_BORDER_WIDTH;
int x2=x1+CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_BUTTON_SIZE;
//--- create
if(!m_inc.Create(m_chart_id,m_name+"Inc",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_inc.BmpNames("::res\\Down.bmp"))
return(false);
if(!Add(m_inc))
return(false);
//--- property
m_inc.PropFlags(WND_PROP_FLAG_CLICKS_BY_PRESS);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "Decrement" button |
//+------------------------------------------------------------------+
bool CScrollV::CreateDec(void)
{
//--- calculate coordinates
int x1=CONTROLS_BORDER_WIDTH;
int y1=CONTROLS_BORDER_WIDTH;
int x2=x1+CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_BUTTON_SIZE;
//--- create
if(!m_dec.Create(m_chart_id,m_name+"Dec",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_dec.BmpNames("::res\\Up.bmp"))
return(false);
if(!Add(m_dec))
return(false);
//--- property
m_dec.PropFlags(WND_PROP_FLAG_CLICKS_BY_PRESS);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create scroll box |
//+------------------------------------------------------------------+
bool CScrollV::CreateThumb(void)
{
//--- calculate coordinates
int x1=CONTROLS_BORDER_WIDTH;
int y1=CONTROLS_SCROLL_SIZE-CONTROLS_BORDER_WIDTH;
int x2=x1+CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_SCROLL_THUMB_SIZE;
//--- create
if(!m_thumb.Create(m_chart_id,m_name+"Thumb",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_thumb.BmpNames("::res\\ThumbVert.bmp"))
return(false);
if(!Add(m_thumb))
return(false);
m_thumb.PropFlags(WND_PROP_FLAG_CAN_DRAG);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Handler of changing current state |
//+------------------------------------------------------------------+
bool CScrollV::OnChangePos(void)
{
//--- check if scrolling is possible
if(m_max_pos-m_min_pos<=0)
return(Visible(false));
else
if(!Visible(true))
return(false);
//--- calculate new coordinated of the scrollbar
int steps =m_max_pos-m_min_pos; // number of steps to change position
int min_coord=m_dec.Bottom(); // minimum possible coordinate (corresponds to the m_min_pos value)
int max_coord=m_inc.Top()-m_thumb.Height(); // maximum possible coordinate (corresponds to the m_max_pos value)
int new_coord=min_coord+(max_coord-min_coord)*m_curr_pos/steps; // new coordinate
//--- adjust the scroll box position
return(m_thumb.Move(m_thumb.Left(),new_coord));
}
//+------------------------------------------------------------------+
//| Handler of resizing |
//+------------------------------------------------------------------+
bool CScrollV::OnResize(void)
{
//--- can not change the lateral size
if(Width()!=CONTROLS_SCROLL_SIZE)
m_rect.Width(CONTROLS_SCROLL_SIZE);
//--- resize the scrollbar background
if(!m_back.Size(Size()))
return(false);
//--- move the "Increment" button
if(!m_inc.Move(m_inc.Left(),Bottom()-CONTROLS_SCROLL_SIZE))
return(false);
//--- adjust the scroll box position
return(OnChangePos());
}
//+------------------------------------------------------------------+
//| Start dragging the "slider" |
//+------------------------------------------------------------------+
bool CScrollV::OnThumbDragStart(void)
{
if(m_drag_object==NULL)
{
m_drag_object=new CDragWnd;
if(m_drag_object==NULL)
return(false);
}
//--- calculate coordinates
int x1=m_thumb.Left()-CONTROLS_DRAG_SPACING;
int y1=m_thumb.Top()-CONTROLS_DRAG_SPACING;
int x2=m_thumb.Right()+CONTROLS_DRAG_SPACING;
int y2=m_thumb.Bottom()+CONTROLS_DRAG_SPACING;
//--- create
m_drag_object.Create(m_chart_id,"",m_subwin,x1,y1,x2,y2);
m_drag_object.PropFlags(WND_PROP_FLAG_CAN_DRAG);
//--- îãðàíè÷åíèÿ
m_drag_object.Limits(x1,m_dec.Bottom()-CONTROLS_DRAG_SPACING,x2,m_inc.Top()+CONTROLS_DRAG_SPACING);
//--- set mouse params
m_drag_object.MouseX(m_thumb.MouseX());
m_drag_object.MouseY(m_thumb.MouseY());
m_drag_object.MouseFlags(m_thumb.MouseFlags());
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Continue dragging the "slider" |
//+------------------------------------------------------------------+
bool CScrollV::OnThumbDragProcess(void)
{
//--- checking
if(m_drag_object==NULL)
return(false);
//--- calculate coordinates
int x=m_drag_object.Left()+CONTROLS_DRAG_SPACING;
int y=m_drag_object.Top()+CONTROLS_DRAG_SPACING;
//--- calculate new position
int new_pos=CalcPos(y);
if(new_pos!=m_curr_pos)
{
ushort event_id=(m_curr_pos<new_pos) ? ON_SCROLL_INC : ON_SCROLL_DEC;
m_curr_pos=new_pos;
EventChartCustom(CONTROLS_SELF_MESSAGE,event_id,m_id,0.0,m_name);
}
//--- move thumb
m_thumb.Move(x,y);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| End dragging the "slider" |
//+------------------------------------------------------------------+
bool CScrollV::OnThumbDragEnd(void)
{
if(m_drag_object!=NULL)
{
m_thumb.MouseFlags(m_drag_object.MouseFlags());
delete m_drag_object;
m_drag_object=NULL;
}
//--- succeed
return(m_thumb.Pressed(false));
}
//+------------------------------------------------------------------+
//| Calculate position by coordinate |
//+------------------------------------------------------------------+
int CScrollV::CalcPos(const int coord)
{
//--- calculate new position of the scrollbar
int steps =m_max_pos-m_min_pos; // number of steps to change position
int min_coord=m_dec.Bottom(); // minimum possible coordinate (corresponds to the m_min_pos value)
int max_coord=m_inc.Top()-m_thumb.Height(); // maximum possible coordinate (corresponds to the m_max_pos value)
//--- checkeng
if(max_coord==min_coord)
return(0);
if(coord<min_coord || coord>max_coord)
return(m_curr_pos);
//---
int new_pos=(int)MathRound((((double)(coord-min_coord))/(max_coord-min_coord))*steps); // new position
//---
return(new_pos);
}
//+------------------------------------------------------------------+
//| Class CScrollH |
//| Usage: class of horizontal scrollbar |
//+------------------------------------------------------------------+
class CScrollH : public CScroll
{
public:
CScrollH(void);
~CScrollH(void);
protected:
//--- create dependent controls
virtual bool CreateInc(void);
virtual bool CreateDec(void);
virtual bool CreateThumb(void);
//--- internal event handlers
virtual bool OnResize(void);
virtual bool OnChangePos(void);
//--- handlers of dragging
virtual bool OnThumbDragStart(void);
virtual bool OnThumbDragProcess(void);
virtual bool OnThumbDragEnd(void);
//--- calculate position by coordinate
virtual int CalcPos(const int coord);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CScrollH::CScrollH(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CScrollH::~CScrollH(void)
{
}
//+------------------------------------------------------------------+
//| Create the "Increment" button |
//+------------------------------------------------------------------+
bool CScrollH::CreateInc(void)
{
//--- calculate coordinates
int x1=Width()-CONTROLS_SCROLL_SIZE+CONTROLS_BORDER_WIDTH;
int y1=CONTROLS_BORDER_WIDTH;
int x2=x1+CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_BUTTON_SIZE;
//--- create
if(!m_inc.Create(m_chart_id,m_name+"Inc",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_inc.BmpNames("::res\\Right.bmp"))
return(false);
if(!Add(m_inc))
return(false);
//--- property
m_inc.PropFlags(WND_PROP_FLAG_CLICKS_BY_PRESS);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "Decrement" button |
//+------------------------------------------------------------------+
bool CScrollH::CreateDec(void)
{
//--- calculate coordinates
int x1=CONTROLS_BORDER_WIDTH;
int y1=CONTROLS_BORDER_WIDTH;
int x2=x1+CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_BUTTON_SIZE;
//--- create
if(!m_dec.Create(m_chart_id,m_name+"Dec",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_dec.BmpNames("::res\\Left.bmp"))
return(false);
if(!Add(m_dec))
return(false);
//--- property
m_dec.PropFlags(WND_PROP_FLAG_CLICKS_BY_PRESS);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create scroll box |
//+------------------------------------------------------------------+
bool CScrollH::CreateThumb(void)
{
//--- calculate coordinates
int x1=CONTROLS_SCROLL_SIZE-CONTROLS_BORDER_WIDTH;
int y1=CONTROLS_BORDER_WIDTH;
int x2=x1+CONTROLS_SCROLL_THUMB_SIZE;
int y2=y1+CONTROLS_BUTTON_SIZE;
//--- create
if(!m_thumb.Create(m_chart_id,m_name+"Thumb",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_thumb.BmpNames("::res\\ThumbHor.bmp"))
return(false);
if(!Add(m_thumb))
return(false);
m_thumb.PropFlags(WND_PROP_FLAG_CAN_DRAG);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Handler of changing current state |
//+------------------------------------------------------------------+
bool CScrollH::OnChangePos(void)
{
//--- check if scrolling is possible
if(m_max_pos-m_min_pos<=0)
return(Visible(false));
else
if(!Visible(true))
return(false);
//--- calculate new coordinated of the scrollbar
int steps=m_max_pos-m_min_pos; // number of steps to change position
int min_coord=m_dec.Right(); // minimum possible coordinate (corresponds to the m_min_pos value)
int max_coord=m_inc.Left()-m_thumb.Width(); // maximum possible coordinate (corresponds to the m_max_pos value)
int new_coord=min_coord+(max_coord-min_coord)*m_curr_pos/steps; // new coordinate
//--- adjust the scroll box position
return(m_thumb.Move(new_coord,m_thumb.Top()));
}
//+------------------------------------------------------------------+
//| Handler of resizing |
//+------------------------------------------------------------------+
bool CScrollH::OnResize(void)
{
//--- can not change the lateral size
if(Height()!=CONTROLS_SCROLL_SIZE)
m_rect.Height(CONTROLS_SCROLL_SIZE);
//--- resize the scrollbar background
if(!m_back.Size(Size()))
return(false);
//--- move the "Increment" button
if(!m_inc.Move(Right()-CONTROLS_SCROLL_SIZE,m_inc.Top()))
return(false);
//--- adjust the scroll box position
return(OnChangePos());
}
//+------------------------------------------------------------------+
//| Start dragging the "slider" |
//+------------------------------------------------------------------+
bool CScrollH::OnThumbDragStart(void)
{
if(m_drag_object==NULL)
{
m_drag_object=new CDragWnd;
if(m_drag_object==NULL)
return(false);
}
//--- calculate coordinates
int x1=m_thumb.Left()-CONTROLS_DRAG_SPACING;
int y1=m_thumb.Top()-CONTROLS_DRAG_SPACING;
int x2=m_thumb.Right()+CONTROLS_DRAG_SPACING;
int y2=m_thumb.Bottom()+CONTROLS_DRAG_SPACING;
//--- create
m_drag_object.Create(m_chart_id,"",m_subwin,x1,y1,x2,y2);
m_drag_object.PropFlags(WND_PROP_FLAG_CAN_DRAG);
//--- îãðàíè÷åíèÿ
m_drag_object.Limits(m_dec.Right()-CONTROLS_DRAG_SPACING,y1,m_inc.Left()+CONTROLS_DRAG_SPACING,y2);
//--- set mouse params
m_drag_object.MouseX(m_thumb.MouseX());
m_drag_object.MouseY(m_thumb.MouseY());
m_drag_object.MouseFlags(m_thumb.MouseFlags());
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Continue dragging the "slider" |
//+------------------------------------------------------------------+
bool CScrollH::OnThumbDragProcess(void)
{
//--- checking
if(m_drag_object==NULL)
return(false);
//--- calculate coordinates
int x=m_drag_object.Left()+CONTROLS_DRAG_SPACING;
int y=m_drag_object.Top()+CONTROLS_DRAG_SPACING;
//--- calculate new position
int new_pos=CalcPos(x);
if(new_pos!=m_curr_pos)
{
ushort event_id=(m_curr_pos<new_pos)?ON_SCROLL_INC:ON_SCROLL_DEC;
m_curr_pos=new_pos;
EventChartCustom(CONTROLS_SELF_MESSAGE,event_id,m_id,0.0,m_name);
}
//--- move thumb
m_thumb.Move(x,y);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| End dragging the "slider" |
//+------------------------------------------------------------------+
bool CScrollH::OnThumbDragEnd(void)
{
if(m_drag_object!=NULL)
{
m_thumb.MouseFlags(m_drag_object.MouseFlags());
delete m_drag_object;
m_drag_object=NULL;
}
//--- succeed
return(m_thumb.Pressed(false));
}
//+------------------------------------------------------------------+
//| Calculate position by coordinate |
//+------------------------------------------------------------------+
int CScrollH::CalcPos(const int coord)
{
//--- calculate new position of the scrollbar
int steps =m_max_pos-m_min_pos; // number of steps to change position
int min_coord=m_dec.Right(); // minimum possible coordinate (corresponds to the m_min_pos value)
int max_coord=m_inc.Left()-m_thumb.Width(); // maximum possible coordinate (corresponds to the m_max_pos value)
//--- checkeng
if(max_coord==min_coord)
return(0);
if(coord<min_coord || coord>max_coord)
return(m_curr_pos);
//---
int new_pos=(int)MathRound((((double)(coord-min_coord))/(max_coord-min_coord))*steps); // new position
//---
return(new_pos);
}
//+------------------------------------------------------------------+
+265
View File
@@ -0,0 +1,265 @@
//+------------------------------------------------------------------+
//| SpinEdit.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndContainer.mqh"
#include "Edit.mqh"
#include "BmpButton.mqh"
//+------------------------------------------------------------------+
//| Resources |
//+------------------------------------------------------------------+
#resource "res\\SpinInc.bmp"
#resource "res\\SpinDec.bmp"
//+------------------------------------------------------------------+
//| Class CSpinEdit |
//| Usage: class that implements the "Up-Down" control |
//+------------------------------------------------------------------+
class CSpinEdit : public CWndContainer
{
private:
//--- dependent controls
CEdit m_edit; // the entry field object
CBmpButton m_inc; // the "Increment button" object
CBmpButton m_dec; // the "Decrement button" object
//--- adjusted parameters
int m_min_value; // minimum value
int m_max_value; // maximum value
//--- state
int m_value; // current value
public:
CSpinEdit(void);
~CSpinEdit(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- set up
int MinValue(void) const { return(m_min_value); }
void MinValue(const int value);
int MaxValue(void) const { return(m_min_value); }
void MaxValue(const int value);
//--- state
int Value(void) const { return(m_value); }
bool Value(int value);
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
protected:
//--- create dependent controls
virtual bool CreateEdit(void);
virtual bool CreateInc(void);
virtual bool CreateDec(void);
//--- handlers of the dependent controls events
virtual bool OnClickInc(void);
virtual bool OnClickDec(void);
//--- internal event handlers
virtual bool OnChangeValue(void);
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CSpinEdit)
ON_EVENT(ON_CLICK,m_inc,OnClickInc)
ON_EVENT(ON_CLICK,m_dec,OnClickDec)
EVENT_MAP_END(CWndContainer)
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CSpinEdit::CSpinEdit(void) : m_min_value(0),
m_max_value(0),
m_value(0)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CSpinEdit::~CSpinEdit(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CSpinEdit::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- check height
if(y2-y1<CONTROLS_SPIN_MIN_HEIGHT)
return(false);
//--- call method of the parent class
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- create dependent controls
if(!CreateEdit())
return(false);
if(!CreateInc())
return(false);
if(!CreateDec())
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Set current value |
//+------------------------------------------------------------------+
bool CSpinEdit::Value(int value)
{
//--- check value
if(value<m_min_value)
value=m_min_value;
if(value>m_max_value)
value=m_max_value;
//--- if value was changed
if(m_value!=value)
{
m_value=value;
//--- call virtual handler
return(OnChangeValue());
}
//--- value has not been changed
return(false);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CSpinEdit::Save(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//---
FileWriteInteger(file_handle,m_value);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
bool CSpinEdit::Load(const int file_handle)
{
//--- check
if(file_handle==INVALID_HANDLE)
return(false);
//---
if(!FileIsEnding(file_handle))
Value(FileReadInteger(file_handle));
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Set minimum value |
//+------------------------------------------------------------------+
void CSpinEdit::MinValue(const int value)
{
//--- if value was changed
if(m_min_value!=value)
{
m_min_value=value;
//--- adjust the edit value
Value(m_value);
}
}
//+------------------------------------------------------------------+
//| Set maximum value |
//+------------------------------------------------------------------+
void CSpinEdit::MaxValue(const int value)
{
//--- if value was changed
if(m_max_value!=value)
{
m_max_value=value;
//--- adjust the edit value
Value(m_value);
}
}
//+------------------------------------------------------------------+
//| Create the edit field |
//+------------------------------------------------------------------+
bool CSpinEdit::CreateEdit(void)
{
//--- create
if(!m_edit.Create(m_chart_id,m_name+"Edit",m_subwin,0,0,Width(),Height()))
return(false);
if(!m_edit.Text(""))
return(false);
if(!m_edit.ReadOnly(true))
return(false);
if(!Add(m_edit))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "Increment" button |
//+------------------------------------------------------------------+
bool CSpinEdit::CreateInc(void)
{
//--- right align button (try to make equal offsets from top and bottom)
int x1=Width()-(CONTROLS_BUTTON_SIZE+CONTROLS_SPIN_BUTTON_X_OFF);
int y1=(Height()-2*CONTROLS_SPIN_BUTTON_SIZE)/2;
int x2=x1+CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_SPIN_BUTTON_SIZE;
//--- create
if(!m_inc.Create(m_chart_id,m_name+"Inc",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_inc.BmpNames("::res\\SpinInc.bmp"))
return(false);
if(!Add(m_inc))
return(false);
//--- property
m_inc.PropFlags(WND_PROP_FLAG_CLICKS_BY_PRESS);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create the "Decrement" button |
//+------------------------------------------------------------------+
bool CSpinEdit::CreateDec(void)
{
//--- right align button (try to make equal offsets from top and bottom)
int x1=Width()-(CONTROLS_BUTTON_SIZE+CONTROLS_SPIN_BUTTON_X_OFF);
int y1=(Height()-2*CONTROLS_SPIN_BUTTON_SIZE)/2+CONTROLS_SPIN_BUTTON_SIZE;
int x2=x1+CONTROLS_BUTTON_SIZE;
int y2=y1+CONTROLS_SPIN_BUTTON_SIZE;
//--- create
if(!m_dec.Create(m_chart_id,m_name+"Dec",m_subwin,x1,y1,x2,y2))
return(false);
if(!m_dec.BmpNames("::res\\SpinDec.bmp"))
return(false);
if(!Add(m_dec))
return(false);
//--- property
m_dec.PropFlags(WND_PROP_FLAG_CLICKS_BY_PRESS);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Handler of click on the "increment" button |
//+------------------------------------------------------------------+
bool CSpinEdit::OnClickInc(void)
{
//--- try to increment current value
return(Value(m_value+1));
}
//+------------------------------------------------------------------+
//| Handler of click on the "decrement" button |
//+------------------------------------------------------------------+
bool CSpinEdit::OnClickDec(void)
{
//--- try to decrement current value
return(Value(m_value-1));
}
//+------------------------------------------------------------------+
//| Handler of changing current state |
//+------------------------------------------------------------------+
bool CSpinEdit::OnChangeValue(void)
{
//--- copy text to the edit field edit
m_edit.Text(IntegerToString(m_value));
//--- send notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CHANGE,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
+755
View File
@@ -0,0 +1,755 @@
//+------------------------------------------------------------------+
//| Wnd.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "Rect.mqh"
#include "Defines.mqh"
#include <Object.mqh>
class CDragWnd;
//+------------------------------------------------------------------+
//| Class CWnd |
//| Usage: base class of the control object that creates |
//| control panels and indicator panels |
//+------------------------------------------------------------------+
class CWnd : public CObject
{
protected:
//--- parameters of creation
long m_chart_id; // chart ID
int m_subwin; // chart subwindow
string m_name; // object name
//--- geometry
CRect m_rect; // chart area
//--- ID
long m_id; // object ID
//--- state flags
int m_state_flags;
//--- properties flags
int m_prop_flags;
//--- alignment
int m_align_flags; // alignment flags
int m_align_left; // fixed offset from left border
int m_align_top; // fixed offset from top border
int m_align_right; // fixed offset from right border
int m_align_bottom; // fixed offset from bottom border
//--- the last saved state of mouse
int m_mouse_x; // X coordinate
int m_mouse_y; // Y coordinate
int m_mouse_flags; // state of buttons
uint m_last_click; // last click time
//--- drag object
CDragWnd *m_drag_object; // pointer to the dragged object
public:
CWnd(void);
~CWnd(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
//--- release memory
virtual void Destroy(const int reason=0);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
virtual bool OnMouseEvent(const int x,const int y,const int flags);
//--- naming (read only)
string Name(void) const { return(m_name); }
//--- access the contents of container
int ControlsTotal(void) const { return(0); }
CWnd* Control(const int ind) const { return(NULL); }
virtual CWnd* ControlFind(const long id);
//--- geometry
const CRect Rect(void) const { return(m_rect); }
int Left(void) const { return(m_rect.left); }
virtual void Left(const int x) { m_rect.left=x; }
int Top(void) const { return(m_rect.top); }
virtual void Top(const int y) { m_rect.top=y; }
int Right(void) const { return(m_rect.right); }
virtual void Right(const int x) { m_rect.right=x; }
int Bottom(void) const { return(m_rect.bottom); }
virtual void Bottom(const int y) { m_rect.bottom=y; }
int Width(void) const { return(m_rect.Width()); }
virtual bool Width(const int w);
int Height(void) const { return(m_rect.Height()); }
virtual bool Height(const int h);
CSize Size(void) const { return(m_rect.Size()); }
virtual bool Size(const int w,const int h);
virtual bool Size(const CSize &size);
virtual bool Move(const int x,const int y);
virtual bool Move(const CPoint &point);
virtual bool Shift(const int dx,const int dy);
bool Contains(const int x,const int y) const { return(m_rect.Contains(x,y)); }
bool Contains(CWnd *control) const;
//--- alignment
void Alignment(const int flags,const int left,const int top,const int right,const int bottom);
virtual bool Align(const CRect &rect);
//--- ID
virtual long Id(const long id);
long Id(void) const { return(m_id); }
//--- state
bool IsEnabled(void) const { return(IS_ENABLED); }
virtual bool Enable(void);
virtual bool Disable(void);
bool IsVisible(void) const { return(IS_VISIBLE); }
virtual bool Visible(const bool flag);
virtual bool Show(void);
virtual bool Hide(void);
bool IsActive(void) const { return(IS_ACTIVE); }
virtual bool Activate(void);
virtual bool Deactivate(void);
//--- state flags
int StateFlags(void) const { return(m_state_flags); }
void StateFlags(const int flags) { m_state_flags=flags; }
void StateFlagsSet(const int flags) { m_state_flags|=flags; }
void StateFlagsReset(const int flags) { m_state_flags&=~flags; }
//--- properties flags
int PropFlags(void) const { return(m_prop_flags); }
void PropFlags(const int flags) { m_prop_flags=flags; }
void PropFlagsSet(const int flags) { m_prop_flags|=flags; }
void PropFlagsReset(const int flags) { m_prop_flags&=~flags; }
//--- for mouse operations
int MouseX(void) const { return(m_mouse_x); }
void MouseX(const int value) { m_mouse_x=value; }
int MouseY(void) const { return(m_mouse_y); }
void MouseY(const int value) { m_mouse_y=value; }
int MouseFlags(void) const { return(m_mouse_flags); }
virtual void MouseFlags(const int value) { m_mouse_flags=value; }
bool MouseFocusKill(const long id=CONTROLS_INVALID_ID);
bool BringToTop(void);
protected:
//--- internal event handlers
virtual bool OnCreate(void) { return(true); }
virtual bool OnDestroy(void) { return(true); }
virtual bool OnMove(void) { return(true); }
virtual bool OnResize(void) { return(true); }
virtual bool OnEnable(void) { return(true); }
virtual bool OnDisable(void) { return(true); }
virtual bool OnShow(void) { return(true); }
virtual bool OnHide(void) { return(true); }
virtual bool OnActivate(void) { return(true); }
virtual bool OnDeactivate(void) { return(true); }
virtual bool OnClick(void);
virtual bool OnDblClick(void);
virtual bool OnChange(void) { return(true); }
//--- mouse event handlers
virtual bool OnMouseDown(void);
virtual bool OnMouseUp(void);
//--- handlers of dragging
virtual bool OnDragStart(void);
virtual bool OnDragProcess(const int x,const int y);
virtual bool OnDragEnd(void);
//--- methods for drag-object
virtual bool DragObjectCreate(void) { return(false); }
virtual bool DragObjectDestroy(void);
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
bool CWnd::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
if((id!=CHARTEVENT_MOUSE_MOVE))
return(false);
if(!IS_VISIBLE)
return(false);
int x=(int)lparam;
int y=(int)dparam;
int flags=(int)StringToInteger(sparam);
//---
if(m_drag_object!=NULL)
return(m_drag_object.OnMouseEvent(x,y,flags));
//---
return(OnMouseEvent(x,y,flags));
}
//+------------------------------------------------------------------+
//| Common handler of mouse events |
//+------------------------------------------------------------------+
bool CWnd::OnMouseEvent(const int x,const int y,const int flags)
{
if(!Contains(x,y))
{
//--- if cursor is not inside the element and this element is active - deactivate
if(IS_ACTIVE)
{
//--- reset state and coordinates
m_mouse_x =0;
m_mouse_y =0;
m_mouse_flags=MOUSE_INVALID_FLAGS;
//--- deactivate
Deactivate();
}
return(false);
}
//--- check the state of the left mouse button
if((flags&MOUSE_LEFT)!=0)
{
//--- left mouse button is pressed
if(m_mouse_flags==MOUSE_INVALID_FLAGS)
{
//--- but not in this control (i.e., cursor entered the element with mouse button pressed)
//--- activate the control, but there will be no click
if(!IS_ACTIVE)
{
//--- generate event
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_MOUSE_FOCUS_SET,m_id,0.0,m_name);
//--- activate
return(Activate());
}
return(true);
}
if((m_mouse_flags&MOUSE_LEFT)!=0)
{
//--- mouse button has already been pressed
if(IS_CAN_DRAG)
return(OnDragProcess(x,y));
if(IS_CLICKS_BY_PRESS)
{
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CLICK,m_id,0.0,m_name);
//--- handled
return(true);
}
}
else
{
//--- mouse button has been released (pressing)
//--- save the state and coordinates
m_mouse_flags=flags;
m_mouse_x =x;
m_mouse_y =y;
//--- call the handler
return(OnMouseDown());
}
}
else
{
//--- left mouse button is released
if(m_mouse_flags==MOUSE_INVALID_FLAGS)
{
//--- cursor entered the control with mouse button released
//--- activate control and save state to the member
m_mouse_flags=flags;
//--- generate event
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_MOUSE_FOCUS_SET,m_id,0.0,m_name);
//--- activate
return(Activate());
}
if((m_mouse_flags&MOUSE_LEFT)!=0)
{
//--- mouse button has been pressed (clicking)
//--- save the state and coordinates
m_mouse_flags=flags;
m_mouse_x =x;
m_mouse_y =y;
//--- call the handler
return(OnMouseUp());
}
}
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CWnd::CWnd(void) : m_chart_id(CONTROLS_INVALID_ID),
m_subwin(CONTROLS_INVALID_ID),
m_name(NULL),
m_id(CONTROLS_INVALID_ID),
m_state_flags(WND_STATE_FLAG_ENABLE+WND_STATE_FLAG_VISIBLE),
m_prop_flags(0),
m_align_flags(WND_ALIGN_NONE),
m_align_left(0),
m_align_top(0),
m_align_right(0),
m_align_bottom(0),
m_mouse_x(0),
m_mouse_y(0),
m_mouse_flags(MOUSE_INVALID_FLAGS),
m_last_click(0),
m_drag_object(NULL)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CWnd::~CWnd(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CWnd::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- attach to chart
m_chart_id=chart;
m_name =name;
m_subwin =subwin;
//--- set coordinates of area
Left(x1);
Top(y1);
Right(x2);
Bottom(y2);
//--- always successful
return(true);
}
//+------------------------------------------------------------------+
//| Destruction of the control |
//+------------------------------------------------------------------+
void CWnd::Destroy(const int reason)
{
//--- call virtual event handler
if(OnDestroy())
m_name="";
}
//+------------------------------------------------------------------+
//| Find control by specified ID |
//+------------------------------------------------------------------+
CWnd* CWnd::ControlFind(const long id)
{
CWnd *result=NULL;
//--- check
if(id==m_id)
result=GetPointer(this);
//--- return the result
return(result);
}
//+------------------------------------------------------------------+
//| Change width of control |
//+------------------------------------------------------------------+
bool CWnd::Width(const int w)
{
//--- change width
m_rect.Width(w);
//--- call virtual event handler
return(OnResize());
}
//+------------------------------------------------------------------+
//| Change height of control |
//+------------------------------------------------------------------+
bool CWnd::Height(const int h)
{
//--- change height
m_rect.Height(h);
//--- call virtual event handler
return(OnResize());
}
//+------------------------------------------------------------------+
//| Resize control |
//+------------------------------------------------------------------+
bool CWnd::Size(const int w,const int h)
{
//--- change size
m_rect.Size(w,h);
//--- call virtual event handler
return(OnResize());
}
//+------------------------------------------------------------------+
//| Resize control |
//+------------------------------------------------------------------+
bool CWnd::Size(const CSize &size)
{
//--- change size
m_rect.Size(size);
//--- call virtual event handler
return(OnResize());
}
//+------------------------------------------------------------------+
//| Absolute movement of the control |
//+------------------------------------------------------------------+
bool CWnd::Move(const int x,const int y)
{
//--- moving
m_rect.Move(x,y);
//--- call virtual event handler
return(OnMove());
}
//+------------------------------------------------------------------+
//| Absolute movement of the control |
//+------------------------------------------------------------------+
bool CWnd::Move(const CPoint &point)
{
//--- moving
m_rect.Move(point);
//--- call virtual event handler
return(OnMove());
}
//+------------------------------------------------------------------+
//| Relative movement of the control |
//+------------------------------------------------------------------+
bool CWnd::Shift(const int dx,const int dy)
{
//--- moving
m_rect.Shift(dx,dy);
//--- call virtual event handler
return(OnMove());
}
//+------------------------------------------------------------------+
//| Check contains |
//+------------------------------------------------------------------+
bool CWnd::Contains(CWnd *control) const
{
//--- check
if(control==NULL)
return(false);
//--- result
return(Contains(control.Left(),control.Top()) && Contains(control.Right(),control.Bottom()));
}
//+------------------------------------------------------------------+
//| Enables event handling by the control |
//+------------------------------------------------------------------+
bool CWnd::Enable(void)
{
//--- if there are now changes, then succeed
if(IS_ENABLED)
return(true);
//--- change flag
StateFlagsSet(WND_STATE_FLAG_ENABLE);
//--- call virtual event handler
return(OnEnable());
}
//+------------------------------------------------------------------+
//| Disables event handling by the control |
//+------------------------------------------------------------------+
bool CWnd::Disable(void)
{
//--- if there are now changes, then succeed
if(!IS_ENABLED)
return(true);
//--- change flag
StateFlagsReset(WND_STATE_FLAG_ENABLE);
//--- call virtual event handler
return(OnDisable());
}
//+------------------------------------------------------------------+
//| Set the "object is visible" flag for the control |
//+------------------------------------------------------------------+
bool CWnd::Visible(const bool flag)
{
//--- if there are now changes, then succeed
if(IS_VISIBLE==flag)
return(true);
//--- call virtual event handler
return(flag ? Show() : Hide());
}
//+------------------------------------------------------------------+
//| Makes the control visible |
//+------------------------------------------------------------------+
bool CWnd::Show(void)
{
//--- change flag
StateFlagsSet(WND_STATE_FLAG_VISIBLE);
//--- call virtual event handler
return(OnShow());
}
//+------------------------------------------------------------------+
//| Makes the control hidden |
//+------------------------------------------------------------------+
bool CWnd::Hide(void)
{
//--- change flag
StateFlagsReset(WND_STATE_FLAG_VISIBLE);
//--- call virtual event handler
return(OnHide());
}
//+------------------------------------------------------------------+
//| Makes the control active |
//+------------------------------------------------------------------+
bool CWnd::Activate(void)
{
//--- if there are now changes, then succeed
if(IS_ACTIVE)
return(true);
//--- change flag
StateFlagsSet(WND_STATE_FLAG_ACTIVE);
//--- call virtual event handler
return(OnActivate());
}
//+------------------------------------------------------------------+
//| Makes the control inactive |
//+------------------------------------------------------------------+
bool CWnd::Deactivate(void)
{
//--- if there are now changes, then succeed
if(!IS_ACTIVE)
return(true);
//--- change flag
StateFlagsReset(WND_STATE_FLAG_ACTIVE);
//--- call virtual event handler
return(OnDeactivate());
}
//+------------------------------------------------------------------+
//| Set ID of control |
//+------------------------------------------------------------------+
long CWnd::Id(const long id)
{
m_id=id;
//--- always use only one ID
return(1);
}
//+------------------------------------------------------------------+
//| Set parameters of alignment |
//+------------------------------------------------------------------+
void CWnd::Alignment(const int flags,const int left,const int top,const int right,const int bottom)
{
m_align_flags =flags;
m_align_left =left;
m_align_top =top;
m_align_right =right;
m_align_bottom=bottom;
}
//+------------------------------------------------------------------+
//| Align element in specified chart area |
//+------------------------------------------------------------------+
bool CWnd::Align(const CRect &rect)
{
int new_value=0;
//--- check
if(m_align_flags==WND_ALIGN_NONE)
return(true);
//--- we are interested only in alignment by right and bottom borders,
//--- as left and right borders are processed in the OnMove()
if((m_align_flags&WND_ALIGN_RIGHT)!=0)
{
//--- there is alignment by right border,
if((m_align_flags&WND_ALIGN_LEFT)!=0)
{
//--- and by left border (change size)
new_value=rect.Width()-m_align_left-m_align_right;
if(!Size(new_value,Height()))
return(false);
}
else
{
//--- no alignment by left border (move)
new_value=rect.right-Width()-m_align_right;
if(!Move(new_value,Top()))
return(false);
}
}
if((m_align_flags&WND_ALIGN_BOTTOM)!=0)
{
//--- there is alignment by bottom border,
if((m_align_flags&WND_ALIGN_TOP)!=0)
{
//--- and by top border (change size)
new_value=rect.Height()-m_align_top-m_align_bottom;
if(!Size(Width(),new_value))
return(false);
}
else
{
//--- no alignment by top border (move)
new_value=rect.bottom-Height()-m_align_bottom;
if(!Move(Left(),new_value))
return(false);
}
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Remove the mouse focus from control |
//+------------------------------------------------------------------+
bool CWnd::MouseFocusKill(const long id)
{
//--- check
if(id==m_id)
return(false);
//--- reset flag
Deactivate();
//--- clean
m_mouse_x =0;
m_mouse_y =0;
m_mouse_flags=MOUSE_INVALID_FLAGS;
//--- call the handler
return(OnDeactivate());
}
//+------------------------------------------------------------------+
//| Increases the priority of an element |
//+------------------------------------------------------------------+
bool CWnd::BringToTop(void)
{
//--- generate event
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_BRING_TO_TOP,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of the "click" event |
//+------------------------------------------------------------------+
bool CWnd::OnClick(void)
{
//--- send notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_CLICK,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of the "doubl click" event |
//+------------------------------------------------------------------+
bool CWnd::OnDblClick(void)
{
//--- send notification
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_DBL_CLICK,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of click on the left mouse button |
//+------------------------------------------------------------------+
bool CWnd::OnMouseDown(void)
{
if(IS_CAN_DRAG)
return(OnDragStart());
if(IS_CLICKS_BY_PRESS)
return(OnClick());
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of releasing the left mouse button |
//+------------------------------------------------------------------+
bool CWnd::OnMouseUp(void)
{
if(IS_CAN_DBL_CLICK)
{
uint last_time=GetTickCount();
if(m_last_click==0 || last_time-m_last_click>CONTROLS_DBL_CLICK_TIME)
{
m_last_click=(last_time==0) ? 1 : last_time;
}
else
{
m_last_click=0;
return(OnDblClick());
}
}
if(IS_CAN_DRAG)
return(OnDragEnd());
if(!IS_CLICKS_BY_PRESS)
return(OnClick());
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of the control dragging start |
//+------------------------------------------------------------------+
bool CWnd::OnDragStart(void)
{
if(!IS_CAN_DRAG)
return(true);
//--- disable scrolling of chart with mouse
ChartSetInteger(m_chart_id,CHART_MOUSE_SCROLL,false);
//--- generate event
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_DRAG_START,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of control dragging process |
//+------------------------------------------------------------------+
bool CWnd::OnDragProcess(const int x,const int y)
{
Shift(x-m_mouse_x,y-m_mouse_y);
//--- save
m_mouse_x=x;
m_mouse_y=y;
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of the control dragging end |
//+------------------------------------------------------------------+
bool CWnd::OnDragEnd(void)
{
if(!IS_CAN_DRAG)
return(true);
//--- enable scrolling of chart with mouse
ChartSetInteger(m_chart_id,CHART_MOUSE_SCROLL,true);
//--- generate event
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_DRAG_END,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Destroy the dragged object |
//+------------------------------------------------------------------+
bool CWnd::DragObjectDestroy(void)
{
if(m_drag_object!=NULL)
{
delete m_drag_object;
m_drag_object=NULL;
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Class CDragWnd |
//| Usage: base class for drag |
//+------------------------------------------------------------------+
class CDragWnd : public CWnd
{
protected:
int m_limit_left; // left constraint
int m_limit_top; // top constraint
int m_limit_right; // right constraint
int m_limit_bottom; // bottom constraint
public:
CDragWnd(void);
~CDragWnd(void);
//--- constraints
void Limits(const int l,const int t,const int r,const int b);
protected:
virtual bool OnDragProcess(const int x,const int y);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CDragWnd::CDragWnd(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CDragWnd::~CDragWnd(void)
{
}
//+------------------------------------------------------------------+
//| Constrain the control dragging |
//+------------------------------------------------------------------+
void CDragWnd::Limits(const int l,const int t,const int r,const int b)
{
//--- save
m_limit_left =l;
m_limit_top =t;
m_limit_right =r;
m_limit_bottom=b;
}
//+------------------------------------------------------------------+
//| Handler of control dragging process |
//+------------------------------------------------------------------+
bool CDragWnd::OnDragProcess(const int x,const int y)
{
int dx=x-m_mouse_x;
int dy=y-m_mouse_y;
//--- check shift
if(Left()+dx<m_limit_left)
dx=m_limit_left-Left();
if(Top()+dy<m_limit_top)
dy=m_limit_top-Top();
if(Right()+dx>m_limit_right)
dx=m_limit_right-Right();
if(Bottom()+dy>m_limit_bottom)
dy=m_limit_bottom-Bottom();
//--- shift
Shift(dx,dy);
//--- save
m_mouse_x=x;
m_mouse_y=y;
//--- generate event
EventChartCustom(CONTROLS_SELF_MESSAGE,ON_DRAG_PROCESS,m_id,0.0,m_name);
//--- handled
return(true);
}
//+------------------------------------------------------------------+
+307
View File
@@ -0,0 +1,307 @@
//+------------------------------------------------------------------+
//| WndClient.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "WndContainer.mqh"
#include "Panel.mqh"
#include "Scrolls.mqh"
//+------------------------------------------------------------------+
//| Class CWndClient |
//| Usage: base class to create areas with |
//| the scrollbars |
//+------------------------------------------------------------------+
class CWndClient : public CWndContainer
{
protected:
//--- flags
bool m_v_scrolled; // "vertical scrolling is possible" flag
bool m_h_scrolled; // "horizontal scrolling is possible" flag
//--- dependent controls
CPanel m_background; // the "scrollbar background" object
CScrollV m_scroll_v; // the vertical scrollbar object
CScrollH m_scroll_h; // the horizontal scrollbar object
public:
CWndClient(void);
~CWndClient(void);
//--- create
virtual bool Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- parameters
virtual bool ColorBackground(const color value) { return(m_background.ColorBackground(value)); }
virtual bool ColorBorder(const color value) { return(m_background.ColorBorder(value)); }
virtual bool BorderType(const ENUM_BORDER_TYPE flag) { return(m_background.BorderType(flag)); }
//--- settings
virtual bool VScrolled(void) { return(m_v_scrolled); }
virtual bool VScrolled(const bool flag);
virtual bool HScrolled(void) { return(m_h_scrolled); }
virtual bool HScrolled(const bool flag);
//--- ID
virtual long Id(const long id);
//--- state
virtual bool Show(void);
protected:
//--- create dependent controls
virtual bool CreateBack(void);
virtual bool CreateScrollV(void);
virtual bool CreateScrollH(void);
//--- internal event handlers
virtual bool OnResize(void);
//--- handlers of the dependent controls events
virtual bool OnVScrollShow(void) { return(true); }
virtual bool OnVScrollHide(void) { return(true); }
virtual bool OnHScrollShow(void) { return(true); }
virtual bool OnHScrollHide(void) { return(true); }
virtual bool OnScrollLineDown(void) { return(true); }
virtual bool OnScrollLineUp(void) { return(true); }
virtual bool OnScrollLineLeft(void) { return(true); }
virtual bool OnScrollLineRight(void) { return(true); }
//--- resize
virtual bool Rebound(const CRect &rect);
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
EVENT_MAP_BEGIN(CWndClient)
ON_NAMED_EVENT(ON_SHOW,m_scroll_v,OnVScrollShow)
ON_NAMED_EVENT(ON_HIDE,m_scroll_v,OnVScrollHide)
ON_EVENT(ON_SCROLL_DEC,m_scroll_v,OnScrollLineUp)
ON_EVENT(ON_SCROLL_INC,m_scroll_v,OnScrollLineDown)
ON_NAMED_EVENT(ON_SHOW,m_scroll_h,OnHScrollShow)
ON_NAMED_EVENT(ON_HIDE,m_scroll_h,OnHScrollHide)
ON_EVENT(ON_SCROLL_DEC,m_scroll_h,OnScrollLineLeft)
ON_EVENT(ON_SCROLL_INC,m_scroll_h,OnScrollLineRight)
EVENT_MAP_END(CWndContainer)
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CWndClient::CWndClient(void) : m_v_scrolled(false),
m_h_scrolled(false)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CWndClient::~CWndClient(void)
{
}
//+------------------------------------------------------------------+
//| Create a control |
//+------------------------------------------------------------------+
bool CWndClient::Create(const long chart,const string name,const int subwin,const int x1,const int y1,const int x2,const int y2)
{
//--- call of the method of the parent class
if(!CWndContainer::Create(chart,name,subwin,x1,y1,x2,y2))
return(false);
//--- create dependent controls
if(!CreateBack())
return(false);
if(m_v_scrolled && !CreateScrollV())
return(false);
if(m_h_scrolled && !CreateScrollH())
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create scrollbar background |
//+------------------------------------------------------------------+
bool CWndClient::CreateBack(void)
{
//--- create
if(!m_background.Create(m_chart_id,m_name+"Back",m_subwin,0,0,Width(),Height()))
return(false);
if(!m_background.ColorBorder(CONTROLS_CLIENT_COLOR_BORDER))
return(false);
if(!m_background.ColorBackground(CONTROLS_CLIENT_COLOR_BG))
return(false);
if(!Add(m_background))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create vertical scrollbar |
//+------------------------------------------------------------------+
bool CWndClient::CreateScrollV(void)
{
//--- calculate coordinates
int x1=Width()-CONTROLS_SCROLL_SIZE-CONTROLS_BORDER_WIDTH;
int y1=CONTROLS_BORDER_WIDTH;
int x2=Width()-CONTROLS_BORDER_WIDTH;
int y2=Height()-CONTROLS_BORDER_WIDTH;
if(m_h_scrolled) y2-=CONTROLS_SCROLL_SIZE;
//--- create
if(!m_scroll_v.Create(m_chart_id,m_name+"VScroll",m_subwin,x1,y1,x2,y2))
return(false);
if(!Add(m_scroll_v))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create horizontal scrollbar |
//+------------------------------------------------------------------+
bool CWndClient::CreateScrollH(void)
{
//--- calculate coordinates
int x1=CONTROLS_BORDER_WIDTH;
int y1=Height()-CONTROLS_SCROLL_SIZE-CONTROLS_BORDER_WIDTH;
int x2=Width()-CONTROLS_BORDER_WIDTH;
int y2=Height()-CONTROLS_BORDER_WIDTH;
if(m_v_scrolled) x2-=CONTROLS_SCROLL_SIZE;
//--- create
if(!m_scroll_h.Create(m_chart_id,m_name+"HScroll",m_subwin,x1,y1,x2,y2))
return(false);
if(!Add(m_scroll_h))
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Set up vertical scrollbar |
//+------------------------------------------------------------------+
bool CWndClient::VScrolled(const bool flag)
{
if(m_v_scrolled==flag)
return(true);
//--- there are changes
int d_size=0;
if(flag)
{
//--- create vertical scrollbar
if(!CreateScrollV())
return(false);
//--- need to shorten horizontal scrollbar (if there is one)
d_size=-CONTROLS_SCROLL_SIZE;
}
else
{
//--- delete vertical scrollbar
m_scroll_v.Destroy();
if(!Delete(m_scroll_v))
return(false);
//--- need to lengthen horizontal scrollbar (if there is one)
d_size=CONTROLS_SCROLL_SIZE;
}
m_v_scrolled=flag;
//--- change width of horizontal scrollbar (if there is one)
if(m_h_scrolled)
{
if(!m_scroll_h.Width(m_scroll_h.Width()+d_size))
return(false);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Set up horizontal scrollbar |
//+------------------------------------------------------------------+
bool CWndClient::HScrolled(const bool flag)
{
if(m_h_scrolled==flag)
return(true);
//--- there are changes
int d_size=0;
if(flag)
{
//--- create horizontal scrollbar
if(!CreateScrollH())
return(false);
//--- need to shorten vertical scrollbar (if there is one)
d_size=-CONTROLS_SCROLL_SIZE;
}
else
{
//--- delete horizontal scrollbar
m_scroll_h.Destroy();
if(!Delete(m_scroll_h))
return(false);
//--- need to lengthen vertical scrollbar (if there is one)
d_size=CONTROLS_SCROLL_SIZE;
}
m_h_scrolled=flag;
//--- change width of vertical scrollbar (if there is one)
if(m_v_scrolled)
{
if(!m_scroll_v.Height(m_scroll_v.Height()+d_size))
return(false);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Set ID of control |
//+------------------------------------------------------------------+
long CWndClient::Id(const long id)
{
//--- reserve ID for container
long id_used=CWndContainer::Id(id);
//---
if(!m_v_scrolled)
id_used+=m_scroll_v.Id(id+id_used);
if(!m_h_scrolled)
id_used+=m_scroll_h.Id(id+id_used);
//--- return number of used IDs
return(id_used);
}
//+------------------------------------------------------------------+
//| Makes the control visible |
//+------------------------------------------------------------------+
bool CWndClient::Show(void)
{
//--- call of the method of the parent class
CWndContainer::Show();
//---
if(!m_v_scrolled)
m_scroll_v.Hide();
if(!m_h_scrolled)
m_scroll_h.Hide();
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Handler of resizing |
//+------------------------------------------------------------------+
bool CWndClient::OnResize(void)
{
//--- call of the method of the parent class
if(!CWndContainer::OnResize())
return(false);
//--- resize background
int d_size=0;
m_background.Width(Width());
m_background.Height(Height());
//---
if(m_v_scrolled)
{
//--- move vertical scrollbar
m_scroll_v.Move(Right()-CONTROLS_SCROLL_SIZE,Top());
//--- modify vertical scrollbar
d_size=(m_h_scrolled) ? CONTROLS_SCROLL_SIZE : 0;
m_scroll_v.Height(Height()-d_size);
}
if(m_h_scrolled)
{
//--- move horizontal scrollbar
m_scroll_h.Move(Left(),Bottom()-CONTROLS_SCROLL_SIZE);
//--- modify horizontal scrollbar
d_size=(m_v_scrolled) ? CONTROLS_SCROLL_SIZE : 0;
m_scroll_h.Width(Width()-d_size);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Resize |
//+------------------------------------------------------------------+
bool CWndClient::Rebound(const CRect &rect)
{
m_rect.SetBound(rect);
//--- call virtual event handler
return(OnResize());
}
//+------------------------------------------------------------------+
+472
View File
@@ -0,0 +1,472 @@
//+------------------------------------------------------------------+
//| WndContainer.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "Wnd.mqh"
#include <Arrays\ArrayObj.mqh>
//+------------------------------------------------------------------+
//| Class CWndContainer |
//| Usage: base class of the combined control |
//+------------------------------------------------------------------+
class CWndContainer : public CWnd
{
private:
CArrayObj m_controls; // container of the control
public:
CWndContainer(void);
~CWndContainer(void);
//--- release memory
virtual void Destroy(const int reason=0);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
virtual bool OnMouseEvent(const int x,const int y,const int flags);
//--- access the contents of container
int ControlsTotal(void) const { return(m_controls.Total()); }
CWnd* Control(const int ind) const { return(dynamic_cast<CWnd *>(m_controls.At(ind))); }
virtual CWnd* ControlFind(const long id);
//--- for mouse cursor focus
virtual bool MouseFocusKill(const long id=-1);
//--- fill
bool Add(CWnd *control);
bool Add(CWnd &control);
//--- underflowing
bool Delete(CWnd *control);
bool Delete(CWnd &control);
//--- geometry
virtual bool Move(const int x,const int y);
virtual bool Move(const CPoint &point);
virtual bool Shift(const int dx,const int dy);
//--- ID
virtual long Id(const long id);
//--- state
virtual bool Enable(void);
virtual bool Disable(void);
virtual bool Show(void);
virtual bool Hide(void);
//--- methods for working with files
virtual bool Save(const int file_handle);
virtual bool Load(const int file_handle);
protected:
//--- internal event handlers
virtual bool OnResize(void);
virtual bool OnActivate(void);
virtual bool OnDeactivate(void);
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
bool CWndContainer::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
//--- if an object is being dragged, pass control to the special drag object
if(m_drag_object!=NULL && m_drag_object.OnEvent(id,lparam,dparam,sparam))
return(true);
//--- loop by elements of group
int total=m_controls.Total();
for(int i=total-1;i>=0;i--)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
if(control.OnEvent(id,lparam,dparam,sparam))
return(true);
}
//--- not handled
return(false);
}
//+------------------------------------------------------------------+
//| Common handler of mouse events |
//+------------------------------------------------------------------+
bool CWndContainer::OnMouseEvent(const int x,const int y,const int flags)
{
if(!IS_VISIBLE)
return(false);
//--- if an object is being dragged, pass control to the special drag object
if(m_drag_object!=NULL && m_drag_object.OnMouseEvent(x,y,flags))
return(true);
//--- loop by elements of group
int total=m_controls.Total();
for(int i=total-1;i>=0;i--)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
if(control.OnMouseEvent(x,y,flags))
return(true);
}
//--- call of the method of the parent class
return(CWnd::OnMouseEvent(x,y,flags));
}
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CWndContainer::CWndContainer(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CWndContainer::~CWndContainer(void)
{
}
//+------------------------------------------------------------------+
//| Delete group of controls |
//+------------------------------------------------------------------+
void CWndContainer::Destroy(const int reason)
{
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(0);
//--- check of pointer
if(control==NULL)
continue;
control.Destroy();
m_controls.Delete(0);
}
}
//+------------------------------------------------------------------+
//| Find control by specified ID |
//+------------------------------------------------------------------+
CWnd* CWndContainer::ControlFind(const long id)
{
CWnd *result=CWnd::ControlFind(id);
//---
if(result!=NULL)
return(result);
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
result=control.ControlFind(id);
if(result!=NULL)
break;
}
//--- return the result
return(result);
}
//+------------------------------------------------------------------+
//| Remove the mouse focus from control |
//+------------------------------------------------------------------+
bool CWndContainer::MouseFocusKill(const long id=-1)
{
if(!IS_ACTIVE)
return(false);
Deactivate();
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
control.MouseFocusKill();
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Add control to the group (by pointer) |
//+------------------------------------------------------------------+
bool CWndContainer::Add(CWnd *control)
{
//--- check of pointer
if(control==NULL)
return(false);
//--- correct the coordinates of added control
control.Shift(Left(),Top());
//--- "projecting" the group flag "visibility" to the added element
if(IS_VISIBLE && control.IsVisible())
{
//--- element will be "visible" only if the group is "visible" and the element is completely "within" this group
control.Visible(Contains(control));
}
else
control.Hide();
//--- "projecting" the group flag "enabled" to the added element
if(IS_ENABLED)
control.Enable();
else
control.Disable();
//--- adding
return(m_controls.Add(control));
}
//+------------------------------------------------------------------+
//| Add control to the group (by reference) |
//+------------------------------------------------------------------+
bool CWndContainer::Add(CWnd &control)
{
//--- add by pointer
return(Add((CWnd*)GetPointer(control)));
}
//+------------------------------------------------------------------+
//| Delete control from the group (by pointer) |
//+------------------------------------------------------------------+
bool CWndContainer::Delete(CWnd *control)
{
//--- check of pointer
if(control==NULL)
return(false);
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *pointer=Control(i);
//--- check of pointer
if(pointer==NULL)
continue;
//--- delete item from group
if(pointer==control)
return(m_controls.Delete(i));
}
//--- failure
return(false);
}
//+------------------------------------------------------------------+
//| Delete control from the group (by reference) |
//+------------------------------------------------------------------+
bool CWndContainer::Delete(CWnd &control)
{
//--- delete by pointer
return(Delete((CWnd*)GetPointer(control)));
}
//+------------------------------------------------------------------+
//| Absolute movement of the controls group |
//+------------------------------------------------------------------+
bool CWndContainer::Move(const int x,const int y)
{
//--- relative movement
return(Shift(x-Left(),y-Top()));
}
//+------------------------------------------------------------------+
//| Absolute movement of the controls group |
//+------------------------------------------------------------------+
bool CWndContainer::Move(const CPoint &point)
{
//--- relative movement
return(Shift(point.x-Left(),point.y-Top()));
}
//+------------------------------------------------------------------+
//| Relative movement of the controls group |
//+------------------------------------------------------------------+
bool CWndContainer::Shift(const int dx,const int dy)
{
//--- call of the method of the parent class
if(!CWnd::Shift(dx,dy)) return(false);
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
//--- move the group item
control.Shift(dx,dy);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Set ID of control |
//+------------------------------------------------------------------+
long CWndContainer::Id(const long id)
{
//--- reserve ID for container
long id_used=1;
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
id_used+=control.Id(id+id_used);
}
m_id=id;
//--- return number of used IDs
return(id_used);
}
//+------------------------------------------------------------------+
//| Enables event handling by the group of controls |
//+------------------------------------------------------------------+
bool CWndContainer::Enable(void)
{
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
control.Enable();
}
//--- call of the method of the parent class
return(CWnd::Enable());
}
//+------------------------------------------------------------------+
//| Disables event handling by the group of controls |
//+------------------------------------------------------------------+
bool CWndContainer::Disable(void)
{
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
control.Disable();
}
//--- call of the method of the parent class
return(CWnd::Disable());
}
//+------------------------------------------------------------------+
//| Makes the group of controls visible |
//+------------------------------------------------------------------+
bool CWndContainer::Show(void)
{
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
control.Show();
}
//--- call of the method of the parent class
return(CWnd::Show());
}
//+------------------------------------------------------------------+
//| Makes the group of controls hidden |
//+------------------------------------------------------------------+
bool CWndContainer::Hide(void)
{
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
control.Hide();
}
//--- call of the method of the parent class
return(CWnd::Hide());
}
//+------------------------------------------------------------------+
//| Handler of resizing |
//+------------------------------------------------------------------+
bool CWndContainer::OnResize()
{
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
if(!control.Align(Rect()))
return(false);
}
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of activating the group of controls |
//+------------------------------------------------------------------+
bool CWndContainer::OnActivate(void)
{
if(IS_ACTIVE)
return(false);
Activate();
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
control.Activate();
}
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of deactivating the group of controls |
//+------------------------------------------------------------------+
bool CWndContainer::OnDeactivate(void)
{
if(!IS_ACTIVE)
return(false);
Deactivate();
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
control.Deactivate();
}
//--- handled
return(true);
}
//+------------------------------------------------------------------+
//| Save |
//+------------------------------------------------------------------+
bool CWndContainer::Save(const int file_handle)
{
bool result=true;
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
result&=control.Save(file_handle);
}
//--- result
return(result);
}
//+------------------------------------------------------------------+
//| Load |
//+------------------------------------------------------------------+
bool CWndContainer::Load(const int file_handle)
{
bool result=true;
//--- loop by elements of group
int total=m_controls.Total();
for(int i=0;i<total;i++)
{
CWnd *control=Control(i);
//--- check of pointer
if(control==NULL)
continue;
result&=control.Load(file_handle);
}
//--- result
return(result);
}
//+------------------------------------------------------------------+
+262
View File
@@ -0,0 +1,262 @@
//+------------------------------------------------------------------+
//| WndObj.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "Wnd.mqh"
//+------------------------------------------------------------------+
//| Class CWndObj |
//| Usage: base class to work with chart objects |
//+------------------------------------------------------------------+
class CWndObj : public CWnd
{
private:
//--- flags of object
bool m_undeletable; // "object is not deletable" flag
bool m_unchangeable; // "object is not changeable" flag
bool m_unmoveable; // "object is not movable" flag
protected:
//--- parameters of the chart object
string m_text; // object text
color m_color; // object color
color m_color_background; // object background color
color m_color_border; // object border color
string m_font; // object font
int m_font_size; // object font size
long m_zorder; // Z order
public:
CWndObj(void);
~CWndObj(void);
//--- chart event handler
virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam);
//--- set up the object
string Text(void) const { return(m_text); }
bool Text(const string value);
color Color(void) const { return(m_color); }
bool Color(const color value);
color ColorBackground(void) const { return(m_color_background); }
bool ColorBackground(const color value);
color ColorBorder(void) const { return(m_color_border); }
bool ColorBorder(const color value);
string Font(void) const { return(m_font); }
bool Font(const string value);
int FontSize(void) const { return(m_font_size); }
bool FontSize(const int value);
long ZOrder(void) const { return(m_zorder); }
bool ZOrder(const long value);
protected:
//--- handlers of object events
virtual bool OnObjectCreate(void);
virtual bool OnObjectChange(void);
virtual bool OnObjectDelete(void);
virtual bool OnObjectDrag(void);
//--- handlers of object settings
virtual bool OnSetText(void) { return(true); }
virtual bool OnSetColor(void) { return(true); }
virtual bool OnSetColorBackground(void) { return(true); }
virtual bool OnSetColorBorder(void) { return(true); }
virtual bool OnSetFont(void) { return(true); }
virtual bool OnSetFontSize(void) { return(true); }
virtual bool OnSetZOrder(void) { return(true); }
//--- internal event handlers
virtual bool OnDestroy(void) { return(ObjectDelete(m_chart_id,m_name)); }
virtual bool OnChange(void);
};
//+------------------------------------------------------------------+
//| Common handler of chart events |
//+------------------------------------------------------------------+
bool CWndObj::OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam)
{
if(m_name==sparam)
{
//--- object name and string parameters are equal
//--- this means that event should be handled
switch(id)
{
case CHARTEVENT_OBJECT_CREATE: return(OnObjectCreate());
case CHARTEVENT_OBJECT_CHANGE: return(OnObjectChange());
case CHARTEVENT_OBJECT_DELETE: return(OnObjectDelete());
case CHARTEVENT_OBJECT_DRAG : return(OnObjectDrag());
}
}
//--- event was not handled
return(CWnd::OnEvent(id,lparam,dparam,sparam));
}
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CWndObj::CWndObj(void) : m_color(clrNONE),
m_color_background(clrNONE),
m_color_border(clrNONE),
m_font(CONTROLS_FONT_NAME),
m_font_size(CONTROLS_FONT_SIZE),
m_zorder(0),
m_undeletable(true),
m_unchangeable(true),
m_unmoveable(true)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CWndObj::~CWndObj(void)
{
}
//+------------------------------------------------------------------+
//| Set the "Text" parameter |
//+------------------------------------------------------------------+
bool CWndObj::Text(const string value)
{
//--- save new value of parameter
m_text=value;
//--- call virtual event handler
return(OnSetText());
}
//+------------------------------------------------------------------+
//| Set the "Color" parameter |
//+------------------------------------------------------------------+
bool CWndObj::Color(const color value)
{
//--- save new value of parameter
m_color=value;
//--- call virtual event handler
return(OnSetColor());
}
//+------------------------------------------------------------------+
//| Setting the "Background color" parameter |
//+------------------------------------------------------------------+
bool CWndObj::ColorBackground(const color value)
{
//--- save new value of parameter
m_color_background=value;
//--- call virtual event handler
return(OnSetColorBackground());
}
//+------------------------------------------------------------------+
//| Set the "Border color" parameter |
//+------------------------------------------------------------------+
bool CWndObj::ColorBorder(const color value)
{
//--- save new value of parameter
m_color_border=value;
//--- call virtual event handler
return(OnSetColorBorder());
}
//+------------------------------------------------------------------+
//| Set the "Font" parameter |
//+------------------------------------------------------------------+
bool CWndObj::Font(const string value)
{
//--- save new value of parameter
m_font=value;
//--- call virtual event handler
return(OnSetFont());
}
//+------------------------------------------------------------------+
//| Set the "Font size" parameter |
//+------------------------------------------------------------------+
bool CWndObj::FontSize(const int value)
{
//--- save new value of parameter
m_font_size=value;
//--- call virtual event handler
return(OnSetFontSize());
}
//+------------------------------------------------------------------+
//| Set the "Z order" parameter |
//+------------------------------------------------------------------+
bool CWndObj::ZOrder(const long value)
{
//--- save new value of parameter
m_zorder=value;
//--- call virtual event handler
return(OnSetZOrder());
}
//+------------------------------------------------------------------+
//| Handler of the "Object creation" event |
//+------------------------------------------------------------------+
bool CWndObj::OnObjectCreate(void)
{
//--- event is handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of the "Object modification" event |
//+------------------------------------------------------------------+
bool CWndObj::OnObjectChange(void)
{
//--- if object is not changeable
if(m_unchangeable)
{
//--- restore position
if(!OnMove())
return(false);
//--- restore size
if(!OnResize())
return(false);
//--- restore settings
if(!OnChange())
return(false);
}
//--- event is handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of the "Object deletion" event |
//+------------------------------------------------------------------+
bool CWndObj::OnObjectDelete(void)
{
//--- if object is not deletable
if(m_undeletable)
{
//--- restore the object
if(!OnCreate())
return(false);
//--- restore settings
if(!OnChange())
return(false);
//--- restore visibility
return(IS_VISIBLE ? OnShow():OnHide());
}
//--- event is handled
return(true);
}
//+------------------------------------------------------------------+
//| Handler of the "Object dragging" event |
//+------------------------------------------------------------------+
bool CWndObj::OnObjectDrag(void)
{
//--- if object is not movable
if(m_unmoveable)
{
//--- restore position
return(OnMove());
}
//--- event is handled
return(true);
}
//+------------------------------------------------------------------+
//| Set up the object |
//+------------------------------------------------------------------+
bool CWndObj::OnChange(void)
{
//--- set up the chart object according to previously set parameters
if(!OnSetText())
return(false);
if(!OnSetFont())
return(false);
if(!OnSetFontSize())
return(false);
if(!OnSetColor())
return(false);
if(!OnSetColorBackground())
return(false);
if(!OnSetColorBorder())
return(false);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 576 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 632 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 568 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 568 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 824 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

File diff suppressed because it is too large Load Diff
+715
View File
@@ -0,0 +1,715 @@
//+------------------------------------------------------------------+
//| ExpertBase.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include <Trade\SymbolInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\OrderInfo.mqh>
#include <Trade\DealInfo.mqh>
#include <Trade\HistoryOrderInfo.mqh>
#include <Indicators\Indicators.mqh>
//+------------------------------------------------------------------+
//| enumerations |
//+------------------------------------------------------------------+
//--- constants of identification of trend
enum ENUM_TYPE_TREND
{
TYPE_TREND_HARD_DOWN =0, // strong down trend
TYPE_TREND_DOWN =1, // down trend
TYPE_TREND_SOFT_DOWN =2, // weak down trend
TYPE_TREND_FLAT =3, // no trend
TYPE_TREND_SOFT_UP =4, // weak up trend
TYPE_TREND_UP =5, // up trend
TYPE_TREND_HARD_UP =6 // strong up trend
};
//--- flags of used timeseries
enum ENUM_USED_SERIES
{
USE_SERIES_OPEN =0x1,
USE_SERIES_HIGH =0x2,
USE_SERIES_LOW =0x4,
USE_SERIES_CLOSE =0x8,
USE_SERIES_SPREAD =0x10,
USE_SERIES_TIME =0x20,
USE_SERIES_TICK_VOLUME=0x40,
USE_SERIES_REAL_VOLUME=0x80
};
//--- phases of initialization of an object
enum ENUM_INIT_PHASE
{
INIT_PHASE_FIRST =0, // start phase (only Init(...) can be called)
INIT_PHASE_TUNING =1, // phase of tuning (set in Init(...))
INIT_PHASE_VALIDATION =2, // phase of checking of parameters(set in ValidationSettings(...))
INIT_PHASE_COMPLETE =3 // end phase (set in InitIndicators(...))
};
//+------------------------------------------------------------------+
//| Macro definitions. |
//+------------------------------------------------------------------+
//--- check the use of timeseries
#define IS_OPEN_SERIES_USAGE ((m_used_series&USE_SERIES_OPEN)!=0)
#define IS_HIGH_SERIES_USAGE ((m_used_series&USE_SERIES_HIGH)!=0)
#define IS_LOW_SERIES_USAGE ((m_used_series&USE_SERIES_LOW)!=0)
#define IS_CLOSE_SERIES_USAGE ((m_used_series&USE_SERIES_CLOSE)!=0)
#define IS_SPREAD_SERIES_USAGE ((m_used_series&USE_SERIES_SPREAD)!=0)
#define IS_TIME_SERIES_USAGE ((m_used_series&USE_SERIES_TIME)!=0)
#define IS_TICK_VOLUME_SERIES_USAGE ((m_used_series&USE_SERIES_TICK_VOLUME)!=0)
#define IS_REAL_VOLUME_SERIES_USAGE ((m_used_series&USE_SERIES_REAL_VOLUME)!=0)
//+------------------------------------------------------------------+
//| Class CExpertBase. |
//| Purpose: Base class of component of Expert Advisor. |
//| Derives from class CObject. |
//+------------------------------------------------------------------+
class CExpertBase : public CObject
{
protected:
//--- variables
ulong m_magic; // expert magic number
ENUM_INIT_PHASE m_init_phase; // the phase (stage) of initialization of object
bool m_other_symbol; // flag of a custom work symbols (different from one of the Expert Advisor)
CSymbolInfo *m_symbol; // pointer to the object-symbol
bool m_other_period; // flag of a custom timeframe (different from one of the Expert Advisor)
ENUM_TIMEFRAMES m_period; // work timeframe
double m_adjusted_point; // "weight" 2/4 of a point
CAccountInfo m_account; // object-deposit
ENUM_ACCOUNT_MARGIN_MODE m_margin_mode; // netting or hedging
ENUM_TYPE_TREND m_trend_type; // identifier of trend
bool m_every_tick; // flag of starting the analysis from current (incomplete) bar
//--- timeseries
int m_used_series; // flags of using of series
CiOpen *m_open; // pointer to the object for access to open prices of bars
CiHigh *m_high; // pointer to the object for access to high prices of bars
CiLow *m_low; // pointer to the object for access to low prices of bars
CiClose *m_close; // pointer to the object for access to close prices of bars
CiSpread *m_spread; // pointer to the object for access to spreads
CiTime *m_time; // pointer to the object for access to time of closing of bars
CiTickVolume *m_tick_volume; // pointer to the object for access to tick volumes of bars
CiRealVolume *m_real_volume; // pointer to the object for access to real volumes of bars
public:
CExpertBase(void);
~CExpertBase(void);
//--- methods of access to protected data
ENUM_INIT_PHASE InitPhase(void) const { return(m_init_phase); }
void TrendType(ENUM_TYPE_TREND value) { m_trend_type=value; }
int UsedSeries(void) const;
void EveryTick(bool value) { m_every_tick=value; }
//--- methods of access to protected data
double Open(int ind) const;
double High(int ind) const;
double Low(int ind) const;
double Close(int ind) const;
int Spread(int ind) const;
datetime Time(int ind) const;
long TickVolume(int ind) const;
long RealVolume(int ind) const;
//--- methods of initialization of the object
virtual bool Init(CSymbolInfo *symbol,ENUM_TIMEFRAMES period,double point);
bool Symbol(string name);
bool Period(ENUM_TIMEFRAMES value);
void Magic(ulong value) { m_magic=value; }
void SetMarginMode(void) { m_margin_mode=(ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE); }
//--- method of verification of settings
virtual bool ValidationSettings();
//--- methods of creating the indicator and timeseries
virtual bool SetPriceSeries(CiOpen *open,CiHigh *high,CiLow *low,CiClose *close);
virtual bool SetOtherSeries(CiSpread *spread,CiTime *time,CiTickVolume *tick_volume,CiRealVolume *real_volume);
virtual bool InitIndicators(CIndicators *indicators=NULL);
protected:
//--- methods initialization of timeseries
bool InitOpen(CIndicators *indicators);
bool InitHigh(CIndicators *indicators);
bool InitLow(CIndicators *indicators);
bool InitClose(CIndicators *indicators);
bool InitSpread(CIndicators *indicators);
bool InitTime(CIndicators *indicators);
bool InitTickVolume(CIndicators *indicators);
bool InitRealVolume(CIndicators *indicators);
//--- method of getting the measure units of price levels
virtual double PriceLevelUnit(void) { return(m_adjusted_point); }
//--- method of getting index of bar the analysis starts with
virtual int StartIndex(void) { return((m_every_tick?0:1)); }
virtual bool CompareMagic(ulong magic) { return(m_magic==magic); }
bool IsHedging(void) const { return(m_margin_mode==ACCOUNT_MARGIN_MODE_RETAIL_HEDGING); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
void CExpertBase::CExpertBase(void) : m_magic(0),
m_margin_mode(ACCOUNT_MARGIN_MODE_RETAIL_NETTING),
m_init_phase(INIT_PHASE_FIRST),
m_other_symbol(false),
m_symbol(NULL),
m_other_period(false),
m_period(PERIOD_CURRENT),
m_adjusted_point(1.0),
m_trend_type(TYPE_TREND_FLAT),
m_every_tick(false),
m_used_series(0),
m_open(NULL),
m_high(NULL),
m_low(NULL),
m_close(NULL),
m_spread(NULL),
m_time(NULL),
m_tick_volume(NULL),
m_real_volume(NULL)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
void CExpertBase::~CExpertBase(void)
{
//--- if the symbol is "custom", delete it
if(m_other_symbol && m_symbol!=NULL)
delete m_symbol;
//--- release of "custom" timeseries
if(m_other_symbol || m_other_period)
{
if(IS_OPEN_SERIES_USAGE && CheckPointer(m_open)==POINTER_DYNAMIC)
delete m_open;
if(IS_HIGH_SERIES_USAGE && CheckPointer(m_high)==POINTER_DYNAMIC)
delete m_high;
if(IS_LOW_SERIES_USAGE && CheckPointer(m_low)==POINTER_DYNAMIC)
delete m_low;
if(IS_CLOSE_SERIES_USAGE && CheckPointer(m_close)==POINTER_DYNAMIC)
delete m_close;
if(IS_SPREAD_SERIES_USAGE && CheckPointer(m_spread)==POINTER_DYNAMIC)
delete m_spread;
if(IS_TIME_SERIES_USAGE && CheckPointer(m_time)==POINTER_DYNAMIC)
delete m_time;
if(IS_TICK_VOLUME_SERIES_USAGE && CheckPointer(m_tick_volume)==POINTER_DYNAMIC)
delete m_tick_volume;
if(IS_REAL_VOLUME_SERIES_USAGE && CheckPointer(m_real_volume)==POINTER_DYNAMIC)
delete m_real_volume;
}
}
//+------------------------------------------------------------------+
//| Get flags of used timeseries |
//+------------------------------------------------------------------+
int CExpertBase::UsedSeries(void) const
{
if(m_other_symbol || m_other_period)
return(0);
//---
return(m_used_series);
}
//+------------------------------------------------------------------+
//| Initialization of object. |
//+------------------------------------------------------------------+
bool CExpertBase::Init(CSymbolInfo *symbol,ENUM_TIMEFRAMES period,double point)
{
//--- check the initialization phase
if(m_init_phase!=INIT_PHASE_FIRST)
{
Print(__FUNCTION__+": attempt of re-initialization");
return(false);
}
//--- check of pointer
if(symbol==NULL)
{
Print(__FUNCTION__+": error initialization");
return(false);
}
//--- initialization
m_symbol =symbol;
m_period =period;
m_adjusted_point=point;
m_other_symbol =false;
m_other_period =false;
SetMarginMode();
//--- primary initialization is successful, pass to the phase of tuning
m_init_phase=INIT_PHASE_TUNING;
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Changing work symbol. |
//+------------------------------------------------------------------+
bool CExpertBase::Symbol(string name)
{
//--- check the initialization phase
if(m_init_phase!=INIT_PHASE_TUNING)
{
Print(__FUNCTION__+": changing of symbol is forbidden");
return(false);
}
if(m_symbol!=NULL)
{
//--- symbol has been already set
if(m_symbol.Name()==name)
return(true);
//--- symbol is not the one required, but is already "custom"
if(m_other_symbol)
{
if(!m_symbol.Name(name))
{
//--- failed to initialize the symbol
delete m_symbol;
return(false);
}
return(true);
}
}
m_symbol=new CSymbolInfo;
//--- check of pointer
if(m_symbol==NULL)
{
Print(__FUNCTION__+": error of changing of symbol");
return(false);
}
if(!m_symbol.Name(name))
{
//--- failed to initialize the symbol
delete m_symbol;
return(false);
}
m_other_symbol=true;
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Changing work timeframe. |
//+------------------------------------------------------------------+
bool CExpertBase::Period(ENUM_TIMEFRAMES value)
{
//--- check the initialization phase
if(m_init_phase!=INIT_PHASE_TUNING)
{
Print(__FUNCTION__+": changing of timeframe is forbidden");
return(false);
}
if(m_period==value)
return(true);
//--- change work timeframe
m_period=value;
m_other_period=true;
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Checking adjustable parameters |
//+------------------------------------------------------------------+
bool CExpertBase::ValidationSettings()
{
//--- rechecking parameters
if(m_init_phase==INIT_PHASE_VALIDATION)
return(true);
//--- check the initialization phase
if(m_init_phase!=INIT_PHASE_TUNING)
{
Print(__FUNCTION__+": not the right time to check parameters");
return(false);
}
//--- initial check of parameters is successful, phase of tuning is over
m_init_phase=INIT_PHASE_VALIDATION;
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Setting pointers of price timeseries. |
//+------------------------------------------------------------------+
bool CExpertBase::SetPriceSeries(CiOpen *open,CiHigh *high,CiLow *low,CiClose *close)
{
//--- check the initialization phase
if(m_init_phase!=INIT_PHASE_VALIDATION)
{
Print(__FUNCTION__+": changing of timeseries is forbidden");
return(false);
}
//--- check pointers
if((IS_OPEN_SERIES_USAGE && open==NULL) ||
(IS_HIGH_SERIES_USAGE && high==NULL) ||
(IS_LOW_SERIES_USAGE && low==NULL) ||
(IS_CLOSE_SERIES_USAGE && close==NULL))
{
Print(__FUNCTION__+": NULL pointer");
return(false);
}
m_open =open;
m_high =high;
m_low =low;
m_close=close;
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Setting pointers of other timeseries. |
//+------------------------------------------------------------------+
bool CExpertBase::SetOtherSeries(CiSpread *spread,CiTime *time,CiTickVolume *tick_volume,CiRealVolume *real_volume)
{
//--- check the initialization phase
if(m_init_phase!=INIT_PHASE_VALIDATION)
{
Print(__FUNCTION__+": changing of timeseries is forbidden");
return(false);
}
//--- check pointers
if((IS_SPREAD_SERIES_USAGE && spread==NULL) ||
(IS_TIME_SERIES_USAGE && time==NULL) ||
(IS_TICK_VOLUME_SERIES_USAGE && tick_volume==NULL) ||
(IS_REAL_VOLUME_SERIES_USAGE && real_volume==NULL))
{
Print(__FUNCTION__+": NULL pointer");
return(false);
}
m_spread =spread;
m_time =time;
m_tick_volume=tick_volume;
m_real_volume=real_volume;
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Initialization of indicators and timeseries. |
//+------------------------------------------------------------------+
bool CExpertBase::InitIndicators(CIndicators *indicators)
{
//--- this call is for compatibility with the previous version
if(!ValidationSettings())
return(false);
//--- check the initialization phase
if(m_init_phase!=INIT_PHASE_VALIDATION)
{
Print(__FUNCTION__+": parameters of setting are not checked");
return(false);
}
if(!m_other_symbol && !m_other_period)
return(true);
//--- check pointers
if(m_symbol==NULL)
return(false);
if(indicators==NULL)
return(false);
//--- initialization of required timeseries
if(IS_OPEN_SERIES_USAGE && !InitOpen(indicators))
return(false);
if(IS_HIGH_SERIES_USAGE && !InitHigh(indicators))
return(false);
if(IS_LOW_SERIES_USAGE && !InitLow(indicators))
return(false);
if(IS_CLOSE_SERIES_USAGE && !InitClose(indicators))
return(false);
if(IS_SPREAD_SERIES_USAGE && !InitSpread(indicators))
return(false);
if(IS_TIME_SERIES_USAGE && !InitTime(indicators))
return(false);
if(IS_TICK_VOLUME_SERIES_USAGE && !InitTickVolume(indicators))
return(false);
if(IS_REAL_VOLUME_SERIES_USAGE && !InitRealVolume(indicators))
return(false);
//--- initialization of object (from the point of view of the base class) has been performed successfully
//--- now it's impossible to change anything in the settings
m_init_phase=INIT_PHASE_COMPLETE;
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Access to data of the Open timeseries. |
//+------------------------------------------------------------------+
double CExpertBase::Open(int ind) const
{
//--- check pointer
if(m_open==NULL)
return(EMPTY_VALUE);
//--- return the result
return(m_open.GetData(ind));
}
//+------------------------------------------------------------------+
//| Access to data of the High timeseries. |
//+------------------------------------------------------------------+
double CExpertBase::High(int ind) const
{
//--- check pointer
if(m_high==NULL)
return(EMPTY_VALUE);
//--- return the result
return(m_high.GetData(ind));
}
//+------------------------------------------------------------------+
//| Access to data of the Low timeseries. |
//+------------------------------------------------------------------+
double CExpertBase::Low(int ind) const
{
//--- check pointer
if(m_low==NULL)
return(EMPTY_VALUE);
//--- return the result
return(m_low.GetData(ind));
}
//+------------------------------------------------------------------+
//| Access to data of the Close timeseries. |
//+------------------------------------------------------------------+
double CExpertBase::Close(int ind) const
{
//--- check pointer
if(m_close==NULL)
return(EMPTY_VALUE);
//--- return the result
return(m_close.GetData(ind));
}
//+------------------------------------------------------------------+
//| Access to data of the Spread timeseries. |
//+------------------------------------------------------------------+
int CExpertBase::Spread(int ind) const
{
//--- check pointer
if(m_spread==NULL)
return(INT_MAX);
//--- return the result
return(m_spread.GetData(ind));
}
//+------------------------------------------------------------------+
//| Access to data of the Time timeseries. |
//+------------------------------------------------------------------+
datetime CExpertBase::Time(int ind) const
{
//--- check pointer
if(m_time==NULL)
return(0);
//--- return the result
return(m_time.GetData(ind));
}
//+------------------------------------------------------------------+
//| Access to data of the TickVolume timeseries. |
//+------------------------------------------------------------------+
long CExpertBase::TickVolume(int ind) const
{
//--- check pointer
if(m_tick_volume==NULL)
return(0);
//--- return the result
return(m_tick_volume.GetData(ind));
}
//+------------------------------------------------------------------+
//| Access to data of the RealVolume timeseries. |
//+------------------------------------------------------------------+
long CExpertBase::RealVolume(int ind) const
{
//--- check pointer
if(m_real_volume==NULL)
return(0);
//--- return the result
return(m_real_volume.GetData(ind));
}
//+------------------------------------------------------------------+
//| Initialization of the Open timeseries. |
//+------------------------------------------------------------------+
bool CExpertBase::InitOpen(CIndicators *indicators)
{
//--- create object
if((m_open=new CiOpen)==NULL)
{
Print(__FUNCTION__+": error creating object");
return(false);
}
//--- add object to collection
if(!indicators.Add(m_open))
{
Print(__FUNCTION__+": error adding object");
delete m_open;
return(false);
}
//--- initialize object
if(!m_open.Create(m_symbol.Name(),m_period))
{
Print(__FUNCTION__+": error initializing object");
return(false);
}
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Initialization of the High timeseries. |
//+------------------------------------------------------------------+
bool CExpertBase::InitHigh(CIndicators *indicators)
{
//--- create object
if((m_high=new CiHigh)==NULL)
{
Print(__FUNCTION__+": error creating object");
return(false);
}
//--- add object to collection
if(!indicators.Add(m_high))
{
Print(__FUNCTION__+": error adding object");
delete m_high;
return(false);
}
//--- initialize object
if(!m_high.Create(m_symbol.Name(),m_period))
{
Print(__FUNCTION__+": error initializing object");
return(false);
}
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Initialization of the Low timeseries. |
//+------------------------------------------------------------------+
bool CExpertBase::InitLow(CIndicators *indicators)
{
//--- create object
if((m_low=new CiLow)==NULL)
{
Print(__FUNCTION__+": error creating object");
return(false);
}
//--- add object to collection
if(!indicators.Add(m_low))
{
Print(__FUNCTION__+": error adding object");
delete m_low;
return(false);
}
//--- initialize object
if(!m_low.Create(m_symbol.Name(),m_period))
{
Print(__FUNCTION__+": error initializing object");
return(false);
}
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Initialization of the Close timeseries. |
//+------------------------------------------------------------------+
bool CExpertBase::InitClose(CIndicators *indicators)
{
//--- create object
if((m_close=new CiClose)==NULL)
{
Print(__FUNCTION__+": error creating object");
return(false);
}
//--- add object to collection
if(!indicators.Add(m_close))
{
Print(__FUNCTION__+": error adding object");
delete m_close;
return(false);
}
//--- initialize object
if(!m_close.Create(m_symbol.Name(),m_period))
{
Print(__FUNCTION__+": error initializing object");
return(false);
}
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Initialization of the Spread timeseries. |
//+------------------------------------------------------------------+
bool CExpertBase::InitSpread(CIndicators *indicators)
{
//--- create object
if((m_spread=new CiSpread)==NULL)
{
Print(__FUNCTION__+": error creating object");
return(false);
}
//--- add object to collection
if(!indicators.Add(m_spread))
{
Print(__FUNCTION__+": error adding object");
delete m_spread;
return(false);
}
//--- initialize object
if(!m_spread.Create(m_symbol.Name(),m_period))
{
Print(__FUNCTION__+": error initializing object");
return(false);
}
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Initialization of the Time timeseries. |
//+------------------------------------------------------------------+
bool CExpertBase::InitTime(CIndicators *indicators)
{
//--- create object
if((m_time=new CiTime)==NULL)
{
Print(__FUNCTION__+": error creating object");
return(false);
}
//--- add object to collection
if(!indicators.Add(m_time))
{
Print(__FUNCTION__+": error adding object");
delete m_time;
return(false);
}
//--- initialize object
if(!m_time.Create(m_symbol.Name(),m_period))
{
Print(__FUNCTION__+": error initializing object");
return(false);
}
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Initialization of the TickVolume timeseries. |
//+------------------------------------------------------------------+
bool CExpertBase::InitTickVolume(CIndicators *indicators)
{
//--- create object
if((m_tick_volume=new CiTickVolume)==NULL)
{
Print(__FUNCTION__+": error creating object");
return(false);
}
//--- add object to collection
if(!indicators.Add(m_tick_volume))
{
Print(__FUNCTION__+": error adding object");
delete m_tick_volume;
return(false);
}
//--- initialize object
if(!m_tick_volume.Create(m_symbol.Name(),m_period))
{
Print(__FUNCTION__+": error initializing object");
return(false);
}
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Initialization of the RealVolume timeseries. |
//+------------------------------------------------------------------+
bool CExpertBase::InitRealVolume(CIndicators *indicators)
{
//--- create object
if((m_real_volume=new CiRealVolume)==NULL)
{
Print(__FUNCTION__+": error creating object");
return(false);
}
//--- add object to collection
if(!indicators.Add(m_real_volume))
{
Print(__FUNCTION__+": error adding object");
delete m_real_volume;
return(false);
}
//--- initialize object
if(!m_real_volume.Create(m_symbol.Name(),m_period))
{
Print(__FUNCTION__+": error initializing object");
return(false);
}
//--- ok
return(true);
}
//+------------------------------------------------------------------+
+124
View File
@@ -0,0 +1,124 @@
//+------------------------------------------------------------------+
//| ExpertMoney.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "ExpertBase.mqh"
//+------------------------------------------------------------------+
//| Class CExpertMoney. |
//| Purpose: Base class money managment. |
//| Derives from class CExpertBase. |
//+------------------------------------------------------------------+
class CExpertMoney : public CExpertBase
{
protected:
//--- input parameters
double m_percent;
public:
CExpertMoney(void);
~CExpertMoney(void);
//--- methods of setting adjustable parameters
void Percent(double percent) { m_percent=percent; }
//--- method of verification of settings
virtual bool ValidationSettings();
//---
virtual double CheckOpenLong(double price,double sl);
virtual double CheckOpenShort(double price,double sl);
virtual double CheckReverse(CPositionInfo *position,double sl);
virtual double CheckClose(CPositionInfo *position);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
void CExpertMoney::CExpertMoney(void) : m_percent(10.0)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
void CExpertMoney::~CExpertMoney(void)
{
}
//+------------------------------------------------------------------+
//| Validation settings protected data. |
//+------------------------------------------------------------------+
bool CExpertMoney::ValidationSettings()
{
if(!CExpertBase::ValidationSettings())
return(false);
//--- initial data checks
if(m_percent<0.0 || m_percent>100.0)
{
printf(__FUNCTION__+": percentage of risk should be in the range from 0 to 100 inclusive");
return(false);
}
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Getting lot size for open long position. |
//+------------------------------------------------------------------+
double CExpertMoney::CheckOpenLong(double price,double sl)
{
if(m_symbol==NULL)
return(0.0);
//---
double lot;
if(price==0.0)
lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_BUY,m_symbol.Ask(),m_percent);
else
lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_BUY,price,m_percent);
if(lot<m_symbol.LotsMin())
return(0.0);
//---
return(m_symbol.LotsMin());
}
//+------------------------------------------------------------------+
//| Getting lot size for open short position. |
//+------------------------------------------------------------------+
double CExpertMoney::CheckOpenShort(double price,double sl)
{
if(m_symbol==NULL)
return(0.0);
//---
double lot;
if(price==0.0)
lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_SELL,m_symbol.Bid(),m_percent);
else
lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_SELL,price,m_percent);
if(lot<m_symbol.LotsMin())
return(0.0);
//---
return(m_symbol.LotsMin());
}
//+------------------------------------------------------------------+
//| Getting lot size for reverse. |
//+------------------------------------------------------------------+
double CExpertMoney::CheckReverse(CPositionInfo *position,double sl)
{
double lots=0.0;
//---
if(position.PositionType()==POSITION_TYPE_BUY)
lots=CheckOpenShort(m_symbol.Bid(),sl);
if(position.PositionType()==POSITION_TYPE_SELL)
lots=CheckOpenLong(m_symbol.Ask(),sl);
//---
if(lots!=0.0) lots+=position.Volume();
//---
return(lots);
}
//+------------------------------------------------------------------+
//| Getting lot size for close. |
//+------------------------------------------------------------------+
double CExpertMoney::CheckClose(CPositionInfo *position)
{
if(m_percent==0.0)
return(0.0);
//---
if(-position.Profit()>m_account.Balance()*m_percent/100.0)
return(position.Volume());
//---
return(0.0);
}
//+------------------------------------------------------------------+
+464
View File
@@ -0,0 +1,464 @@
//+------------------------------------------------------------------+
//| ExpertSignal.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "ExpertBase.mqh"
//+------------------------------------------------------------------+
//| Macro definitions. |
//+------------------------------------------------------------------+
//--- check if a market model is used
#define IS_PATTERN_USAGE(p) ((m_patterns_usage&(((int)1)<<p))!=0)
//+------------------------------------------------------------------+
//| Class CExpertSignal. |
//| Purpose: Base class trading signals. |
//| Derives from class CExpertBase. |
//+------------------------------------------------------------------+
class CExpertSignal : public CExpertBase
{
protected:
//--- variables
double m_base_price; // base price for detection of level of entering (and/or exit?)
//--- variables for working with additional filters
CArrayObj m_filters; // array of additional filters (maximum number of fileter is 64)
//--- Adjusted parameters
double m_weight; // "weight" of a signal in a combined filter
int m_patterns_usage; // bit mask of using of the market models of signals
int m_general; // index of the "main" signal (-1 - no)
long m_ignore; // bit mask of "ignoring" the additional filter
long m_invert; // bit mask of "inverting" the additional filter
int m_threshold_open; // threshold value for opening
int m_threshold_close;// threshold level for closing
double m_price_level; // level of placing a pending orders relatively to the base price
double m_stop_level; // level of placing of the "stop loss" order relatively to the open price
double m_take_level; // level of placing of the "take profit" order relatively to the open price
int m_expiration; // time of expiration of a pending order in bars
double m_direction; // weighted direction
public:
CExpertSignal(void);
~CExpertSignal(void);
//--- methods of access to protected data
void BasePrice(double value) { m_base_price=value; }
int UsedSeries(void);
//--- methods of setting adjustable parameters
void Weight(double value) { m_weight=value; }
void PatternsUsage(int value) { m_patterns_usage=value; }
void General(int value) { m_general=value; }
void Ignore(long value) { m_ignore=value; }
void Invert(long value) { m_invert=value; }
void ThresholdOpen(int value) { m_threshold_open=value; }
void ThresholdClose(int value) { m_threshold_close=value; }
void PriceLevel(double value) { m_price_level=value; }
void StopLevel(double value) { m_stop_level=value; }
void TakeLevel(double value) { m_take_level=value; }
void Expiration(int value) { m_expiration=value; }
//--- method of initialization of the object
void Magic(ulong value);
//--- method of verification of settings
virtual bool ValidationSettings(void);
//--- method of creating the indicator and timeseries
virtual bool InitIndicators(CIndicators *indicators);
//--- methods for working with additional filters
virtual bool AddFilter(CExpertSignal *filter);
//--- methods for generating signals of entering the market
virtual bool CheckOpenLong(double &price,double &sl,double &tp,datetime &expiration);
virtual bool CheckOpenShort(double &price,double &sl,double &tp,datetime &expiration);
//--- methods for detection of levels of entering the market
virtual bool OpenLongParams(double &price,double &sl,double &tp,datetime &expiration);
virtual bool OpenShortParams(double &price,double &sl,double &tp,datetime &expiration);
//--- methods for generating signals of exit from the market
virtual bool CheckCloseLong(double &price);
virtual bool CheckCloseShort(double &price);
//--- methods for detection of levels of exit from the market
virtual bool CloseLongParams(double &price);
virtual bool CloseShortParams(double &price);
//--- methods for generating signals of reversal of positions
virtual bool CheckReverseLong(double &price,double &sl,double &tp,datetime &expiration);
virtual bool CheckReverseShort(double &price,double &sl,double &tp,datetime &expiration);
//--- methods for generating signals of modification of pending orders
virtual bool CheckTrailingOrderLong(COrderInfo *order,double &price) { return(false); }
virtual bool CheckTrailingOrderShort(COrderInfo *order,double &price) { return(false); }
//--- methods of checking if the market models are formed
virtual int LongCondition(void) { return(0); }
virtual int ShortCondition(void) { return(0); }
virtual double Direction(void);
void SetDirection(void) { m_direction=Direction(); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CExpertSignal::CExpertSignal(void) : m_base_price(0.0),
m_general(-1), // no "main" signal
m_weight(1.0),
m_patterns_usage(-1), // all models are used
m_ignore(0), // all additional filters are used
m_invert(0),
m_threshold_open(50),
m_threshold_close(100),
m_price_level(0.0),
m_stop_level(0.0),
m_take_level(0.0),
m_expiration(0),
m_direction(EMPTY_VALUE)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CExpertSignal::~CExpertSignal(void)
{
}
//+------------------------------------------------------------------+
//| Get flags of used timeseries |
//+------------------------------------------------------------------+
int CExpertSignal::UsedSeries(void)
{
if(m_other_symbol || m_other_period)
return(0);
//--- check of the flags of using timeseries in the additional filters
int total=m_filters.Total();
//--- loop by the additional filters
for(int i=0;i<total;i++)
{
CExpertSignal *filter=m_filters.At(i);
//--- check pointer
if(filter==NULL)
return(false);
m_used_series|=filter.UsedSeries();
}
//---
return(m_used_series);
}
//+------------------------------------------------------------------+
//| Sets magic number for object and its dependent objects |
//+------------------------------------------------------------------+
void CExpertSignal::Magic(ulong value)
{
int total=m_filters.Total();
//--- loop by the additional filters
for(int i=0;i<total;i++)
{
CExpertSignal *filter=m_filters.At(i);
//--- check pointer
if(filter==NULL)
continue;
filter.Magic(value);
}
//---
CExpertBase::Magic(value);
}
//+------------------------------------------------------------------+
//| Validation settings protected data |
//+------------------------------------------------------------------+
bool CExpertSignal::ValidationSettings(void)
{
if(!CExpertBase::ValidationSettings())
return(false);
//--- check of parameters in the additional filters
int total=m_filters.Total();
//--- loop by the additional filters
for(int i=0;i<total;i++)
{
CExpertSignal *filter=m_filters.At(i);
//--- check pointer
if(filter==NULL)
return(false);
if(!filter.ValidationSettings())
return(false);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Create indicators |
//+------------------------------------------------------------------+
bool CExpertSignal::InitIndicators(CIndicators *indicators)
{
//--- check pointer
if(indicators==NULL)
return(false);
//---
CExpertSignal *filter;
int total=m_filters.Total();
//--- gather information about using of timeseries
for(int i=0;i<total;i++)
{
filter=m_filters.At(i);
m_used_series|=filter.UsedSeries();
}
//--- create required timeseries
if(!CExpertBase::InitIndicators(indicators))
return(false);
//--- initialization of indicators and timeseries in the additional filters
for(int i=0;i<total;i++)
{
filter=m_filters.At(i);
filter.SetPriceSeries(m_open,m_high,m_low,m_close);
filter.SetOtherSeries(m_spread,m_time,m_tick_volume,m_real_volume);
if(!filter.InitIndicators(indicators))
return(false);
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Setting an additional filter |
//+------------------------------------------------------------------+
bool CExpertSignal::AddFilter(CExpertSignal *filter)
{
//--- check pointer
if(filter==NULL)
return(false);
//--- primary initialization of the filter
if(!filter.Init(m_symbol,m_period,m_adjusted_point))
return(false);
//--- add the filter to the array of filters
if(!m_filters.Add(filter))
return(false);
filter.EveryTick(m_every_tick);
filter.Magic(m_magic);
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Generating a buy signal |
//+------------------------------------------------------------------+
bool CExpertSignal::CheckOpenLong(double &price,double &sl,double &tp,datetime &expiration)
{
bool result =false;
//--- the "prohibition" signal
if(m_direction==EMPTY_VALUE)
return(false);
//--- check of exceeding the threshold value
if(m_direction>=m_threshold_open)
{
//--- there's a signal
result=true;
//--- try to get the levels of opening
if(!OpenLongParams(price,sl,tp,expiration))
result=false;
}
//--- zeroize the base price
m_base_price=0.0;
//--- return the result
return(result);
}
//+------------------------------------------------------------------+
//| Generating a sell signal |
//+------------------------------------------------------------------+
bool CExpertSignal::CheckOpenShort(double &price,double &sl,double &tp,datetime &expiration)
{
bool result =false;
//--- the "prohibition" signal
if(m_direction==EMPTY_VALUE)
return(false);
//--- check of exceeding the threshold value
if(-m_direction>=m_threshold_open)
{
//--- there's a signal
result=true;
//--- try to get the levels of opening
if(!OpenShortParams(price,sl,tp,expiration))
result=false;
}
//--- zeroize the base price
m_base_price=0.0;
//--- return the result
return(result);
}
//+------------------------------------------------------------------+
//| Detecting the levels for buying |
//+------------------------------------------------------------------+
bool CExpertSignal::OpenLongParams(double &price,double &sl,double &tp,datetime &expiration)
{
CExpertSignal *general=(m_general!=-1) ? m_filters.At(m_general) : NULL;
//---
if(general==NULL)
{
//--- if a base price is not specified explicitly, take the current market price
double base_price=(m_base_price==0.0) ? m_symbol.Ask() : m_base_price;
price =m_symbol.NormalizePrice(base_price-m_price_level*PriceLevelUnit());
sl =(m_stop_level==0.0) ? 0.0 : m_symbol.NormalizePrice(price-m_stop_level*PriceLevelUnit());
tp =(m_take_level==0.0) ? 0.0 : m_symbol.NormalizePrice(price+m_take_level*PriceLevelUnit());
expiration+=m_expiration*PeriodSeconds(m_period);
return(true);
}
//---
return(general.OpenLongParams(price,sl,tp,expiration));
}
//+------------------------------------------------------------------+
//| Detecting the levels for selling |
//+------------------------------------------------------------------+
bool CExpertSignal::OpenShortParams(double &price,double &sl,double &tp,datetime &expiration)
{
CExpertSignal *general=(m_general!=-1) ? m_filters.At(m_general) : NULL;
//---
if(general==NULL)
{
//--- if a base price is not specified explicitly, take the current market price
double base_price=(m_base_price==0.0) ? m_symbol.Bid() : m_base_price;
price =m_symbol.NormalizePrice(base_price+m_price_level*PriceLevelUnit());
sl =(m_stop_level==0.0) ? 0.0 : m_symbol.NormalizePrice(price+m_stop_level*PriceLevelUnit());
tp =(m_take_level==0.0) ? 0.0 : m_symbol.NormalizePrice(price-m_take_level*PriceLevelUnit());
expiration+=m_expiration*PeriodSeconds(m_period);
return(true);
}
//---
return(general.OpenShortParams(price,sl,tp,expiration));
}
//+------------------------------------------------------------------+
//| Generating a signal for closing of a long position |
//+------------------------------------------------------------------+
bool CExpertSignal::CheckCloseLong(double &price)
{
bool result =false;
//--- the "prohibition" signal
if(m_direction==EMPTY_VALUE)
return(false);
//--- check of exceeding the threshold value
if(-m_direction>=m_threshold_close)
{
//--- there's a signal
result=true;
//--- try to get the level of closing
if(!CloseLongParams(price))
result=false;
}
//--- zeroize the base price
m_base_price=0.0;
//--- return the result
return(result);
}
//+------------------------------------------------------------------+
//| Generating a signal for closing a short position |
//+------------------------------------------------------------------+
bool CExpertSignal::CheckCloseShort(double &price)
{
bool result =false;
//--- the "prohibition" signal
if(m_direction==EMPTY_VALUE)
return(false);
//--- check of exceeding the threshold value
if(m_direction>=m_threshold_close)
{
//--- there's a signal
result=true;
//--- try to get the level of closing
if(!CloseShortParams(price))
result=false;
}
//--- zeroize the base price
m_base_price=0.0;
//--- return the result
return(result);
}
//+------------------------------------------------------------------+
//| Detecting the levels for closing a long position |
//+------------------------------------------------------------------+
bool CExpertSignal::CloseLongParams(double &price)
{
CExpertSignal *general=(m_general!=-1) ? m_filters.At(m_general) : NULL;
//---
if(general==NULL)
{
//--- if a base price is not specified explicitly, take the current market price
price=(m_base_price==0.0) ? m_symbol.Bid() : m_base_price;
return(true);
}
//---
return(general.CloseLongParams(price));
}
//+------------------------------------------------------------------+
//| Detecting the levels for closing a short position |
//+------------------------------------------------------------------+
bool CExpertSignal::CloseShortParams(double &price)
{
CExpertSignal *general=(m_general!=-1) ? m_filters.At(m_general) : NULL;
//---
if(general==NULL)
{
//--- if a base price is not specified explicitly, take the current market price
price=(m_base_price==0.0)?m_symbol.Ask():m_base_price;
return(true);
}
//--- ok
return(general.CloseShortParams(price));
}
//+------------------------------------------------------------------+
//| Generating a signal for reversing a long position |
//+------------------------------------------------------------------+
bool CExpertSignal::CheckReverseLong(double &price,double &sl,double &tp,datetime &expiration)
{
double c_price;
//--- check the signal of closing a long position
if(!CheckCloseLong(c_price))
return(false);
//--- check the signal of opening a short position
if(!CheckOpenShort(price,sl,tp,expiration))
return(false);
//--- difference between the close and open prices must not exceed two spreads
if(c_price!=price)
return(false);
//--- there's a signal
return(true);
}
//+------------------------------------------------------------------+
//| Generating a signal for reversing a short position |
//+------------------------------------------------------------------+
bool CExpertSignal::CheckReverseShort(double &price,double &sl,double &tp,datetime &expiration)
{
double c_price;
//--- check the signal of closing a short position
if(!CheckCloseShort(c_price))
return(false);
//--- check the signal of opening a long position
if(!CheckOpenLong(price,sl,tp,expiration))
return(false);
//--- difference between the close and open prices must not exceed two spreads
if(c_price!=price)
return(false);
//--- there's a signal
return(true);
}
//+------------------------------------------------------------------+
//| Detecting the "weighted" direction |
//+------------------------------------------------------------------+
double CExpertSignal::Direction(void)
{
long mask;
double direction;
double result=m_weight*(LongCondition()-ShortCondition());
int number=(result==0.0)? 0 : 1; // number of "voted"
//---
int total=m_filters.Total();
//--- loop by filters
for(int i=0;i<total;i++)
{
//--- mask for bit maps
mask=((long)1)<<i;
//--- check of the flag of ignoring the signal of filter
if((m_ignore&mask)!=0)
continue;
CExpertSignal *filter=m_filters.At(i);
//--- check pointer
if(filter==NULL)
continue;
direction=filter.Direction();
//--- the "prohibition" signal
if(direction==EMPTY_VALUE)
return(EMPTY_VALUE);
//--- check of flag of inverting the signal of filter
if((m_invert&mask)!=0)
result-=direction;
else
result+=direction;
number++;
}
//--- normalization
if(number!=0)
result/=number;
//--- return the result
return(result);
}
//+------------------------------------------------------------------+
+171
View File
@@ -0,0 +1,171 @@
//+------------------------------------------------------------------+
//| ExpertTrade.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include <Trade\SymbolInfo.mqh>
#include <Trade\PositionInfo.mqh>
#include <Trade\OrderInfo.mqh>
#include <Trade\AccountInfo.mqh>
#include <Trade\Trade.mqh>
//+------------------------------------------------------------------+
//| Class CExpertTrade. |
//| Appointment: Class simple trade operations. |
//| Derives from class CTrade. |
//+------------------------------------------------------------------+
class CExpertTrade : public CTrade
{
protected:
ENUM_ORDER_TYPE_TIME m_order_type_time;
datetime m_order_expiration;
CSymbolInfo *m_symbol; // symbol object
CAccountInfo m_account; // account object
public:
CExpertTrade(void);
~CExpertTrade(void);
//--- methods for easy trade
bool SetSymbol(CSymbolInfo *symbol);
bool SetOrderTypeTime(ENUM_ORDER_TYPE_TIME order_type_time);
bool SetOrderExpiration(datetime order_expiration);
bool Buy(double volume,double price,double sl,double tp,const string comment="");
bool Sell(double volume,double price,double sl,double tp,const string comment="");
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
void CExpertTrade::CExpertTrade(void) : m_symbol(NULL),
m_order_type_time(ORDER_TIME_GTC),
m_order_expiration(0)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CExpertTrade::~CExpertTrade(void)
{
}
//+------------------------------------------------------------------+
//| Setting working symbol for easy trade operations. |
//+------------------------------------------------------------------+
bool CExpertTrade::SetSymbol(CSymbolInfo *symbol)
{
if(symbol!=NULL)
{
m_symbol=symbol;
return(true);
}
//---
return(false);
}
//+------------------------------------------------------------------+
//| Setting order expiration type for easy trade operations |
//+------------------------------------------------------------------+
bool CExpertTrade::SetOrderTypeTime(ENUM_ORDER_TYPE_TIME order_type_time)
{
if(m_symbol==NULL)
return(false);
//---
if(order_type_time==ORDER_TIME_SPECIFIED)
{
if((m_symbol.TradeTimeFlags()&SYMBOL_EXPIRATION_SPECIFIED)==0)
{
m_order_type_time =ORDER_TIME_GTC;
m_order_expiration=0;
return(false);
}
}
//---
m_order_type_time=order_type_time;
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Setting order expiration time for easy trade operations |
//+------------------------------------------------------------------+
bool CExpertTrade::SetOrderExpiration(datetime order_expiration)
{
if(m_symbol==NULL)
return(false);
//--- check expiration
if(order_expiration>=TimeCurrent()+60)
{
if(!SetOrderTypeTime(ORDER_TIME_SPECIFIED))
return(false);
m_order_expiration=order_expiration;
}
else
{
m_order_type_time=ORDER_TIME_GTC;
m_order_expiration=0;
}
//--- succeed
return(true);
}
//+------------------------------------------------------------------+
//| Easy LONG trade operation |
//+------------------------------------------------------------------+
bool CExpertTrade::Buy(double volume,double price,double sl,double tp,const string comment="")
{
double ask,stops_level;
//--- checking
if(m_symbol==NULL)
return(false);
string symbol=m_symbol.Name();
if(symbol=="")
return(false);
//---
ask=m_symbol.Ask();
stops_level=m_symbol.StopsLevel()*m_symbol.Point();
if(price!=0.0)
{
if(price>ask+stops_level)
{
//--- send "BUY_STOP" order
return(OrderOpen(symbol,ORDER_TYPE_BUY_STOP,volume,0.0,price,sl,tp,
m_order_type_time,m_order_expiration,comment));
}
if(price<ask-stops_level)
{
//--- send "BUY_LIMIT" order
return(OrderOpen(symbol,ORDER_TYPE_BUY_LIMIT,volume,0.0,price,sl,tp,
m_order_type_time,m_order_expiration,comment));
}
}
//---
return(PositionOpen(symbol,ORDER_TYPE_BUY,volume,ask,sl,tp,comment));
}
//+------------------------------------------------------------------+
//| Easy SHORT trade operation |
//+------------------------------------------------------------------+
bool CExpertTrade::Sell(double volume,double price,double sl,double tp,const string comment="")
{
double bid,stops_level;
//--- checking
if(m_symbol==NULL)
return(false);
string symbol=m_symbol.Name();
if(symbol=="")
return(false);
//---
bid=m_symbol.Bid();
stops_level=m_symbol.StopsLevel()*m_symbol.Point();
if(price!=0.0)
{
if(price>bid+stops_level)
{
//--- send "SELL_LIMIT" order
return(OrderOpen(symbol,ORDER_TYPE_SELL_LIMIT,volume,0.0,price,sl,tp,
m_order_type_time,m_order_expiration,comment));
}
if(price<bid-stops_level)
{
//--- send "SELL_STOP" order
return(OrderOpen(symbol,ORDER_TYPE_SELL_STOP,volume,0.0,price,sl,tp,
m_order_type_time,m_order_expiration,comment));
}
}
//---
return(PositionOpen(symbol,ORDER_TYPE_SELL,volume,bid,sl,tp,comment));
}
//+------------------------------------------------------------------+
+33
View File
@@ -0,0 +1,33 @@
//+------------------------------------------------------------------+
//| ExpertTrailing.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include "ExpertBase.mqh"
//+------------------------------------------------------------------+
//| Class CExpertTrailing. |
//| Purpose: Base class traling stops. |
//| Derives from class CExpertBase. |
//+------------------------------------------------------------------+
class CExpertTrailing : public CExpertBase
{
public:
CExpertTrailing(void);
~CExpertTrailing(void);
//---
virtual bool CheckTrailingStopLong(CPositionInfo *position,double &sl,double &tp) { return(false); }
virtual bool CheckTrailingStopShort(CPositionInfo *position,double &sl,double &tp) { return(false); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CExpertTrailing::CExpertTrailing(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CExpertTrailing::~CExpertTrailing(void)
{
}
//+------------------------------------------------------------------+
+73
View File
@@ -0,0 +1,73 @@
//+------------------------------------------------------------------+
//| MoneyFixedLot.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include <Expert\ExpertMoney.mqh>
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class |
//| Title=Trading with fixed trade volume |
//| Type=Money |
//| Name=FixLot |
//| Class=CMoneyFixedLot |
//| Page= |
//| Parameter=Percent,double,10.0,Percent |
//| Parameter=Lots,double,0.1,Fixed volume |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CMoneyFixedLot. |
//| Purpose: Class of money management with fixed lot. |
//| Derives from class CExpertMoney. |
//+------------------------------------------------------------------+
class CMoneyFixedLot : public CExpertMoney
{
protected:
//--- input parameters
double m_lots;
public:
CMoneyFixedLot(void);
~CMoneyFixedLot(void);
//---
void Lots(double lots) { m_lots=lots; }
virtual bool ValidationSettings(void);
//---
virtual double CheckOpenLong(double price,double sl) { return(m_lots); }
virtual double CheckOpenShort(double price,double sl) { return(m_lots); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
void CMoneyFixedLot::CMoneyFixedLot(void) : m_lots(0.1)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
void CMoneyFixedLot::~CMoneyFixedLot(void)
{
}
//+------------------------------------------------------------------+
//| Validation settings protected data. |
//+------------------------------------------------------------------+
bool CMoneyFixedLot::ValidationSettings(void)
{
if(!CExpertMoney::ValidationSettings())
return(false);
//--- initial data checks
if(m_lots<m_symbol.LotsMin() || m_lots>m_symbol.LotsMax())
{
printf(__FUNCTION__+": lots amount must be in the range from %f to %f",m_symbol.LotsMin(),m_symbol.LotsMax());
return(false);
}
if(MathAbs(m_lots/m_symbol.LotsStep()-MathRound(m_lots/m_symbol.LotsStep()))>1.0E-10)
{
printf(__FUNCTION__+": lots amount is not corresponding with lot step %f",m_symbol.LotsStep());
return(false);
}
//--- ok
return(true);
}
//+------------------------------------------------------------------+
+76
View File
@@ -0,0 +1,76 @@
//+------------------------------------------------------------------+
//| MoneyFixedMargin.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include <Expert\ExpertMoney.mqh>
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class |
//| Title=Trading with fixed margin |
//| Type=Money |
//| Name=FixMargin |
//| Class=CMoneyFixedMargin |
//| Page= |
//| Parameter=Percent,double,10.0,Percentage of margin |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CMoneyFixedMargin. |
//| Purpose: Class of money management with fixed percent margin. |
//| Derives from class CExpertMoney. |
//+------------------------------------------------------------------+
class CMoneyFixedMargin : public CExpertMoney
{
public:
CMoneyFixedMargin(void);
~CMoneyFixedMargin(void);
//---
virtual double CheckOpenLong(double price,double sl);
virtual double CheckOpenShort(double price,double sl);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
void CMoneyFixedMargin::CMoneyFixedMargin(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
void CMoneyFixedMargin::~CMoneyFixedMargin(void)
{
}
//+------------------------------------------------------------------+
//| Getting lot size for open long position. |
//+------------------------------------------------------------------+
double CMoneyFixedMargin::CheckOpenLong(double price,double sl)
{
if(m_symbol==NULL)
return(0.0);
//--- select lot size
double lot;
if(price==0.0)
lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_BUY,m_symbol.Ask(),m_percent);
else
lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_BUY,price,m_percent);
//--- return trading volume
return(lot);
}
//+------------------------------------------------------------------+
//| Getting lot size for open short position. |
//+------------------------------------------------------------------+
double CMoneyFixedMargin::CheckOpenShort(double price,double sl)
{
if(m_symbol==NULL)
return(0.0);
//--- select lot size
double lot;
if(price==0.0)
lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_SELL,m_symbol.Bid(),m_percent);
else
lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_SELL,price,m_percent);
//--- return trading volume
return(lot);
}
//+------------------------------------------------------------------+
+109
View File
@@ -0,0 +1,109 @@
//+------------------------------------------------------------------+
//| MoneyFixedRisk.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include <Expert\ExpertMoney.mqh>
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class |
//| Title=Trading with fixed risk |
//| Type=Money |
//| Name=FixRisk |
//| Class=CMoneyFixedRisk |
//| Page= |
//| Parameter=Percent,double,10.0,Risk percentage |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CMoneyFixedRisk. |
//| Purpose: Class of money management with fixed percent risk. |
//| Derives from class CExpertMoney. |
//+------------------------------------------------------------------+
class CMoneyFixedRisk : public CExpertMoney
{
public:
CMoneyFixedRisk(void);
~CMoneyFixedRisk(void);
//---
virtual double CheckOpenLong(double price,double sl);
virtual double CheckOpenShort(double price,double sl);
virtual double CheckClose(CPositionInfo *position) { return(0.0); }
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
void CMoneyFixedRisk::CMoneyFixedRisk(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
void CMoneyFixedRisk::~CMoneyFixedRisk(void)
{
}
//+------------------------------------------------------------------+
//| Getting lot size for open long position. |
//+------------------------------------------------------------------+
double CMoneyFixedRisk::CheckOpenLong(double price,double sl)
{
if(m_symbol==NULL)
return(0.0);
//--- select lot size
double lot;
double minvol=m_symbol.LotsMin();
if(sl==0.0)
lot=minvol;
else
{
double loss;
if(price==0.0)
loss=-m_account.OrderProfitCheck(m_symbol.Name(),ORDER_TYPE_BUY,1.0,m_symbol.Ask(),sl);
else
loss=-m_account.OrderProfitCheck(m_symbol.Name(),ORDER_TYPE_BUY,1.0,price,sl);
double stepvol=m_symbol.LotsStep();
lot=MathFloor(m_account.Balance()*m_percent/loss/100.0/stepvol)*stepvol;
}
//---
if(lot<minvol)
lot=minvol;
//---
double maxvol=m_symbol.LotsMax();
if(lot>maxvol)
lot=maxvol;
//--- return trading volume
return(lot);
}
//+------------------------------------------------------------------+
//| Getting lot size for open short position. |
//+------------------------------------------------------------------+
double CMoneyFixedRisk::CheckOpenShort(double price,double sl)
{
if(m_symbol==NULL)
return(0.0);
//--- select lot size
double lot;
double minvol=m_symbol.LotsMin();
if(sl==0.0)
lot=minvol;
else
{
double loss;
if(price==0.0)
loss=-m_account.OrderProfitCheck(m_symbol.Name(),ORDER_TYPE_SELL,1.0,m_symbol.Bid(),sl);
else
loss=-m_account.OrderProfitCheck(m_symbol.Name(),ORDER_TYPE_SELL,1.0,price,sl);
double stepvol=m_symbol.LotsStep();
lot=MathFloor(m_account.Balance()*m_percent/loss/100.0/stepvol)*stepvol;
}
//---
if(lot<minvol)
lot=minvol;
//---
double maxvol=m_symbol.LotsMax();
if(lot>maxvol)
lot=maxvol;
//--- return trading volume
return(lot);
}
//+------------------------------------------------------------------+
+71
View File
@@ -0,0 +1,71 @@
//+------------------------------------------------------------------+
//| MoneyNone.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include <Expert\ExpertMoney.mqh>
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class |
//| Title=Trading with minimal allowed trade volume |
//| Type=Money |
//| Name=MinLot |
//| Class=CMoneyNone |
//| Page= |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CMoneyNone. |
//| Appointment: Class no money managment. |
//| Derives from class CExpertMoney. |
//+------------------------------------------------------------------+
class CMoneyNone : public CExpertMoney
{
public:
CMoneyNone(void);
~CMoneyNone(void);
//---
virtual bool ValidationSettings(void);
//---
virtual double CheckOpenLong(double price,double sl);
virtual double CheckOpenShort(double price,double sl);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
void CMoneyNone::CMoneyNone(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
void CMoneyNone::~CMoneyNone(void)
{
}
//+------------------------------------------------------------------+
//| Validation settings protected data. |
//+------------------------------------------------------------------+
bool CMoneyNone::ValidationSettings(void)
{
Percent(100.0);
//--- initial data checks
if(!CExpertMoney::ValidationSettings())
return(false);
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Getting lot size for open long position. |
//+------------------------------------------------------------------+
double CMoneyNone::CheckOpenLong(double price,double sl)
{
return(m_symbol.LotsMin());
}
//+------------------------------------------------------------------+
//| Getting lot size for open short position. |
//+------------------------------------------------------------------+
double CMoneyNone::CheckOpenShort(double price,double sl)
{
return(m_symbol.LotsMin());
}
//+------------------------------------------------------------------+
+155
View File
@@ -0,0 +1,155 @@
//+------------------------------------------------------------------+
//| MoneySizeOptimized.mqh |
//| Copyright 2009-2017, MetaQuotes Software Corp. |
//| http://www.mql5.com |
//+------------------------------------------------------------------+
#include <Expert\ExpertMoney.mqh>
#include <Trade\DealInfo.mqh>
// wizard description start
//+------------------------------------------------------------------+
//| Description of the class |
//| Title=Trading with optimized trade volume |
//| Type=Money |
//| Name=SizeOptimized |
//| Class=CMoneySizeOptimized |
//| Page= |
//| Parameter=DecreaseFactor,double,3.0,Decrease factor |
//| Parameter=Percent,double,10.0,Percent |
//+------------------------------------------------------------------+
// wizard description end
//+------------------------------------------------------------------+
//| Class CMoneySizeOptimized. |
//| Purpose: Class of money management with size optimized. |
//| Derives from class CExpertMoney. |
//+------------------------------------------------------------------+
class CMoneySizeOptimized : public CExpertMoney
{
protected:
double m_decrease_factor;
public:
CMoneySizeOptimized(void);
~CMoneySizeOptimized(void);
//---
void DecreaseFactor(double decrease_factor) { m_decrease_factor=decrease_factor; }
virtual bool ValidationSettings(void);
//---
virtual double CheckOpenLong(double price,double sl);
virtual double CheckOpenShort(double price,double sl);
protected:
double Optimize(double lots);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
void CMoneySizeOptimized::CMoneySizeOptimized(void) : m_decrease_factor(3.0)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
void CMoneySizeOptimized::~CMoneySizeOptimized(void)
{
}
//+------------------------------------------------------------------+
//| Validation settings protected data. |
//+------------------------------------------------------------------+
bool CMoneySizeOptimized::ValidationSettings(void)
{
if(!CExpertMoney::ValidationSettings())
return(false);
//--- initial data checks
if(m_decrease_factor<=0.0)
{
printf(__FUNCTION__+": decrease factor must be greater then 0");
return(false);
}
//--- ok
return(true);
}
//+------------------------------------------------------------------+
//| Getting lot size for open long position. |
//+------------------------------------------------------------------+
double CMoneySizeOptimized::CheckOpenLong(double price,double sl)
{
if(m_symbol==NULL)
return(0.0);
//--- select lot size
double lot;
if(price==0.0)
lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_BUY,m_symbol.Ask(),m_percent);
else
lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_BUY,price,m_percent);
//--- return trading volume
return(Optimize(lot));
}
//+------------------------------------------------------------------+
//| Getting lot size for open short position. |
//+------------------------------------------------------------------+
double CMoneySizeOptimized::CheckOpenShort(double price,double sl)
{
if(m_symbol==NULL)
return(0.0);
//--- select lot size
double lot;
if(price==0.0)
lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_SELL,m_symbol.Bid(),m_percent);
else
lot=m_account.MaxLotCheck(m_symbol.Name(),ORDER_TYPE_SELL,price,m_percent);
//--- return trading volume
return(Optimize(lot));
}
//+------------------------------------------------------------------+
//| Optimizing lot size for open. |
//+------------------------------------------------------------------+
double CMoneySizeOptimized::Optimize(double lots)
{
double lot=lots;
//--- calculate number of losses orders without a break
if(m_decrease_factor>0)
{
//--- select history for access
HistorySelect(0,TimeCurrent());
//---
int orders=HistoryDealsTotal(); // total history deals
int losses=0; // number of consequent losing orders
CDealInfo deal;
//---
for(int i=orders-1;i>=0;i--)
{
deal.Ticket(HistoryDealGetTicket(i));
if(deal.Ticket()==0)
{
Print("CMoneySizeOptimized::Optimize: HistoryDealGetTicket failed, no trade history");
break;
}
//--- check symbol
if(deal.Symbol()!=m_symbol.Name())
continue;
//--- check profit
double profit=deal.Profit();
if(profit>0.0)
break;
if(profit<0.0)
losses++;
}
//---
if(losses>1)
lot=NormalizeDouble(lot-lot*losses/m_decrease_factor,2);
}
//--- normalize and check limits
double stepvol=m_symbol.LotsStep();
lot=stepvol*NormalizeDouble(lot/stepvol,0);
//---
double minvol=m_symbol.LotsMin();
if(lot<minvol)
lot=minvol;
//---
double maxvol=m_symbol.LotsMax();
if(lot>maxvol)
lot=maxvol;
//---
return(lot);
}
//+------------------------------------------------------------------+

Some files were not shown because too many files have changed in this diff Show More