mirror of
https://github.com/rithsila/MT5-EA-Sniper-Strategy.git
synced 2026-08-13 18:58:10 +00:00
fix
This commit is contained in:
Vendored
+5
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"files.associations": {
|
||||
"*.mqh": "cpp"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -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.
@@ -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.
@@ -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.
@@ -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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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.
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.
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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));
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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.
@@ -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
@@ -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.
@@ -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.
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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
@@ -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());
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -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
Reference in New Issue
Block a user