This commit is contained in:
Nkondog Anselme
2021-11-15 02:36:56 +01:00
parent 799718d859
commit 62a1482923
304 changed files with 5 additions and 216569 deletions
+5
View File
@@ -0,0 +1,5 @@
{
"files.associations": {
"*.mqh": "cpp"
}
}
Binary file not shown.
-168
View File
@@ -1,168 +0,0 @@
//+------------------------------------------------------------------+
//| 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();
}
//+------------------------------------------------------------------+
Binary file not shown.
-175
View File
@@ -1,175 +0,0 @@
//+------------------------------------------------------------------+
//| 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();
}
//+------------------------------------------------------------------+
Binary file not shown.
-171
View File
@@ -1,171 +0,0 @@
//+------------------------------------------------------------------+
//| 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();
}
//+------------------------------------------------------------------+
Binary file not shown.
@@ -1,176 +0,0 @@
//+------------------------------------------------------------------+
//| 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();
}
//+------------------------------------------------------------------+
Binary file not shown.
@@ -1,353 +0,0 @@
//+------------------------------------------------------------------+
//| 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);
}
//+------------------------------------------------------------------+
Binary file not shown.
-45
View File
@@ -1,45 +0,0 @@
//+------------------------------------------------------------------+
//| 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);
}
//+------------------------------------------------------------------+
@@ -1,427 +0,0 @@
//+------------------------------------------------------------------+
//| 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()));
}
//+------------------------------------------------------------------+
Binary file not shown.
-451
View File
@@ -1,451 +0,0 @@
//+------------------------------------------------------------------+
//| 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;
}
}
}
//+------------------------------------------------------------------+
@@ -1,372 +0,0 @@
//+------------------------------------------------------------------+
//| Functions.mqh |
//| Copyright 2019,MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
//--- custom function y=f(x,y)
typedef double(*MathFunction)(double,double);
//+------------------------------------------------------------------+
//| math functions |
//+------------------------------------------------------------------+
enum EnMathFunction
{
Peaks=0,
Chomolungma=1,
ClimberDream=2,
Granite=3,
Hedgehog=4,
Hill=5,
Josephine=6,
Screw=7,
DoubleScrew=8,
MultiExtremalScrew=9,
Sink=10,
Skin=11,
Trapfall=12,
};
//+------------------------------------------------------------------+
//| Names of the math functions |
//+------------------------------------------------------------------+
const string ExtFunctionsNames[]=
{
"Peaks",
"Chomolungma",
"Climber Dream",
"Granite",
"Hedgehog",
"Hill",
"Josephine",
"Screw",
"Double Screw",
"Multi Extremal Screw",
"Sinc",
"Skin",
"Trapfall"
};
//+------------------------------------------------------------------+
//| Function Peaks |
//+------------------------------------------------------------------+
double PeaksFunction(double x,double y)
{
double res = 3*MathPow((1-x),2)*MathExp(-x*x-(y+1)*(y+1))-10*(0.2*x-MathPow(x,3)-MathPow(y,5))*MathExp(-x*x-y*y)-1/3*MathExp(-(x+1)*(x+1)-y*y);
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Chomolungma |
//+------------------------------------------------------------------+
double ChomolungmaFunction(double x,double y)
{
double a= MathCos(x*x)+MathCos(y*y);
double b= MathPow(MathCos(5*x*y),5);
double c=1.0/MathPow(2,b);
//--- calculate result
double res=a-c;
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function ClimberDream |
//+------------------------------------------------------------------+
double ClimberDreamFunction(double x,double y)
{
double a= MathSin(MathSqrt(MathAbs(x - 1.3) + MathAbs(y)));
double b= MathCos(MathSqrt(MathAbs(MathSin(x))) + MathSqrt(MathAbs(MathSin(y))));
double f=a+b;
//--- calculate result
double res=MathPow(f,4);
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Granite |
//+------------------------------------------------------------------+
double GraniteFunction(double x,double y)
{
double a= MathPow(MathSin(MathSqrt(MathAbs(x)+MathAbs(y))),2);
double b= MathPow(MathCos(MathSqrt(MathAbs(x)+MathAbs(y))),2);
//--- calculate result
double res=a*b;
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Hedgehog |
//+------------------------------------------------------------------+
double HedgehogFunction(double x,double y)
{
double a1=MathSin(MathSqrt(MathAbs(x-2)+MathAbs(y)));
double a2=MathCos(MathSqrt(MathAbs(MathSin(x)))+MathSqrt(MathAbs(MathSin(y))));
//--- calculate result
double res=a1+a2;
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Hill |
//+------------------------------------------------------------------+
double HillFunction(double x,double y)
{
//--- calculate result
double res=MathExp(-x*x-y*y);
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Josephine |
//+------------------------------------------------------------------+
double JosephineFunction(double x,double y)
{
double a= MathSin(MathPow(MathAbs(x)+MathAbs(y),0.5));
double b= MathCos(MathPow(MathAbs(x),0.5)+MathPow(MathAbs(y),0.5));
//--- calculate function
double res=a+b;
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Screw |
//+------------------------------------------------------------------+
double ScrewFunction(double x,double y)
{
double a=(y==0)?0:((x*y<0)?MathArctan(x/y):MathArctan(x/y)+M_PI);
double b=x*x+y*y;
double f=MathSin(b+a);
//--- calculate result
double res=(f*f);
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function DoubleScrew |
//+------------------------------------------------------------------+
double DoubleScrewFunction(double x,double y)
{
double a=(y==0)?0:((x*y<0)?MathArctan(x/y):MathArctan(x/y)+M_PI);
double b=x*x+y*y;
double res1=MathCos(b/2+a*3);
res1=((res1*res1)/sqrt(b+1)-0.2);
double res2=MathCos(b/2-a*3);
res2=((res2*res2)/sqrt(b+1)-0.2);
double f=fmax(res1,res2);
//--- calculate result
double res=(f>0)?f:0;
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function MultiExtremalScrew |
//+------------------------------------------------------------------+
double MultiExtremalScrewFunction(double x,double y)
{
double a=(y==0)?0:((x*y<0)?MathArctan(x/y):MathArctan(x/y)+M_PI);
double b=x*x+y*y;
double res1=MathCos(b/2+a*3);
res1=((res1*res1)/sqrt(b+1)-0.2);
double res2=MathCos(b/2-a*3);
res2=((res2*res2)/sqrt(b+1)-0.2);
//--- calculate function
double res=fmin(res1,res2);
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Sink |
//+------------------------------------------------------------------+
double SinkFunction(double x,double y)
{
static double k=5.0;
static double p=6.0;
//--- calculate result
double res=MathSin(x*x+y*y)+k*MathExp(-p*x*x-p*y*y);
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Skin |
//+------------------------------------------------------------------+
double SkinFunction(double x,double y)
{
double a1=2*x*x;
double a2=2*y*y;
double b1=MathCos(a1)-1.1;
b1=b1*b1;
double c1=MathSin(0.5*x)-1.2;
c1=c1*c1;
double d1=MathCos(a2)-1.1;
d1=d1*d1;
double e1=MathSin(0.5*y)-1.2;
e1=e1*e1;
//--- calculate result
double res=b1+c1-d1+e1;
//---
return(res);
}
//+------------------------------------------------------------------+
//| Function Trapfall |
//+------------------------------------------------------------------+
double TrapfallFunction(double x,double y)
{
double a1=MathSqrt(MathAbs(MathSin(x-1.0)));
double b1=MathSqrt(MathAbs(MathSin(y+2.0)));
//--- calculate result
double res=-MathSqrt(MathAbs(MathSin(MathSin(a1+b1))));
//---
return(res);
}
//+------------------------------------------------------------------+
//| GenerateFunctionData |
//+------------------------------------------------------------------+
void GenerateFunctionData(double &data[],int &x_size,int &y_size,double x_min,double x_max,double y_min,double y_max,MathFunction function)
{
double dx = 0.1;
double dy = 0.1;
//---
x_size = (int)((x_max - x_min)/dx) + 1;
y_size = (int)((y_max - y_min)/dy) + 1;
ArrayResize(data,x_size*y_size);
//---
for(int j = 0; j < y_size; j++)
{
for(int i = 0; i < x_size; i++)
{
double x = x_min + i*dx;
double y = y_min + j*dy;
data[j*x_size + i] = function(x,y);
}
}
}
//+------------------------------------------------------------------+
//| GenerateData |
//+------------------------------------------------------------------+
void GenerateData(EnMathFunction function_id,double &data[],int &x_size,int &y_size)
{
//---
switch(function_id)
{
case Peaks:
GenerateFunctionData(data,x_size,y_size,-3.0,+3.0,-3.0,+3.0,PeaksFunction);
break;
case Chomolungma:
GenerateFunctionData(data,x_size,y_size,-2.0,+2.0,-2.0,+2.0,ChomolungmaFunction);
break;
case ClimberDream:
GenerateFunctionData(data,x_size,y_size,-10.0,+10.0,-10.0,+10.0,ClimberDreamFunction);
break;
case Granite:
GenerateFunctionData(data,x_size,y_size,-4.0,+4.0,-4.0,+4.0,GraniteFunction);
break;
case Hedgehog:
GenerateFunctionData(data,x_size,y_size,-10.0,+10.0,-10.0,+10.0,HedgehogFunction);
break;
case Hill:
GenerateFunctionData(data,x_size,y_size,-1.5,+1.5,-1.5,+1.5,HillFunction);
break;
case Josephine:
GenerateFunctionData(data,x_size,y_size,-200.0,+200.0,-200.0,+200.0,JosephineFunction);
break;
case Screw:
GenerateFunctionData(data,x_size,y_size,-3.0,+3.0,-3.0,+3.0,ScrewFunction);
break;
case DoubleScrew:
GenerateFunctionData(data,x_size,y_size,-3.0,+3.0,-3.0,+3.0,DoubleScrewFunction);
break;
case MultiExtremalScrew:
GenerateFunctionData(data,x_size,y_size,-3.0,+3.0,-3.0,+3.0,MultiExtremalScrewFunction);
break;
case Sink:
GenerateFunctionData(data,x_size,y_size,-3.0,+3.0,-3.0,+3.0,SinkFunction);
break;
case Skin:
GenerateFunctionData(data,x_size,y_size,-5.0,+5.0,-5.0,+5.0,SkinFunction);
break;
case Trapfall:
GenerateFunctionData(data,x_size,y_size,-5.0,+5.0,-5.0,+5.0,TrapfallFunction);
break;
}
}
//+------------------------------------------------------------------+
//| GenerateFunctionDataFixedSize |
//+------------------------------------------------------------------+
bool GenerateFunctionDataFixedSize(int x_size,int y_size,double &data[],double x_min,double x_max,double y_min,double y_max,MathFunction function)
{
if(x_size<2 || y_size<2)
{
PrintFormat("Error in data sizes: x_size=%d,y_size=%d",x_size,y_size);
return(false);
}
double dx = (x_max - x_min)/(x_size-1);
double dy = (y_max - y_min)/(y_size-1);
ArrayResize(data,x_size*y_size);
//---
for(int j = 0; j < y_size; j++)
{
for(int i = 0; i < x_size; i++)
{
double x = x_min + i*dx;
double y = y_min + j*dy;
data[j*x_size + i] = function(x,y);
}
}
return(true);
}
//+------------------------------------------------------------------+
//| GenerateDataFixedSize |
//+------------------------------------------------------------------+
bool GenerateDataFixedSize(int x_size,int y_size,EnMathFunction function_id,double &data[])
{
if(x_size<2 || y_size<2)
{
PrintFormat("Error in data sizes: x_size=%d,y_size=%d",x_size,y_size);
return(false);
}
bool result=false;
//---
switch(function_id)
{
case Peaks:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-3.0,+3.0,-3.0,+3.0,PeaksFunction);
break;
case Chomolungma:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-2.0,+2.0,-2.0,+2.0,ChomolungmaFunction);
break;
case ClimberDream:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-10.0,+10.0,-10.0,+10.0,ClimberDreamFunction);
break;
case Granite:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-4.0,+4.0,-4.0,+4.0,GraniteFunction);
break;
case Hedgehog:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-10.0,+10.0,-10.0,+10.0,HedgehogFunction);
break;
case Hill:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-1.5,+1.5,-1.5,+1.5,HillFunction);
break;
case Josephine:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-200.0,+200.0,-200.0,+200.0,JosephineFunction);
break;
case Screw:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-3.0,+3.0,-3.0,+3.0,ScrewFunction);
break;
case DoubleScrew:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-3.0,+3.0,-3.0,+3.0,DoubleScrewFunction);
break;
case MultiExtremalScrew:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-3.0,+3.0,-3.0,+3.0,MultiExtremalScrewFunction);
break;
case Sink:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-3.0,+3.0,-3.0,+3.0,SinkFunction);
break;
case Skin:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-5.0,+5.0,-5.0,+5.0,SkinFunction);
break;
case Trapfall:
result=GenerateFunctionDataFixedSize(x_size,y_size,data,-5.0,+5.0,-5.0,+5.0,TrapfallFunction);
break;
}
//---
return(result);
}
//+------------------------------------------------------------------+
Binary file not shown.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,233 +0,0 @@
//+------------------------------------------------------------------+
//| 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)
{
}
//+------------------------------------------------------------------+
Binary file not shown.
Binary file not shown.
-62
View File
@@ -1,62 +0,0 @@
//+------------------------------------------------------------------+
//| A_LotSizeCal.mqh |
//| Copyright 2021, Nkondog Anselme Venceslas |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Nkondog Anselme Venceslas"
#property link "https://www.mql5.com"
//Lot Size Calculator
void LotSizeCalculate(double SL=0)
{
//If the position size is dynamic
if(RiskDefaultSize==RISK_DEFAULT_AUTO)
{
//If the stop loss is not zero then calculate the lot size
if(SL!=0)
{
double RiskBaseAmount=0;
//TickValue is the value of the individual price increment for 1 lot of the instrument, expressed in the account currenty
TickValue=SymbolInfoDouble(Symb,SYMBOL_TRADE_TICK_VALUE);
//Define the base for the risk calculation depending on the parameter chosen
if(RiskBase==RISK_BASE_BALANCE)
RiskBaseAmount=AccountInfoDouble(ACCOUNT_BALANCE);
if(RiskBase==RISK_BASE_EQUITY)
RiskBaseAmount=AccountInfoDouble(ACCOUNT_EQUITY);
if(RiskBase==RISK_BASE_FREEMARGIN)
RiskBaseAmount=AccountInfoDouble(ACCOUNT_FREEMARGIN);
//Calculate the Position Size
Print("Multiplier ", lotMultiplier, "Before lot multiplier ", (RiskBaseAmount*MaxRiskPerTrade/100)/(SL*TickValue));
Print("RiskBaseAmount ", RiskBaseAmount, " MaxRiskPerTrade ", MaxRiskPerTrade, "Stop loss ", SL, " TickValue ", TickValue);
LotSize=((RiskBaseAmount*MaxRiskPerTrade/100)/(SL*TickValue));
Print("After lot multiplier ", LotSize, " Lot multiplier ", lotMultiplier);
if(ActiveMartingale)
{
LotSize = LotSize * lotMultiplier;
}
}
//If the stop loss is zero then the lot size is the default one
if(SL==0)
{
LotSize=DefaultLotSize;
}
}
//Normalize the Lot Size to satisfy the allowed lot increment and minimum and maximum position size
LotSize=MathFloor(LotSize/SymbolInfoDouble(Symb,SYMBOL_VOLUME_STEP))*SymbolInfoDouble(Symb,SYMBOL_VOLUME_STEP);
//Limit the lot size in case it is greater than the maximum allowed by the user
if(LotSize>MaxLotSize)
LotSize=MaxLotSize;
//Limit the lot size in case it is greater than the maximum allowed by the broker
if(LotSize>SymbolInfoDouble(Symb,SYMBOL_VOLUME_MAX))
LotSize=SymbolInfoDouble(Symb,SYMBOL_VOLUME_MAX);
Print("Lot ", LotSize, " Max lot ", SymbolInfoDouble(Symb,SYMBOL_VOLUME_MAX));
//If the lot size is too small then set it to 0 and don't trade
if(LotSize < SymbolInfoDouble(Symb,SYMBOL_VOLUME_MIN))
{
LotSize=0;
Print("Lot size too small");
}
}
-213
View File
@@ -1,213 +0,0 @@
//+------------------------------------------------------------------+
//| A_Parameters.mqh |
//| Copyright 2021, Nkondog Anselme Venceslas |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Nkondog Anselme Venceslas"
#property link "https://www.mql5.com"
//+------------------------------------------------------------------+
//| defines |
//+------------------------------------------------------------------+
//-ENUMERATIVE VARIABLES-//
//Enumerative variables are useful to associate numerical values to easy to remember strings
//It is similar to constants but also helps if the variable is set from the input page of the EA
//The text after the // is what you see in the input paramenters when the EA loads
//It is good practice to place all the enumberative at the start
//Enumerative for the entry signal value
enum ENUM_SIGNAL_ENTRY
{
SIGNAL_ENTRY_NEUTRAL=0, //SIGNAL ENTRY NEUTRAL
SIGNAL_ENTRY_BUY=1, //SIGNAL ENTRY BUY
SIGNAL_ENTRY_SELL=-1, //SIGNAL ENTRY SELL
};
//Enumerative for the exit signal value
enum ENUM_SIGNAL_EXIT
{
SIGNAL_EXIT_NEUTRAL=0, //SIGNAL EXIT NEUTRAL
SIGNAL_EXIT_BUY=1, //SIGNAL EXIT BUY
SIGNAL_EXIT_SELL=-1, //SIGNAL EXIT SELL
SIGNAL_EXIT_ALL=2, //SIGNAL EXIT ALL
};
//Enumerative for the allowed trading direction
enum ENUM_TRADING_ALLOW_DIRECTION
{
TRADING_ALLOW_BOTH=0, //ALLOW BOTH BUY AND SELL
TRADING_ALLOW_BUY=1, //ALLOW BUY ONLY
TRADING_ALLOW_SELL=-1, //ALLOW SELL ONLY
};
//Enumerative for the base used for risk calculation
enum ENUM_RISK_BASE
{
RISK_BASE_EQUITY=1, //EQUITY
RISK_BASE_BALANCE=2, //BALANCE
RISK_BASE_FREEMARGIN=3, //FREE MARGIN
};
//Enumerative for the default risk size
enum ENUM_RISK_DEFAULT_SIZE
{
RISK_DEFAULT_FIXED=1, //FIXED SIZE
RISK_DEFAULT_AUTO=2, //AUTOMATIC SIZE BASED ON RISK
};
//Enumerative for the Stop Loss mode
enum ENUM_MODE_SL
{
SL_FIXED=0, //FIXED STOP LOSS
SL_AUTO=1, //AUTOMATIC STOP LOSS
};
//Enumerative for the Take Profit Mode
enum ENUM_MODE_TP
{
TP_FIXED=0, //FIXED TAKE PROFIT
TP_AUTO=1, //AUTOMATIC TAKE PROFIT
};
//Enumerative for the stop loss calculation
enum ENUM_MODE_SL_BY
{
SL_BY_POINTS=0, //STOP LOSS PASSED IN POINTS
SL_BY_PRICE=1, //STOP LOSS PASSED BY PRICE
};
//Enumerative for candle type
enum ENUM_CANDLE_TYPE
{
NEUTRAL_CANDLE=0,
BEARISH_CANDLE=1,
BULLISH_CANDLE=2,
};
//Enumerative for price momentum
enum ENUM_PRICE_MOMENTUM
{
UP=2,
DOWN=1,
NEUTRAL=0,
};
struct LastTransaction
{
string time;
int type;
double profit;
} lt;
//-INPUT PARAMETERS-//
//The input parameters are the ones that can be set by the user when launching the EA
//If you place a comment following the input variable this will be shown as description of the field
//This is where you should include the input parameters for your entry and exit signals
input string Comment_strategy="=========="; //Entry And Exit Settings
//Add in this section the parameters for the indicators used in your entry and exit
//General input parameters
input string Comment_0="=========="; //Risk Management Settings
input ENUM_RISK_DEFAULT_SIZE RiskDefaultSize=RISK_DEFAULT_AUTO; //Position Size Mode
input double DefaultLotSize=1; //Position Size (if fixed or if no stop loss defined)
input ENUM_RISK_BASE RiskBase=RISK_BASE_BALANCE; //Risk Base
input double MaxRiskPerTrade=0.5; //Percentage To Risk Each Trade
input double MinLotSize=0.01; //Minimum Position Size Allowed
input double MaxLotSize=100; //Maximum Position Size Allowed
input string Comment_1="=========="; //Trading Hours Settings
input bool UseTradingHours=false; //Limit Trading Hours
input string TradingHourStart="01"; //Trading Start Hour (Broker Server Hour)
input string TradingHourEnd="23"; //Trading End Hour (Broker Server Hour)
input string TradingStartMin="30"; //Trading Start minute (Broker Server Hour)
input string TradingEndMin="00"; //Trading End minute
input string Comment_2="=========="; //Stop Loss And Take Profit Settings
input ENUM_MODE_SL StopLossMode=SL_AUTO; //Stop Loss Mode
input int DefaultStopLoss=0; //Default Stop Loss In Points (0=No Stop Loss)
input int MinStopLoss=0; //Minimum Allowed Stop Loss In Points
input int MaxStopLoss=5000; //Maximum Allowed Stop Loss In Points
input bool AtrStopLoss=false; //Set Stop loss based on ATR
input int atr_sl_factor=3; //Multiplicator for ATR stop loss
input ENUM_MODE_TP TakeProfitMode=TP_AUTO; //Take Profit Mode
input int DefaultTakeProfit=0; //Default Take Profit In Points (0=No Take Profit)
input int MinTakeProfit=0; //Minimum Allowed Take Profit In Points
input int MaxTakeProfit=5000; //Maximum Allowed Take Profit In Points
input double TakeProfitPercent=1.0; //Take Profit percent on risk base
input double Breakevent=1.0; //Minimum Profit to breakeven
input bool ProfitRun=true;
input bool ActiveMartingale=false;
input string Comment_3="=========="; //Trailing Stop Settings
input bool UseTrailingStop=false; //Use Trailing Stop
input string Comment_4="=========="; //Additional Settings
input int MagicNumber=0; //Magic Number For The Orders Opened By This EA
input string OrderNote=""; //Comment For The Orders Opened By This EA
input int Slippage=5; //Slippage in points
input double MaxSpread=10.0; //Maximum Allowed Spread To Trade In Points
input string Comment_5="==========="; //Zigzag indicator setting
input int Depth=5;
input int Deviation=5;
input int Backstep=3;
input int GapPoint=100; //Minimum gap between peaks
input int Sensitivity=2; //Minimum peak at same level
input int LookBack=50; //Maximum peak to consider
input int NumberOfCandles=3;
//-GLOBAL VARIABLES-//
//The variables included in this section are global, hence they can be used in any part of the code
string Symb=Symbol(), server_time;
long current_chart_id = ChartID();
bool IsPreChecksOk=false; //Indicates if the pre checks are satisfied
bool IsNewCandle=false; //Indicates if this is a new candle formed
bool IsSpreadOK=false; //Indicates if the spread is low enough to trade
bool IsOperatingHours=false; //Indicates if it is possible to trade at the current time (server time)
bool IsTradedThisBar=false; //Indicates if an order was already executed in the current candle
bool In_Trade = true; //Indicates if trade range has been formed
bool CanBuy = true;
bool CanSell = true;
bool ClosePosition = false;
bool FollowProfit = false;
bool UpTrendingMarket = false;
bool DownTrendingMarket = false;
double TickValue=0; //Value of a tick in account currency at 1 lot
double LotSize=0; //Lot size for the position
double Tick_Size = SymbolInfoDouble(Symb,SYMBOL_TRADE_TICK_SIZE); //Tick size
double High[];
double Low[];
double PositionProfit;
//Indicators
//+------------------------------------------------------------------+
//| |
//+------------------------------------------------------------------+
long Spread = SymbolInfoInteger(Symb,SYMBOL_SPREAD) / 100; //Check the impact. It's originally a double
int OrderOpRetry=10; //Number of attempts to retry the order submission
int TotalOpenOrders=0; //Number of total open orders
int TotalOpenBuy=0; //Number of total open buy orders
int TotalOpenSell=0; //Number of total open sell orders
int StopLossBy=SL_BY_POINTS; //How the stop loss is passed for the lot size calculation
double lotMultiplier =1; //Adust lot size according to loosing trades
int candleCounter =0;
double firstCandleOpen =0;
double lastCandleClose=0;
double ProfitRunTargetPercent=10.0;
datetime LastBarTraded;
MqlDateTime dt;
MqlTick last_tick;
ENUM_SIGNAL_ENTRY SignalEntry=SIGNAL_ENTRY_NEUTRAL; //Entry signal variable
ENUM_SIGNAL_EXIT SignalExit=SIGNAL_EXIT_NEUTRAL;
ENUM_CANDLE_TYPE candleType=NEUTRAL_CANDLE;
ENUM_PRICE_MOMENTUM priceMomentum=NEUTRAL;
//+------------------------------------------------------------------+
-123
View File
@@ -1,123 +0,0 @@
//+------------------------------------------------------------------+
//| A_PositionsManager.mqh |
//| Copyright 2021, Nkondog Anselme Venceslas |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Nkondog Anselme Venceslas"
#property link "https://www.mql5.com"
CTrade trade;
//Scan all positions to find the ones submitted by the EA
//NOTE This function is defined as bool because we want to return true if it is successful and false if it fails
bool ScanPositions()
{
//Scan all the orders, retrieving some of the details
TotalOpenOrders = 0;
TotalOpenBuy = 0;
TotalOpenSell = 0;
for(int i=0; i<PositionsTotal(); i++)
{
//If there is a problem reading the order print the error, exit the function and return false
if(PositionGetTicket(i) == 0)
{
int Error=GetLastError();
string ErrorText=GetLastErrorText(Error);
Print("ERROR - Unable to select the order - ",Error," - ",ErrorText);
return false;
}
//If the order is not for the instrument on chart we can ignore it
if(PositionGetSymbol(i)!=Symb)
continue;
//If the order has Magic Number different from the Magic Number of the EA then we can ignore it
if(PositionGetInteger(POSITION_MAGIC)!=MagicNumber)
continue;
//If it is a buy order then increment the total count of buy orders
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_BUY)
TotalOpenBuy++;
//If it is a sell order then increment the total count of sell orders
if(PositionGetInteger(POSITION_TYPE)==POSITION_TYPE_SELL)
TotalOpenSell++;
//Increment the total orders count
TotalOpenOrders++;
//Find what is the open time of the most recent trade and assign it to LastBarTraded
//this is necessary to check if we already traded in the current candle
if((datetime)PositionGetInteger(POSITION_TIME)>LastBarTraded || LastBarTraded==0)
LastBarTraded=(datetime)PositionGetInteger(POSITION_TIME);
}
Print("Total positions ", TotalOpenOrders, " - Total buys ", TotalOpenBuy, " - Total sells ", TotalOpenSell);
return true;
}
// We declare a function CloseOpenPositions of type int and we want to return
// the number of positions that are closed.
void CloseOpenPositions()
{
int TotalClose=0; // We want to count how many orders have been closed.
int c_slippage = Slippage;
Print("Close position status ", ClosePosition);
// Normalization of the slippage.
if(_Digits==3 || _Digits==5)
{
c_slippage=c_slippage*10;
}
// We scan all the orders backwards.
// This is required as if we start from the first order, we will have problems with the counters and the loop.
for(int i=PositionsTotal()-1; i>=0; i--)
{
ulong ticket = PositionGetTicket(i);
Print("Position profit is ", PositionGetDouble(POSITION_PROFIT));
PositionProfit = PositionGetDouble(POSITION_PROFIT);
/*if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_BUY && iClose(Symb, PERIOD_CURRENT, 1) < Senkouspanb && iClose(Symb, PERIOD_CURRENT, 1) < Senkouspana)
{
// We select the order of index i, selecting by position and from the pool of market/pending trades.
//If the selection is successful we try to close the order.
if(trade.PositionClose(ticket, c_slippage))
{
TotalClose++;
}
else
{
// If the order fails to be closed, we print the error.
Print("Order failed to close with error - ",GetLastError());
}
}
if(PositionGetInteger(POSITION_TYPE) == POSITION_TYPE_SELL && iClose(Symb, PERIOD_CURRENT, 1) > Senkouspanb && iClose(Symb, PERIOD_CURRENT, 1) > Senkouspana)
{
// We select the order of index i, selecting by position and from the pool of market/pending trades.
//If the selection is successful we try to close the order.
if(trade.PositionClose(ticket, c_slippage))
{
TotalClose++;
}
else
{
// If the order fails to be closed, we print the error.
Print("Order failed to close with error - ",GetLastError());
}
}*/
if(ClosePosition)
{
if(trade.PositionClose(ticket, c_slippage))
{
TotalClose++;
ClosePosition = false;
}
else
{
// If the order fails to be closed, we print the error.
Print("Order failed to close with error - ",GetLastError());
}
}
// We can use a delay if the execution is too fast.
// Sleep() will wait X milliseconds before proceeding with the code.
// Sleep(300);
}
}
//+------------------------------------------------------------------+
-23
View File
@@ -1,23 +0,0 @@
//+------------------------------------------------------------------+
//| A_TradeManager.mqh |
//| Copyright 2021, Nkondog Anselme Venceslas |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Nkondog Anselme Venceslas"
#property link "https://www.mql5.com"
void ProfitRunner()
{
if(ProfitRun)
{
if(iClose(Symb, _Period, 1) < iClose(Symb, _Period, 2) && TotalOpenBuy > 0)
{
ClosePosition = true;
}
if(iClose(Symb, _Period, 1) > iClose(Symb, _Period, 2) && TotalOpenSell > 0)
{
ClosePosition = true;
}
}
Print("Looking to close this position ", ClosePosition);
}
-27
View File
@@ -1,27 +0,0 @@
//+------------------------------------------------------------------+
//| A_TradingHour.mqh |
//| Copyright 2021, Nkondog Anselme Venceslas |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2021, Nkondog Anselme Venceslas"
#property link "https://www.mql5.com"
//+------------------------------------------------------------------+
//| defines |
//+------------------------------------------------------------------+
// #define MacrosHello "Hello, world!"
// #define MacrosYear 2010
//+------------------------------------------------------------------+
//| DLL imports |
//+------------------------------------------------------------------+
// #import "user32.dll"
// int SendMessageA(int hWnd,int Msg,int wParam,int lParam);
// #import "my_expert.dll"
// int ExpertRecalculate(int wParam,int lParam);
// #import
//+------------------------------------------------------------------+
//| EX5 imports |
//+------------------------------------------------------------------+
// #import "stdlib.ex5"
// string ErrorDescription(int error_code);
// #import
//+------------------------------------------------------------------+
-182
View File
@@ -1,182 +0,0 @@
//+------------------------------------------------------------------+
//| 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
@@ -1,771 +0,0 @@
//+------------------------------------------------------------------+
//| 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(CArray::Minimum(m_data,start,count)); }
int Maximum(const int start,const int count) const { return(CArray::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
@@ -1,777 +0,0 @@
//+------------------------------------------------------------------+
//| 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(CArray::Minimum(m_data,start,count)); }
int Maximum(const int start,const int count) const { return(CArray::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
@@ -1,778 +0,0 @@
//+------------------------------------------------------------------+
//| 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(CArray::Minimum(m_data,start,count)); }
int Maximum(const int start,const int count) const { return(CArray::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
@@ -1,770 +0,0 @@
//+------------------------------------------------------------------+
//| 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(CArray::Minimum(m_data,start,count)); }
int Maximum(const int start,const int count) const { return(CArray::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
@@ -1,770 +0,0 @@
//+------------------------------------------------------------------+
//| 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(CArray::Minimum(m_data,start,count)); }
int Maximum(const int start,const int count) const { return(CArray::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
@@ -1,759 +0,0 @@
//+------------------------------------------------------------------+
//| 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
@@ -1,770 +0,0 @@
//+------------------------------------------------------------------+
//| 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(CArray::Minimum(m_data,start,count)); }
int Maximum(const int start,const int count) const { return(CArray::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
@@ -1,780 +0,0 @@
//+------------------------------------------------------------------+
//| 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
@@ -1,657 +0,0 @@
//+------------------------------------------------------------------+
//| 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
@@ -1,415 +0,0 @@
//+------------------------------------------------------------------+
//| 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
@@ -1,174 +0,0 @@
//+------------------------------------------------------------------+
//| 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
Binary file not shown.
File diff suppressed because it is too large Load Diff
-347
View File
@@ -1,347 +0,0 @@
//+------------------------------------------------------------------+
//| 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
@@ -1,383 +0,0 @@
//+------------------------------------------------------------------+
//| 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
@@ -1,414 +0,0 @@
//+------------------------------------------------------------------+
//| 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);
}
//+------------------------------------------------------------------+
-77
View File
@@ -1,77 +0,0 @@
//+------------------------------------------------------------------+
//| DXBox.mqh |
//| Copyright 2019, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
//---
#include "DXMesh.mqh"
#include "DXMath.mqh"
#include "DXUtils.mqh"
//+------------------------------------------------------------------+
//| 3D Box object |
//+------------------------------------------------------------------+
class CDXBox : public CDXMesh
{
public:
CDXBox();
~CDXBox();
//--- create bon in specified context
bool Create(CDXDispatcher &dispatcher,CDXInput* buffer_scene,const DXVector3 &from,const DXVector3 &to);
//--- update box
bool Update(const DXVector3 &from,const DXVector3 &to);
private:
//---
void PrepareVertices(const DXVector3 &from,const DXVector3 &to);
};
//+------------------------------------------------------------------+
//| Class constructor |
//+------------------------------------------------------------------+
void CDXBox::CDXBox() : CDXMesh()
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
void CDXBox::~CDXBox(void)
{
}
//+------------------------------------------------------------------+
//| Create box in specified context |
//+------------------------------------------------------------------+
bool CDXBox::Create(CDXDispatcher &dispatcher,CDXInput* buffer_scene,const DXVector3 &from,const DXVector3 &to)
{
//--- release previous buffers
Shutdown();
//---
DXVertex vertices[];
uint indices[];
//--- prepare box vertices and indices
DXColor white=DXColor(1.0f,1.0f,1.0f,1.0f);
if(!DXComputeBox(from,to,vertices,indices))
return(false);
for(int i=0; i<ArraySize(vertices); i++)
vertices[i].vcolor=white;
//--- create mesh
return(CDXMesh::Create(dispatcher,buffer_scene,vertices,indices));
}
//+------------------------------------------------------------------+
//| Update box bounds |
//+------------------------------------------------------------------+
bool CDXBox::Update(const DXVector3 &from,const DXVector3 &to)
{
//---
DXVertex vertices[];
uint indices[];
//--- prepare box vertices and indices
DXColor white=DXColor(1.0f,1.0f,1.0f,1.0f);
if(!DXComputeBox(from,to,vertices,indices))
return(false);
for(int i=0; i<ArraySize(vertices); i++)
vertices[i].vcolor=white;
//--- update mesh vertices, indices are the same
return(CDXMesh::VerticesSet(vertices));
}
//+------------------------------------------------------------------+
-92
View File
@@ -1,92 +0,0 @@
//+------------------------------------------------------------------+
//| DXVertexBuffer.mqh |
//| Copyright 2019, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#include "DXHandle.mqh"
//+------------------------------------------------------------------+
//| DX vertex buffer |
//+------------------------------------------------------------------+
class CDXVertexBuffer : public CDXHandleShared
{
public:
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
virtual ~CDXVertexBuffer(void)
{
Shutdown();
}
//+------------------------------------------------------------------+
//| Create vertex buffer in specified context |
//+------------------------------------------------------------------+
template<typename TVertex>
bool Create(int context_handle,const TVertex &vertices[],uint start=0,uint count=WHOLE_ARRAY)
{
Shutdown();
m_context=context_handle;
m_handle=DXBufferCreate(m_context,DX_BUFFER_VERTEX,vertices,start,count);
return(m_handle!=INVALID_HANDLE);
}
//+------------------------------------------------------------------+
//| Render |
//+------------------------------------------------------------------+
bool Render(uint start=0,uint count=WHOLE_ARRAY)
{
return(DXBufferSet(m_context,m_handle,start,count));
}
//+------------------------------------------------------------------+
//| Shutdown |
//+------------------------------------------------------------------+
void Shutdown(void)
{
//--- relase handle
if(m_handle!=INVALID_HANDLE)
DXRelease(m_handle);
m_handle=INVALID_HANDLE;
}
};
//+------------------------------------------------------------------+
//| DX index buffer |
//+------------------------------------------------------------------+
class CDXIndexBuffer : public CDXHandleShared
{
public:
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
virtual ~CDXIndexBuffer(void)
{
Shutdown();
}
//+------------------------------------------------------------------+
//| Create index buffer in specified context |
//+------------------------------------------------------------------+
bool Create(int context_handle,const uint &indices[],uint start=0,uint count=WHOLE_ARRAY)
{
Shutdown();
m_context=context_handle;
m_handle=DXBufferCreate(m_context,DX_BUFFER_INDEX,indices,start,count);
return(m_handle!=INVALID_HANDLE);
}
//+------------------------------------------------------------------+
//| Render |
//+------------------------------------------------------------------+
bool Render(uint start=0,uint count=WHOLE_ARRAY)
{
return(DXBufferSet(m_context,m_handle,start,count));
}
//+------------------------------------------------------------------+
//| Shutdown |
//+------------------------------------------------------------------+
void Shutdown(void)
{
//--- relase handle
if(m_handle!=INVALID_HANDLE)
DXRelease(m_handle);
m_handle=INVALID_HANDLE;
}
};
//+------------------------------------------------------------------+
Binary file not shown.
-373
View File
@@ -1,373 +0,0 @@
//+------------------------------------------------------------------+
//| DXDispatcher.mqh |
//| Copyright 2019, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
//---
#include "DXObjectBase.mqh"
#include "DXData.mqh"
#include "DXBuffers.mqh"
#include "DXInput.mqh"
#include "DXTexture.mqh"
#include "DXShader.mqh"
//--- default shaders
#resource "Shaders/DefaultShaderVertex.hlsl" as string ExtDefaultShaderVertex;
#resource "Shaders/DefaultShaderPixel.hlsl" as string ExtDefaultShaderPixel;
//+------------------------------------------------------------------+
//| DX dispatcher which holds all resources |
//+------------------------------------------------------------------+
class CDXDispatcher : public CDXObjectBase
{
protected:
CDXObjectBase m_dx_resources; // DX resources list (Textures, Shaders, etc.)
//--- default shaders
CDXShader* m_default_vs;
CDXShader* m_default_ps;
public:
CDXDispatcher(void);
~CDXDispatcher(void);
//--- create/destroy
bool Create(int context);
void Destroy(void);
//--- check resources
void Check(void);
//--- get DX Context Handle
int DXContext(void) const { return(m_context); }
//--- create shaders
CDXShader* ShaderCreateDefault(ENUM_DX_SHADER_TYPE shader_type);
CDXShader* ShaderCreateFromFile(ENUM_DX_SHADER_TYPE shader_type,string path,string entry_point);
CDXShader* ShaderCreateFromSource(ENUM_DX_SHADER_TYPE shader_type,string source,string entry_point);
//--- create buffers
template<typename TVertex>
CDXVertexBuffer* VertexBufferCreate(const TVertex &vertices[],uint start=0,uint count=WHOLE_ARRAY);
CDXIndexBuffer* IndexBufferCreate(const uint &indicies[],uint start=0,uint count=WHOLE_ARRAY);
//--- create shader inputs
template<typename TInput>
CDXInput* InputCreate(void);
CDXTexture* TextureCreateFromFile(string path,uint data_x=0,uint data_y=0,uint data_width=0,uint data_height=0);
CDXTexture* TextureCreateFromData(ENUM_DX_FORMAT format,uint width,uint height,const uint &data[],uint data_x=0,uint data_y=0,uint data_width=0,uint data_height=0);
private:
//--- add resource to list
bool ResourceAdd(CDXObjectBase *resource);
//--- check resources
void ResourcesCheck(void);
};
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CDXDispatcher::CDXDispatcher(void)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
CDXDispatcher::~CDXDispatcher(void)
{
Destroy();
}
//+------------------------------------------------------------------+
//| Create |
//+------------------------------------------------------------------+
bool CDXDispatcher::Create(int context)
{
//--- check if context already exist
if(m_context!=INVALID_HANDLE)
return(false);
//--- save context
m_context=context;
//---
return(true);
}
//+------------------------------------------------------------------+
//| Destroy |
//+------------------------------------------------------------------+
void CDXDispatcher::Destroy(void)
{
//--- release default shaders
if(m_default_ps)
{
m_default_ps.Release();
m_default_ps=NULL;
}
if(m_default_vs)
{
m_default_vs.Release();
m_default_vs=NULL;
}
//--- release and delete all DX resources
while(m_dx_resources.Next())
{
CDXHandleShared* resource=(CDXHandleShared*)m_dx_resources.Next();
resource.Release();
}
//--- forget context
m_context=INVALID_HANDLE;
}
//+------------------------------------------------------------------+
//| Check resources |
//+------------------------------------------------------------------+
void CDXDispatcher::Check(void)
{
//---
CDXHandleShared* resource=(CDXHandleShared*)m_dx_resources.Next();
//--- release and delete all DX resources
while(CheckPointer(resource)!=POINTER_INVALID)
{
CDXHandleShared* next=(CDXHandleShared*)resource.Next();
//--- if references count 1 or less, then only we hold the resource
if(resource.References()<=1)
resource.Release();
//---
resource=next;
}
}
//+------------------------------------------------------------------+
//| Create default shader of specified type |
//+------------------------------------------------------------------+
CDXShader* CDXDispatcher::ShaderCreateDefault(ENUM_DX_SHADER_TYPE shader_type)
{
switch(shader_type)
{
//--- default pixel shader
case DX_SHADER_PIXEL:
{
if(m_default_ps==NULL)
m_default_ps=ShaderCreateFromSource(DX_SHADER_PIXEL,ExtDefaultShaderPixel,"PSMain");
return(m_default_ps);
}
//--- default vertex shader
case DX_SHADER_VERTEX:
{
if(m_default_vs==NULL)
{
m_default_vs=ShaderCreateFromSource(DX_SHADER_VERTEX,ExtDefaultShaderVertex,"VSMain");
if(m_default_vs && !m_default_vs.LayoutSet<DXVertex>())
{
m_default_vs.Release();
m_default_vs=NULL;
}
}
return(m_default_vs);
}
}
//--- return result
return(NULL);
}
//+------------------------------------------------------------------+
//| Create new shader of specified type from file |
//+------------------------------------------------------------------+
CDXShader* CDXDispatcher::ShaderCreateFromFile(ENUM_DX_SHADER_TYPE shader_type,string path,string entry_point)
{
//--- open source file
int file=FileOpen(path,FILE_READ);
if(file==INVALID_HANDLE)
return(NULL);
//--- check file size
uint size=(uint)FileSize(file);
FileClose(file);
if(size>16*1024*1024)
return(NULL);
//--- prepare buffer
char buffer[];
ArrayResize(buffer,size);
//--- read file into buffer
int read=(int)FileLoad(path,buffer);
if(read<=0)
return(NULL);
//--- convert vuffer to string
string source=CharArrayToString(buffer,0,WHOLE_ARRAY,CP_UTF8);
//--- add shader by source
return(ShaderCreateFromSource(shader_type,source,entry_point));
}
//+------------------------------------------------------------------+
//| Create new shader of specified type from source code |
//+------------------------------------------------------------------+
CDXShader* CDXDispatcher::ShaderCreateFromSource(ENUM_DX_SHADER_TYPE shader_type,string source,string entry_point)
{
//--- check context
if(m_context==INVALID_HANDLE)
return(NULL);
//--- allocate new shader
CDXShader* shader=new CDXShader();
if(shader==NULL)
return(NULL);
//--- create shader
if(!shader.Create(m_context,shader_type,source,entry_point))
{
shader.Release();
return(NULL);
}
//--- add shader to resources list
if(!ResourceAdd(shader))
{
shader.Release();
return(NULL);
}
//--- return shader
return(shader);
}
//+------------------------------------------------------------------+
//| Create vertex buffer |
//+------------------------------------------------------------------+
template<typename TVertex>
CDXVertexBuffer* CDXDispatcher::VertexBufferCreate(const TVertex &vertices[],uint start=0,uint count=WHOLE_ARRAY)
{
//--- check context
if(m_context==INVALID_HANDLE)
return(NULL);
//--- allocate new buffer
CDXVertexBuffer* buffer=new CDXVertexBuffer();
if(buffer==NULL)
return(NULL);
//--- create buffer
if(!buffer.Create(m_context,vertices,start,count))
{
buffer.Release();
return(NULL);
}
//--- add buffer to resources list
if(!ResourceAdd(buffer))
{
buffer.Release();
return(NULL);
}
//--- return buffer
return(buffer);
}
//+------------------------------------------------------------------+
//| Create vertex buffer |
//+------------------------------------------------------------------+
CDXIndexBuffer* CDXDispatcher::IndexBufferCreate(const uint &indicies[],uint start=0,uint count=WHOLE_ARRAY)
{
//--- check context
if(m_context==INVALID_HANDLE)
return(NULL);
//--- allocate new buffer
CDXIndexBuffer* buffer=new CDXIndexBuffer();
if(buffer==NULL)
return(NULL);
//--- create buffer
if(!buffer.Create(m_context,indicies,start,count))
{
buffer.Release();
return(NULL);
}
//--- add buffer to resources list
if(!ResourceAdd(buffer))
{
buffer.Release();
return(NULL);
}
//--- return input buffer
return(buffer);
}
//+------------------------------------------------------------------+
//| Create shader input buffer |
//+------------------------------------------------------------------+
template<typename TInput>
CDXInput* CDXDispatcher::InputCreate(void)
{
//--- check context
if(m_context==INVALID_HANDLE)
return(NULL);
//--- allocate new input buffer
CDXInput* input_buffer=new CDXInput();
if(input_buffer==NULL)
return(NULL);
//--- create buffer
if(!input_buffer.Create<TInput>(m_context))
{
input_buffer.Release();
return(NULL);
}
//--- add buffer to resources list
if(!ResourceAdd(input_buffer))
{
input_buffer.Release();
return(NULL);
}
//--- return shader
return(input_buffer);
}
//+------------------------------------------------------------------+
//| Create texture from bitmap file |
//+------------------------------------------------------------------+
CDXTexture* CDXDispatcher::TextureCreateFromFile(string path,uint data_x=0,uint data_y=0,uint data_width=0,uint data_height=0)
{
//--- check context
if(m_context==INVALID_HANDLE)
return(NULL);
//--- allocate new texture
CDXTexture* texture=new CDXTexture();
if(texture==NULL)
return(NULL);
//--- create texture
if(!texture.Create(m_context,path,data_x,data_y,data_width,data_height))
{
texture.Release();
return(NULL);
}
//--- add texture to resources list
if(!ResourceAdd(texture))
{
texture.Release();
return(NULL);
}
//--- return shader
return(texture);
}
//+------------------------------------------------------------------+
//| Create texture from raw data, only 32-bit pixel formats supported|
//+------------------------------------------------------------------+
CDXTexture* CDXDispatcher::TextureCreateFromData(ENUM_DX_FORMAT format,uint width,uint height,const uint &data[],uint data_x=0,uint data_y=0,uint data_width=0,uint data_height=0)
{
//--- check context
if(m_context==INVALID_HANDLE)
return(NULL);
//--- allocate new texture
CDXTexture* texture=new CDXTexture();
if(texture==NULL)
return(NULL);
//--- create texture
if(!texture.Create(m_context,format,width,height,data,data_x,data_y,data_width,data_height))
{
texture.Release();
return(NULL);
}
//--- add texture to resources list
if(!ResourceAdd(texture))
{
texture.Release();
return(NULL);
}
//--- return shader
return(texture);
}
//+------------------------------------------------------------------+
//| Add DX resource |
//+------------------------------------------------------------------+
bool CDXDispatcher::ResourceAdd(CDXObjectBase *resource)
{
//--- add resource
if(!CheckPointer(resource))
return(false);
//---
CDXObjectBase *last=&m_dx_resources;
while(CheckPointer(last.Next())!=POINTER_INVALID)
{
if(last==resource)
return(false);
//---
last=last.Next();
}
//---
resource.Next(NULL);
resource.Prev(last);
last.Next(resource);
return(true);
}
//+------------------------------------------------------------------+
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large Load Diff
-375
View File
@@ -1,375 +0,0 @@
//+------------------------------------------------------------------+
//| DXMesh.mqh |
//| Copyright 2019, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
#include "DXObject.mqh"
#include "DXDispatcher.mqh"
#include "DXData.mqh"
#include "DXUtils.mqh"
//+------------------------------------------------------------------+
//| DX simple mesh object with default shader |
//+------------------------------------------------------------------+
class CDXMesh : public CDXObject
{
protected:
//--- DX resources
CDXVertexBuffer* m_buffer_vertex;
CDXIndexBuffer* m_buffer_index;
CDXInput* m_buffer_object;
CDXInput* m_buffer_scene;
CDXShader* m_shader_vertex;
CDXShader* m_shader_pixel;
CDXTexture* m_texture;
//--- object data
DXMatrix m_transform_matrix;
DXColor m_diffuse_color;
DXColor m_emission_color;
DXColor m_specular_color;
float m_specular_power;
ENUM_DX_PRIMITIVE_TOPOLOGY m_topology;
public:
//+------------------------------------------------------------------+
//| Constructor |
//+------------------------------------------------------------------+
CDXMesh(void):m_buffer_vertex(NULL),m_buffer_index(NULL),m_buffer_object(NULL),m_buffer_scene(NULL),m_shader_vertex(NULL),m_shader_pixel(NULL),m_topology(WRONG_VALUE)
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
~CDXMesh(void)
{
Shutdown();
}
//+------------------------------------------------------------------+
//| Create mesh object from vertices and indices list |
//+------------------------------------------------------------------+
bool Create(CDXDispatcher &dispatcher,CDXInput* buffer_scene,const DXVertex &vertices[],const uint &indices[],ENUM_DX_PRIMITIVE_TOPOLOGY topology=DX_PRIMITIVE_TOPOLOGY_TRIANGLELIST)
{
Shutdown();
//--- check data
if(buffer_scene==NULL || buffer_scene.Handle()==INVALID_HANDLE ||
ArraySize(vertices)<1 || ArraySize(indices)<1)
return(false);
//--- update context
m_context=dispatcher.DXContext();
//--- initialize default parameters
DXMatrixIdentity(m_transform_matrix);
m_diffuse_color =DXColor(1.0,1.0,1.0,1.0);
m_emission_color=DXColor(0.0,0.0,0.0,0.0);
m_specular_color=DXColor(0.0,0.0,0.0,0.0);
m_specular_power=16.0f;
//--- create object input
m_buffer_object=dispatcher.InputCreate<DXInputObject>();
if(m_buffer_object!=NULL)
{
m_buffer_object.AddRef();
//--- use default vertex shader
m_shader_vertex=dispatcher.ShaderCreateDefault(DX_SHADER_VERTEX);
if(m_shader_vertex!=NULL)
{
m_shader_vertex.AddRef();
//--- use default pixel shader
m_shader_pixel=dispatcher.ShaderCreateDefault(DX_SHADER_PIXEL);
if(m_shader_pixel!=NULL)
{
m_shader_pixel.AddRef();
//--- create vertex buffer
m_buffer_vertex=dispatcher.VertexBufferCreate(vertices);
if(m_buffer_vertex!=NULL)
{
m_buffer_vertex.AddRef();
//--- create index buffer
m_buffer_index=dispatcher.IndexBufferCreate(indices);
if(m_buffer_index!=NULL)
m_buffer_index.AddRef();
}
}
}
}
//--- set object buffer to shaders
if(m_buffer_object==NULL || m_shader_vertex==NULL || m_shader_pixel==NULL || m_buffer_vertex==NULL || m_buffer_index==NULL)
{
Shutdown();
return(false);
}
//--- save scene buffer
m_buffer_scene=buffer_scene;
m_buffer_scene.AddRef();
//--- save topology
m_topology=topology;
//---
return(true);
}
//+------------------------------------------------------------------+
//| Create mesh object from OBJ mesh file |
//+------------------------------------------------------------------+
bool Create(CDXDispatcher &dispatcher,CDXInput* buffer_scene,string obj_path,float scale=1.0f,bool inverse_winding=false)
{
DXVertex vertices[];
uint indices[];
//--- load model
if(!DXLoadObjModel(obj_path,vertices,indices,scale))
return(false);
//--- set white vertices color
DXColor white=DXColor(1.0f,1.0f,1.0f,1.0f);
int count=ArraySize(vertices);
for(int i=0; i<count; i++)
vertices[i].vcolor=white;
//--- inverse winding
if(inverse_winding)
DXInverseWinding(vertices,indices);
//--- create mesh
return(Create(dispatcher,buffer_scene,vertices,indices));
}
//+------------------------------------------------------------------+
//| Update vertices |
//+------------------------------------------------------------------+
bool VerticesSet(const DXVertex &vertices[])
{
//--- check size
if(ArraySize(vertices)<1)
return(false);
//--- create new vertex buffer
if(!m_buffer_vertex.Create(m_context,vertices))
{
Shutdown();
return(false);
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| Update indices |
//+------------------------------------------------------------------+
bool IndicesSet(const uint &indices[])
{
//--- check size
if(ArraySize(indices)<1)
return(false);
//--- create new index buffer
if(!m_buffer_index.Create(m_context,indices))
{
Shutdown();
return(false);
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| Update indices |
//+------------------------------------------------------------------+
bool TopologySet(ENUM_DX_PRIMITIVE_TOPOLOGY topology)
{
m_topology=topology;
//---
return(true);
}
//+------------------------------------------------------------------+
//| Get transform matrix |
//+------------------------------------------------------------------+
void TransformMatrixGet(DXMatrix &mat) const
{
mat=m_transform_matrix;
}
//+------------------------------------------------------------------+
//| Set transform matrix |
//+------------------------------------------------------------------+
void TransformMatrixSet(const DXMatrix &mat)
{
m_transform_matrix=mat;
}
//+------------------------------------------------------------------+
//| Get diffuse color |
//+------------------------------------------------------------------+
void DiffuseColorGet(DXColor &clr) const
{
clr=m_diffuse_color;
}
//+------------------------------------------------------------------+
//| Set diffuse color |
//+------------------------------------------------------------------+
void DiffuseColorSet(const DXColor &clr)
{
m_diffuse_color=clr;
}
//+------------------------------------------------------------------+
//| Get specular color |
//+------------------------------------------------------------------+
void SpecularColorGet(DXColor &clr) const
{
clr=m_specular_color;
}
//+------------------------------------------------------------------+
//| Set specular color |
//+------------------------------------------------------------------+
void SpecularColorSet(const DXColor &clr)
{
m_specular_color=clr;
}
//+------------------------------------------------------------------+
//| Get specular power |
//+------------------------------------------------------------------+
void SpecularPowerGet(float &power) const
{
power=m_specular_power;
}
//+------------------------------------------------------------------+
//| Set specular power |
//+------------------------------------------------------------------+
void SpecularPowerSet(float power)
{
m_specular_power=power;
}
//+------------------------------------------------------------------+
//| Get emission color |
//+------------------------------------------------------------------+
void EmissionColorGet(DXColor &clr) const
{
clr=m_emission_color;
}
//+------------------------------------------------------------------+
//| Set emission color |
//+------------------------------------------------------------------+
void EmissionColorSet(const DXColor &clr)
{
m_emission_color=clr;
}
//+------------------------------------------------------------------+
//| Render mesh |
//+------------------------------------------------------------------+
virtual bool Render(void) override
{
//--- update object buffer
DXInputObject input_data;
DXMatrixTranspose(input_data.transform,m_transform_matrix);
input_data.diffuse_color =m_diffuse_color;
input_data.emission_color=m_emission_color;
input_data.specular_color=m_specular_color;
input_data.specular_power=m_specular_power;
//--- clear shader textures
m_shader_pixel.TexturesClear();
//--- set buffers, shaders, topology and render
if(m_buffer_object.InputSet(input_data))
if(m_buffer_vertex.Render())
if(m_buffer_index.Render())
if(m_shader_vertex.InputSet(0,m_buffer_scene) && m_shader_vertex.InputSet(1,m_buffer_object))
if(m_shader_pixel.InputSet(0,m_buffer_scene) && m_shader_pixel.InputSet(1,m_buffer_object))
if(CheckPointer(m_texture)==POINTER_INVALID || m_shader_pixel.TextureSet(0,m_texture))
if(m_shader_vertex.Render())
if(m_shader_pixel.Render())
if(DXPrimiveTopologySet(m_context,m_topology))
return(DXDrawIndexed(m_context));
//---
return(false);
}
//+------------------------------------------------------------------+
//| Set texture from image file |
//+------------------------------------------------------------------+
bool TextureSet(CDXDispatcher &dispatcher,string path,uint data_x=0,uint data_y=0,uint data_width=0,uint data_height=0)
{
//--- check if texture already exist
if(CheckPointer(m_texture)==POINTER_INVALID)
{
m_texture=dispatcher.TextureCreateFromFile(path,data_x,data_y,data_width,data_height);
if(m_texture==NULL)
return(false);
m_texture.AddRef();
return(true);
}
//--- update texture data
if(!m_texture.Create(m_context,path,data_x,data_y,data_width,data_height))
{
m_texture.Release();
m_texture=NULL;
return(false);
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| Set texture from image data |
//+------------------------------------------------------------------+
bool TextureSet(CDXDispatcher &dispatcher,ENUM_DX_FORMAT format,uint width,uint height,const uint &data[],uint data_x=0,uint data_y=0,uint data_width=0,uint data_height=0)
{
//--- check if texture already exist
if(CheckPointer(m_texture)==POINTER_INVALID)
{
m_texture=dispatcher.TextureCreateFromData(format,width,height,data,data_x,data_y,data_width,data_height);
if(m_texture==NULL)
return(false);
m_texture.AddRef();
return(true);
}
//--- update texture data
if(!m_texture.Create(m_context,format,width,height,data,data_x,data_y,data_width,data_height))
{
m_texture.Release();
m_texture=NULL;
return(false);
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| Delete used texture |
//+------------------------------------------------------------------+
void TextureDelete()
{
//--- release texture
if(CheckPointer(m_texture)!=POINTER_INVALID)
{
m_texture.Release();
m_texture=NULL;
}
}
//+------------------------------------------------------------------+
//| Shutdown |
//+------------------------------------------------------------------+
virtual void Shutdown(void)
{
//--- release all dx resources
if(CheckPointer(m_buffer_vertex)!=POINTER_INVALID)
{
m_buffer_vertex.Release();
m_buffer_vertex=NULL;
}
if(CheckPointer(m_buffer_index)!=POINTER_INVALID)
{
m_buffer_index.Release();
m_buffer_index=NULL;
}
if(CheckPointer(m_buffer_object)!=POINTER_INVALID)
{
m_buffer_object.Release();
m_buffer_object=NULL;
}
if(CheckPointer(m_texture)!=POINTER_INVALID)
{
m_texture.Release();
m_texture=NULL;
}
if(CheckPointer(m_buffer_scene)!=POINTER_INVALID)
{
m_buffer_scene.Release();
m_buffer_scene=NULL;
}
if(CheckPointer(m_shader_pixel)!=POINTER_INVALID)
{
m_shader_pixel.Release();
m_shader_pixel=NULL;
}
if(CheckPointer(m_shader_vertex)!=POINTER_INVALID)
{
m_shader_vertex.Release();
m_shader_vertex=NULL;
}
m_topology =WRONG_VALUE;
}
};
//+------------------------------------------------------------------+
Binary file not shown.
Binary file not shown.
Binary file not shown.
-162
View File
@@ -1,162 +0,0 @@
//+------------------------------------------------------------------+
//| DXSurface.mqh |
//| Copyright 2019, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
//---
#include "DXMesh.mqh"
#include "DXMath.mqh"
#include "DXUtils.mqh"
//+------------------------------------------------------------------+
//| 3D Box object |
//+------------------------------------------------------------------+
class CDXSurface : public CDXMesh
{
public:
//--- surface creation flags
enum EN_SURFACE_FLAGS
{
SF_NONE =0x0,
SF_TWO_SIDED =0x1,
SF_USE_NORMALS =0x2,
};
//--- surface color scheme
enum EN_COLOR_SCHEME
{
CS_NONE =0,
CS_JET =1,
CS_COLD_TO_HOT =2,
CS_RED_TO_GREEN=3
};
protected:
uint m_data_width;
uint m_data_height;
uint m_flags;
EN_COLOR_SCHEME m_color_scheme;
public:
CDXSurface();
~CDXSurface();
//--- create bon in specified context
bool Create(CDXDispatcher &dispatcher,CDXInput* buffer_scene,double &data[],uint m_data_widht,uint m_data_height,float data_range,const DXVector3 &from,const DXVector3 &to,DXVector2 &texture_size,uint flags=SF_NONE,EN_COLOR_SCHEME color_scheme=CS_NONE);
//--- update box
bool Update(double &data[],uint m_data_widht,uint m_data_height,float data_range,const DXVector3 &from,const DXVector3 &to,DXVector2 &texture_size,uint flags=0,EN_COLOR_SCHEME color_scheme=CS_NONE);
private:
//---
void PrepareColors(DXVertex &vertices[],const DXVector3 &from,const DXVector3 &to);
};
//+------------------------------------------------------------------+
//| Class constructor |
//+------------------------------------------------------------------+
void CDXSurface::CDXSurface() : CDXMesh()
{
}
//+------------------------------------------------------------------+
//| Destructor |
//+------------------------------------------------------------------+
void CDXSurface::~CDXSurface(void)
{
}
//+------------------------------------------------------------------+
//| Create box in specified context |
//+------------------------------------------------------------------+
bool CDXSurface::Create(CDXDispatcher &dispatcher,CDXInput* buffer_scene,
double &data[],uint data_width,uint data_height,float data_range,
const DXVector3 &from,const DXVector3 &to,DXVector2 &texture_size,
uint flags=SF_NONE,EN_COLOR_SCHEME color_scheme=CS_NONE)
{
//--- release previous buffers
Shutdown();
//--- save parameters
m_data_width =data_width;
m_data_height =data_height;
m_flags =flags;
m_color_scheme=color_scheme;
//---
DXVertex vertices[];
uint indices[];
//--- prepare surface vertices and indices
DXColor white=DXColor(1.0f,1.0f,1.0f,1.0f);
if(!DXComputeSurface(data,data_width,data_height,data_range,from,to,texture_size,flags&SF_TWO_SIDED,flags&SF_USE_NORMALS,vertices,indices))
return(false);
//--- calculate colors
PrepareColors(vertices,from,to);
//--- create mesh
return(CDXMesh::Create(dispatcher,buffer_scene,vertices,indices));
}
//+------------------------------------------------------------------+
//| Update box bounds |
//+------------------------------------------------------------------+
bool CDXSurface::Update(double &data[],uint data_width,uint data_height,float data_range,
const DXVector3 &from,const DXVector3 &to,DXVector2 &texture_size,
uint flags=0,EN_COLOR_SCHEME color_scheme=CS_NONE)
{
//---
DXVertex vertices[];
uint indices[];
//--- prepare surface vertices and indices
DXColor white=DXColor(1.0f,1.0f,1.0f,1.0f);
if(!DXComputeSurface(data,data_width,data_height,data_range,from,to,texture_size,flags&SF_TWO_SIDED,flags&SF_USE_NORMALS,vertices,indices))
return(false);
//--- calculate colors
m_color_scheme=color_scheme;
PrepareColors(vertices,from,to);
//--- update vertices
bool res=CDXMesh::VerticesSet(vertices);
//--- do not update indices if vertices relations are the same
if(m_data_width!=data_width || m_data_height!=data_height || (m_flags&SF_TWO_SIDED)!=(flags&SF_TWO_SIDED))
res=res && CDXMesh::IndicesSet(indices);
//--- check result
if(!res)
{
Shutdown();
return(false);
}
//--- save parameters
m_data_width =data_width;
m_data_height =data_height;
m_flags =flags;
//--- success
return(true);
}
//+------------------------------------------------------------------+
//| Update box bounds |
//+------------------------------------------------------------------+
void CDXSurface::PrepareColors(DXVertex &vertices[],const DXVector3 &from,const DXVector3 &to)
{
uint count=ArraySize(vertices);
float scale=1.0f/(fmax(FLT_EPSILON,to.y-from.y));
switch(m_color_scheme)
{
case CS_JET:
{
for(uint i=0; i<count; i++)
DXComputeColorJet((vertices[i].position.y-from.y)*scale,vertices[i].vcolor);
break;
}
case CS_COLD_TO_HOT:
{
for(uint i=0; i<count; i++)
DXComputeColorColdToHot((vertices[i].position.y-from.y)*scale,vertices[i].vcolor);
break;
}
case CS_RED_TO_GREEN:
{
for(uint i=0; i<count; i++)
DXComputeColorRedToGreen((vertices[i].position.y-from.y)*scale,vertices[i].vcolor);
break;
}
default:
{
DXColor white=DXColor(1.0f,1.0f,1.0f,1.0f);
for(uint i=0; i<count; i++)
vertices[i].vcolor=white;
break;
}
}
}
//+------------------------------------------------------------------+
Binary file not shown.
-942
View File
@@ -1,942 +0,0 @@
//+------------------------------------------------------------------+
//| DXUtils.mqh |
//| Copyright 2019, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2019, MetaQuotes Software Corp."
#property link "https://www.mql5.com"
//---
#include "DXMath.mqh"
#include "DXData.mqh"
//--- data types in Wavefront OBJ file format
#define OBJ_DATA_UNKNOWN 0
#define OBJ_DATA_V 1
#define OBJ_DATA_VT 2
#define OBJ_DATA_VN 3
#define OBJ_DATA_F 4
//+------------------------------------------------------------------+
//| OBJFaceType |
//+------------------------------------------------------------------+
struct OBJFaceType
{
int total;
int v[4];
int t[4];
int n[4];
};
//+------------------------------------------------------------------+
//| Transforms right to left hand system, or backward |
//| TVertex must have |
//| DXVector4 normal and DXVector2 tcoord members |
//+------------------------------------------------------------------+
template <typename TVertex>
void DXInverseWinding(TVertex &vertices[],uint &indices[])
{
//--- proccess vertices
uint count=ArraySize(vertices);
for(uint i=0; i<count; i++)
{
//--- invert normals
vertices[i].normal.x=-vertices[i].normal.x;
vertices[i].normal.y=-vertices[i].normal.y;
vertices[i].normal.z=-vertices[i].normal.z;
//--- flip texture coordinates
vertices[i].tcoord.x=1.0f-vertices[i].tcoord.x;
}
//--- change indices order
count=ArraySize(indices);
for(uint i=2; i<count; i+=3)
{
uint tmp =indices[i];
indices[i] =indices[i-2];
indices[i-2]=tmp;
}
}
//+------------------------------------------------------------------+
//| Load static 3D models from Maya 2011 |
//| https://en.wikibooks.org/wiki/DirectX/10.0/Direct3D/Loading_Maya |
//+------------------------------------------------------------------+
bool DXLoadObjData(const string filename,DXVector4 &v_positions[],DXVector2 &v_tcoords[],DXVector4 &v_normals[],OBJFaceType &faces[],bool show_debug=false)
{
int total_positions=0;
int total_tcoords=0;
int total_normals=0;
int total_faces=0;
//---
ResetLastError();
int file_handle=FileOpen(filename,FILE_READ|FILE_TXT|FILE_ANSI);
if(file_handle==INVALID_HANDLE)
{
printf("FileOpen %s failed, error code=%d",filename,GetLastError());
return(false);
}
int str_length=0;
string str="";
int total_lines=0;
string str_parsed[];
string str_parsed_faces[];
//---
while(!FileIsEnding(file_handle))
{
str=FileReadString(file_handle,str_length);
total_lines++;
//--- replace two spaces to one
StringReplace(str,"\t"," ");
while(StringFind(str," ",0)!=-1)
StringReplace(str," "," ");
//--- split string to tokens
int total_items=StringSplit(str,' ',str_parsed);
if(total_items<1)
continue;
//--- when examining the file you can ignore every line unless it starts with a "V", "VT", "VN", or "F".
//--- the extra information in the file will not be needed for converting .obj to our file format.
StringToUpper(str_parsed[0]);
//--- parse data type
int data_type=OBJ_DATA_UNKNOWN;
if(str_parsed[0]=="V")
data_type=OBJ_DATA_V;
else
if(str_parsed[0]=="VT")
data_type=OBJ_DATA_VT;
else
if(str_parsed[0]=="VN")
data_type=OBJ_DATA_VN;
else
if(str_parsed[0]=="F")
data_type=OBJ_DATA_F;
//--- proceed data type
switch(data_type)
{
//--- 1. "V" lines are for the vertices, each is listed in X, Y, Z float format.
case OBJ_DATA_V:
{
total_positions++;
if(total_items<4)
{
PrintFormat("obj data error at line=%d: %s",total_lines,str);
FileClose(file_handle);
return(false);
}
ArrayResize(v_positions,total_positions,total_positions+1000);
int idx=total_positions-1;
v_positions[idx].x=(float)StringToDouble(str_parsed[1]);
v_positions[idx].y=(float)StringToDouble(str_parsed[2]);
v_positions[idx].z=(float)StringToDouble(str_parsed[3]);
v_positions[idx].w=1.0f;
//--- debug message
if(show_debug)
printf("posiiton %d: %f %f %f",idx,v_positions[idx].x,v_positions[idx].y,v_positions[idx].z);
//---
break;
}
//--- 2. "VT" lines are for the texture coordinates, they are listed in TU, TV float format.
case OBJ_DATA_VT:
{
total_tcoords++;
if(total_items<3)
{
PrintFormat("obj data error at line=%d: %s",total_lines,str);
FileClose(file_handle);
return(false);
}
ArrayResize(v_tcoords,total_tcoords,total_tcoords+1000);
int idx=total_tcoords-1;
v_tcoords[idx].x=(float)StringToDouble(str_parsed[1]);
v_tcoords[idx].y=(float)StringToDouble(str_parsed[2]);
//--- debug message
if(show_debug)
printf("tcoord %d: %f %f",idx,v_tcoords[idx].x,v_tcoords[idx].y);
//---
break;
}
//--- 3. "VN" lines are for the normal vectors, most of them are duplicated again
//--- since it records them for every vertex in every triangle in the model, they are listed in NX, NY, NZ float format.
case OBJ_DATA_VN:
{
total_normals++;
if(total_items<4)
{
PrintFormat("obj data error at line=%d: %s",total_lines,str);
FileClose(file_handle);
return(false);
}
//---
ArrayResize(v_normals,total_normals,total_normals+1000);
int idx=total_normals-1;
v_normals[idx].x=(float)StringToDouble(str_parsed[1]);
v_normals[idx].y=(float)StringToDouble(str_parsed[2]);
v_normals[idx].z=(float)StringToDouble(str_parsed[3]);
v_normals[idx].w=0.0f;
//--- debug message
if(show_debug)
printf("normal %d: %f %f %f",idx,v_normals[idx].x,v_normals[idx].y,v_normals[idx].z);
//---
break;
}
//--- 4. "F" lines are for each face in the model.
//--- the values listed are indexes into the vertices, texture coordinates, and normal vectors. The format of each face is:
//--- f Vertex1/Texture1/Normal1 Vertex2/Texture2/Normal2 Vertex3/Texture3/Normal3
//--- so a line that says "f 3/13/5 4/14/6 5/15/7" then translates to "Vertex3/Texture13/Normal5 Vertex4/Texture14/Normal6 Vertex5/Texture15/Normal7".
case OBJ_DATA_F:
{
total_faces++;
//--- check size
if(total_items<4)
{
PrintFormat("obj data error at line=%d: %s",total_lines,str);
FileClose(file_handle);
return(false);
}
//---
ArrayResize(faces,total_faces,total_faces+1000);
int idx=total_faces-1;
//--- clear all face indices
for(uint i=0; i<4; i++)
{
faces[idx].v[0]=0;
faces[idx].t[0]=0;
faces[idx].n[0]=0;
}
//--- read indices
faces[idx].total=MathMin(total_items-1,4);
for(int i=0; i<faces[idx].total; i++)
{
int elements=StringSplit(str_parsed[i+1],'/',str_parsed_faces);
if(elements>0)
faces[idx].v[i]=(int)StringToInteger(str_parsed_faces[0]);
if(elements>1)
faces[idx].t[i]=(int)StringToInteger(str_parsed_faces[1]);
if(elements>2)
faces[idx].n[i]=(int)StringToInteger(str_parsed_faces[2]);
}
//--- debug message
if(show_debug)
printf("%face d: %d vertex(%d,%d,%d,%d) texture(%d,%d,%d,%d) normal(%d,%d,%d,%d)",idx+1,
faces[idx].v[0],faces[idx].v[1],faces[idx].v[2],faces[idx].v[3],
faces[idx].t[0],faces[idx].t[1],faces[idx].t[2],faces[idx].t[3],
faces[idx].n[0],faces[idx].n[1],faces[idx].n[2],faces[idx].n[3]);
//---
break;
}
default:
{
break;
}
}
}
//--- close the file
FileClose(file_handle);
//---
if(show_debug)
{
printf("File %s loaded successfully. Total lines: %d",filename,total_lines);
printf("total v_positions=%d",total_positions);
printf("total v_normals=%d",total_normals);
printf("total v_tcoords=%d",total_tcoords);
printf("total faces=%d",total_faces);
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| Load static 3D models from Maya 2011 |
//| https://en.wikibooks.org/wiki/DirectX/10.0/Direct3D/Loading_Maya |
//| TVertex must have |
//| DXVector4 position, normal and DXVector2 tcoord members |
//+------------------------------------------------------------------+
template <typename TVertex>
bool DXLoadObjModel(const string filename,TVertex &vertices[],uint &indices[],float scale=1.0f)
{
//--- intermediate data arrays
DXVector4 v_positions[];
DXVector2 v_tcoords[];
DXVector4 v_normals[];
OBJFaceType faces[];
//--- load data
if(!DXLoadObjData(filename,v_positions,v_tcoords,v_normals,faces,false))
{
printf("Error loading model data from %s",filename);
return(false);
}
//---
int total_v_positions=ArraySize(v_positions);
int total_v_tcoords =ArraySize(v_tcoords);
int total_v_normals =ArraySize(v_normals);
int total_faces =ArraySize(faces);
//--- check faces
if(total_faces==0)
{
printf("No model data.");
return(false);
}
//--- check consistency of the indices
int vertices_count=0;
int indices_count =0;
bool split_vertices=false;
for(int i=0; i<total_faces; i++)
{
//--- each face have to be 3 or 4 sided
if(faces[i].total<3 || faces[i].total>4)
{
printf("Error in %d face, face vertices count is %d",i,faces[i].total);
return(false);
}
//---
for(int j=0; j<faces[i].total; j++)
{
if(faces[i].v[j]<=0 || faces[i].v[j]>total_v_positions)
{
printf("Error in %d face, %d vertext index is %d. Total posiitons=%d",i,j,faces[i].v[j],total_v_positions);
return(false);
}
if(total_v_tcoords>0)
{
if(faces[i].t[j]<=0 || faces[i].t[j]>total_v_tcoords)
{
printf("Error in %d face, %d tcoord index is %d. Total tcoords=%d",i,j,faces[i].v[j],total_v_positions);
return(false);
}
if(faces[i].t[j]!=faces[i].v[j])
split_vertices=true;
}
if(total_v_normals>0)
{
if(faces[i].n[j]<=0 || faces[i].n[j]>total_v_normals)
{
printf("Error in %d face, %d normal index is %d. Total normals=%d",i,j,faces[i].v[j],total_v_positions);
return(false);
}
if(faces[i].n[j]!=faces[i].v[j])
split_vertices=true;
}
}
//--- calc counts
vertices_count+=faces[i].total;
if(faces[i].total<4)
indices_count+=3;
else
indices_count+=6;
}
printf("Data consistency checked.");
//--- prepare arrays
if(!split_vertices)
vertices_count=total_v_positions;
ArrayResize(vertices,vertices_count);
ArrayResize(indices, indices_count);
int v_idx=0,i_idx=0;
for(int i=0; i<total_faces; i++)
{
for(int j=0; j<faces[i].total; j++)
{
if(!split_vertices)
v_idx=faces[i].v[j]-1;
//--- posiitons
vertices[v_idx].position.x=v_positions[faces[i].v[j]-1].x*scale;
vertices[v_idx].position.y=v_positions[faces[i].v[j]-1].y*scale;
vertices[v_idx].position.z=v_positions[faces[i].v[j]-1].z*scale;
vertices[v_idx].position.w=1.0f;
//--- normal
if(faces[i].n[j])
DXVec4Normalize(vertices[v_idx].normal,v_normals[faces[i].n[j]-1]);
//--- tcoord
if(faces[i].t[j])
vertices[v_idx].tcoord=v_tcoords[faces[i].t[j]-1];
//--- indices
indices[i_idx++]=v_idx;
//--- increment indx
if(split_vertices)
v_idx++;
}
//--- the end of second triangle in 4-sided face
if(faces[i].total==4)
{
indices[i_idx]=indices[i_idx-4];
i_idx++;
indices[i_idx]=indices[i_idx-3];
i_idx++;
}
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| Box |
//| TVertex must have |
//| DXVector4 position, DXVector4 normal and DXVector2 tcoord members|
//+------------------------------------------------------------------+
template <typename TVertex>
bool DXComputeBox(const DXVector3 &from,const DXVector3 &to,TVertex &vertices[],uint &indices[])
{
//--- prepare arrays
const int faces=6;
if(ArrayResize(vertices,4*faces)!=4*faces)
return(false);
//--- set indices
uint ind[]= {0,1,2, 2,3,0, 4,5,6, 6,7,4, 8,9,10, 10,11,8, 12,13,14, 14,15,12, 16,17,18, 18,19,16, 20,21,22, 22,23,20};
ArrayResize(indices,0);
if(ArrayCopy(indices,ind)!=ArraySize(ind))
return(false);
//--- prepare boundaries
float left=from.x,right=to.x,bottom=from.y,top=to.y,near=from.z,far=to.z;
if(from.x>to.x)
{
right=from.x;
left= to.x;
}
if(from.y>to.y)
{
top= from.y;
bottom=to.y;
}
if(from.z>to.z)
{
far=from.z;
near=to.z;
}
//--- left face
vertices[0].position=DXVector4(left,top, far, 1.0);
vertices[1].position=DXVector4(left,top, near,1.0);
vertices[2].position=DXVector4(left,bottom,near,1.0);
vertices[3].position=DXVector4(left,bottom,far, 1.0);
for(int i=0; i<4; i++)
vertices[i].normal=DXVector4(-1.0,0.0,0.0,0.0);
//--- right face
vertices[4].position=DXVector4(right,top, near,1.0);
vertices[5].position=DXVector4(right,top, far, 1.0);
vertices[6].position=DXVector4(right,bottom,far, 1.0);
vertices[7].position=DXVector4(right,bottom,near,1.0);
for(int i=4; i<8; i++)
vertices[i].normal=DXVector4(1.0,0.0,0.0,0.0);
//--- front face
vertices[8].position =DXVector4(left, top, near,1.0);
vertices[9].position =DXVector4(right,top, near,1.0);
vertices[10].position=DXVector4(right,bottom,near,1.0);
vertices[11].position=DXVector4(left, bottom,near,1.0);
for(int i=8; i<12; i++)
vertices[i].normal=DXVector4(0.0,0.0,-1.0,0.0);
//--- back face
vertices[12].position=DXVector4(right,top, far,1.0);
vertices[13].position=DXVector4(left, top, far,1.0);
vertices[14].position=DXVector4(left, bottom,far,1.0);
vertices[15].position=DXVector4(right,bottom,far,1.0);
for(int i=12; i<16; i++)
vertices[i].normal=DXVector4(0.0,0.0,1.0,0.0);
//--- top face
vertices[16].position=DXVector4(left, top,far, 1.0);
vertices[17].position=DXVector4(right,top,far, 1.0);
vertices[18].position=DXVector4(right,top,near,1.0);
vertices[19].position=DXVector4(left, top,near,1.0);
for(int i=16; i<20; i++)
vertices[i].normal=DXVector4(0.0,1.0,0.0,0.0);
//--- bottom face
vertices[20].position=DXVector4(left, bottom,near,1.0);
vertices[21].position=DXVector4(right,bottom,near,1.0);
vertices[22].position=DXVector4(right,bottom,far, 1.0);
vertices[23].position=DXVector4(left, bottom,far, 1.0);
for(int i=20; i<24; i++)
vertices[i].normal=DXVector4(0.0,-1.0,0.0,0.0);
//--- texture coordinates
for(int i=0; i<faces; i++)
{
vertices[i*4+0].tcoord=DXVector2(0.0f,0.0f);
vertices[i*4+1].tcoord=DXVector2(1.0f,0.0f);
vertices[i*4+2].tcoord=DXVector2(1.0f,1.0f);
vertices[i*4+3].tcoord=DXVector2(0.0f,1.0f);
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| Sphere |
//| TVertex must have |
//| DXVector4 position, DXVector4 normal and DXVector2 tcoord members|
//+------------------------------------------------------------------+
template <typename TVertex>
bool DXComputeSphere(float radius,uint tessellation,TVertex &vertices[],uint &indices[])
{
if(tessellation<3)
tessellation=3;
uint segments_y =tessellation;
uint segments_xz=tessellation*2;
//--- prepare arrays
uint count=(segments_y+1)*(segments_xz+1);
if(ArrayResize(vertices,count)!=count)
return(false);
count=6*segments_y*(segments_xz);
if(ArrayResize(indices,count)!=count)
return(false);
//--- create rings of vertices at progressively higher latitudes.
for(uint i=0,idx=0; i<=segments_y; i++)
{
DXVector2 tcoord=DXVector2(0.0f,1.0f-(float)i/segments_y);
float latitude=(i*DX_PI/segments_y)-DX_PI_DIV2;
float dy =(float)sin(latitude);
float dxz=(float)cos(latitude);
//--- create a single ring of vertices at this latitude.
for(uint j=0; j<=segments_xz; j++,idx++)
{
float longitude=(j%segments_xz)*DX_PI_MUL2/segments_xz;
//--- normal
DXVector3 normal=DXVector3((float)sin(longitude)*dxz,dy,(float)cos(longitude)*dxz);
vertices[idx].normal =DXVector4(normal.x,normal.y,normal.z,0.0);
//--- position
DXVec3Scale(normal,normal,radius);
vertices[idx].position=DXVector4(normal.x,normal.y,normal.z,1.0);
//--- texture coords
tcoord.x = float(j)/segments_xz;
vertices[idx].tcoord =tcoord;
}
}
//--- fill the index buffer with triangles joining each pair of latitude rings.
uint stride=segments_xz+1;
uint idx=0;
for(uint i=0; i<segments_y; i++)
{
for(uint j=0; j<segments_xz; j++)
{
uint next_i=i+1;
uint next_j=(j+1)%stride;
indices[idx++]=next_i*stride + next_j;
indices[idx++]=next_i*stride + j;
indices[idx++]= i*stride + j;
indices[idx++]= i*stride + j;
indices[idx++]= i*stride + next_j;
indices[idx++]=next_i*stride + next_j;
}
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| Torus |
//| TVertex must have |
//| DXVector4 position, DXVector4 normal and DXVector2 tcoord members|
//+------------------------------------------------------------------+
template <typename TVertex>
bool DXComputeTorus(float outer_radius,float inner_radius,uint tessellation,TVertex &vertices[],uint &indices[])
{
if(tessellation<3)
tessellation=3;
//--- prepare arrays
uint count=(tessellation+1)*(tessellation+1);
if(ArrayResize(vertices,count)!=count)
return(false);
count=6*tessellation*tessellation;
if(ArrayResize(indices,count)!=count)
return(false);
//---
uint v=0,idx=0;
uint stride=tessellation+1;
//--- first we loop around the main ring of the torus.
for(uint i=0; i<=tessellation; i++)
{
DXVector2 tcoord=DXVector2(float(i)/tessellation,0.0f);
//--- create a transform matrix that will align geometry to slice perpendicularly though the current ring position.
DXMatrix rotation,transform;
DXMatrixRotationY(rotation,-1.0f*(i%tessellation)*DX_PI_MUL2/tessellation-DX_PI_DIV2);
DXMatrixTranslation(transform,outer_radius,0.0f,0.0f);
DXMatrixMultiply(transform,transform,rotation);
//--- now we loop along the other axis, around the side of the tube.
for(uint j=0; j<=tessellation; j++)
{
//--- calc normal and position
float angle=(j%tessellation)*DX_PI_MUL2/tessellation+DX_PI;
vertices[v].normal=DXVector4((float)cos(angle),(float)sin(angle),0.0f,0.0f);
vertices[v].position=DXVector4(vertices[v].normal.x*inner_radius,vertices[v].normal.y*inner_radius,0.0f,1.0f);
DXVec4Transform(vertices[v].normal, vertices[v].normal, transform);
DXVec4Transform(vertices[v].position,vertices[v].position,transform);
//--- calc texture coord
tcoord.y=1-float(j)/tessellation;
vertices[v].tcoord=tcoord;
v++;
//--- create indices for two triangles.
if(i<tessellation && j<tessellation)
{
uint next_i=i+1;
uint next_j=j+1;
indices[idx++]=next_i*stride + next_j;
indices[idx++]=next_i*stride + j;
indices[idx++]= i*stride + j;
indices[idx++]= i*stride + j;
indices[idx++]= i*stride + next_j;
indices[idx++]=next_i*stride + next_j;
}
}
}
//---
return(true);
}
//+------------------------------------------------------------------+
//| Cylinder |
//| TVertex must have |
//| DXVector4 position, DXVector4 normal and DXVector2 tcoord members|
//+------------------------------------------------------------------+
template <typename TVertex>
bool DXComputeCylinder(float radius,float height,uint tessellation,TVertex &vertices[],uint &indices[])
{
return(DXComputeTruncatedCone(radius,radius,height,tessellation,vertices,indices));
}
//+------------------------------------------------------------------+
//| Truncated Cone |
//| TVertex must have |
//| DXVector4 position, DXVector4 normal and DXVector2 tcoord members|
//+------------------------------------------------------------------+
template <typename TVertex>
bool DXComputeTruncatedCone(float radius_top,float radius_bottom,float height,uint tessellation,TVertex &vertices[],uint &indices[])
{
if(tessellation<3)
tessellation=3;
//--- prepare arrays
uint count=2*(tessellation+1)+2*tessellation;
if(ArrayResize(vertices,count)!=count)
return(false);
count=6*tessellation+6*(tessellation-1);
if(ArrayResize(indices,count)!=count)
return(false);
//--- prepare normal
DXVector2 normal=DXVector2(height,radius_bottom-radius_top);
DXVec2Normalize(normal,normal);
float dy=height/2.0f;
uint v=0,idx=0;
uint stride=2;
//--- create top and bottom rings of vertices
for(uint i=0; i<=tessellation; i++)
{
float u=1.0f-(float)i/tessellation;
float angle=(i*DX_PI_MUL2/tessellation);
float dx=(float)sin(angle);
float dz=(float)cos(angle);
//---
vertices[v].normal =DXVector4(dx*normal.x,normal.y,dz*normal.x,0.0f);
vertices[v].position=DXVector4(dx*radius_bottom,-dy,dz*radius_bottom,1.0f);
vertices[v].tcoord =DXVector2(u,1.0f);
v++;
vertices[v].normal =vertices[v-1].normal;
vertices[v].position=DXVector4(dx*radius_top,dy,dz*radius_top,1.0f);
vertices[v].tcoord =DXVector2(u,0.0f);
v++;
//--- creater side surface
if(i<tessellation)
{
uint next_i=i+1;
indices[idx++]=next_i*stride + 1;
indices[idx++]= i*stride + 0;
indices[idx++]=next_i*stride + 0;
indices[idx++]= i*stride + 0;
indices[idx++]=next_i*stride + 1;
indices[idx++]= i*stride + 1;
}
}
//--- first cap vertex
uint cap_first=v;
//--- create caps
for(uint i=0; i<tessellation; i++)
{
float angle=(i*DX_PI_MUL2/tessellation);
float dx=(float)sin(angle);
float dz=(float)cos(angle);
vertices[v].normal =DXVector4(0.0f,-1.0f,0.0f,0.0f);
vertices[v].position=DXVector4(dx*radius_bottom,-dy,dz*radius_bottom,1.0f);
vertices[v].tcoord =DXVector2(0.5f+0.5f*dx,0.5f+0.5f*dz);
v++;
vertices[v].normal =DXVector4(0.0f,1.0f,0.0f,0.0f);
vertices[v].position=DXVector4(dx*radius_top,dy,dz*radius_top,1.0f);
vertices[v].tcoord =DXVector2(0.5f+0.5f*dx,0.5f-0.5f*dz);
v++;
//--- creater caps surface
if(i>0 && i<tessellation-1)
{
uint next_i=i+1;
indices[idx++]=cap_first;
indices[idx++]=cap_first+next_i*stride;
indices[idx++]=cap_first+ i*stride;
indices[idx++]=cap_first+1;
indices[idx++]=cap_first+ i*stride+1;
indices[idx++]=cap_first+next_i*stride+1;
}
}
return(true);
}
//+------------------------------------------------------------------+
//| Cone |
//| TVertex must have |
//| DXVector4 position, DXVector4 normal and DXVector2 tcoord members|
//+------------------------------------------------------------------+
template <typename TVertex>
bool DXComputeCone(float radius,float height,uint tessellation,TVertex &vertices[],uint &indices[])
{
if(tessellation<3)
tessellation=3;
//--- prepare arrays
uint count=2*(tessellation+1)+tessellation;
if(ArrayResize(vertices,count)!=count)
return(false);
count=3*tessellation+3*(tessellation-1);
if(ArrayResize(indices,count)!=count)
return(false);
//--- prepare normal
DXVector2 normal=DXVector2(height,radius);
DXVec2Normalize(normal,normal);
float dy=height/2.0f;
uint v=0,idx=0;
uint stride=2;
//--- create top and bottom rings of vertices
for(uint i=0; i<=tessellation; i++)
{
float u=1.0f-(float)i/tessellation;
float angle=(i*DX_PI_MUL2/tessellation);
float dx=(float)sin(angle);
float dz=(float)cos(angle);
//---
vertices[v].normal =DXVector4(dx*normal.x,normal.y,dz*normal.x,0.0f);
vertices[v].position=DXVector4(dx*radius,-dy,dz*radius,1.0f);
vertices[v].tcoord =DXVector2(u,1.0f);
v++;
vertices[v].normal =vertices[v-1].normal;
vertices[v].position=DXVector4(0.0f,dy,0.0f,1.0f);
vertices[v].tcoord =DXVector2(u,0.0f);
v++;
//--- creater side surface
if(i<tessellation)
{
uint next_i=i+1;
indices[idx++]=next_i*stride + 1;
indices[idx++]= i*stride + 0;
indices[idx++]=next_i*stride + 0;
}
}
//--- first cap vertex
uint cap_first=v;
//--- create caps
for(uint i=0; i<tessellation; i++)
{
float angle=(i*DX_PI_MUL2/tessellation);
float dx=(float)sin(angle);
float dz=(float)cos(angle);
vertices[v].normal =DXVector4(0.0f,-1.0f,0.0f,0.0f);
vertices[v].position=DXVector4(dx*radius,-dy,dz*radius,1.0f);
vertices[v].tcoord =DXVector2(0.5f+0.5f*dx,0.5f+0.5f*dz);
v++;
//--- creater caps surface
if(i>0 && i<tessellation-1)
{
indices[idx++]=cap_first;
indices[idx++]=cap_first+i+1;
indices[idx++]=cap_first+i;
}
}
return(true);
}
//+------------------------------------------------------------------+
//| Surface |
//| TVertex must have |
//| DXVector4 position, DXVector4 normal and DXVector2 tcoord members|
//+------------------------------------------------------------------+
template <typename TVertex>
bool DXComputeSurface(double &data[],uint data_width,uint data_height,double data_range,
const DXVector3 &from,const DXVector3 &to,DXVector2 &texture_size,
bool two_sided,bool use_normals,
TVertex &vertices[],uint &indices[])
{
//---
if(data_width<2 || data_height<2)
return(false);
//--- prepare arrays for vertices and triangles
uint count=data_width*data_height*(two_sided?2:1);
if(!ArrayResize(vertices,count))
return(false);
count=6*(data_width-1)*(data_height-1)*(two_sided?2:1);
if(!ArrayResize(indices,count))
return(false);
//--- find min and max value
float min_value=+FLT_MAX;
float max_value=-FLT_MAX;
for(uint j=0; j<data_height; j++)
for(uint i=0; i<data_width; i++)
{
float value=(float)data[j*data_width+i];
if(min_value>value)
min_value=value;
if(max_value<value)
max_value=value;
}
//--- check and fix data range
float avg_value=0.5f*(max_value+min_value);
float range=(float)data_range;
if(range<=0.0f)
range=max_value-min_value;
if(range<FLT_EPSILON)
range=FLT_EPSILON;
//---
min_value=avg_value-0.5f*range;
max_value=avg_value+0.5f*range;
//---
DXVector3 range_3d;
DXVec3Subtract(range_3d,to,from);
float step_x=range_3d.x/(data_width-1);
float step_y=range_3d.y/range;
float step_z=range_3d.z/(data_height-1);
//--- calculate vertices positions and colors
for(uint j=0; j<data_height; j++)
{
for(uint i=0; i<data_width; i++)
{
uint idx=j*data_width+i;
//--- calc value
float value=(float)data[idx]-min_value;
//--- calc position
vertices[idx].position.x = from.x+i *step_x;
vertices[idx].position.y = from.y+value*step_y;
vertices[idx].position.z = from.z+j *step_z;
vertices[idx].position.w = 1.0f;
//--- set texture coordinates
vertices[idx].tcoord=DXVector2(i*step_x/texture_size.x,j*step_z/texture_size.y);
}
}
//--- calculate normals
if(use_normals)
{
for(uint j=0; j<data_height; j++)
{
for(uint i=0; i<data_width; i++)
{
DXVector4 v1,v2,normal;
//--- v1
if(i<=0)
DXVec4Subtract(v1,vertices[j*data_width+i].position,vertices[j*data_width+i+1].position);
else
if(i>=data_width-1)
DXVec4Subtract(v1,vertices[j*data_width+i-1].position,vertices[j*data_width+i].position);
else
DXVec4Subtract(v1,vertices[j*data_width+i-1].position,vertices[j*data_width+i+1].position);
//--- v2
if(j<=0)
DXVec4Subtract(v2,vertices[j*data_width+i].position,vertices[(j+1)*data_width+i].position);
else
if(j>=data_height-1)
DXVec4Subtract(v2,vertices[(j-1)*data_width+i].position,vertices[j*data_width+i].position);
else
DXVec4Subtract(v2,vertices[(j-1)*data_width+i].position,vertices[(j+1)*data_width+i].position);
//--- normal
DXVec4Cross(normal,v2,v1,DXVector4(0.0f,0.0f,0.0f,1.0f));
float inv_len=(float)(1.0/sqrt(normal.x*normal.x+normal.y*normal.y+normal.z*normal.z));
vertices[j*data_width+i].normal.x=normal.x*inv_len;
vertices[j*data_width+i].normal.y=normal.y*inv_len;
vertices[j*data_width+i].normal.z=normal.z*inv_len;
vertices[j*data_width+i].normal.w=0.0f;
}
}
}
else
{
DXVector4 n=DXVector4(0.0f,0.0f,0.0f,0.0f);
for(int i=0; i<ArraySize(vertices); i++)
vertices[i].normal=n;
}
//--- calculate triangles for every rectangle
int n=0;
for(uint i=0; i<data_width-1; i++)
{
for(uint j=0; j<data_height-1; j++)
{
//--- left triangle
indices[n++]=j*data_width+(i+1);
indices[n++]=j*data_width+i;
indices[n++]=(j+1)*data_width+i;
//--- right triangle
indices[n++]=(j+1)*data_width+(i+1);
indices[n++]=j*data_width+(i+1);
indices[n++]=(j+1)*data_width+(i);
}
}
//--- generate back side
if(two_sided)
{
uint offset=data_height*data_width;
for(uint j=0; j<data_height; j++)
{
for(uint i=0; i<data_width; i++)
{
uint idx=offset+j*data_width+i;
//--- copy vertices in backward direction
vertices[idx]=vertices[j*data_width+data_width-i-1];
//--- inverse normals
DXVec4Scale(vertices[idx].normal,vertices[idx].normal,-1.0f);
}
}
//--- calculate triangles for opposit side
for(uint i=0; i<data_width-1; i++)
{
for(uint j=0; j<data_height-1; j++)
{
//--- left triangle
indices[n++]=offset+j*data_width+(i+1);
indices[n++]=offset+j*data_width+i;
indices[n++]=offset+(j+1)*data_width+i;
//--- right triangle
indices[n++]=offset+(j+1)*data_width+(i+1);
indices[n++]=offset+j*data_width+(i+1);
indices[n++]=offset+(j+1)*data_width+(i);
}
}
}
//---
return(true);
}
//+---------------------------------------------------------------------+
//| Computes Matlab jet color scheme colors on [0;1] range |
//| dark blue > blue > light blue > green > yellow > red > dark red |
//+---------------------------------------------------------------------+
void DXComputeColorJet(const float value,DXColor &cout)
{
float v=value*1.1f-0.05f;
cout.r = fmin(fmax(v<0.75f ? 4*v-1.5f : 4.5f-4*v,0.0f),1.0f);
cout.g = fmin(fmax(v<0.5f ? 4*v-0.5f : 3.5f-4*v,0.0f),1.0f);
cout.b = fmin(fmax(v<0.25f ? 4*v+0.5f : 2.5f-4*v,0.0f),1.0f);
cout.a = 1.0;
}
//+---------------------------------------------------------------------+
//| Computes hot to cold color scheme colors on [0;1] range |
//| blue > light blue > green > yellow > red |
//+---------------------------------------------------------------------+
void DXComputeColorColdToHot(const float value,DXColor &cout)
{
float v=2*value-1.0f;
cout.r = fmin(fmax(2*v,0.0f),1.0f);
cout.g = fmin(fmax(2.0f-2*fabs(v),0.0f),1.0f);
cout.b = fmin(fmax(-2*v,0.0f),1.0f);
cout.a = 1.0;
}
//+---------------------------------------------------------------------+
//| Computes red to green color scheme colors on [0;1] range |
//| red > yellow > dark green |
//+---------------------------------------------------------------------+
void DXComputeColorRedToGreen(const float value,DXColor &cout)
{
if(value<=0.5)
{
cout.r=1.0f;
cout.g=DXScalarLerp(0.01f,0.95f,fmin(fmax(2*value,0.0f),1.0f));
}
else
{
cout.r=DXScalarLerp(0.1f,1.0f, fmin(fmax(2.0f-2*value,0.0f),1.0f));
cout.g=DXScalarLerp(0.6f,0.95f,fmin(fmax(2.0f-2*value,0.0f),1.0f));
}
cout.b=0.0f;
cout.a=1.0f;
}
//+------------------------------------------------------------------+
@@ -1,71 +0,0 @@
//+------------------------------------------------------------------+
//| Default Pixel Shader |
//| Copyright 2019, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Inputs for whole scene |
//+------------------------------------------------------------------+
cbuffer InputScene : register(b0)
{
matrix view;
matrix projection;
float4 light_direction;
float4 light_color;
float4 ambient_color;
};
//+------------------------------------------------------------------+
//| Inputs for single object |
//+------------------------------------------------------------------+
cbuffer InputObject : register(b1)
{
matrix transform;
float4 diffuse_color;
float4 emission_color;
float4 specular_color;
float specular_power;
float dummy[3];
};
//+------------------------------------------------------------------+
//| Input texture |
//+------------------------------------------------------------------+
Texture2D<float4> diffuse_tex : register(t0);
//+------------------------------------------------------------------+
//| Texture sampler |
//+------------------------------------------------------------------+
SamplerState diffuse_samp
{
Filter =MIN_MAG_MIP_LINEAR;
AddressU=Wrap;
AddressV=Wrap;
};
//+------------------------------------------------------------------+
//| Pixel shader input type |
//+------------------------------------------------------------------+
struct PSInput
{
float4 position : SV_POSITION;
float4 camera : CAMERA;
float4 normal : NORMAL;
float2 tcoord : TEXCOORD;
float4 color : COLOR;
};
//+------------------------------------------------------------------+
//| Pixel shader entry point |
//+------------------------------------------------------------------+
float4 PSMain(PSInput input) : SV_TARGET
{
float3 diffuse =saturate(-dot(light_direction.xyz,input.normal.xyz))*light_color.rgb*light_color.a;
float3 ambient =ambient_color.rgb *ambient_color.a;
float3 light =(diffuse+ambient)*diffuse_color.rgb*diffuse_color.a+emission_color.rgb*emission_color.a;
float4 specular=float4(light_color.rgb*specular_color.rgb,pow(saturate(dot(reflect(normalize(light_direction.xyz),input.normal.xyz),normalize(input.camera.xyz))),specular_power)*light_color.a*specular_color.a);
float4 clr=input.color;
//--- use texture if it exist
uint width,height;
diffuse_tex.GetDimensions(width,height);
if(width*height>0)
clr*=diffuse_tex.Sample(diffuse_samp,frac(input.tcoord));
//--- combine light with colors
return(lerp(float4(light*clr.rgb,clr.a),float4(specular.rgb,1.0),specular.a));
}
//+------------------------------------------------------------------+
@@ -1,72 +0,0 @@
//+------------------------------------------------------------------+
//| Default Vertex Shader |
//| Copyright 2019, MetaQuotes Software Corp. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
//+------------------------------------------------------------------+
//| Inputs for whole scene |
//+------------------------------------------------------------------+
cbuffer InputScene : register(b0)
{
matrix view;
matrix projection;
float4 light_direction;
float4 light_color;
float4 ambient_color;
};
//+------------------------------------------------------------------+
//| Inputs for single object |
//+------------------------------------------------------------------+
cbuffer InputObject : register(b1)
{
matrix transform;
float4 diffuse_color;
float4 emission_color;
float4 specular_color;
float specular_power;
float dummy[3];
};
//+------------------------------------------------------------------+
//| Vertex shader input type |
//+------------------------------------------------------------------+
struct VSInput
{
float4 position : POSITION;
float4 normal : NORMAL;
float2 tcoord : TEXCOORD;
float4 color : COLOR;
};
//+------------------------------------------------------------------+
//| Pixel shader input type |
//+------------------------------------------------------------------+
struct PSInput
{
float4 position : SV_POSITION;
float4 camera : CAMERA;
float4 normal : NORMAL;
float2 tcoord : TEXCOORD;
float4 color : COLOR;
};
//+------------------------------------------------------------------+
//| Vertex shader entry point |
//+------------------------------------------------------------------+
PSInput VSMain(VSInput input)
{
PSInput output;
//--- posiiton and camera direction
output.position=mul(input .position,transform);
output.position=mul(output.position,view);
output.camera =-output.position;
output.position=mul(output.position,projection);
//--- transform normals
output.normal = mul(input.normal, transform);
output.normal = mul(output.normal, view);
output.normal = normalize(output.normal);
//--- color and texture coordinates
output.tcoord =input.tcoord;
output.color =input.color;
//---
return(output);
}
//+------------------------------------------------------------------+
-751
View File
@@ -1,751 +0,0 @@
//+------------------------------------------------------------------+
//| 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);
CCanvas::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
-205
View File
@@ -1,205 +0,0 @@
//+------------------------------------------------------------------+
//| 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);
int X_Distance(void) const { return(CChartObjectButton::X_Distance()); }
bool Y_Distance(const int Y);
int Y_Distance(void) const { return(CChartObjectButton::Y_Distance()); }
int X_Size() const;
int X_Size(const int Y) const { return(CChartObjectButton::X_Size()); }
int Y_Size() const;
int Y_Size(const int Y) const { return(CChartObjectButton::Y_Size()); }
int Timeframes(void) const { return(CChartObjectButton::Timeframes()); }
virtual bool Timeframes(const int timeframes);
bool State(const bool state);
bool State(void) const { return(CChartObjectButton::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);
}
//+------------------------------------------------------------------+
@@ -1,398 +0,0 @@
//+------------------------------------------------------------------+
//| 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);
//--- 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 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
datetime Time(const int point) const { return(CChartObject::Time(point)); }
bool Time(const int point,const datetime time) const { return(false); }
double Price(const int point) const { return(CChartObject::Price(point)); }
bool Price(const int point,const double price) const { return(false); }
//--- 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((bool)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((bool)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);
}
//+------------------------------------------------------------------+
-479
View File
@@ -1,479 +0,0 @@
//+------------------------------------------------------------------+
//| 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);
//--- 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 of access to properties of the object
char ArrowCode(void) const;
virtual bool ArrowCode(const char code) const;
ENUM_ARROW_ANCHOR Anchor(void) const;
virtual bool Anchor(const ENUM_ARROW_ANCHOR anchor) const;
//--- 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);
//--- 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 override { return(OBJ_ARROW_THUMB_UP); }
//--- change of arrow code is blocked
virtual bool ArrowCode(const char code) const override { return(false); }
char ArrowCode(void) const { return(CChartObjectArrow::ArrowCode()); }
};
//+------------------------------------------------------------------+
//| 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);
//--- 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 override { return(OBJ_ARROW_THUMB_DOWN); }
//--- change of arrow code is blocked
virtual bool ArrowCode(const char code) const override { return(false); }
char ArrowCode(void) const { return(CChartObjectArrow::ArrowCode()); }
};
//+------------------------------------------------------------------+
//| 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);
//--- 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 override { return(OBJ_ARROW_UP); }
//--- change of arrow code is blocked
virtual bool ArrowCode(const char code) const override { return(false); }
char ArrowCode(void) const { return(CChartObjectArrow::ArrowCode()); }
};
//+------------------------------------------------------------------+
//| 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);
//--- 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 override { return(OBJ_ARROW_DOWN); }
//--- change of arrow code is blocked
virtual bool ArrowCode(const char code) const override { return(false); }
char ArrowCode(void) const { return(CChartObjectArrow::ArrowCode()); }
};
//+------------------------------------------------------------------+
//| 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);
//--- 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 override { return(OBJ_ARROW_STOP); }
//--- change of arrow code is blocked
virtual bool ArrowCode(const char code) const override { return(false); }
char ArrowCode(void) const { return(CChartObjectArrow::ArrowCode()); }
};
//+------------------------------------------------------------------+
//| 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);
//--- 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 override { return(OBJ_ARROW_CHECK); }
//--- change of arrow code is blocked
virtual bool ArrowCode(const char code) const override { return(false); }
char ArrowCode(void) const { return(CChartObjectArrow::ArrowCode()); }
};
//+------------------------------------------------------------------+
//| 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);
//--- 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 override { return(OBJ_ARROW_LEFT_PRICE); }
//--- change of arrow code and anchor point is blocked
virtual bool ArrowCode(const char code) const override { return(false); }
char ArrowCode(void) const { return(CChartObjectArrow::ArrowCode()); }
virtual bool Anchor(const ENUM_ARROW_ANCHOR anchor) const override { return(false); }
ENUM_ARROW_ANCHOR Anchor(void) const { return(CChartObjectArrow::Anchor()); }
};
//+------------------------------------------------------------------+
//| 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);
//--- 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 override { return(OBJ_ARROW_RIGHT_PRICE); }
//--- change of arrow code and anchor point is blocked
virtual bool ArrowCode(const char code) const override { return(false); }
char ArrowCode(void) const { return(CChartObjectArrow::ArrowCode()); }
virtual bool Anchor(const ENUM_ARROW_ANCHOR anchor) const override { return(false); }
ENUM_ARROW_ANCHOR Anchor(void) const { return(CChartObjectArrow::Anchor()); }
};
//+------------------------------------------------------------------+
//| 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);
}
//+------------------------------------------------------------------+
@@ -1,512 +0,0 @@
//+------------------------------------------------------------------+
//| 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((bool)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);
}
//+------------------------------------------------------------------+
@@ -1,246 +0,0 @@
//+------------------------------------------------------------------+
//| 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);
}
//+------------------------------------------------------------------+
@@ -1,201 +0,0 @@
//+------------------------------------------------------------------+
//| 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((bool)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
@@ -1,365 +0,0 @@
//+------------------------------------------------------------------+
//| 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((bool)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
@@ -1,390 +0,0 @@
//+------------------------------------------------------------------+
//| 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((bool)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((bool)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
@@ -1,335 +0,0 @@
//+------------------------------------------------------------------+
//| 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((bool)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((bool)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 object 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_CYCLES); }
};
//+------------------------------------------------------------------+
//| 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
@@ -1,142 +0,0 @@
//+------------------------------------------------------------------+
//| 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);
}
//+------------------------------------------------------------------+
@@ -1,895 +0,0 @@
//+------------------------------------------------------------------+
//| 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);
//--- 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 override { return(OBJ_TEXT); }
//--- 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;
//--- 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);
//--- 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 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
datetime Time(const int point) const { return(CChartObjectText::Time(point)); }
bool Time(const int point,const datetime time) const { return(false); }
double Price(const int point) const { return(CChartObjectText::Price(point)); }
bool Price(const int point,const double price) const { return(false); }
//--- 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);
//--- 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 override { return(OBJ_EDIT); }
//--- methods of access to properties of the object
bool X_Size(const int X) const;
int X_Size(void) const { return(CChartObjectLabel::X_Size()); }
bool Y_Size(const int Y) const;
int Y_Size(void) const { return(CChartObjectLabel::Y_Size()); }
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); }
double Angle(void) const { return(CChartObjectLabel::Angle()); }
//--- 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((bool)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);
//--- method of identifying the object
virtual int Type(void) const override { return(OBJ_BUTTON); }
//--- methods of access to properties of the object
bool State(void) const;
bool State(const bool state) const;
//--- 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((bool)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);
//--- 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 of access to properties of the object
bool X_Size(const int X) const;
int X_Size(void)const { return(CChartObjectLabel::X_Size()); }
bool Y_Size(const int Y) const;
int Y_Size(void)const { return(CChartObjectLabel::Y_Size()); }
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); }
double Angle(void) const { return(CChartObjectLabel::Angle()); }
//--- 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
@@ -1,268 +0,0 @@
//+------------------------------------------------------------------+
//| 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
@@ -1,146 +0,0 @@
//+------------------------------------------------------------------+
//| 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());
}
//+------------------------------------------------------------------+

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