Add files via upload
This commit is contained in:
@@ -0,0 +1,173 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalAC.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of indicator 'Accelerator Oscillator' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=Accelerator Oscillator |
|
||||
//| ShortName=AC |
|
||||
//| Class=CSignalAC |
|
||||
//| Page=signal_ac |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalAC. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Accelerator Oscillator' indicator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalAC : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiAC m_ac; // object-indicator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "first analyzed bar has required color"
|
||||
int m_pattern_1; // model 1 "there is a condition for entering the market"
|
||||
int m_pattern_2; // model 2 "condition for entering the market has just appeared"
|
||||
|
||||
public:
|
||||
CSignalAC(void);
|
||||
~CSignalAC(void);
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
void Pattern_2(int value) { m_pattern_2=value; }
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
virtual int ShortCondition(void);
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the indicator
|
||||
bool InitAC(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double AC(int ind) { return(m_ac.Main(ind)); }
|
||||
double DiffAC(int ind) { return(AC(ind)-AC(ind+1)); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalAC::CSignalAC(void) : m_pattern_0(90),
|
||||
m_pattern_1(50),
|
||||
m_pattern_2(30)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalAC::~CSignalAC(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalAC::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize AC indicator
|
||||
if(!InitAC(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize AC indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalAC::InitAC(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- add object to collection
|
||||
if(!indicators.Add(GetPointer(m_ac)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize object
|
||||
if(!m_ac.Create(m_symbol.Name(),m_period))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalAC::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- if the first analyzed bar is "red", don't "vote" for buying
|
||||
if(DiffAC(idx++)<0.0)
|
||||
return(result);
|
||||
//--- first analyzed bar is "green" (the indicator has no objections to buying)
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
//--- if the second analyzed bar is "red", there is no condition for buying
|
||||
if(DiffAC(idx)<0.0)
|
||||
return(result);
|
||||
//--- second analyzed bar is "green" (the condition for buying may be fulfilled)
|
||||
//--- if the second analyzed bar is less than zero, we need to analyzed the third bar
|
||||
if(AC(idx++)<0.0)
|
||||
{
|
||||
//--- if the third analyzed bar is "red", there is no condition for buying
|
||||
if(DiffAC(idx++)<0.0)
|
||||
return(result);
|
||||
}
|
||||
//--- there is a condition for buying
|
||||
if(IS_PATTERN_USAGE(1))
|
||||
result=m_pattern_1;
|
||||
//--- if the previously analyzed bar is "red", the condition for buying has just been fulfilled
|
||||
if(IS_PATTERN_USAGE(2) && DiffAC(idx)<0.0)
|
||||
result=m_pattern_2;
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalAC::ShortCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- if the first analyzed bar is "green", don't "vote" for selling
|
||||
if(DiffAC(idx++)>0.0)
|
||||
return(result);
|
||||
//--- first analyzed bar is "red" (the indicator has no objections to selling)
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
//--- if the second analyzed bar is "green", there is no condition for selling
|
||||
if(DiffAC(idx)>0.0)
|
||||
return(result);
|
||||
//--- second analyzed bar is "red" (the condition for selling may be fulfilled)
|
||||
//--- if the second analyzed bar is greater than zero, we need to analyze the third bar
|
||||
if(AC(idx++)>0.0)
|
||||
{
|
||||
//--- if the third analyzed bar is "green", there is no condition for selling
|
||||
if(DiffAC(idx++)>0.0)
|
||||
return(result);
|
||||
}
|
||||
//--- there us a condition for selling
|
||||
if(IS_PATTERN_USAGE(1))
|
||||
result=m_pattern_1;
|
||||
//--- if the previously analyzed bar is "green", the condition for selling has just been fulfilled
|
||||
if(IS_PATTERN_USAGE(2) && DiffAC(idx)>0.0)
|
||||
result=m_pattern_2;
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,265 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalAMA.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of indicator 'Adaptive Moving Average' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=Adaptive Moving Average |
|
||||
//| ShortName=AMA |
|
||||
//| Class=CSignalAMA |
|
||||
//| Page=signal_ama |
|
||||
//| Parameter=PeriodMA,int,10,Period of averaging |
|
||||
//| Parameter=PeriodFast,int,2,Period of fast EMA |
|
||||
//| Parameter=PeriodSlow,int,30,Period of slow EMA |
|
||||
//| Parameter=Shift,int,0,Time shift |
|
||||
//| Parameter=Applied,ENUM_APPLIED_PRICE,PRICE_CLOSE,Prices series |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalAMA. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Adaptive Moving Average' indicator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalAMA : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiAMA m_ma; // object-indicator
|
||||
//--- adjusted parameters
|
||||
int m_ma_period; // the "period of averaging" parameter of the indicator
|
||||
int m_period_fast; // the "period of fast EMA" parameter of the indicator
|
||||
int m_period_slow; // the "period of slow EMA" parameter of the indicator
|
||||
int m_ma_shift; // the "time shift" parameter of the indicator
|
||||
ENUM_APPLIED_PRICE m_ma_applied; // the "object of averaging" parameter" of the indicator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "price is on the necessary side from the indicator"
|
||||
int m_pattern_1; // model 1 "price crossed the indicator with opposite direction"
|
||||
int m_pattern_2; // model 2 "price crossed the indicator with the same direction"
|
||||
int m_pattern_3; // model 3 "piercing"
|
||||
|
||||
public:
|
||||
CSignalAMA(void);
|
||||
~CSignalAMA(void);
|
||||
//--- methods of setting adjustable parameters
|
||||
void PeriodMA(int value) { m_ma_period=value; }
|
||||
void PeriodFast(int value) { m_period_fast=value; }
|
||||
void PeriodSlow(int value) { m_period_slow=value; }
|
||||
void Shift(int value) { m_ma_shift=value; }
|
||||
void Applied(ENUM_APPLIED_PRICE value) { m_ma_applied=value; }
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
void Pattern_2(int value) { m_pattern_2=value; }
|
||||
void Pattern_3(int value) { m_pattern_3=value; }
|
||||
//--- method of verification of settings
|
||||
virtual bool ValidationSettings(void);
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
virtual int ShortCondition(void);
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the indicator
|
||||
bool InitMA(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double MA(int ind) { return(m_ma.Main(ind)); }
|
||||
double DiffMA(int ind) { return(MA(ind)-MA(ind+1)); }
|
||||
double DiffOpenMA(int ind) { return(Open(ind)-MA(ind)); }
|
||||
double DiffHighMA(int ind) { return(High(ind)-MA(ind)); }
|
||||
double DiffLowMA(int ind) { return(Low(ind)-MA(ind)); }
|
||||
double DiffCloseMA(int ind) { return(Close(ind)-MA(ind)); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalAMA::CSignalAMA(void) : m_ma_period(10),
|
||||
m_ma_shift(0),
|
||||
m_period_fast(2),
|
||||
m_period_slow(30),
|
||||
m_ma_applied(PRICE_CLOSE),
|
||||
m_pattern_0(10),
|
||||
m_pattern_1(70),
|
||||
m_pattern_2(100),
|
||||
m_pattern_3(60)
|
||||
{
|
||||
//--- initialization of protected data
|
||||
m_used_series=USE_SERIES_OPEN+USE_SERIES_HIGH+USE_SERIES_LOW+USE_SERIES_CLOSE;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalAMA::~CSignalAMA(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalAMA::ValidationSettings(void)
|
||||
{
|
||||
//--- call of the method of the parent class
|
||||
if(!CExpertSignal::ValidationSettings())
|
||||
return(false);
|
||||
//--- initial data checks
|
||||
if(m_ma_period<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": period MA must be greater than 0");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalAMA::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize AMA indicator
|
||||
if(!InitMA(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create MA indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalAMA::InitMA(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- add object to collection
|
||||
if(!indicators.Add(GetPointer(m_ma)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize object
|
||||
if(!m_ma.Create(m_symbol.Name(),m_period,m_ma_period,m_period_fast,m_period_slow,m_ma_shift,m_ma_applied))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalAMA::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- analyze positional relationship of the close price and the indicator at the first analyzed bar
|
||||
if(DiffCloseMA(idx)<0.0)
|
||||
{
|
||||
//--- the close price is below the indicator
|
||||
if(IS_PATTERN_USAGE(1) && DiffOpenMA(idx)>0.0 && DiffMA(idx)>0.0)
|
||||
{
|
||||
//--- the open price is above the indicator (i.e. there was an intersection), but the indicator is directed upwards
|
||||
result=m_pattern_1;
|
||||
//--- consider that this is an unformed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- the close price is above the indicator (the indicator has no objections to buying)
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
//--- if the indicator is directed upwards
|
||||
if(DiffMA(idx)>0.0)
|
||||
{
|
||||
if(DiffOpenMA(idx)<0.0)
|
||||
{
|
||||
//--- if the model 2 is used
|
||||
if(IS_PATTERN_USAGE(2))
|
||||
{
|
||||
//--- the open price is below the indicator (i.e. there was an intersection)
|
||||
result=m_pattern_2;
|
||||
//--- suggest to enter the market at the "roll back"
|
||||
m_base_price=m_symbol.NormalizePrice(MA(idx));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- if the model 3 is used and the open price is above the indicator
|
||||
if(IS_PATTERN_USAGE(3) && DiffLowMA(idx)<0.0)
|
||||
{
|
||||
//--- the low price is below the indicator
|
||||
result=m_pattern_3;
|
||||
//--- consider that this is a formed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalAMA::ShortCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- analyze positional relationship of the close price and the indicator at the first analyzed bar
|
||||
if(DiffCloseMA(idx)>0.0)
|
||||
{
|
||||
//--- the close price is above the indicator
|
||||
if(IS_PATTERN_USAGE(1) && DiffOpenMA(idx)<0.0 && DiffMA(idx)<0.0)
|
||||
{
|
||||
//--- the open price is below the indicator (i.e. there was an intersection), but the indicator is directed downwards
|
||||
result=m_pattern_1;
|
||||
//--- consider that this is an unformed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- the close price is below the indicator (the indicator has no objections to buying)
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
//--- the indicator is directed downwards
|
||||
if(DiffMA(idx)<0.0)
|
||||
{
|
||||
if(DiffOpenMA(idx)>0.0)
|
||||
{
|
||||
//--- if the model 2 is used
|
||||
if(IS_PATTERN_USAGE(2))
|
||||
{
|
||||
//--- the open price is above the indicator (i.e. there was an intersection)
|
||||
result=m_pattern_2;
|
||||
//--- suggest to enter the market at the "roll back"
|
||||
m_base_price=m_symbol.NormalizePrice(MA(idx));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- if the model 3 is used and the open price is below the indicator
|
||||
if(IS_PATTERN_USAGE(3) && DiffHighMA(idx)>0.0)
|
||||
{
|
||||
//--- the high price is above the indicator
|
||||
result=m_pattern_3;
|
||||
//--- consider that this is a formed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,339 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalAO.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of indicator 'Awesome Oscillator' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=Awesome Oscillator |
|
||||
//| ShortName=AO |
|
||||
//| Class=CSignalAO |
|
||||
//| Page=signal_ao |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalAO. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Awesome Oscillator' indicator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalAO : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiAO m_ao; // object-indicator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "first analyzed bar has required color"
|
||||
int m_pattern_1; // model 1 "the 'saucer' signal"
|
||||
int m_pattern_2; // model 2 "the 'crossing of the zero line' signal"
|
||||
int m_pattern_3; // model 2 "the 'divergence' signal"
|
||||
//--- variables
|
||||
double m_extr_osc[10]; // array of values of extremums of the oscillator
|
||||
double m_extr_pr[10]; // array of values of the corresponding extremums of price
|
||||
int m_extr_pos[10]; // array of shifts of extremums (in bars)
|
||||
uint m_extr_map; // resulting bit-map of ratio of extremums of the oscillator and the price
|
||||
|
||||
public:
|
||||
CSignalAO(void);
|
||||
~CSignalAO(void);
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
void Pattern_2(int value) { m_pattern_2=value; }
|
||||
void Pattern_3(int value) { m_pattern_3=value; }
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
virtual int ShortCondition(void);
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the indicator
|
||||
bool InitAO(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double AO(int ind) { return(m_ao.Main(ind)); }
|
||||
double DiffAO(int ind) { return(AO(ind)-AO(ind+1)); }
|
||||
int StateAO(int ind);
|
||||
bool ExtStateAO(int ind);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalAO::CSignalAO(void) : m_pattern_0(30),
|
||||
m_pattern_1(20),
|
||||
m_pattern_2(70),
|
||||
m_pattern_3(90)
|
||||
{
|
||||
//--- initialization of protected data
|
||||
m_used_series=USE_SERIES_HIGH+USE_SERIES_LOW;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalAO::~CSignalAO(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalAO::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize AO indicator
|
||||
if(!InitAO(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize AO indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalAO::InitAO(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- add object to collection
|
||||
if(!indicators.Add(GetPointer(m_ao)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize object
|
||||
if(!m_ao.Create(m_symbol.Name(),m_period))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check of the indicator state. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalAO::StateAO(int ind)
|
||||
{
|
||||
int res=0;
|
||||
double var;
|
||||
//---
|
||||
for(int i=ind;;i++)
|
||||
{
|
||||
if(AO(i+1)==EMPTY_VALUE)
|
||||
break;
|
||||
var=DiffAO(i);
|
||||
if(res>0)
|
||||
{
|
||||
if(var<0)
|
||||
break;
|
||||
res++;
|
||||
continue;
|
||||
}
|
||||
if(res<0)
|
||||
{
|
||||
if(var>0)
|
||||
break;
|
||||
res--;
|
||||
continue;
|
||||
}
|
||||
if(var>0)
|
||||
res++;
|
||||
if(var<0)
|
||||
res--;
|
||||
}
|
||||
//---
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Extended check of the oscillator state consists |
|
||||
//| in forming a bit-map according to certain rules, |
|
||||
//| which shows ratios of extremums of the oscillator and price. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalAO::ExtStateAO(int ind)
|
||||
{
|
||||
//--- operation of this method results in a bit-map of extremums
|
||||
//--- practically, the bit-map of extremums is an "array" of 4-bit fields
|
||||
//--- each "element of the array" definitely describes the ratio
|
||||
//--- of current extremums of the oscillator and the price with previous ones
|
||||
//--- purpose of bits of an element of the analyzed bit-map
|
||||
//--- bit 3 - not used (always 0)
|
||||
//--- bit 2 - is equal to 1 if the current extremum of the oscillator is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- bit 1 - not used (always 0)
|
||||
//--- bit 0 - is equal to 1 if the current extremum of price is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- in addition to them, the following is formed:
|
||||
//--- array of values of extremums of the oscillator,
|
||||
//--- array of values of price extremums and
|
||||
//--- array of "distances" between extremums of the oscillator (in bars)
|
||||
//--- it should be noted that when using the results of the extended check of state,
|
||||
//--- you should consider, which extremum of the oscillator (peak or valley)
|
||||
//--- is the "reference point" (i.e. was detected first during the analysis)
|
||||
//--- if a peak is detected first then even elements of all arrays
|
||||
//--- will contain information about peaks, and odd elements will contain information about valleys
|
||||
//--- if a valley is detected first, then respectively in reverse
|
||||
int pos=ind,off,index;
|
||||
uint map; // intermediate bit-map for one extremum
|
||||
//---
|
||||
m_extr_map=0;
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
off=StateAO(pos);
|
||||
if(off>0)
|
||||
{
|
||||
//--- minimum of the oscillator is detected
|
||||
pos+=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=AO(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_low.MinValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]<m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]<m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_low.MinValue(pos-1,4,index);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- maximum of the oscillator is detected
|
||||
pos-=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=AO(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]>m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]>m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-1,4,index);
|
||||
}
|
||||
}
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalAO::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- if the first analyzed bar is "red", don't "vote" for buying
|
||||
if(DiffAO(idx)<0.0)
|
||||
return(result);
|
||||
//--- first analyzed bar is "green" (the indicator has no objections to buying)
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
if(AO(idx++)>0.0)
|
||||
{
|
||||
//--- first analyzed bar is greater than zero, search for the "saucer" and "crosing of the zero line" signals
|
||||
if(IS_PATTERN_USAGE(1) && DiffAO(idx)<0.0)
|
||||
{
|
||||
//--- the "saucer" signal
|
||||
//--- there is a condition for buying
|
||||
return(m_pattern_1);
|
||||
}
|
||||
if(IS_PATTERN_USAGE(2) && AO(idx)<0.0)
|
||||
{
|
||||
//--- the "crossing of the zero line" signal
|
||||
//--- there is a condition for buying
|
||||
return(m_pattern_2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- first analyzed bar is less than zero, search for the "divergence" signal
|
||||
//--- if the second analyzed bar is "red", the condition for buying may be fulfilled
|
||||
if(IS_PATTERN_USAGE(3) && DiffAO(idx)<0.0)
|
||||
{
|
||||
idx=StartIndex();
|
||||
//--- search for the "divergence" signal
|
||||
ExtStateAO(idx);
|
||||
if((m_extr_map&0xF)==1)
|
||||
{
|
||||
if(m_extr_osc[0]<0.0 && m_extr_osc[1]<0.0 && m_extr_osc[2]<0.0)
|
||||
{
|
||||
//--- both valleys are below zero, the peak is between them and it hasn't raised above zero
|
||||
//--- we suppose that this is "divergence"
|
||||
return(m_pattern_3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalAO::ShortCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- if the first analyzed bar is "green", don't "vote" for selling
|
||||
if(DiffAO(idx)>0.0)
|
||||
return(result);
|
||||
//--- first analyzed bar is "red" (the indicator has no objections to selling)
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
if(AO(idx++)<0.0)
|
||||
{
|
||||
//--- first analyzed bar is below zero, search for the "saucer" and "crossing of the zero line" signals
|
||||
if(IS_PATTERN_USAGE(1) && DiffAO(idx)>0.0)
|
||||
{
|
||||
//--- the "saucer" signal
|
||||
//--- there is a condition for buying
|
||||
return(m_pattern_1);
|
||||
}
|
||||
if(IS_PATTERN_USAGE(2) && AO(idx)>0.0)
|
||||
{
|
||||
//--- the "crossing of the zero line" signal
|
||||
//--- there is a condition for buying
|
||||
return(m_pattern_2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- first analyzed bar is above zero, search for the "divergence" signal
|
||||
//--- if the second analyzed bar is "green", the condition for buying may be fulfilled
|
||||
if(IS_PATTERN_USAGE(3) && DiffAO(idx)>0.0)
|
||||
{
|
||||
idx=StartIndex();
|
||||
//--- search for the "divergence" signal
|
||||
ExtStateAO(idx);
|
||||
if((m_extr_map&0xF)==1)
|
||||
{
|
||||
if(m_extr_osc[0]>0.0 && m_extr_osc[1]>0.0 && m_extr_osc[2]>0.0)
|
||||
{
|
||||
//--- both peaks are above zero and the valley between them hasn't fallen below zero
|
||||
//--- we suppose that this is "divergence"
|
||||
return(m_pattern_3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,289 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalBearsPower.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of oscillator 'Bears Power' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=Bears Power |
|
||||
//| ShortName=BearsPower |
|
||||
//| Class=CSignalBearsPower |
|
||||
//| Page=signal_bears |
|
||||
//| Parameter=PeriodBears,int,13,Period of calculation |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalBearsPower. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Bears Power' oscillator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalBearsPower : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiBearsPower m_bears; // object-oscillator
|
||||
//--- adjusted parameters
|
||||
int m_period_bears; // the "period of calculation" parameter of the oscillator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "reverse of the oscillator to required direction"
|
||||
int m_pattern_1; // model 1 "divergence of the oscillator and price"
|
||||
//--- variables
|
||||
double m_extr_osc[10]; // array of values of extremums of the oscillator
|
||||
double m_extr_pr[10]; // array of values of the corresponding extremums of price
|
||||
int m_extr_pos[10]; // array of shifts of extremums (in bars)
|
||||
uint m_extr_map; // resulting bit-map of ratio of extremums of the oscillator and the price
|
||||
|
||||
public:
|
||||
CSignalBearsPower(void);
|
||||
~CSignalBearsPower(void);
|
||||
//--- methods of setting adjustable parameters
|
||||
void PeriodBears(int value) { m_period_bears=value; }
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
//--- method of verification of settings
|
||||
virtual bool ValidationSettings(void);
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
//--- the oscillator doesn't identify conditions for selling
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the oscillator
|
||||
bool InitBears(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double Bears(int ind) { return(m_bears.Main(ind)); }
|
||||
double DiffBears(int ind) { return(Bears(ind)-Bears(ind+1)); }
|
||||
int StateBears(int ind);
|
||||
bool ExtStateBears(int ind);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalBearsPower::CSignalBearsPower(void) : m_period_bears(13),
|
||||
m_pattern_0(20),
|
||||
m_pattern_1(80)
|
||||
{
|
||||
//--- initialization of protected data
|
||||
m_used_series=USE_SERIES_HIGH+USE_SERIES_LOW;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalBearsPower::~CSignalBearsPower(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalBearsPower::ValidationSettings(void)
|
||||
{
|
||||
//--- validation settings of additional filters
|
||||
if(!CExpertSignal::ValidationSettings())
|
||||
return(false);
|
||||
//--- initial data checks
|
||||
if(m_period_bears<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": period Bears must be greater than 0");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalBearsPower::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize BearsPower oscillator
|
||||
if(!InitBears(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize BearsPower oscillators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalBearsPower::InitBears(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- add object to collection
|
||||
if(!indicators.Add(GetPointer(m_bears)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize object
|
||||
if(!m_bears.Create(m_symbol.Name(),m_period,m_period_bears))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check of the oscillator state. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalBearsPower::StateBears(int ind)
|
||||
{
|
||||
int res=0;
|
||||
double var;
|
||||
//---
|
||||
for(int i=ind;;i++)
|
||||
{
|
||||
if(Bears(i+1)==EMPTY_VALUE)
|
||||
break;
|
||||
var=DiffBears(i);
|
||||
if(res>0)
|
||||
{
|
||||
if(var<0)
|
||||
break;
|
||||
res++;
|
||||
continue;
|
||||
}
|
||||
if(res<0)
|
||||
{
|
||||
if(var>0)
|
||||
break;
|
||||
res--;
|
||||
continue;
|
||||
}
|
||||
if(var>0)
|
||||
res++;
|
||||
if(var<0)
|
||||
res--;
|
||||
}
|
||||
//--- return the result
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Extended check of the oscillator state consists |
|
||||
//| in forming a bit-map according to certain rules, |
|
||||
//| which shows ratios of extremums of the oscillator and price. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalBearsPower::ExtStateBears(int ind)
|
||||
{
|
||||
//--- operation of this method results in a bit-map of extremums
|
||||
//--- practically, the bit-map of extremums is an "array" of 4-bit fields
|
||||
//--- each "element of the array" definitely describes the ratio
|
||||
//--- of current extremums of the oscillator and the price with previous ones
|
||||
//--- purpose of bits of an element of the analyzed bit-map
|
||||
//--- bit 3 - not used (always 0)
|
||||
//--- bit 2 - is equal to 1 if the current extremum of the oscillator is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- bit 1 - not used (always 0)
|
||||
//--- bit 0 - is equal to 1 if the current extremum of price is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- in addition to them, the following is formed:
|
||||
//--- array of values of extremums of the oscillator,
|
||||
//--- array of values of price extremums and
|
||||
//--- array of "distances" between extremums of the oscillator (in bars)
|
||||
//--- it should be noted that when using the results of the extended check of state,
|
||||
//--- you should consider, which extremum of the oscillator (peak or valley)
|
||||
//--- is the "reference point" (i.e. was detected first during the analysis)
|
||||
//--- if a peak is detected first then even elements of all arrays
|
||||
//--- will contain information about peaks, and odd elements will contain information about valleys
|
||||
//--- if a valley is detected first, then respectively in reverse
|
||||
int pos=ind,off,index;
|
||||
uint map; // intermediate bit-map for one extremum
|
||||
//---
|
||||
m_extr_map=0;
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
off=StateBears(pos);
|
||||
if(off>0)
|
||||
{
|
||||
//--- minimum of the oscillator is detected
|
||||
pos+=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=Bears(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_low.MinValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]<m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]<m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_low.MinValue(pos-1,4,index);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- maximum of the oscillator is detected
|
||||
pos-=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=Bears(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]>m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]>m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-1,4,index);
|
||||
}
|
||||
}
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalBearsPower::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- if the oscillator is above zero, don't "vote" for buying
|
||||
if(Bears(idx)>0.0)
|
||||
return(result);
|
||||
//--- the oscillator is below zero
|
||||
if(StateBears(idx)>0)
|
||||
{
|
||||
//--- the oscillator has turned upwards at a previous bar
|
||||
//--- there is a condition for buying
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
//--- if the model 1 is used, search for the "divergence" signal
|
||||
if(IS_PATTERN_USAGE(1))
|
||||
{
|
||||
ExtStateBears(idx);
|
||||
if((m_extr_map&0xF)==1)
|
||||
{
|
||||
if(m_extr_osc[0]<0.0 && m_extr_osc[2]<0.0)
|
||||
{
|
||||
//--- both valleys are below zero
|
||||
//--- we suppose that this is "divergence"
|
||||
result=m_pattern_1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,289 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalBullsPower.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of oscillator 'Bulls Power' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=Bulls Power |
|
||||
//| ShortName=BullsPower |
|
||||
//| Class=CSignalBullsPower |
|
||||
//| Page=signal_bulls |
|
||||
//| Parameter=PeriodBulls,int,13,Period of calculation |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalBullsPower. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Bulls Power' oscillator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalBullsPower : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiBullsPower m_bulls; // object-oscillator
|
||||
//--- adjusted parameters
|
||||
int m_period_bulls; // the "period of calculation" parameter of the oscillator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "reverse of the oscillator to required direction"
|
||||
int m_pattern_1; // model 1 "divergence of the oscillator and price"
|
||||
//--- variables
|
||||
double m_extr_osc[10]; // array of values of extremums of the oscillator
|
||||
double m_extr_pr[10]; // array of values of the corresponding extremums of price
|
||||
int m_extr_pos[10]; // array of shifts of extremums (in bars)
|
||||
uint m_extr_map; // resulting bit-map of ratio of extremums of the oscillator and the price
|
||||
|
||||
public:
|
||||
CSignalBullsPower(void);
|
||||
~CSignalBullsPower(void);
|
||||
//--- methods of setting adjustable parameters
|
||||
void PeriodBulls(int value) { m_period_bulls=value; }
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
//--- method of verification of settings
|
||||
virtual bool ValidationSettings(void);
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int ShortCondition(void);
|
||||
//--- the oscillator doesn't identify conditions for buying
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the oscillator
|
||||
bool InitBears(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double Bulls(int ind) { return(m_bulls.Main(ind)); }
|
||||
double DiffBulls(int ind) { return(Bulls(ind)-Bulls(ind+1)); }
|
||||
int StateBulls(int ind);
|
||||
bool ExtStateBulls(int ind);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalBullsPower::CSignalBullsPower(void) : m_period_bulls(13),
|
||||
m_pattern_0(20),
|
||||
m_pattern_1(80)
|
||||
{
|
||||
//--- initialization of protected data
|
||||
m_used_series=USE_SERIES_HIGH+USE_SERIES_LOW;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalBullsPower::~CSignalBullsPower(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalBullsPower::ValidationSettings(void)
|
||||
{
|
||||
//--- validation settings of additional filters
|
||||
if(!CExpertSignal::ValidationSettings())
|
||||
return(false);
|
||||
//--- initial data checks
|
||||
if(m_period_bulls<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": period Bulls must be greater than 0");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalBullsPower::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize BullsPower oscillator
|
||||
if(!InitBears(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize BearsPower oscillators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalBullsPower::InitBears(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- add object to collection
|
||||
if(!indicators.Add(GetPointer(m_bulls)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize object
|
||||
if(!m_bulls.Create(m_symbol.Name(),m_period,m_period_bulls))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check of the oscillator state. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalBullsPower::StateBulls(int ind)
|
||||
{
|
||||
int res=0;
|
||||
double var;
|
||||
//---
|
||||
for(int i=ind;;i++)
|
||||
{
|
||||
if(Bulls(i+1)==EMPTY_VALUE)
|
||||
break;
|
||||
var=DiffBulls(i);
|
||||
if(res>0)
|
||||
{
|
||||
if(var<0)
|
||||
break;
|
||||
res++;
|
||||
continue;
|
||||
}
|
||||
if(res<0)
|
||||
{
|
||||
if(var>0)
|
||||
break;
|
||||
res--;
|
||||
continue;
|
||||
}
|
||||
if(var>0)
|
||||
res++;
|
||||
if(var<0)
|
||||
res--;
|
||||
}
|
||||
//--- return the result
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Extended check of the oscillator state consists |
|
||||
//| in forming a bit-map according to certain rules, |
|
||||
//| which shows ratios of extremums of the oscillator and price. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalBullsPower::ExtStateBulls(int ind)
|
||||
{
|
||||
//--- operation of this method results in a bit-map of extremums
|
||||
//--- practically, the bit-map of extremums is an "array" of 4-bit fields
|
||||
//--- each "element of the array" definitely describes the ratio
|
||||
//--- of current extremums of the oscillator and the price with previous ones
|
||||
//--- purpose of bits of an element of the analyzed bit-map
|
||||
//--- bit 3 - not used (always 0)
|
||||
//--- bit 2 - is equal to 1 if the current extremum of the oscillator is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- bit 1 - not used (always 0)
|
||||
//--- bit 0 - is equal to 1 if the current extremum of price is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- in addition to them, the following is formed:
|
||||
//--- array of values of extremums of the oscillator,
|
||||
//--- array of values of price extremums and
|
||||
//--- array of "distances" between extremums of the oscillator (in bars)
|
||||
//--- it should be noted that when using the results of the extended check of state,
|
||||
//--- you should consider, which extremum of the oscillator (peak or valley)
|
||||
//--- is the "reference point" (i.e. was detected first during the analysis)
|
||||
//--- if a peak is detected first then even elements of all arrays
|
||||
//--- will contain information about peaks, and odd elements will contain information about valleys
|
||||
//--- if a valley is detected first, then respectively in reverse
|
||||
int pos=ind,off,index;
|
||||
uint map; // intermediate bit-map for one extremum
|
||||
//---
|
||||
m_extr_map=0;
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
off=StateBulls(pos);
|
||||
if(off>0)
|
||||
{
|
||||
//--- minimum of the oscillator is detected
|
||||
pos+=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=Bulls(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_low.MinValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]<m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]<m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_low.MinValue(pos-1,4,index);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- maximum of the oscillator is detected
|
||||
pos-=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=Bulls(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]>m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]>m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-1,4,index);
|
||||
}
|
||||
}
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalBullsPower::ShortCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- if the oscillator is below zero, don't "vote" for selling
|
||||
if(Bulls(idx)<0.0)
|
||||
return(result);
|
||||
//--- the oscillator is above zero
|
||||
if(StateBulls(idx)<0)
|
||||
{
|
||||
//--- the oscillator has turned downwards at a previous bar
|
||||
//--- there us a condition for selling
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
//--- if the model 1 is used, search for the "divergence" signal
|
||||
if(IS_PATTERN_USAGE(1))
|
||||
{
|
||||
ExtStateBulls(idx);
|
||||
if((m_extr_map&0xF)==1)
|
||||
{
|
||||
if(m_extr_osc[0]>0.0 && m_extr_osc[2]>0.0)
|
||||
{
|
||||
//--- both peaks are above zero
|
||||
//--- we suppose that this is "divergence"
|
||||
result=m_pattern_1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,382 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalCCI.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of oscilator 'Commodity Channel Index' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=Commodity Channel Index |
|
||||
//| ShortName=CCI |
|
||||
//| Class=CSignalCCI |
|
||||
//| Page=signal_cci |
|
||||
//| Parameter=PeriodCCI,int,8,Period of calculation |
|
||||
//| Parameter=Applied,ENUM_APPLIED_PRICE,PRICE_CLOSE,Prices series |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalCCI. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Commodity Channel Index' oscillator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalCCI : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiCCI m_cci; // object-oscillator
|
||||
//--- adjusted parameters
|
||||
int m_periodCCI; // the "period of calculation" parameter of the oscillator
|
||||
ENUM_APPLIED_PRICE m_applied; // the "prices series" parameter of the oscillator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "the oscillator has required direction"
|
||||
int m_pattern_1; // model 1 "reverse behind the level of overbuying/overselling"
|
||||
int m_pattern_2; // model 2 "divergence of the oscillator and price"
|
||||
int m_pattern_3; // model 3 "double divergence of the oscillator and price"
|
||||
//--- variables
|
||||
double m_extr_osc[10]; // array of values of extremums of the oscillator
|
||||
double m_extr_pr[10]; // array of values of the corresponding extremums of price
|
||||
int m_extr_pos[10]; // array of shifts of extremums (in bars)
|
||||
uint m_extr_map; // resulting bit-map of ratio of extremums of the oscillator and the price
|
||||
|
||||
public:
|
||||
CSignalCCI(void);
|
||||
~CSignalCCI(void);
|
||||
//--- methods of setting adjustable parameters
|
||||
void PeriodCCI(int value) { m_periodCCI=value; }
|
||||
void Applied(ENUM_APPLIED_PRICE value) { m_applied=value; }
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
void Pattern_2(int value) { m_pattern_2=value; }
|
||||
void Pattern_3(int value) { m_pattern_3=value; }
|
||||
//--- method of verification of settings
|
||||
virtual bool ValidationSettings(void);
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
virtual int ShortCondition(void);
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the oscillator
|
||||
bool InitStoch(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double CCI(int ind) { return(m_cci.Main(ind)); }
|
||||
double Diff(int ind) { return(CCI(ind)-CCI(ind+1)); }
|
||||
int State(int ind);
|
||||
bool ExtState(int ind);
|
||||
bool CompareMaps(int map,int count,bool minimax=false,int start=0);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalCCI::CSignalCCI(void) : m_periodCCI(14),
|
||||
m_applied(PRICE_CLOSE),
|
||||
m_pattern_0(90),
|
||||
m_pattern_1(60),
|
||||
m_pattern_2(100),
|
||||
m_pattern_3(50)
|
||||
{
|
||||
//--- initialization of protected data
|
||||
m_used_series=USE_SERIES_HIGH+USE_SERIES_LOW;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalCCI::~CSignalCCI(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalCCI::ValidationSettings(void)
|
||||
{
|
||||
//--- validation settings of additional filters
|
||||
if(!CExpertSignal::ValidationSettings())
|
||||
return(false);
|
||||
//--- initial data checks
|
||||
if(m_periodCCI<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": period of the CCI oscillator must be greater than 0");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalCCI::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize CCI oscillator
|
||||
if(!InitStoch(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize CCI oscillators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalCCI::InitStoch(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- add object to collection
|
||||
if(!indicators.Add(GetPointer(m_cci)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize object
|
||||
if(!m_cci.Create(m_symbol.Name(),m_period,m_periodCCI,m_applied))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check of the oscillator state. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalCCI::State(int ind)
|
||||
{
|
||||
int res=0;
|
||||
double var;
|
||||
//---
|
||||
for(int i=ind;;i++)
|
||||
{
|
||||
if(CCI(i+1)==EMPTY_VALUE)
|
||||
break;
|
||||
var=Diff(i);
|
||||
if(res>0)
|
||||
{
|
||||
if(var<0)
|
||||
break;
|
||||
res++;
|
||||
continue;
|
||||
}
|
||||
if(res<0)
|
||||
{
|
||||
if(var>0)
|
||||
break;
|
||||
res--;
|
||||
continue;
|
||||
}
|
||||
if(var>0)
|
||||
res++;
|
||||
if(var<0)
|
||||
res--;
|
||||
}
|
||||
//--- return the result
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Extended check of the oscillator state consists |
|
||||
//| in forming a bit-map according to certain rules, |
|
||||
//| which shows ratios of extremums of the oscillator and price. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalCCI::ExtState(int ind)
|
||||
{
|
||||
//--- operation of this method results in a bit-map of extremums
|
||||
//--- practically, the bit-map of extremums is an "array" of 4-bit fields
|
||||
//--- each "element of the array" definitely describes the ratio
|
||||
//--- of current extremums of the oscillator and the price with previous ones
|
||||
//--- purpose of bits of an element of the analyzed bit-map
|
||||
//--- bit 3 - not used (always 0)
|
||||
//--- bit 2 - is equal to 1 if the current extremum of the oscillator is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- bit 1 - not used (always 0)
|
||||
//--- bit 0 - is equal to 1 if the current extremum of price is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- in addition to them, the following is formed:
|
||||
//--- array of values of extremums of the oscillator,
|
||||
//--- array of values of price extremums and
|
||||
//--- array of "distances" between extremums of the oscillator (in bars)
|
||||
//--- it should be noted that when using the results of the extended check of state,
|
||||
//--- you should consider, which extremum of the oscillator (peak or valley)
|
||||
//--- is the "reference point" (i.e. was detected first during the analysis)
|
||||
//--- if a peak is detected first then even elements of all arrays
|
||||
//--- will contain information about peaks, and odd elements will contain information about valleys
|
||||
//--- if a valley is detected first, then respectively in reverse
|
||||
int pos=ind,off,index;
|
||||
uint map; // intermediate bit-map for one extremum
|
||||
//---
|
||||
m_extr_map=0;
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
off=State(pos);
|
||||
if(off>0)
|
||||
{
|
||||
//--- minimum of the oscillator is detected
|
||||
pos+=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=CCI(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_low.MinValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]<m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]<m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_low.MinValue(pos-1,3,index);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- maximum of the oscillator is detected
|
||||
pos-=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=CCI(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]>m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]>m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-1,3,index);
|
||||
}
|
||||
}
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Comparing the bit-map of extremums with pattern. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalCCI::CompareMaps(int map,int count,bool minimax,int start)
|
||||
{
|
||||
int step =(minimax)?4:8;
|
||||
int total=step*(start+count);
|
||||
//--- check input parameters for a possible going out of range of the bit-map
|
||||
if(total>32)
|
||||
return(false);
|
||||
//--- bit-map of the patter is an "array" of 4-bit fields
|
||||
//--- each "element of the array" definitely describes the desired ratio
|
||||
//--- of current extremums of the oscillator and the price with previous ones
|
||||
//--- purpose of bits of an elements of the pattern of the bit-map pattern
|
||||
//--- bit 3 - is equal to if the ratio of extremums of the oscillator is insignificant for us
|
||||
//--- is equal to 0 if we want to "find" the ratio of extremums of the oscillator determined by the value of bit 2
|
||||
//--- bit 2 - is equal to 1 if we want to "discover" the situation when the current extremum of the "oscillator" is "more extreme" than the previous one
|
||||
//--- (current peak is higher or current valley is deeper)
|
||||
//--- is equal to 0 if we want to "discover" the situation when the current extremum of the oscillator is "less extreme" than the previous one
|
||||
//--- (current peak is lower or current valley is less deep)
|
||||
//--- bit 1 - is equal to 1 if the ratio of extremums is insignificant for us
|
||||
//--- it is equal to 0 if we want to "find" the ratio of price extremums determined by the value of bit 0
|
||||
//--- bit 0 - is equal to 1 if we want to "discover" the situation when the current price extremum is "more extreme" than the previous one
|
||||
//--- (current peak is higher or current valley is deeper)
|
||||
//--- it is equal to 0 if we want to "discover" the situation when the current price extremum is "less extreme" than the previous one
|
||||
//--- (current peak is lower or current valley is less deep)
|
||||
uint inp_map,check_map;
|
||||
int i,j;
|
||||
//--- loop by extremums (4 minimums and 4 maximums)
|
||||
//--- price and the oscillator are checked separately (thus, there are 16 checks)
|
||||
for(i=step*start,j=0;i<total;i+=step,j+=4)
|
||||
{
|
||||
//--- "take" two bits - patter of the corresponding extremum of the price
|
||||
inp_map=(map>>j)&3;
|
||||
//--- if the higher-order bit=1, then any ratio is suitable for us
|
||||
if(inp_map<2)
|
||||
{
|
||||
//--- "take" two bits of the corresponding extremum of the price (higher-order bit is always 0)
|
||||
check_map=(m_extr_map>>i)&3;
|
||||
if(inp_map!=check_map)
|
||||
return(false);
|
||||
}
|
||||
//--- "take" two bits - pattern of the corresponding oscillator extremum
|
||||
inp_map=(map>>(j+2))&3;
|
||||
//--- if the higher-order bit=1, then any ratio is suitable for us
|
||||
if(inp_map>=2)
|
||||
continue;
|
||||
//--- "take" two bits of the corresponding oscillator extremum (higher-order bit is always 0)
|
||||
check_map=(m_extr_map>>(i+2))&3;
|
||||
if(inp_map!=check_map)
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalCCI::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//---
|
||||
if(Diff(idx)>0.0)
|
||||
{
|
||||
//--- the oscillator is directed upwards confirming the possibility of price growth
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0; // "confirming" signal number 0
|
||||
//--- if the model 1 is used, search for a reverse of the oscillator upwards behind the level of overselling
|
||||
if(IS_PATTERN_USAGE(1) && Diff(idx+1)<0.0 && CCI(idx+1)<-100.0)
|
||||
result=m_pattern_1; // signal number 1
|
||||
//--- if the model 2 or 3 is used, perform the extended analysis of the oscillator state
|
||||
if(IS_PATTERN_USAGE(2) || IS_PATTERN_USAGE(3))
|
||||
{
|
||||
ExtState(idx);
|
||||
//--- if the model 2 is used, search for the "divergence" signal
|
||||
if(IS_PATTERN_USAGE(2) && CompareMaps(1,1)) // 00000001b
|
||||
result=m_pattern_2; // signal number 2
|
||||
//--- if the model 3 is used, search for the "double divergence" signal
|
||||
if(IS_PATTERN_USAGE(3) && CompareMaps(0x11,2)) // 00010001b
|
||||
return(m_pattern_3); // signal number 3
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalCCI::ShortCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//---
|
||||
if(Diff(idx)<0.0)
|
||||
{
|
||||
//--- the oscillator is directed downwards confirming the possibility of falling of price
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0; // "confirming" signal number 0
|
||||
//--- if the model 1 is used, search for a reverse of the oscillator downwards behind the level of overbuying
|
||||
if(IS_PATTERN_USAGE(1) && Diff(idx+1)>0.0 && CCI(idx+1)>100.0)
|
||||
result=m_pattern_1; // signal number 1
|
||||
//--- if the model 2 or 3 is used, perform the extended analysis of the oscillator state
|
||||
if(IS_PATTERN_USAGE(2) || IS_PATTERN_USAGE(3))
|
||||
{
|
||||
ExtState(idx);
|
||||
//--- if the model 2 is used, search for the "divergence" signal
|
||||
if(IS_PATTERN_USAGE(2) && CompareMaps(1,1)) // 00000001b
|
||||
result=m_pattern_2; // signal number 2
|
||||
//--- if the model 3 is used, search for the "double divergence" signal
|
||||
if(IS_PATTERN_USAGE(3) && CompareMaps(0x11,2)) // 00010001b
|
||||
return(m_pattern_3); // signal number 3
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,257 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalDEMA.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of indicator 'Double Exponential Moving Average' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=Double Exponential Moving Average |
|
||||
//| ShortName=DEMA |
|
||||
//| Class=CSignalDEMA |
|
||||
//| Page=signal_dema |
|
||||
//| Parameter=PeriodMA,int,12,Period of averaging |
|
||||
//| Parameter=Shift,int,0,Time shift |
|
||||
//| Parameter=Applied,ENUM_APPLIED_PRICE,PRICE_CLOSE,Prices series |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalDEMA. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Double Exponential Moving Average' indicator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalDEMA : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiDEMA m_ma; // object-indicator
|
||||
//--- adjusted parameters
|
||||
int m_ma_period; // the "period of averaging" parameter of the indicator
|
||||
int m_ma_shift; // the "time shift" parameter of the indicator
|
||||
ENUM_APPLIED_PRICE m_ma_applied; // the "object of averaging" parameter" of the indicator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "price is on the necessary side from the indicator"
|
||||
int m_pattern_1; // model 1 "price crossed the indicator with opposite direction"
|
||||
int m_pattern_2; // model 2 "price crossed the indicator with the same direction"
|
||||
int m_pattern_3; // model 3 "piercing"
|
||||
|
||||
public:
|
||||
CSignalDEMA(void);
|
||||
~CSignalDEMA(void);
|
||||
//--- methods of setting adjustable parameters
|
||||
void PeriodMA(int value) { m_ma_period=value; }
|
||||
void Shift(int value) { m_ma_shift=value; }
|
||||
void Applied(ENUM_APPLIED_PRICE value) { m_ma_applied=value; }
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
void Pattern_2(int value) { m_pattern_2=value; }
|
||||
void Pattern_3(int value) { m_pattern_3=value; }
|
||||
//--- method of verification of settings
|
||||
virtual bool ValidationSettings(void);
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
virtual int ShortCondition(void);
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the indicator
|
||||
bool InitMA(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double MA(int ind) { return(m_ma.Main(ind)); }
|
||||
double DiffMA(int ind) { return(MA(ind)-MA(ind+1)); }
|
||||
double DiffOpenMA(int ind) { return(Open(ind)-MA(ind)); }
|
||||
double DiffHighMA(int ind) { return(High(ind)-MA(ind)); }
|
||||
double DiffLowMA(int ind) { return(Low(ind)-MA(ind)); }
|
||||
double DiffCloseMA(int ind) { return(Close(ind)-MA(ind)); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalDEMA::CSignalDEMA(void) : m_ma_period(12),
|
||||
m_ma_shift(0),
|
||||
m_ma_applied(PRICE_CLOSE),
|
||||
m_pattern_0(20),
|
||||
m_pattern_1(60),
|
||||
m_pattern_2(80),
|
||||
m_pattern_3(60)
|
||||
{
|
||||
//--- initialization of protected data
|
||||
m_used_series=USE_SERIES_OPEN+USE_SERIES_HIGH+USE_SERIES_LOW+USE_SERIES_CLOSE;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalDEMA::~CSignalDEMA(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalDEMA::ValidationSettings(void)
|
||||
{
|
||||
//--- call of the method of the parent class
|
||||
if(!CExpertSignal::ValidationSettings())
|
||||
return(false);
|
||||
//--- initial data checks
|
||||
if(m_ma_period<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": period MA must be greater than 0");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalDEMA::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize DEMA indicator
|
||||
if(!InitMA(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create MA indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalDEMA::InitMA(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- add indicator to collection
|
||||
if(!indicators.Add(GetPointer(m_ma)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize indicator
|
||||
if(!m_ma.Create(m_symbol.Name(),m_period,m_ma_period,m_ma_shift,m_ma_applied))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalDEMA::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- analyze positional relationship of the close price and the indicator at the first analyzed bar
|
||||
if(DiffCloseMA(idx)<0.0)
|
||||
{
|
||||
//--- the close price is below the indicator
|
||||
if(IS_PATTERN_USAGE(1) && DiffOpenMA(idx)>0.0 && DiffMA(idx)>0.0)
|
||||
{
|
||||
//--- the open price is above the indicator (i.e. there was an intersection), but the indicator is directed upwards
|
||||
result=m_pattern_1;
|
||||
//--- consider that this is an unformed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- the close price is above the indicator (the indicator has no objections to buying)
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
//--- if the indicator is directed upwards
|
||||
if(DiffMA(idx)>0.0)
|
||||
{
|
||||
if(DiffOpenMA(idx)<0.0)
|
||||
{
|
||||
//--- if the model 2 is used
|
||||
if(IS_PATTERN_USAGE(2))
|
||||
{
|
||||
//--- the open price is below the indicator (i.e. there was an intersection)
|
||||
result=m_pattern_2;
|
||||
//--- suggest to enter the market at the "roll back"
|
||||
m_base_price=m_symbol.NormalizePrice(MA(idx));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- if the model 3 is used and the open price is above the indicator
|
||||
if(IS_PATTERN_USAGE(3) && DiffLowMA(idx)<0.0)
|
||||
{
|
||||
//--- the low price is below the indicator
|
||||
result=m_pattern_3;
|
||||
//--- consider that this is a formed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalDEMA::ShortCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- analyze positional relationship of the close price and the indicator at the first analyzed bar
|
||||
if(DiffCloseMA(idx)>0.0)
|
||||
{
|
||||
//--- the close price is above the indicator
|
||||
if(IS_PATTERN_USAGE(1) && DiffOpenMA(idx)<0.0 && DiffMA(idx)<0.0)
|
||||
{
|
||||
//--- the open price is below the indicator (i.e. there was an intersection), but the indicator is directed downwards
|
||||
result=m_pattern_1;
|
||||
//--- consider that this is an unformed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- the close price is below the indicator (the indicator has no objections to buying)
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
//--- the indicator is directed downwards
|
||||
if(DiffMA(idx)<0.0)
|
||||
{
|
||||
if(DiffOpenMA(idx)>0.0)
|
||||
{
|
||||
//--- if the model 2 is used
|
||||
if(IS_PATTERN_USAGE(2))
|
||||
{
|
||||
//--- the open price is above the indicator (i.e. there was an intersection)
|
||||
result=m_pattern_2;
|
||||
//--- suggest to enter the market at the "roll back"
|
||||
m_base_price=m_symbol.NormalizePrice(MA(idx));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- if the model 3 is used and the open price is below the indicator
|
||||
if(IS_PATTERN_USAGE(3) && DiffHighMA(idx)>0.0)
|
||||
{
|
||||
//--- the high price is above the indicator
|
||||
result=m_pattern_3;
|
||||
//--- consider that this is a formed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,378 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalDeMarker.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of oscillator 'DeMarker' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=DeMarker |
|
||||
//| ShortName=DeM |
|
||||
//| Class=CSignalDeM |
|
||||
//| Page=signal_demarker |
|
||||
//| Parameter=PeriodDeM,int,8,Period of calculation |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalDeM. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Commodity Channel Index' oscillator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalDeM : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiDeMarker m_dem; // object-oscillator
|
||||
//--- adjusted parameters
|
||||
int m_periodDeM; // the "period of calculation" parameter of the oscillator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "the oscillator has required direction"
|
||||
int m_pattern_1; // model 1 "reverse behind the level of overbuying/overselling"
|
||||
int m_pattern_2; // model 2 "divergence of the oscillator and price"
|
||||
int m_pattern_3; // model 3 "double divergence of the oscillator and price"
|
||||
//--- variables
|
||||
double m_extr_osc[10]; // array of values of extremums of the oscillator
|
||||
double m_extr_pr[10]; // array of values of the corresponding extremums of price
|
||||
int m_extr_pos[10]; // array of shifts of extremums (in bars)
|
||||
uint m_extr_map; // resulting bit-map of ratio of extremums of the oscillator and the price
|
||||
|
||||
public:
|
||||
CSignalDeM(void);
|
||||
~CSignalDeM(void);
|
||||
//--- methods of setting adjustable parameters
|
||||
void PeriodDeM(int value) { m_periodDeM=value; }
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
void Pattern_2(int value) { m_pattern_2=value; }
|
||||
void Pattern_3(int value) { m_pattern_3=value; }
|
||||
//--- method of verification of settings
|
||||
virtual bool ValidationSettings(void);
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
virtual int ShortCondition(void);
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the oscillator
|
||||
bool InitStoch(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double DeM(int ind) { return(m_dem.Main(ind)); }
|
||||
double DiffDeM(int ind) { return(DeM(ind)-DeM(ind+1)); }
|
||||
int StateDeM(int ind);
|
||||
bool ExtStateDeM(int ind);
|
||||
bool CompareMaps(int map,int count,bool minimax=false,int start=0);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalDeM::CSignalDeM(void) : m_periodDeM(14),
|
||||
m_pattern_0(90),
|
||||
m_pattern_1(60),
|
||||
m_pattern_2(100),
|
||||
m_pattern_3(80)
|
||||
{
|
||||
//--- initialization of protected data
|
||||
m_used_series=USE_SERIES_HIGH+USE_SERIES_LOW;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalDeM::~CSignalDeM(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalDeM::ValidationSettings(void)
|
||||
{
|
||||
//--- validation settings of additional filters
|
||||
if(!CExpertSignal::ValidationSettings())
|
||||
return(false);
|
||||
//--- initial data checks
|
||||
if(m_periodDeM<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": period of the DeMarker oscillator must be greater than 0");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalDeM::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize DeMarker oscillator
|
||||
if(!InitStoch(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize DeMarker oscillators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalDeM::InitStoch(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- add object to collection
|
||||
if(!indicators.Add(GetPointer(m_dem)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize object
|
||||
if(!m_dem.Create(m_symbol.Name(),m_period,m_periodDeM))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check of the oscillator state. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalDeM::StateDeM(int ind)
|
||||
{
|
||||
int res=0;
|
||||
double var;
|
||||
//---
|
||||
for(int i=ind;;i++)
|
||||
{
|
||||
if(DeM(i+1)==EMPTY_VALUE)
|
||||
break;
|
||||
var=DiffDeM(i);
|
||||
if(res>0)
|
||||
{
|
||||
if(var<0)
|
||||
break;
|
||||
res++;
|
||||
continue;
|
||||
}
|
||||
if(res<0)
|
||||
{
|
||||
if(var>0)
|
||||
break;
|
||||
res--;
|
||||
continue;
|
||||
}
|
||||
if(var>0)
|
||||
res++;
|
||||
if(var<0)
|
||||
res--;
|
||||
}
|
||||
//---
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Extended check of the oscillator state consists |
|
||||
//| in forming a bit-map according to certain rules, |
|
||||
//| which shows ratios of extremums of the oscillator and price. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalDeM::ExtStateDeM(int ind)
|
||||
{
|
||||
//--- operation of this method results in a bit-map of extremums
|
||||
//--- practically, the bit-map of extremums is an "array" of 4-bit fields
|
||||
//--- each "element of the array" definitely describes the ratio
|
||||
//--- of current extremums of the oscillator and the price with previous ones
|
||||
//--- purpose of bits of an element of the analyzed bit-map
|
||||
//--- bit 3 - not used (always 0)
|
||||
//--- bit 2 - is equal to 1 if the current extremum of the oscillator is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- bit 1 - not used (always 0)
|
||||
//--- bit 0 - is equal to 1 if the current extremum of price is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- in addition to them, the following is formed:
|
||||
//--- array of values of extremums of the oscillator,
|
||||
//--- array of values of price extremums and
|
||||
//--- array of "distances" between extremums of the oscillator (in bars)
|
||||
//--- it should be noted that when using the results of the extended check of state,
|
||||
//--- you should consider, which extremum of the oscillator (peak or valley)
|
||||
//--- is the "reference point" (i.e. was detected first during the analysis)
|
||||
//--- if a peak is detected first then even elements of all arrays
|
||||
//--- will contain information about peaks, and odd elements will contain information about valleys
|
||||
//--- if a valley is detected first, then respectively in reverse
|
||||
int pos=ind,off,index;
|
||||
uint map; // intermediate bit-map for one extremum
|
||||
//---
|
||||
m_extr_map=0;
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
off=StateDeM(pos);
|
||||
if(off>0)
|
||||
{
|
||||
//--- minimum of the oscillator is detected
|
||||
pos+=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=DeM(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_low.MinValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]<m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]<m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_low.MinValue(pos-1,4,index);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- maximum of the oscillator is detected
|
||||
pos-=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=DeM(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]>m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]>m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-1,4,index);
|
||||
}
|
||||
}
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Comparing the bit-map of extremums with pattern. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalDeM::CompareMaps(int map,int count,bool minimax,int start)
|
||||
{
|
||||
int step =(minimax)?4:8;
|
||||
int total=step*(start+count);
|
||||
//--- check input parameters for a possible going out of range of the bit-map
|
||||
if(total>32)
|
||||
return(false);
|
||||
//--- bit-map of the patter is an "array" of 4-bit fields
|
||||
//--- each "element of the array" definitely describes the desired ratio
|
||||
//--- of current extremums of the oscillator and the price with previous ones
|
||||
//--- purpose of bits of an elements of the pattern of the bit-map pattern
|
||||
//--- bit 3 - is equal to if the ratio of extremums of the oscillator is insignificant for us
|
||||
//--- is equal to 0 if we want to "find" the ratio of extremums of the oscillator determined by the value of bit 2
|
||||
//--- bit 2 - is equal to 1 if we want to "discover" the situation when the current extremum of the "oscillator" is "more extreme" than the previous one
|
||||
//--- (current peak is higher or current valley is deeper)
|
||||
//--- is equal to 0 if we want to "discover" the situation when the current extremum of the oscillator is "less extreme" than the previous one
|
||||
//--- (current peak is lower or current valley is less deep)
|
||||
//--- bit 1 - is equal to 1 if the ratio of extremums is insignificant for us
|
||||
//--- it is equal to 0 if we want to "find" the ratio of price extremums determined by the value of bit 0
|
||||
//--- bit 0 - is equal to 1 if we want to "discover" the situation when the current price extremum is "more extreme" than the previous one
|
||||
//--- (current peak is higher or current valley is deeper)
|
||||
//--- it is equal to 0 if we want to "discover" the situation when the current price extremum is "less extreme" than the previous one
|
||||
//--- (current peak is lower or current valley is less deep)
|
||||
uint inp_map,check_map;
|
||||
int i,j;
|
||||
//--- loop by extremums (4 minimums and 4 maximums)
|
||||
//--- price and the oscillator are checked separately (thus, there are 16 checks)
|
||||
for(i=step*start,j=0;i<total;i+=step,j+=4)
|
||||
{
|
||||
//--- "take" two bits - patter of the corresponding extremum of the price
|
||||
inp_map=(map>>j)&3;
|
||||
//--- if the higher-order bit=1, then any ratio is suitable for us
|
||||
if(inp_map<2)
|
||||
{
|
||||
//--- "take" two bits of the corresponding extremum of the price (higher-order bit is always 0)
|
||||
check_map=(m_extr_map>>i)&3;
|
||||
if(inp_map!=check_map)
|
||||
return(false);
|
||||
}
|
||||
//--- "take" two bits - pattern of the corresponding oscillator extremum
|
||||
inp_map=(map>>(j+2))&3;
|
||||
//--- if the higher-order bit=1, then any ratio is suitable for us
|
||||
if(inp_map>=2)
|
||||
continue;
|
||||
//--- "take" two bits of the corresponding oscillator extremum (higher-order bit is always 0)
|
||||
check_map=(m_extr_map>>(i+2))&3;
|
||||
if(inp_map!=check_map)
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalDeM::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- check direction of the main line
|
||||
if(DiffDeM(idx)>0.0)
|
||||
{
|
||||
//--- the oscillator is directed upwards confirming the possibility of price growth
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0; // "confirming" signal number 0
|
||||
//--- if the model 1 is used, search for a reverse of the oscillator upwards behind the level of overselling
|
||||
if(IS_PATTERN_USAGE(1) && DiffDeM(idx+1)<0.0 && DeM(idx+1)<0.3)
|
||||
result=m_pattern_1; // signal number 1
|
||||
//--- if the model 2 or 3 is used, perform the extended analysis of the oscillator state
|
||||
if(IS_PATTERN_USAGE(2) || IS_PATTERN_USAGE(3))
|
||||
{
|
||||
ExtStateDeM(idx);
|
||||
//--- if the model 2 is used, search for the "divergence" signal
|
||||
if(IS_PATTERN_USAGE(2) && CompareMaps(1,1)) // 00000001b
|
||||
result=m_pattern_2; // signal number 2
|
||||
//--- if the model 3 is used, search for the "double divergence" signal
|
||||
if(IS_PATTERN_USAGE(3) && CompareMaps(0x11,2)) // 00010001b
|
||||
return(m_pattern_3); // signal number 3
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalDeM::ShortCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- check direction of the main line
|
||||
if(DiffDeM(idx)<0.0)
|
||||
{
|
||||
//--- the oscillator is directed downwards confirming the possibility of falling of price
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0; // "confirming" signal number 0
|
||||
//--- if the model 1 is used, search for a reverse of the oscillator downwards behind the level of overbuying
|
||||
if(IS_PATTERN_USAGE(1) && DiffDeM(idx+1)>0.0 && DeM(idx+1)>0.7)
|
||||
result=m_pattern_1; // signal number 1
|
||||
//--- if the model 2 or 3 is used, perform the extended analysis of the oscillator state
|
||||
if(IS_PATTERN_USAGE(2) || IS_PATTERN_USAGE(3))
|
||||
{
|
||||
ExtStateDeM(idx);
|
||||
//--- if the model 2 is used, search for the "divergence" signal
|
||||
if(IS_PATTERN_USAGE(2) && CompareMaps(1,1)) // 00000001b
|
||||
result=m_pattern_2; // signal number 2
|
||||
//--- if the model 3 is used, search for the "double divergence" signal
|
||||
if(IS_PATTERN_USAGE(3) && CompareMaps(0x11,2)) // 00010001b
|
||||
return(m_pattern_3); // signal number 3
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,193 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalEnvelopes.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of indicator 'Envelopes' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=Envelopes |
|
||||
//| ShortName=Envelopes |
|
||||
//| Class=CSignalEnvelopes |
|
||||
//| Page=signal_envelopes |
|
||||
//| Parameter=PeriodMA,int,45,Period of averaging |
|
||||
//| Parameter=Shift,int,0,Time shift |
|
||||
//| Parameter=Method,ENUM_MA_METHOD,MODE_SMA,Method of averaging |
|
||||
//| Parameter=Applied,ENUM_APPLIED_PRICE,PRICE_CLOSE,Prices series |
|
||||
//| Parameter=Deviation,double,0.15,Deviation |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalEnvelopes. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Envelopes' indicator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalEnvelopes : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiEnvelopes m_env; // object-indicator
|
||||
//--- adjusted parameters
|
||||
int m_ma_period; // the "period of averaging" parameter of the indicator
|
||||
int m_ma_shift; // the "time shift" parameter of the indicator
|
||||
ENUM_MA_METHOD m_ma_method; // the "method of averaging" parameter of the indicator
|
||||
ENUM_APPLIED_PRICE m_ma_applied; // the "object of averaging" parameter of the indicator
|
||||
double m_deviation; // the "deviation" parameter of the indicator
|
||||
double m_limit_in; // threshold sensitivity of the 'rollback zone'
|
||||
double m_limit_out; // threshold sensitivity of the 'break through zone'
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "price is near the necessary border of the envelope"
|
||||
int m_pattern_1; // model 1 "price crossed a border of the envelope"
|
||||
|
||||
public:
|
||||
CSignalEnvelopes(void);
|
||||
~CSignalEnvelopes(void);
|
||||
//--- methods of setting adjustable parameters
|
||||
void PeriodMA(int value) { m_ma_period=value; }
|
||||
void Shift(int value) { m_ma_shift=value; }
|
||||
void Method(ENUM_MA_METHOD value) { m_ma_method=value; }
|
||||
void Applied(ENUM_APPLIED_PRICE value) { m_ma_applied=value; }
|
||||
void Deviation(double value) { m_deviation=value; }
|
||||
void LimitIn(double value) { m_limit_in=value; }
|
||||
void LimitOut(double value) { m_limit_out=value; }
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
//--- method of verification of settings
|
||||
virtual bool ValidationSettings(void);
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
virtual int ShortCondition(void);
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the indicator
|
||||
bool InitMA(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double Upper(int ind) { return(m_env.Upper(ind)); }
|
||||
double Lower(int ind) { return(m_env.Lower(ind)); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalEnvelopes::CSignalEnvelopes(void) : m_ma_period(45),
|
||||
m_ma_shift(0),
|
||||
m_ma_method(MODE_SMA),
|
||||
m_ma_applied(PRICE_CLOSE),
|
||||
m_deviation(0.15),
|
||||
m_limit_in(0.2),
|
||||
m_limit_out(0.2),
|
||||
m_pattern_0(90),
|
||||
m_pattern_1(70)
|
||||
{
|
||||
//--- initialization of protected data
|
||||
m_used_series=USE_SERIES_OPEN+USE_SERIES_HIGH+USE_SERIES_LOW+USE_SERIES_CLOSE;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalEnvelopes::~CSignalEnvelopes(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalEnvelopes::ValidationSettings(void)
|
||||
{
|
||||
//--- validation settings of additional filters
|
||||
if(!CExpertSignal::ValidationSettings())
|
||||
return(false);
|
||||
//--- initial data checks
|
||||
if(m_ma_period<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": period MA must be greater than 0");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalEnvelopes::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize MA indicator
|
||||
if(!InitMA(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize MA indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalEnvelopes::InitMA(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- add object to collection
|
||||
if(!indicators.Add(GetPointer(m_env)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize object
|
||||
if(!m_env.Create(m_symbol.Name(),m_period,m_ma_period,m_ma_shift,m_ma_method,m_ma_applied,m_deviation))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalEnvelopes::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
double close=Close(idx);
|
||||
double upper=Upper(idx);
|
||||
double lower=Lower(idx);
|
||||
double width=upper-lower;
|
||||
//--- if the model 0 is used and price is in the rollback zone, then there is a condition for buying
|
||||
if(IS_PATTERN_USAGE(0) && close<lower+m_limit_in*width && close>lower-m_limit_out*width)
|
||||
result=m_pattern_0;
|
||||
//--- if the model 1 is used and price is above the rollback zone, then there is a condition for buying
|
||||
if(IS_PATTERN_USAGE(1) && close>upper+m_limit_out*width)
|
||||
result=m_pattern_1;
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalEnvelopes::ShortCondition(void)
|
||||
{
|
||||
int result =0;
|
||||
int idx =StartIndex();
|
||||
double close=Close(idx);
|
||||
double upper=Upper(idx);
|
||||
double lower=Lower(idx);
|
||||
double width=upper-lower;
|
||||
//--- if the model 0 is used and price is in the rollback zone, then there is a condition for selling
|
||||
if(IS_PATTERN_USAGE(0) && close>upper-m_limit_in*width && close<upper+m_limit_out*width)
|
||||
result=m_pattern_0;
|
||||
//--- if the model 1 is used and price is above the rollback zone, then there is a condition for selling
|
||||
if(IS_PATTERN_USAGE(1) && close<lower-m_limit_out*width)
|
||||
result=m_pattern_1;
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,257 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalFrAMA.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of indicator 'Fractal Adaptive Moving Average' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=Fractal Adaptive Moving Average |
|
||||
//| ShortName=FraMA |
|
||||
//| Class=CSignalFrAMA |
|
||||
//| Page=signal_frama |
|
||||
//| Parameter=PeriodMA,int,12,Period of averaging |
|
||||
//| Parameter=Shift,int,0,Time shift |
|
||||
//| Parameter=Applied,ENUM_APPLIED_PRICE,PRICE_CLOSE,Prices series |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalFrAMA. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Fractal Adaptive Moving Average' indicator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalFrAMA : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiFrAMA m_ma; // object-indicator
|
||||
//--- adjusted parameters
|
||||
int m_ma_period; // the "period of averaging" parameter of the indicator
|
||||
int m_ma_shift; // the "time shift" parameter of the indicator
|
||||
ENUM_APPLIED_PRICE m_ma_applied; // the "object of averaging" parameter" of the indicator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "price is on the necessary side from the indicator"
|
||||
int m_pattern_1; // model 1 "price crossed the indicator with opposite direction"
|
||||
int m_pattern_2; // model 2 "price crossed the indicator with the same direction"
|
||||
int m_pattern_3; // model 3 "piercing"
|
||||
|
||||
public:
|
||||
CSignalFrAMA(void);
|
||||
~CSignalFrAMA(void);
|
||||
//--- methods of setting adjustable parameters
|
||||
void PeriodMA(int value) { m_ma_period=value; }
|
||||
void Shift(int value) { m_ma_shift=value; }
|
||||
void Applied(ENUM_APPLIED_PRICE value) { m_ma_applied=value; }
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
void Pattern_2(int value) { m_pattern_2=value; }
|
||||
void Pattern_3(int value) { m_pattern_3=value; }
|
||||
//--- method of verification of settings
|
||||
virtual bool ValidationSettings(void);
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
virtual int ShortCondition(void);
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the indicator
|
||||
bool InitMA(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double MA(int ind) { return(m_ma.Main(ind)); }
|
||||
double DiffMA(int ind) { return(MA(ind)-MA(ind+1)); }
|
||||
double DiffOpenMA(int ind) { return(Open(ind)-MA(ind)); }
|
||||
double DiffHighMA(int ind) { return(High(ind)-MA(ind)); }
|
||||
double DiffLowMA(int ind) { return(Low(ind)-MA(ind)); }
|
||||
double DiffCloseMA(int ind) { return(Close(ind)-MA(ind)); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalFrAMA::CSignalFrAMA(void) : m_ma_period(12),
|
||||
m_ma_shift(0),
|
||||
m_ma_applied(PRICE_CLOSE),
|
||||
m_pattern_0(90),
|
||||
m_pattern_1(100),
|
||||
m_pattern_2(80),
|
||||
m_pattern_3(60)
|
||||
{
|
||||
//--- initialization of protected data
|
||||
m_used_series=USE_SERIES_OPEN+USE_SERIES_HIGH+USE_SERIES_LOW+USE_SERIES_CLOSE;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalFrAMA::~CSignalFrAMA(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalFrAMA::ValidationSettings(void)
|
||||
{
|
||||
//--- call of the method of the parent class
|
||||
if(!CExpertSignal::ValidationSettings())
|
||||
return(false);
|
||||
//--- initial data checks
|
||||
if(m_ma_period<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": period MA must be greater than 0");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalFrAMA::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize FrAMA indicator
|
||||
if(!InitMA(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create MA indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalFrAMA::InitMA(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- add indicator to collection
|
||||
if(!indicators.Add(GetPointer(m_ma)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize indicator
|
||||
if(!m_ma.Create(m_symbol.Name(),m_period,m_ma_period,m_ma_shift,m_ma_applied))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalFrAMA::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- analyze positional relationship of the close price and the indicator at the first analyzed bar
|
||||
if(DiffCloseMA(idx)<0.0)
|
||||
{
|
||||
//--- the close price is below the indicator
|
||||
if(IS_PATTERN_USAGE(1) && DiffOpenMA(idx)>0.0 && DiffMA(idx)>0.0)
|
||||
{
|
||||
//--- the open price is above the indicator (i.e. there was an intersection), but the indicator is directed upwards
|
||||
result=m_pattern_1;
|
||||
//--- consider that this is an unformed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- the close price is above the indicator (the indicator has no objections to buying)
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
//--- if the indicator is directed upwards
|
||||
if(DiffMA(idx)>0.0)
|
||||
{
|
||||
if(DiffOpenMA(idx)<0.0)
|
||||
{
|
||||
//--- if the model 2 is used
|
||||
if(IS_PATTERN_USAGE(2))
|
||||
{
|
||||
//--- the open price is below the indicator (i.e. there was an intersection)
|
||||
result=m_pattern_2;
|
||||
//--- suggest to enter the market at the "roll back"
|
||||
m_base_price=m_symbol.NormalizePrice(MA(idx));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- if the model 3 is used and the open price is above the indicator
|
||||
if(IS_PATTERN_USAGE(3) && DiffLowMA(idx)<0.0)
|
||||
{
|
||||
//--- the low price is below the indicator
|
||||
result=m_pattern_3;
|
||||
//--- consider that this is a formed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalFrAMA::ShortCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- analyze positional relationship of the close price and the indicator at the first analyzed bar
|
||||
if(DiffCloseMA(idx)>0.0)
|
||||
{
|
||||
//--- the close price is above the indicator
|
||||
if(IS_PATTERN_USAGE(1) && DiffOpenMA(idx)<0.0 && DiffMA(idx)<0.0)
|
||||
{
|
||||
//--- the open price is below the indicator (i.e. there was an intersection), but the indicator is directed downwards
|
||||
result=m_pattern_1;
|
||||
//--- consider that this is an unformed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- the close price is below the indicator (the indicator has no objections to buying)
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
//--- the indicator is directed downwards
|
||||
if(DiffMA(idx)<0.0)
|
||||
{
|
||||
if(DiffOpenMA(idx)>0.0)
|
||||
{
|
||||
//--- if the model 2 is used
|
||||
if(IS_PATTERN_USAGE(2))
|
||||
{
|
||||
//--- the open price is above the indicator (i.e. there was an intersection)
|
||||
result=m_pattern_2;
|
||||
//--- suggest to enter the market at the "roll back"
|
||||
m_base_price=m_symbol.NormalizePrice(MA(idx));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- if the model 3 is used and the open price is below the indicator
|
||||
if(IS_PATTERN_USAGE(3) && DiffHighMA(idx)>0.0)
|
||||
{
|
||||
//--- the high price is above the indicator
|
||||
result=m_pattern_3;
|
||||
//--- consider that this is a formed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,91 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalITF.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of intraday time filter |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=IntradayTimeFilter |
|
||||
//| ShortName=ITF |
|
||||
//| Class=CSignalITF |
|
||||
//| Page=signal_time_filter |
|
||||
//| Parameter=GoodHourOfDay,int,-1,Good hour |
|
||||
//| Parameter=BadHoursOfDay,int,0,Bad hours (bit-map) |
|
||||
//| Parameter=GoodDayOfWeek,int,-1,Good day of week |
|
||||
//| Parameter=BadDaysOfWeek,int,0,Bad days of week (bit-map) |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalITF. |
|
||||
//| Appointment: Class trading signals time filter. |
|
||||
//| Derives from class CExpertSignal. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalITF : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
//--- input parameters
|
||||
int m_good_minute_of_hour;
|
||||
long m_bad_minutes_of_hour;
|
||||
int m_good_hour_of_day;
|
||||
int m_bad_hours_of_day;
|
||||
int m_good_day_of_week;
|
||||
int m_bad_days_of_week;
|
||||
|
||||
public:
|
||||
CSignalITF(void);
|
||||
~CSignalITF(void);
|
||||
//--- methods initialize protected data
|
||||
void GoodMinuteOfHour(int value) { m_good_minute_of_hour=value; }
|
||||
void BadMinutesOfHour(long value) { m_bad_minutes_of_hour=value; }
|
||||
void GoodHourOfDay(int value) { m_good_hour_of_day=value; }
|
||||
void BadHoursOfDay(int value) { m_bad_hours_of_day=value; }
|
||||
void GoodDayOfWeek(int value) { m_good_day_of_week=value; }
|
||||
void BadDaysOfWeek(int value) { m_bad_days_of_week=value; }
|
||||
//--- methods of checking conditions of entering the market
|
||||
virtual double Direction(void);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalITF::CSignalITF(void) : m_good_minute_of_hour(-1),
|
||||
m_bad_minutes_of_hour(0),
|
||||
m_good_hour_of_day(-1),
|
||||
m_bad_hours_of_day(0),
|
||||
m_good_day_of_week(-1),
|
||||
m_bad_days_of_week(0)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalITF::~CSignalITF(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check conditions for time filter. |
|
||||
//+------------------------------------------------------------------+
|
||||
double CSignalITF::Direction(void)
|
||||
{
|
||||
MqlDateTime s_time;
|
||||
//---
|
||||
TimeCurrent(s_time);
|
||||
//--- check days conditions
|
||||
if(!((m_good_day_of_week==-1 || m_good_day_of_week==s_time.day_of_week) &&
|
||||
!(m_bad_days_of_week&(1<<s_time.day_of_week))))
|
||||
return(EMPTY_VALUE);
|
||||
//--- check hours conditions
|
||||
if(!((m_good_hour_of_day==-1 || m_good_hour_of_day==s_time.hour) &&
|
||||
!(m_bad_hours_of_day&(1<<s_time.hour))))
|
||||
return(EMPTY_VALUE);
|
||||
//--- check minutes conditions
|
||||
if(!((m_good_minute_of_hour==-1 || m_good_minute_of_hour==s_time.min) &&
|
||||
!(m_bad_minutes_of_hour&(1<<s_time.min))))
|
||||
return(EMPTY_VALUE);
|
||||
//--- condition OK
|
||||
return(0.0);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,261 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalMA.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of indicator 'Moving Average' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=Moving Average |
|
||||
//| ShortName=MA |
|
||||
//| Class=CSignalMA |
|
||||
//| Page=signal_ma |
|
||||
//| Parameter=PeriodMA,int,12,Period of averaging |
|
||||
//| Parameter=Shift,int,0,Time shift |
|
||||
//| Parameter=Method,ENUM_MA_METHOD,MODE_SMA,Method of averaging |
|
||||
//| Parameter=Applied,ENUM_APPLIED_PRICE,PRICE_CLOSE,Prices series |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalMA. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Moving Average' indicator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalMA : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiMA m_ma; // object-indicator
|
||||
//--- adjusted parameters
|
||||
int m_ma_period; // the "period of averaging" parameter of the indicator
|
||||
int m_ma_shift; // the "time shift" parameter of the indicator
|
||||
ENUM_MA_METHOD m_ma_method; // the "method of averaging" parameter of the indicator
|
||||
ENUM_APPLIED_PRICE m_ma_applied; // the "object of averaging" parameter of the indicator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "price is on the necessary side from the indicator"
|
||||
int m_pattern_1; // model 1 "price crossed the indicator with opposite direction"
|
||||
int m_pattern_2; // model 2 "price crossed the indicator with the same direction"
|
||||
int m_pattern_3; // model 3 "piercing"
|
||||
|
||||
public:
|
||||
CSignalMA(void);
|
||||
~CSignalMA(void);
|
||||
//--- methods of setting adjustable parameters
|
||||
void PeriodMA(int value) { m_ma_period=value; }
|
||||
void Shift(int value) { m_ma_shift=value; }
|
||||
void Method(ENUM_MA_METHOD value) { m_ma_method=value; }
|
||||
void Applied(ENUM_APPLIED_PRICE value) { m_ma_applied=value; }
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
void Pattern_2(int value) { m_pattern_2=value; }
|
||||
void Pattern_3(int value) { m_pattern_3=value; }
|
||||
//--- method of verification of settings
|
||||
virtual bool ValidationSettings(void);
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
virtual int ShortCondition(void);
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the indicator
|
||||
bool InitMA(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double MA(int ind) { return(m_ma.Main(ind)); }
|
||||
double DiffMA(int ind) { return(MA(ind)-MA(ind+1)); }
|
||||
double DiffOpenMA(int ind) { return(Open(ind)-MA(ind)); }
|
||||
double DiffHighMA(int ind) { return(High(ind)-MA(ind)); }
|
||||
double DiffLowMA(int ind) { return(Low(ind)-MA(ind)); }
|
||||
double DiffCloseMA(int ind) { return(Close(ind)-MA(ind)); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalMA::CSignalMA(void) : m_ma_period(12),
|
||||
m_ma_shift(0),
|
||||
m_ma_method(MODE_SMA),
|
||||
m_ma_applied(PRICE_CLOSE),
|
||||
m_pattern_0(80),
|
||||
m_pattern_1(10),
|
||||
m_pattern_2(60),
|
||||
m_pattern_3(60)
|
||||
{
|
||||
//--- initialization of protected data
|
||||
m_used_series=USE_SERIES_OPEN+USE_SERIES_HIGH+USE_SERIES_LOW+USE_SERIES_CLOSE;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalMA::~CSignalMA(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalMA::ValidationSettings(void)
|
||||
{
|
||||
//--- validation settings of additional filters
|
||||
if(!CExpertSignal::ValidationSettings())
|
||||
return(false);
|
||||
//--- initial data checks
|
||||
if(m_ma_period<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": period MA must be greater than 0");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalMA::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize MA indicator
|
||||
if(!InitMA(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize MA indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalMA::InitMA(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- add object to collection
|
||||
if(!indicators.Add(GetPointer(m_ma)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize object
|
||||
if(!m_ma.Create(m_symbol.Name(),m_period,m_ma_period,m_ma_shift,m_ma_method,m_ma_applied))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalMA::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- analyze positional relationship of the close price and the indicator at the first analyzed bar
|
||||
if(DiffCloseMA(idx)<0.0)
|
||||
{
|
||||
//--- the close price is below the indicator
|
||||
if(IS_PATTERN_USAGE(1) && DiffOpenMA(idx)>0.0 && DiffMA(idx)>0.0)
|
||||
{
|
||||
//--- the open price is above the indicator (i.e. there was an intersection), but the indicator is directed upwards
|
||||
result=m_pattern_1;
|
||||
//--- consider that this is an unformed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- the close price is above the indicator (the indicator has no objections to buying)
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
//--- if the indicator is directed upwards
|
||||
if(DiffMA(idx)>0.0)
|
||||
{
|
||||
if(DiffOpenMA(idx)<0.0)
|
||||
{
|
||||
//--- if the model 2 is used
|
||||
if(IS_PATTERN_USAGE(2))
|
||||
{
|
||||
//--- the open price is below the indicator (i.e. there was an intersection)
|
||||
result=m_pattern_2;
|
||||
//--- suggest to enter the market at the "roll back"
|
||||
m_base_price=m_symbol.NormalizePrice(MA(idx));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- if the model 3 is used and the open price is above the indicator
|
||||
if(IS_PATTERN_USAGE(3) && DiffLowMA(idx)<0.0)
|
||||
{
|
||||
//--- the low price is below the indicator
|
||||
result=m_pattern_3;
|
||||
//--- consider that this is a formed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalMA::ShortCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- analyze positional relationship of the close price and the indicator at the first analyzed bar
|
||||
if(DiffCloseMA(idx)>0.0)
|
||||
{
|
||||
//--- the close price is above the indicator
|
||||
if(IS_PATTERN_USAGE(1) && DiffOpenMA(idx)<0.0 && DiffMA(idx)<0.0)
|
||||
{
|
||||
//--- the open price is below the indicator (i.e. there was an intersection), but the indicator is directed downwards
|
||||
result=m_pattern_1;
|
||||
//--- consider that this is an unformed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- the close price is below the indicator (the indicator has no objections to buying)
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
//--- the indicator is directed downwards
|
||||
if(DiffMA(idx)<0.0)
|
||||
{
|
||||
if(DiffOpenMA(idx)>0.0)
|
||||
{
|
||||
//--- if the model 2 is used
|
||||
if(IS_PATTERN_USAGE(2))
|
||||
{
|
||||
//--- the open price is above the indicator (i.e. there was an intersection)
|
||||
result=m_pattern_2;
|
||||
//--- suggest to enter the market at the "roll back"
|
||||
m_base_price=m_symbol.NormalizePrice(MA(idx));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- if the model 3 is used and the open price is below the indicator
|
||||
if(IS_PATTERN_USAGE(3) && DiffHighMA(idx)>0.0)
|
||||
{
|
||||
//--- the high price is above the indicator
|
||||
result=m_pattern_3;
|
||||
//--- consider that this is a formed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,408 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalMACD.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of oscillator 'MACD' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=MACD |
|
||||
//| ShortName=MACD |
|
||||
//| Class=CSignalMACD |
|
||||
//| Page=signal_macd |
|
||||
//| Parameter=PeriodFast,int,12,Period of fast EMA |
|
||||
//| Parameter=PeriodSlow,int,24,Period of slow EMA |
|
||||
//| Parameter=PeriodSignal,int,9,Period of averaging of difference |
|
||||
//| Parameter=Applied,ENUM_APPLIED_PRICE,PRICE_CLOSE,Prices series |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalMACD. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Moving Average Convergence/Divergence' oscillator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalMACD : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiMACD m_MACD; // object-oscillator
|
||||
//--- adjusted parameters
|
||||
int m_period_fast; // the "period of fast EMA" parameter of the oscillator
|
||||
int m_period_slow; // the "period of slow EMA" parameter of the oscillator
|
||||
int m_period_signal; // the "period of averaging of difference" parameter of the oscillator
|
||||
ENUM_APPLIED_PRICE m_applied; // the "price series" parameter of the oscillator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "the oscillator has required direction"
|
||||
int m_pattern_1; // model 1 "reverse of the oscillator to required direction"
|
||||
int m_pattern_2; // model 2 "crossing of main and signal line"
|
||||
int m_pattern_3; // model 3 "crossing of main line an the zero level"
|
||||
int m_pattern_4; // model 4 "divergence of the oscillator and price"
|
||||
int m_pattern_5; // model 5 "double divergence of the oscillator and price"
|
||||
//--- variables
|
||||
double m_extr_osc[10]; // array of values of extremums of the oscillator
|
||||
double m_extr_pr[10]; // array of values of the corresponding extremums of price
|
||||
int m_extr_pos[10]; // array of shifts of extremums (in bars)
|
||||
uint m_extr_map; // resulting bit-map of ratio of extremums of the oscillator and the price
|
||||
|
||||
public:
|
||||
CSignalMACD(void);
|
||||
~CSignalMACD(void);
|
||||
//--- methods of setting adjustable parameters
|
||||
void PeriodFast(int value) { m_period_fast=value; }
|
||||
void PeriodSlow(int value) { m_period_slow=value; }
|
||||
void PeriodSignal(int value) { m_period_signal=value; }
|
||||
void Applied(ENUM_APPLIED_PRICE value) { m_applied=value; }
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
void Pattern_2(int value) { m_pattern_2=value; }
|
||||
void Pattern_3(int value) { m_pattern_3=value; }
|
||||
void Pattern_4(int value) { m_pattern_4=value; }
|
||||
void Pattern_5(int value) { m_pattern_5=value; }
|
||||
//--- method of verification of settings
|
||||
virtual bool ValidationSettings(void);
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
virtual int ShortCondition(void);
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the oscillator
|
||||
bool InitMACD(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double Main(int ind) { return(m_MACD.Main(ind)); }
|
||||
double Signal(int ind) { return(m_MACD.Signal(ind)); }
|
||||
double DiffMain(int ind) { return(Main(ind)-Main(ind+1)); }
|
||||
int StateMain(int ind);
|
||||
double State(int ind) { return(Main(ind)-Signal(ind)); }
|
||||
bool ExtState(int ind);
|
||||
bool CompareMaps(int map,int count,bool minimax=false,int start=0);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalMACD::CSignalMACD(void) : m_period_fast(12),
|
||||
m_period_slow(24),
|
||||
m_period_signal(9),
|
||||
m_applied(PRICE_CLOSE),
|
||||
m_pattern_0(10),
|
||||
m_pattern_1(30),
|
||||
m_pattern_2(80),
|
||||
m_pattern_3(50),
|
||||
m_pattern_4(60),
|
||||
m_pattern_5(100)
|
||||
{
|
||||
//--- initialization of protected data
|
||||
m_used_series=USE_SERIES_HIGH+USE_SERIES_LOW;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalMACD::~CSignalMACD(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalMACD::ValidationSettings(void)
|
||||
{
|
||||
//--- validation settings of additional filters
|
||||
if(!CExpertSignal::ValidationSettings())
|
||||
return(false);
|
||||
//--- initial data checks
|
||||
if(m_period_fast>=m_period_slow)
|
||||
{
|
||||
printf(__FUNCTION__+": slow period must be greater than fast period");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalMACD::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check of pointer is performed in the method of the parent class
|
||||
//---
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize MACD oscilator
|
||||
if(!InitMACD(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize MACD oscillators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalMACD::InitMACD(CIndicators *indicators)
|
||||
{
|
||||
//--- add object to collection
|
||||
if(!indicators.Add(GetPointer(m_MACD)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize object
|
||||
if(!m_MACD.Create(m_symbol.Name(),m_period,m_period_fast,m_period_slow,m_period_signal,m_applied))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check of the oscillator state. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalMACD::StateMain(int ind)
|
||||
{
|
||||
int res=0;
|
||||
double var;
|
||||
//---
|
||||
for(int i=ind;;i++)
|
||||
{
|
||||
if(Main(i+1)==EMPTY_VALUE)
|
||||
break;
|
||||
var=DiffMain(i);
|
||||
if(res>0)
|
||||
{
|
||||
if(var<0)
|
||||
break;
|
||||
res++;
|
||||
continue;
|
||||
}
|
||||
if(res<0)
|
||||
{
|
||||
if(var>0)
|
||||
break;
|
||||
res--;
|
||||
continue;
|
||||
}
|
||||
if(var>0)
|
||||
res++;
|
||||
if(var<0)
|
||||
res--;
|
||||
}
|
||||
//---
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Extended check of the oscillator state consists |
|
||||
//| in forming a bit-map according to certain rules, |
|
||||
//| which shows ratios of extremums of the oscillator and price. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalMACD::ExtState(int ind)
|
||||
{
|
||||
//--- operation of this method results in a bit-map of extremums
|
||||
//--- practically, the bit-map of extremums is an "array" of 4-bit fields
|
||||
//--- each "element of the array" definitely describes the ratio
|
||||
//--- of current extremums of the oscillator and the price with previous ones
|
||||
//--- purpose of bits of an element of the analyzed bit-map
|
||||
//--- bit 3 - not used (always 0)
|
||||
//--- bit 2 - is equal to 1 if the current extremum of the oscillator is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- bit 1 - not used (always 0)
|
||||
//--- bit 0 - is equal to 1 if the current extremum of price is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- in addition to them, the following is formed:
|
||||
//--- array of values of extremums of the oscillator,
|
||||
//--- array of values of price extremums and
|
||||
//--- array of "distances" between extremums of the oscillator (in bars)
|
||||
//--- it should be noted that when using the results of the extended check of state,
|
||||
//--- you should consider, which extremum of the oscillator (peak or valley)
|
||||
//--- is the "reference point" (i.e. was detected first during the analysis)
|
||||
//--- if a peak is detected first then even elements of all arrays
|
||||
//--- will contain information about peaks, and odd elements will contain information about valleys
|
||||
//--- if a valley is detected first, then respectively in reverse
|
||||
int pos=ind,off,index;
|
||||
uint map; // intermediate bit-map for one extremum
|
||||
//---
|
||||
m_extr_map=0;
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
off=StateMain(pos);
|
||||
if(off>0)
|
||||
{
|
||||
//--- minimum of the oscillator is detected
|
||||
pos+=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=Main(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_low.MinValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]<m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]<m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_low.MinValue(pos-1,4,index);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- maximum of the oscillator is detected
|
||||
pos-=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=Main(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]>m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]>m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-1,4,index);
|
||||
}
|
||||
}
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Comparing the bit-map of extremums with pattern. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalMACD::CompareMaps(int map,int count,bool minimax,int start)
|
||||
{
|
||||
int step =(minimax)?4:8;
|
||||
int total=step*(start+count);
|
||||
//--- check input parameters for a possible going out of range of the bit-map
|
||||
if(total>32)
|
||||
return(false);
|
||||
//--- bit-map of the patter is an "array" of 4-bit fields
|
||||
//--- each "element of the array" definitely describes the desired ratio
|
||||
//--- of current extremums of the oscillator and the price with previous ones
|
||||
//--- purpose of bits of an elements of the pattern of the bit-map pattern
|
||||
//--- bit 3 - is equal to if the ratio of extremums of the oscillator is insignificant for us
|
||||
//--- is equal to 0 if we want to "find" the ratio of extremums of the oscillator determined by the value of bit 2
|
||||
//--- bit 2 - is equal to 1 if we want to "discover" the situation when the current extremum of the "oscillator" is "more extreme" than the previous one
|
||||
//--- (current peak is higher or current valley is deeper)
|
||||
//--- is equal to 0 if we want to "discover" the situation when the current extremum of the oscillator is "less extreme" than the previous one
|
||||
//--- (current peak is lower or current valley is less deep)
|
||||
//--- bit 1 - is equal to 1 if the ratio of extremums is insignificant for us
|
||||
//--- it is equal to 0 if we want to "find" the ratio of price extremums determined by the value of bit 0
|
||||
//--- bit 0 - is equal to 1 if we want to "discover" the situation when the current price extremum is "more extreme" than the previous one
|
||||
//--- (current peak is higher or current valley is deeper)
|
||||
//--- it is equal to 0 if we want to "discover" the situation when the current price extremum is "less extreme" than the previous one
|
||||
//--- (current peak is lower or current valley is less deep)
|
||||
uint inp_map,check_map;
|
||||
int i,j;
|
||||
//--- loop by extremums (4 minimums and 4 maximums)
|
||||
//--- price and the oscillator are checked separately (thus, there are 16 checks)
|
||||
for(i=step*start,j=0;i<total;i+=step,j+=4)
|
||||
{
|
||||
//--- "take" two bits - patter of the corresponding extremum of the price
|
||||
inp_map=(map>>j)&3;
|
||||
//--- if the higher-order bit=1, then any ratio is suitable for us
|
||||
if(inp_map<2)
|
||||
{
|
||||
//--- "take" two bits of the corresponding extremum of the price (higher-order bit is always 0)
|
||||
check_map=(m_extr_map>>i)&3;
|
||||
if(inp_map!=check_map)
|
||||
return(false);
|
||||
}
|
||||
//--- "take" two bits - pattern of the corresponding oscillator extremum
|
||||
inp_map=(map>>(j+2))&3;
|
||||
//--- if the higher-order bit=1, then any ratio is suitable for us
|
||||
if(inp_map>=2)
|
||||
continue;
|
||||
//--- "take" two bits of the corresponding oscillator extremum (higher-order bit is always 0)
|
||||
check_map=(m_extr_map>>(i+2))&3;
|
||||
if(inp_map!=check_map)
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalMACD::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- check direction of the main line
|
||||
if(DiffMain(idx)>0.0)
|
||||
{
|
||||
//--- the main line is directed upwards, and it confirms the possibility of price growth
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0; // "confirming" signal number 0
|
||||
//--- if the model 1 is used, look for a reverse of the main line
|
||||
if(IS_PATTERN_USAGE(1) && DiffMain(idx+1)<0.0)
|
||||
result=m_pattern_1; // signal number 1
|
||||
//--- if the model 2 is used, look for an intersection of the main and signal line
|
||||
if(IS_PATTERN_USAGE(2) && State(idx)>0.0 && State(idx+1)<0.0)
|
||||
result=m_pattern_2; // signal number 2
|
||||
//--- if the model 3 is used, look for an intersection of the main line and the zero level
|
||||
if(IS_PATTERN_USAGE(3) && Main(idx)>0.0 && Main(idx+1)<0.0)
|
||||
result=m_pattern_3; // signal number 3
|
||||
//--- if the models 4 or 5 are used and the main line turned upwards below the zero level, look for divergences
|
||||
if((IS_PATTERN_USAGE(4) || IS_PATTERN_USAGE(5)) && Main(idx)<0.0)
|
||||
{
|
||||
//--- perform the extended analysis of the oscillator state
|
||||
ExtState(idx);
|
||||
//--- if the model 4 is used, look for the "divergence" signal
|
||||
if(IS_PATTERN_USAGE(4) && CompareMaps(1,1)) // 0000 0001b
|
||||
result=m_pattern_4; // signal number 4
|
||||
//--- if the model 5 is used, look for the "double divergence" signal
|
||||
if(IS_PATTERN_USAGE(5) && CompareMaps(0x11,2)) // 0001 0001b
|
||||
return(m_pattern_5); // signal number 5
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalMACD::ShortCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- check direction of the main line
|
||||
if(DiffMain(idx)<0.0)
|
||||
{
|
||||
//--- main line is directed downwards, confirming a possibility of falling of price
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0; // "confirming" signal number 0
|
||||
//--- if the model 1 is used, look for a reverse of the main line
|
||||
if(IS_PATTERN_USAGE(1) && DiffMain(idx+1)>0.0)
|
||||
result=m_pattern_1; // signal number 1
|
||||
//--- if the model 2 is used, look for an intersection of the main and signal line
|
||||
if(IS_PATTERN_USAGE(2) && State(idx)<0.0 && State(idx+1)>0.0)
|
||||
result=m_pattern_2; // signal number 2
|
||||
//--- if the model 3 is used, look for an intersection of the main line and the zero level
|
||||
if(IS_PATTERN_USAGE(3) && Main(idx)<0.0 && Main(idx+1)>0.0)
|
||||
result=m_pattern_3; // signal number 3
|
||||
//--- if the models 4 or 5 are used and the main line turned downwards above the zero level, look for divergences
|
||||
if((IS_PATTERN_USAGE(4) || IS_PATTERN_USAGE(5)) && Main(idx)>0.0)
|
||||
{
|
||||
//--- perform the extended analysis of the oscillator state
|
||||
ExtState(idx);
|
||||
//--- if the model 4 is used, look for the "divergence" signal
|
||||
if(IS_PATTERN_USAGE(4) && CompareMaps(1,1)) // 0000 0001b
|
||||
result=m_pattern_4; // signal number 4
|
||||
//--- if the model 5 is used, look for the "double divergence" signal
|
||||
if(IS_PATTERN_USAGE(5) && CompareMaps(0x11,2)) // 0001 0001b
|
||||
return(m_pattern_5); // signal number 5
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,400 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalRSI.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of oscillator 'Relative Strength Index' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=Relative Strength Index |
|
||||
//| ShortName=RSI |
|
||||
//| Class=CSignalRSI |
|
||||
//| Page=signal_rsi |
|
||||
//| Parameter=PeriodRSI,int,8,Period of calculation |
|
||||
//| Parameter=Applied,ENUM_APPLIED_PRICE,PRICE_CLOSE,Prices series |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalRSI. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Relative Strength Index' oscillator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalRSI : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiRSI m_rsi; // object-oscillator
|
||||
//--- adjusted parameters
|
||||
int m_periodRSI; // the "period of calculation" parameter of the oscillator
|
||||
ENUM_APPLIED_PRICE m_applied; // the "prices series" parameter of the oscillator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "the oscillator has required direction"
|
||||
int m_pattern_1; // model 1 "reverse behind the level of overbuying/overselling"
|
||||
int m_pattern_2; // model 2 "failed swing"
|
||||
int m_pattern_3; // model 3 "divergence of the oscillator and price"
|
||||
int m_pattern_4; // model 4 "double divergence of the oscillator and price"
|
||||
int m_pattern_5; // model 5 "head/shoulders"
|
||||
//--- variables
|
||||
double m_extr_osc[10]; // array of values of extremums of the oscillator
|
||||
double m_extr_pr[10]; // array of values of the corresponding extremums of price
|
||||
int m_extr_pos[10]; // array of shifts of extremums (in bars)
|
||||
uint m_extr_map; // resulting bit-map of ratio of extremums of the oscillator and the price
|
||||
|
||||
public:
|
||||
CSignalRSI(void);
|
||||
~CSignalRSI(void);
|
||||
//--- methods of setting adjustable parameters
|
||||
void PeriodRSI(int value) { m_periodRSI=value; }
|
||||
void Applied(ENUM_APPLIED_PRICE value) { m_applied=value; }
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
void Pattern_2(int value) { m_pattern_2=value; }
|
||||
void Pattern_3(int value) { m_pattern_3=value; }
|
||||
void Pattern_4(int value) { m_pattern_4=value; }
|
||||
void Pattern_5(int value) { m_pattern_5=value; }
|
||||
//--- method of verification of settings
|
||||
virtual bool ValidationSettings(void);
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
virtual int ShortCondition(void);
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the oscillator
|
||||
bool InitRSI(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double RSI(int ind) { return(m_rsi.Main(ind)); }
|
||||
double DiffRSI(int ind) { return(RSI(ind)-RSI(ind+1)); }
|
||||
int StateRSI(int ind);
|
||||
bool ExtStateRSI(int ind);
|
||||
bool CompareMaps(int map,int count,bool minimax=false,int start=0);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalRSI::CSignalRSI(void) : m_periodRSI(14),
|
||||
m_applied(PRICE_CLOSE),
|
||||
m_pattern_0(70),
|
||||
m_pattern_1(100),
|
||||
m_pattern_2(90),
|
||||
m_pattern_3(80),
|
||||
m_pattern_4(100),
|
||||
m_pattern_5(20)
|
||||
{
|
||||
//--- initialization of protected data
|
||||
m_used_series=USE_SERIES_HIGH+USE_SERIES_LOW;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalRSI::~CSignalRSI(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalRSI::ValidationSettings(void)
|
||||
{
|
||||
//--- validation settings of additional filters
|
||||
if(!CExpertSignal::ValidationSettings())
|
||||
return(false);
|
||||
//--- initial data checks
|
||||
if(m_periodRSI<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": period of the RSI oscillator must be greater than 0");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalRSI::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize RSI oscillator
|
||||
if(!InitRSI(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize RSI oscillators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalRSI::InitRSI(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- add object to collection
|
||||
if(!indicators.Add(GetPointer(m_rsi)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize object
|
||||
if(!m_rsi.Create(m_symbol.Name(),m_period,m_periodRSI,m_applied))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check of the oscillator state. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalRSI::StateRSI(int ind)
|
||||
{
|
||||
int res=0;
|
||||
double var;
|
||||
//---
|
||||
for(int i=ind;;i++)
|
||||
{
|
||||
if(RSI(i+1)==EMPTY_VALUE)
|
||||
break;
|
||||
var=DiffRSI(i);
|
||||
if(res>0)
|
||||
{
|
||||
if(var<0)
|
||||
break;
|
||||
res++;
|
||||
continue;
|
||||
}
|
||||
if(res<0)
|
||||
{
|
||||
if(var>0)
|
||||
break;
|
||||
res--;
|
||||
continue;
|
||||
}
|
||||
if(var>0)
|
||||
res++;
|
||||
if(var<0)
|
||||
res--;
|
||||
}
|
||||
//---
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Extended check of the oscillator state consists |
|
||||
//| in forming a bit-map according to certain rules, |
|
||||
//| which shows ratios of extremums of the oscillator and price. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalRSI::ExtStateRSI(int ind)
|
||||
{
|
||||
//--- operation of this method results in a bit-map of extremums
|
||||
//--- practically, the bit-map of extremums is an "array" of 4-bit fields
|
||||
//--- each "element of the array" definitely describes the ratio
|
||||
//--- of current extremums of the oscillator and the price with previous ones
|
||||
//--- purpose of bits of an element of the analyzed bit-map
|
||||
//--- bit 3 - not used (always 0)
|
||||
//--- bit 2 - is equal to 1 if the current extremum of the oscillator is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- bit 1 - not used (always 0)
|
||||
//--- bit 0 - is equal to 1 if the current extremum of price is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- in addition to them, the following is formed:
|
||||
//--- array of values of extremums of the oscillator,
|
||||
//--- array of values of price extremums and
|
||||
//--- array of "distances" between extremums of the oscillator (in bars)
|
||||
//--- it should be noted that when using the results of the extended check of state,
|
||||
//--- you should consider, which extremum of the oscillator (peak or valley)
|
||||
//--- is the "reference point" (i.e. was detected first during the analysis)
|
||||
//--- if a peak is detected first then even elements of all arrays
|
||||
//--- will contain information about peaks, and odd elements will contain information about valleys
|
||||
//--- if a valley is detected first, then respectively in reverse
|
||||
int pos=ind,off,index;
|
||||
uint map; // intermediate bit-map for one extremum
|
||||
//---
|
||||
m_extr_map=0;
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
off=StateRSI(pos);
|
||||
if(off>0)
|
||||
{
|
||||
//--- minimum of the oscillator is detected
|
||||
pos+=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=RSI(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_low.MinValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]<m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]<m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_low.MinValue(pos-1,4,index);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- maximum of the oscillator is detected
|
||||
pos-=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=RSI(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]>m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]>m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-1,4,index);
|
||||
}
|
||||
}
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Comparing the bit-map of extremums with pattern. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalRSI::CompareMaps(int map,int count,bool minimax,int start)
|
||||
{
|
||||
int step =(minimax)?4:8;
|
||||
int total=step*(start+count);
|
||||
//--- check input parameters for a possible going out of range of the bit-map
|
||||
if(total>32)
|
||||
return(false);
|
||||
//--- bit-map of the patter is an "array" of 4-bit fields
|
||||
//--- each "element of the array" definitely describes the desired ratio
|
||||
//--- of current extremums of the oscillator and the price with previous ones
|
||||
//--- purpose of bits of an elements of the pattern of the bit-map pattern
|
||||
//--- bit 3 - is equal to if the ratio of extremums of the oscillator is insignificant for us
|
||||
//--- is equal to 0 if we want to "find" the ratio of extremums of the oscillator determined by the value of bit 2
|
||||
//--- bit 2 - is equal to 1 if we want to "discover" the situation when the current extremum of the "oscillator" is "more extreme" than the previous one
|
||||
//--- (current peak is higher or current valley is deeper)
|
||||
//--- is equal to 0 if we want to "discover" the situation when the current extremum of the oscillator is "less extreme" than the previous one
|
||||
//--- (current peak is lower or current valley is less deep)
|
||||
//--- bit 1 - is equal to 1 if the ratio of extremums is insignificant for us
|
||||
//--- it is equal to 0 if we want to "find" the ratio of price extremums determined by the value of bit 0
|
||||
//--- bit 0 - is equal to 1 if we want to "discover" the situation when the current price extremum is "more extreme" than the previous one
|
||||
//--- (current peak is higher or current valley is deeper)
|
||||
//--- it is equal to 0 if we want to "discover" the situation when the current price extremum is "less extreme" than the previous one
|
||||
//--- (current peak is lower or current valley is less deep)
|
||||
uint inp_map,check_map;
|
||||
int i,j;
|
||||
//--- loop by extremums (4 minimums and 4 maximums)
|
||||
//--- price and the oscillator are checked separately (thus, there are 16 checks)
|
||||
for(i=step*start,j=0;i<total;i+=step,j+=4)
|
||||
{
|
||||
//--- "take" two bits - patter of the corresponding extremum of the price
|
||||
inp_map=(map>>j)&3;
|
||||
//--- if the higher-order bit=1, then any ratio is suitable for us
|
||||
if(inp_map<2)
|
||||
{
|
||||
//--- "take" two bits of the corresponding extremum of the price (higher-order bit is always 0)
|
||||
check_map=(m_extr_map>>i)&3;
|
||||
if(inp_map!=check_map)
|
||||
return(false);
|
||||
}
|
||||
//--- "take" two bits - pattern of the corresponding oscillator extremum
|
||||
inp_map=(map>>(j+2))&3;
|
||||
//--- if the higher-order bit=1, then any ratio is suitable for us
|
||||
if(inp_map>=2)
|
||||
continue;
|
||||
//--- "take" two bits of the corresponding oscillator extremum (higher-order bit is always 0)
|
||||
check_map=(m_extr_map>>(i+2))&3;
|
||||
if(inp_map!=check_map)
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalRSI::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//---
|
||||
if(DiffRSI(idx)>0.0)
|
||||
{
|
||||
//--- the oscillator is directed upwards confirming the possibility of price growth
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0; // "confirming" signal number 0
|
||||
//--- if the model 1 is used, search for a reverse of the oscillator upwards behind the level of overselling
|
||||
if(IS_PATTERN_USAGE(1) && DiffRSI(idx+1)<0.0 && RSI(idx+1)<30.0)
|
||||
result=m_pattern_1; // signal number 1
|
||||
//--- if the model 2, 3, 4 or 5 is used, perform the extended analysis of the oscillator state
|
||||
if(IS_PATTERN_USAGE(2) || IS_PATTERN_USAGE(3) || IS_PATTERN_USAGE(4) || IS_PATTERN_USAGE(5))
|
||||
{
|
||||
ExtStateRSI(idx);
|
||||
//--- search for the "failed swing" signal
|
||||
if(IS_PATTERN_USAGE(2) && RSI(idx)>m_extr_osc[1])
|
||||
result=m_pattern_2; // signal number 2
|
||||
//--- search for the "divergence" signal
|
||||
if(IS_PATTERN_USAGE(3) && CompareMaps(1,1)) // 0000 0001b
|
||||
result=m_pattern_3; // signal number 3
|
||||
//--- search for the "double divergence" signal
|
||||
if(IS_PATTERN_USAGE(4) && CompareMaps(0x11,2)) // 0001 0001b
|
||||
return(m_pattern_4); // signal number 4
|
||||
//--- search for the "head/shoulders" signal
|
||||
if(IS_PATTERN_USAGE(5) && CompareMaps(0x62662,5,true) && RSI(idx)>m_extr_osc[1]) // 01100010011001100010b
|
||||
result=m_pattern_5; // signal number 5
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalRSI::ShortCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//---
|
||||
if(DiffRSI(idx)<0.0)
|
||||
{
|
||||
//--- the oscillator is directed downwards confirming the possibility of falling of price
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0; // "confirming" signal number 0
|
||||
//--- if the model 1 is used, search for a reverse of the oscillator downwards behind the level of overbuying
|
||||
if(IS_PATTERN_USAGE(1) && DiffRSI(idx+1)>0.0 && RSI(idx+1)>70.0)
|
||||
result=m_pattern_1; // signal number 1
|
||||
//--- if the model 2, 3, 4 or 5 is used, perform the extended analysis of the oscillator state
|
||||
if(IS_PATTERN_USAGE(2) || IS_PATTERN_USAGE(3) || IS_PATTERN_USAGE(4) || IS_PATTERN_USAGE(5))
|
||||
{
|
||||
ExtStateRSI(idx);
|
||||
//--- search for the "failed swing" signal
|
||||
if(IS_PATTERN_USAGE(2) && RSI(idx)<m_extr_osc[1])
|
||||
result=m_pattern_2; // signal number 2
|
||||
//--- search for the "divergence" signal
|
||||
if(IS_PATTERN_USAGE(3) && CompareMaps(1,1)) // 0000 0001b
|
||||
result=m_pattern_3; // signal number 3
|
||||
//--- search for the "double divergence" signal
|
||||
if(IS_PATTERN_USAGE(4) && CompareMaps(0x11,2)) // 0001 0001b
|
||||
return(m_pattern_4); // signal number 4
|
||||
//--- search for the "head/shoulders" signal
|
||||
if(IS_PATTERN_USAGE(5) && CompareMaps(0x62662,5,true) && RSI(idx)<m_extr_osc[1]) // 01100010011001100010b
|
||||
result=m_pattern_5; // signal number 5
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,180 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalRVI.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of oscillator 'Relative Vigor Index' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=Relative Vigor Index |
|
||||
//| ShortName=RVI |
|
||||
//| Class=CSignalRVI |
|
||||
//| Page=signal_rvi |
|
||||
//| Parameter=PeriodRVI,int,10,Period of calculation |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalRVI. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Relative Vigor Index' oscillator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalRVI : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiRVI m_rvi; // object-oscillator
|
||||
//--- adjusted parameters
|
||||
int m_periodRVI; // the "period of calculation" parameter of the oscillator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "the oscillator has required direction"
|
||||
int m_pattern_1; // model 1 "crossing of main and signal line"
|
||||
|
||||
public:
|
||||
CSignalRVI(void);
|
||||
~CSignalRVI(void);
|
||||
//--- methods of setting adjustable parameters
|
||||
void PeriodRVI(int value) { m_periodRVI=value; }
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
//--- method of verification of settings
|
||||
virtual bool ValidationSettings(void);
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
virtual int ShortCondition(void);
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the oscillator
|
||||
bool InitRVI(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double Main(int ind) { return(m_rvi.Main(ind)); }
|
||||
double DiffMain(int ind) { return(Main(ind)-Main(ind+1)); }
|
||||
double Signal(int ind) { return(m_rvi.Signal(ind)); }
|
||||
double DiffSignal(int ind) { return(Signal(ind)-Signal(ind+1)); }
|
||||
double DiffMainSignal(int ind) { return(Main(ind)-Signal(ind)); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalRVI::CSignalRVI(void) : m_periodRVI(10),
|
||||
m_pattern_0(60),
|
||||
m_pattern_1(100)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalRVI::~CSignalRVI(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalRVI::ValidationSettings(void)
|
||||
{
|
||||
//--- validation settings of additional filters
|
||||
if(!CExpertSignal::ValidationSettings())
|
||||
return(false);
|
||||
//--- initial data checks
|
||||
if(m_periodRVI<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": the period of calculation of the RVI oscillator must be greater than 0");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalRVI::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize RVI oscillator
|
||||
if(!InitRVI(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize RVI oscillators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalRVI::InitRVI(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- add object to collection
|
||||
if(!indicators.Add(GetPointer(m_rvi)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize object
|
||||
if(!m_rvi.Create(m_symbol.Name(),m_period,m_periodRVI))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalRVI::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//---
|
||||
if(DiffMain(idx)>0.0)
|
||||
{
|
||||
//--- the main line of the oscillator is directed upwards confirming the possibility of price growth
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0; // "confirming" signal
|
||||
//--- if the main line crosses the signal line upwards, this is a signal for buying
|
||||
if(DiffMainSignal(idx)>0 && DiffMainSignal(idx+1)<0)
|
||||
{
|
||||
//--- the main line of the oscillator has crossed the signal line upwards (signal for buying)
|
||||
if(IS_PATTERN_USAGE(1))
|
||||
result=m_pattern_1; // signal number 1
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalRVI::ShortCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//---
|
||||
if(DiffMain(idx)<0.0)
|
||||
{
|
||||
//--- the main line of the oscillator is directed downwards confirming the possibility of falling of price
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0; // "confirming" signal
|
||||
//--- if the main line crosses the signal line from top downwards, this is a signal for selling
|
||||
if(DiffMainSignal(idx)<0 && DiffMainSignal(idx+1)>0)
|
||||
{
|
||||
//--- the main line of the oscillator has crossed the signal line from top downwards (signal for selling)
|
||||
if(IS_PATTERN_USAGE(1))
|
||||
result=m_pattern_1; // signal number 1
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,168 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalSAR.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of indicator 'Parabolic SAR' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=Parabolic SAR |
|
||||
//| ShortName=SAR |
|
||||
//| Class=CSignalSAR |
|
||||
//| Page=signal_sar |
|
||||
//| Parameter=Step,double,0.02,Speed increment |
|
||||
//| Parameter=Maximum,double,0.2,Maximum rate |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalSAR. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Parabolic SAR' indicator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalSAR : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiSAR m_sar; // object-indicator
|
||||
//--- adjusted parameters
|
||||
double m_step; // the "speed increment" parameter of the indicator
|
||||
double m_maximum; // the "maximum rate" parameter of the indicator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "the parabolic is on the necessary side from the price"
|
||||
int m_pattern_1; // model 1 "the parabolic has 'switched'"
|
||||
|
||||
public:
|
||||
CSignalSAR(void);
|
||||
~CSignalSAR(void);
|
||||
//--- methods of setting adjustable parameters
|
||||
void Step(double value) { m_step=value; }
|
||||
void Maximum(double value) { m_maximum=value; }
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
//--- method of verification of settings
|
||||
virtual bool ValidationSettings(void);
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
virtual int ShortCondition(void);
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the indicator
|
||||
bool InitSAR(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double SAR(int ind) { return(m_sar.Main(ind)); }
|
||||
double Close(int ind) { return(m_close.GetData(ind)); }
|
||||
double DiffClose(int ind) { return(Close(ind)-SAR(ind)); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalSAR::CSignalSAR(void) : m_step(0.02),
|
||||
m_maximum(0.2),
|
||||
m_pattern_0(40),
|
||||
m_pattern_1(90)
|
||||
{
|
||||
//--- initialization of protected data
|
||||
m_used_series=USE_SERIES_CLOSE;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalSAR::~CSignalSAR(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalSAR::ValidationSettings(void)
|
||||
{
|
||||
//--- call of the method of the parent class
|
||||
if(!CExpertSignal::ValidationSettings())
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalSAR::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize SAR indicator
|
||||
if(!InitSAR(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create SAR indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalSAR::InitSAR(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- add object to collection
|
||||
if(!indicators.Add(GetPointer(m_sar)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize object
|
||||
if(!m_sar.Create(m_symbol.Name(),m_period,m_step,m_maximum))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalSAR::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- if the indicator is above the price at the first analyzed bar, don't 'vote' buying
|
||||
if(DiffClose(idx++)<0.0)
|
||||
return(result);
|
||||
//--- the indicator is below the price at the first analyzed bar (the indicator has no objections to buying)
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
//--- if the indicator is above the price at the second analyzed bar, then there is a condition for buying
|
||||
if(IS_PATTERN_USAGE(1) && DiffClose(idx)<0.0)
|
||||
return(m_pattern_1);
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalSAR::ShortCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- if the indicator is below the price at the first analyzed bar, don't "vote" for selling
|
||||
if(DiffClose(idx++)>0.0)
|
||||
return(result);
|
||||
//--- the indicator is above the price at the first analyzed bar (the indicator has no objections to selling)
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
//--- if the indicator is below the price at the second analyzed bar, then there is a condition for selling
|
||||
if(IS_PATTERN_USAGE(1) && DiffClose(idx)>0.0)
|
||||
return(m_pattern_1);
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,426 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalStoch.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of oscillator 'Stochastic' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=Stochastic |
|
||||
//| ShortName=Stoch |
|
||||
//| Class=CSignalStoch |
|
||||
//| Page=signal_stochastic |
|
||||
//| Parameter=PeriodK,int,8,K-period |
|
||||
//| Parameter=PeriodD,int,3,D-period |
|
||||
//| Parameter=PeriodSlow,int,3,Period of slowing |
|
||||
//| Parameter=Applied,ENUM_STO_PRICE,STO_LOWHIGH,Prices to apply to |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalStoch. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Stochastic' oscillator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalStoch : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiStochastic m_stoch; // object-oscillator
|
||||
CPriceSeries *m_app_price_high; // pointer to the object-timeseries for determining divergences directed downwards
|
||||
CPriceSeries *m_app_price_low; // pointer to the object-timeseries for determining divergences directed upwards
|
||||
//--- adjusted parameters
|
||||
int m_periodK; // the "period %K" parameter of the oscillator
|
||||
int m_periodD; // the "period %D" parameter of the oscillator
|
||||
int m_period_slow; // the "period of slowing" parameter of the oscillator
|
||||
ENUM_STO_PRICE m_applied; // the "apply to" parameter of the oscillator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "the oscillator has required direction"
|
||||
int m_pattern_1; // model 1 "reverse of the oscillator to required direction"
|
||||
int m_pattern_2; // model 2 "crossing of main and signal line"
|
||||
int m_pattern_3; // model 3 "divergence of the oscillator and price"
|
||||
int m_pattern_4; // model 4 "double divergence of the oscillator and price"
|
||||
//--- variables
|
||||
double m_extr_osc[10]; // array of values of extremums of the oscillator
|
||||
double m_extr_pr[10]; // array of values of the corresponding extremums of price
|
||||
int m_extr_pos[10]; // array of shifts of extremums (in bars)
|
||||
uint m_extr_map; // resulting bit-map of ratio of extremums of the oscillator and the price
|
||||
|
||||
public:
|
||||
CSignalStoch(void);
|
||||
~CSignalStoch(void);
|
||||
//--- methods of setting adjustable parameters
|
||||
void PeriodK(int value) { m_periodK=value; }
|
||||
void PeriodD(int value) { m_periodD=value; }
|
||||
void PeriodSlow(int value) { m_period_slow=value; }
|
||||
void Applied(ENUM_STO_PRICE value) { m_applied=value; }
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
void Pattern_2(int value) { m_pattern_2=value; }
|
||||
void Pattern_3(int value) { m_pattern_3=value; }
|
||||
void Pattern_4(int value) { m_pattern_4=value; }
|
||||
//--- method of verification of settings
|
||||
virtual bool ValidationSettings(void);
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
virtual int ShortCondition(void);
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the oscillator
|
||||
bool InitStoch(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double Main(int ind) { return(m_stoch.Main(ind)); }
|
||||
double DiffMain(int ind) { return(Main(ind)-Main(ind+1)); }
|
||||
double Signal(int ind) { return(m_stoch.Signal(ind)); }
|
||||
double DiffSignal(int ind) { return(Signal(ind)-Signal(ind+1)); }
|
||||
double DiffMainSignal(int ind) { return(Main(ind)-Signal(ind)); }
|
||||
int StateStoch(int ind);
|
||||
bool ExtStateStoch(int ind);
|
||||
bool CompareMaps(int map,int count,bool minimax=false,int start=0);
|
||||
void DiverDebugPrint();
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalStoch::CSignalStoch(void) : m_periodK(8),
|
||||
m_periodD(3),
|
||||
m_period_slow(3),
|
||||
m_applied(STO_LOWHIGH),
|
||||
m_pattern_0(30),
|
||||
m_pattern_1(60),
|
||||
m_pattern_2(50),
|
||||
m_pattern_3(100),
|
||||
m_pattern_4(90)
|
||||
{
|
||||
//--- initialization of protected data
|
||||
m_used_series=USE_SERIES_OPEN+USE_SERIES_HIGH+USE_SERIES_LOW+USE_SERIES_CLOSE;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalStoch::~CSignalStoch(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalStoch::ValidationSettings(void)
|
||||
{
|
||||
//--- validation settings of additional filters
|
||||
if(!CExpertSignal::ValidationSettings())
|
||||
return(false);
|
||||
//--- initial data checks
|
||||
if(m_periodK<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": the period %K of the Stochastic oscillator must be greater than 0");
|
||||
return(false);
|
||||
}
|
||||
if(m_periodD<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": the period %D of the Stochastic oscillator must be greater than 0");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalStoch::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize Stochastic oscillator
|
||||
if(!InitStoch(indicators))
|
||||
return(false);
|
||||
if(m_applied==STO_CLOSECLOSE)
|
||||
{
|
||||
//--- copying the Close timeseries
|
||||
m_app_price_high=GetPointer(m_close);
|
||||
//--- copying the Close timeseries
|
||||
m_app_price_low=GetPointer(m_close);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- copying the High timeseries
|
||||
m_app_price_high=GetPointer(m_high);
|
||||
//--- copying the Low timeseries
|
||||
m_app_price_low=GetPointer(m_low);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize Stochastic oscillators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalStoch::InitStoch(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- add object to collection
|
||||
if(!indicators.Add(GetPointer(m_stoch)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize object
|
||||
if(!m_stoch.Create(m_symbol.Name(),m_period,m_periodK,m_periodD,m_period_slow,MODE_SMA,m_applied))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check of the oscillator state. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalStoch::StateStoch(int ind)
|
||||
{
|
||||
int res=0;
|
||||
double var;
|
||||
//---
|
||||
for(int i=ind;;i++)
|
||||
{
|
||||
if(Main(i+1)==EMPTY_VALUE)
|
||||
break;
|
||||
var=DiffMain(i);
|
||||
if(res>0)
|
||||
{
|
||||
if(var<0)
|
||||
break;
|
||||
res++;
|
||||
continue;
|
||||
}
|
||||
if(res<0)
|
||||
{
|
||||
if(var>0)
|
||||
break;
|
||||
res--;
|
||||
continue;
|
||||
}
|
||||
if(var>0)
|
||||
res++;
|
||||
if(var<0)
|
||||
res--;
|
||||
}
|
||||
//---
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Extended check of the oscillator state consists |
|
||||
//| in forming a bit-map according to certain rules, |
|
||||
//| which shows ratios of extremums of the oscillator and price. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalStoch::ExtStateStoch(int ind)
|
||||
{
|
||||
//--- operation of this method results in a bit-map of extremums
|
||||
//--- practically, the bit-map of extremums is an "array" of 4-bit fields
|
||||
//--- each "element of the array" definitely describes the ratio
|
||||
//--- of current extremums of the oscillator and the price with previous ones
|
||||
//--- purpose of bits of an element of the analyzed bit-map
|
||||
//--- bit 3 - not used (always 0)
|
||||
//--- bit 2 - is equal to 1 if the current extremum of the oscillator is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- bit 1 - not used (always 0)
|
||||
//--- bit 0 - is equal to 1 if the current extremum of price is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- in addition to them, the following is formed:
|
||||
//--- array of values of extremums of the oscillator,
|
||||
//--- array of values of price extremums and
|
||||
//--- array of "distances" between extremums of the oscillator (in bars)
|
||||
//--- it should be noted that when using the results of the extended check of state,
|
||||
//--- you should consider, which extremum of the oscillator (peak or valley)
|
||||
//--- is the "reference point" (i.e. was detected first during the analysis)
|
||||
//--- if a peak is detected first then even elements of all arrays
|
||||
//--- will contain information about peaks, and odd elements will contain information about valleys
|
||||
//--- if a valley is detected first, then respectively in reverse
|
||||
int pos=ind,off,index;
|
||||
uint map; // intermediate bit-map for one extremum
|
||||
//---
|
||||
m_extr_map=0;
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
off=StateStoch(pos);
|
||||
if(off>0)
|
||||
{
|
||||
//--- minimum of the oscillator is detected
|
||||
pos+=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=Main(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_low.MinValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]<m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]<m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_low.MinValue(pos-1,4,index);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- maximum of the oscillator is detected
|
||||
pos-=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=Main(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]>m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]>m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-1,4,index);
|
||||
}
|
||||
}
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Comparing the bit-map of extremums with pattern. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalStoch::CompareMaps(int map,int count,bool minimax=false,int start=0)
|
||||
{
|
||||
int step =(minimax)?4:8;
|
||||
int total=step*(start+count);
|
||||
//--- check input parameters for a possible going out of range of the bit-map
|
||||
if(total>32)
|
||||
return(false);
|
||||
//--- bit-map of the patter is an "array" of 4-bit fields
|
||||
//--- each "element of the array" definitely describes the desired ratio
|
||||
//--- of current extremums of the oscillator and the price with previous ones
|
||||
//--- purpose of bits of an elements of the pattern of the bit-map pattern
|
||||
//--- bit 3 - is equal to if the ratio of extremums of the oscillator is insignificant for us
|
||||
//--- is equal to 0 if we want to "find" the ratio of extremums of the oscillator determined by the value of bit 2
|
||||
//--- bit 2 - is equal to 1 if we want to "discover" the situation when the current extremum of the "oscillator" is "more extreme" than the previous one
|
||||
//--- (current peak is higher or current valley is deeper)
|
||||
//--- is equal to 0 if we want to "discover" the situation when the current extremum of the oscillator is "less extreme" than the previous one
|
||||
//--- (current peak is lower or current valley is less deep)
|
||||
//--- bit 1 - is equal to 1 if the ratio of extremums is insignificant for us
|
||||
//--- it is equal to 0 if we want to "find" the ratio of price extremums determined by the value of bit 0
|
||||
//--- bit 0 - is equal to 1 if we want to "discover" the situation when the current price extremum is "more extreme" than the previous one
|
||||
//--- (current peak is higher or current valley is deeper)
|
||||
//--- it is equal to 0 if we want to "discover" the situation when the current price extremum is "less extreme" than the previous one
|
||||
//--- (current peak is lower or current valley is less deep)
|
||||
uint inp_map,check_map;
|
||||
int i,j;
|
||||
//--- loop by extremums (4 minimums and 4 maximums)
|
||||
//--- price and the oscillator are checked separately (thus, there are 16 checks)
|
||||
for(i=step*start,j=0;i<total;i+=step,j+=4)
|
||||
{
|
||||
//--- "take" two bits - patter of the corresponding extremum of the price
|
||||
inp_map=(map>>j)&3;
|
||||
//--- if the higher-order bit=1, then any ratio is suitable for us
|
||||
if(inp_map<2)
|
||||
{
|
||||
//--- "take" two bits of the corresponding extremum of the price (higher-order bit is always 0)
|
||||
check_map=(m_extr_map>>i)&3;
|
||||
if(inp_map!=check_map)
|
||||
return(false);
|
||||
}
|
||||
//--- "take" two bits - pattern of the corresponding oscillator extremum
|
||||
inp_map=(map>>(j+2))&3;
|
||||
//--- if the higher-order bit=1, then any ratio is suitable for us
|
||||
if(inp_map>=2)
|
||||
continue;
|
||||
//--- "take" two bits of the corresponding oscillator extremum (higher-order bit is always 0)
|
||||
check_map=(m_extr_map>>(i+2))&3;
|
||||
if(inp_map!=check_map)
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalStoch::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- check direction of the main line
|
||||
if(DiffMain(idx)>0.0)
|
||||
{
|
||||
//--- the main line is directed upwards, and it confirms the possibility of price growth
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0; // "confirming" signal number 0
|
||||
//--- if the model 1 is used, look for a reverse of the main line
|
||||
if(IS_PATTERN_USAGE(1) && DiffMain(idx+1)<0.0)
|
||||
result=m_pattern_1; // signal number 1
|
||||
//--- if the model 2 is used, look for an intersection of the main and signal line
|
||||
if(IS_PATTERN_USAGE(2) && DiffMainSignal(idx)>0.0 && DiffMainSignal(idx+1)<0.0)
|
||||
result=m_pattern_2; // signal number 2
|
||||
//--- if the models 3 or 4 are used, look for divergences
|
||||
if((IS_PATTERN_USAGE(3) || IS_PATTERN_USAGE(4)))
|
||||
{
|
||||
//--- perform the extended analysis of the oscillator state
|
||||
ExtStateStoch(idx);
|
||||
//--- if the model 3 is used, look for the "divergence" signal
|
||||
if(IS_PATTERN_USAGE(3) && CompareMaps(1,1)) // 0000 0001b
|
||||
result=m_pattern_3; // signal number 3
|
||||
//--- if the model 4 is used, look for the "double divergence" signal
|
||||
if(IS_PATTERN_USAGE(4) && CompareMaps(0x11,2)) // 0001 0001b
|
||||
return(m_pattern_4); // signal number 4
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalStoch::ShortCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- check direction of the main line
|
||||
if(DiffMain(idx)<0.0)
|
||||
{
|
||||
//--- main line is directed downwards, confirming a possibility of falling of price
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0; // "confirming" signal number 0
|
||||
//--- if the model 1 is used, look for a reverse of the main line
|
||||
if(IS_PATTERN_USAGE(1) && DiffMain(idx+1)>0.0)
|
||||
result=m_pattern_1; // signal number 1
|
||||
//--- if the model 2 is used, look for an intersection of the main and signal line
|
||||
if(IS_PATTERN_USAGE(2) && DiffMainSignal(idx)<0.0 && DiffMainSignal(idx+1)>0.0)
|
||||
result=m_pattern_2; // signal number 2
|
||||
//--- if the models 3 or 4 are used, look for divergences
|
||||
if((IS_PATTERN_USAGE(3) || IS_PATTERN_USAGE(4)))
|
||||
{
|
||||
//--- perform the extended analysis of the oscillator state
|
||||
ExtStateStoch(idx);
|
||||
//--- if the model 3 is used, look for the "divergence" signal
|
||||
if(IS_PATTERN_USAGE(3) && CompareMaps(1,1)) // 0000 0001b
|
||||
result=m_pattern_3; // signal number 3
|
||||
//--- if the model 4 is used, look for the "double divergence" signal
|
||||
if(IS_PATTERN_USAGE(4) && CompareMaps(0x11,2)) // 0001 0001b
|
||||
return(m_pattern_4); // signal number 4
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,257 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalTEMA.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of indicator 'Triple Exponential Moving Average' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=Triple Exponential Moving Average |
|
||||
//| ShortName=TEMA |
|
||||
//| Class=CSignalTEMA |
|
||||
//| Page=signal_tema |
|
||||
//| Parameter=PeriodMA,int,12,Period of averaging |
|
||||
//| Parameter=Shift,int,0,Time shift |
|
||||
//| Parameter=Applied,ENUM_APPLIED_PRICE,PRICE_CLOSE,Prices series |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalTEMA. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Triple Exponential Moving Average' indicator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalTEMA : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiTEMA m_ma; // object-indicator
|
||||
//--- adjusted parameters
|
||||
int m_ma_period; // the "period of averaging" parameter of the indicator
|
||||
int m_ma_shift; // the "time shift" parameter of the indicator
|
||||
ENUM_APPLIED_PRICE m_ma_applied; // the "object of averaging" parameter" of the indicator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "price is on the necessary side from the indicator"
|
||||
int m_pattern_1; // model 1 "price crossed the indicator with opposite direction"
|
||||
int m_pattern_2; // model 2 "price crossed the indicator with the same direction"
|
||||
int m_pattern_3; // model 3 "piercing"
|
||||
|
||||
public:
|
||||
CSignalTEMA(void);
|
||||
~CSignalTEMA(void);
|
||||
//--- methods of setting adjustable parameters
|
||||
void PeriodMA(int value) { m_ma_period=value; }
|
||||
void Shift(int value) { m_ma_shift=value; }
|
||||
void Applied(ENUM_APPLIED_PRICE value) { m_ma_applied=value; }
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
void Pattern_2(int value) { m_pattern_2=value; }
|
||||
void Pattern_3(int value) { m_pattern_3=value; }
|
||||
//--- method of verification of settings
|
||||
virtual bool ValidationSettings(void);
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
virtual int ShortCondition(void);
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the indicator
|
||||
bool InitMA(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double MA(int ind) { return(m_ma.Main(ind)); }
|
||||
double DiffMA(int ind) { return(MA(ind)-MA(ind+1)); }
|
||||
double DiffOpenMA(int ind) { return(Open(ind)-MA(ind)); }
|
||||
double DiffHighMA(int ind) { return(High(ind)-MA(ind)); }
|
||||
double DiffLowMA(int ind) { return(Low(ind)-MA(ind)); }
|
||||
double DiffCloseMA(int ind) { return(Close(ind)-MA(ind)); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalTEMA::CSignalTEMA(void) : m_ma_period(12),
|
||||
m_ma_shift(0),
|
||||
m_ma_applied(PRICE_CLOSE),
|
||||
m_pattern_0(50),
|
||||
m_pattern_1(10),
|
||||
m_pattern_2(60),
|
||||
m_pattern_3(60)
|
||||
{
|
||||
//--- initialization of protected data
|
||||
m_used_series=USE_SERIES_OPEN+USE_SERIES_HIGH+USE_SERIES_LOW+USE_SERIES_CLOSE;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalTEMA::~CSignalTEMA(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalTEMA::ValidationSettings(void)
|
||||
{
|
||||
//--- call of the method of the parent class
|
||||
if(!CExpertSignal::ValidationSettings())
|
||||
return(false);
|
||||
//--- initial data checks
|
||||
if(m_ma_period<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": period MA must be greater than 0");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalTEMA::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize TEMA indicator
|
||||
if(!InitMA(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create MA indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalTEMA::InitMA(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- add object to collection
|
||||
if(!indicators.Add(GetPointer(m_ma)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize object
|
||||
if(!m_ma.Create(m_symbol.Name(),m_period,m_ma_period,m_ma_shift,m_ma_applied))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalTEMA::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- analyze positional relationship of the close price and the indicator at the first analyzed bar
|
||||
if(DiffCloseMA(idx)<0.0)
|
||||
{
|
||||
//--- the close price is below the indicator
|
||||
if(IS_PATTERN_USAGE(1) && DiffOpenMA(idx)>0.0 && DiffMA(idx)>0.0)
|
||||
{
|
||||
//--- the open price is above the indicator (i.e. there was an intersection), but the indicator is directed upwards
|
||||
result=m_pattern_1;
|
||||
//--- consider that this is an unformed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- the close price is above the indicator (the indicator has no objections to buying)
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
//--- if the indicator is directed upwards
|
||||
if(DiffMA(idx)>0.0)
|
||||
{
|
||||
if(DiffOpenMA(idx)<0.0)
|
||||
{
|
||||
//--- if the model 2 is used
|
||||
if(IS_PATTERN_USAGE(2))
|
||||
{
|
||||
//--- the open price is below the indicator (i.e. there was an intersection)
|
||||
result=m_pattern_2;
|
||||
//--- suggest to enter the market at the "roll back"
|
||||
m_base_price=m_symbol.NormalizePrice(MA(idx));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- if the model 3 is used and the open price is above the indicator
|
||||
if(IS_PATTERN_USAGE(3) && DiffLowMA(idx)<0.0)
|
||||
{
|
||||
//--- the low price is below the indicator
|
||||
result=m_pattern_3;
|
||||
//--- consider that this is a formed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalTEMA::ShortCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- analyze positional relationship of the close price and the indicator at the first analyzed bar
|
||||
if(DiffCloseMA(idx)>0.0)
|
||||
{
|
||||
//--- the close price is above the indicator
|
||||
if(IS_PATTERN_USAGE(1) && DiffOpenMA(idx)<0.0 && DiffMA(idx)<0.0)
|
||||
{
|
||||
//--- the open price is below the indicator (i.e. there was an intersection), but the indicator is directed downwards
|
||||
result=m_pattern_1;
|
||||
//--- consider that this is an unformed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- the close price is below the indicator (the indicator has no objections to buying)
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0;
|
||||
//--- the indicator is directed downwards
|
||||
if(DiffMA(idx)<0.0)
|
||||
{
|
||||
if(DiffOpenMA(idx)>0.0)
|
||||
{
|
||||
//--- if the model 2 is used
|
||||
if(IS_PATTERN_USAGE(2))
|
||||
{
|
||||
//--- the open price is above the indicator (i.e. there was an intersection)
|
||||
result=m_pattern_2;
|
||||
//--- suggest to enter the market at the "roll back"
|
||||
m_base_price=m_symbol.NormalizePrice(MA(idx));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- if the model 3 is used and the open price is below the indicator
|
||||
if(IS_PATTERN_USAGE(3) && DiffHighMA(idx)>0.0)
|
||||
{
|
||||
//--- the high price is above the indicator
|
||||
result=m_pattern_3;
|
||||
//--- consider that this is a formed "piercing" and suggest to enter the market at the current price
|
||||
m_base_price=0.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,395 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalTRIX.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of oscillator 'Triple Exponential Average' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=Triple Exponential Average |
|
||||
//| ShortName=TriX |
|
||||
//| Class=CSignalTriX |
|
||||
//| Page=signal_trix |
|
||||
//| Parameter=PeriodTriX,int,14,Period of calculation |
|
||||
//| Parameter=Applied,ENUM_APPLIED_PRICE,PRICE_CLOSE,Prices series |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalTriX. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Triple Exponential Average' oscillator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalTriX : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiTriX m_trix; // object-oscillator
|
||||
//--- adjusted parameters
|
||||
int m_period_trix; // the "period of calculation" parameter of the oscillator
|
||||
ENUM_APPLIED_PRICE m_applied; // the "price series" parameter of the oscillator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "the oscillator has required direction"
|
||||
int m_pattern_1; // model 1 "reverse of the oscillator to required direction"
|
||||
int m_pattern_2; // model 2 "crossing of main line an the zero level"
|
||||
int m_pattern_3; // model 3 "divergence of the oscillator and price"
|
||||
//--- variables
|
||||
double m_extr_osc[10]; // array of values of extremums of the oscillator
|
||||
double m_extr_pr[10]; // array of values of the corresponding extremums of price
|
||||
int m_extr_pos[10]; // array of shifts of extremums (in bars)
|
||||
uint m_extr_map; // resulting bit-map of ratio of extremums of the oscillator and the price
|
||||
|
||||
public:
|
||||
CSignalTriX(void);
|
||||
~CSignalTriX(void);
|
||||
//--- methods of setting adjustable parameters
|
||||
void PeriodTriX(int value) { m_period_trix=value; }
|
||||
void Applied(ENUM_APPLIED_PRICE value) { m_applied=value; }
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
void Pattern_2(int value) { m_pattern_2=value; }
|
||||
void Pattern_3(int value) { m_pattern_3=value; }
|
||||
//--- method of verification of settings
|
||||
virtual bool ValidationSettings(void);
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
virtual int ShortCondition(void);
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the oscillator
|
||||
bool InitTriX(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
double TriX(int ind) { return(m_trix.Main(ind)); }
|
||||
double DiffTriX(int ind) { return(TriX(ind)-TriX(ind+1)); }
|
||||
int State(int ind);
|
||||
bool ExtState(int ind);
|
||||
bool CompareMaps(int map,int count,bool minimax=false,int start=0);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalTriX::CSignalTriX(void) : m_period_trix(12),
|
||||
m_applied(PRICE_CLOSE),
|
||||
m_pattern_0(20),
|
||||
m_pattern_1(80),
|
||||
m_pattern_2(100),
|
||||
m_pattern_3(70)
|
||||
{
|
||||
//--- initialization of protected data
|
||||
m_used_series=USE_SERIES_HIGH+USE_SERIES_LOW;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalTriX::~CSignalTriX(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalTriX::ValidationSettings(void)
|
||||
{
|
||||
if(!CExpertSignal::ValidationSettings())
|
||||
return(false);
|
||||
//---
|
||||
if(m_period_trix<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": period must be greater than 0");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalTriX::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize TriX oscilator
|
||||
if(!InitTriX(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize TriX oscillators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalTriX::InitTriX(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- add object to collection
|
||||
if(!indicators.Add(GetPointer(m_trix)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize object
|
||||
if(!m_trix.Create(m_symbol.Name(),m_period,m_period_trix,m_applied))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check of the oscillator state. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalTriX::State(int ind)
|
||||
{
|
||||
int res=0;
|
||||
double var;
|
||||
//---
|
||||
for(int i=ind;;i++)
|
||||
{
|
||||
if(TriX(i+1)==EMPTY_VALUE)
|
||||
break;
|
||||
var=DiffTriX(i);
|
||||
if(res>0)
|
||||
{
|
||||
if(var<0)
|
||||
break;
|
||||
res++;
|
||||
continue;
|
||||
}
|
||||
if(res<0)
|
||||
{
|
||||
if(var>0)
|
||||
break;
|
||||
res--;
|
||||
continue;
|
||||
}
|
||||
if(var>0)
|
||||
res++;
|
||||
if(var<0)
|
||||
res--;
|
||||
}
|
||||
//---
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Extended check of the oscillator state consists |
|
||||
//| in forming a bit-map according to certain rules, |
|
||||
//| which shows ratios of extremums of the oscillator and price. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalTriX::ExtState(int ind)
|
||||
{
|
||||
//--- operation of this method results in a bit-map of extremums
|
||||
//--- practically, the bit-map of extremums is an "array" of 4-bit fields
|
||||
//--- each "element of the array" definitely describes the ratio
|
||||
//--- of current extremums of the oscillator and the price with previous ones
|
||||
//--- purpose of bits of an element of the analyzed bit-map
|
||||
//--- bit 3 - not used (always 0)
|
||||
//--- bit 2 - is equal to 1 if the current extremum of the oscillator is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- bit 1 - not used (always 0)
|
||||
//--- bit 0 - is equal to 1 if the current extremum of price is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- in addition to them, the following is formed:
|
||||
//--- array of values of extremums of the oscillator,
|
||||
//--- array of values of price extremums and
|
||||
//--- array of "distances" between extremums of the oscillator (in bars)
|
||||
//--- it should be noted that when using the results of the extended check of state,
|
||||
//--- you should consider, which extremum of the oscillator (peak or valley)
|
||||
//--- is the "reference point" (i.e. was detected first during the analysis)
|
||||
//--- if a peak is detected first then even elements of all arrays
|
||||
//--- will contain information about peaks, and odd elements will contain information about valleys
|
||||
//--- if a valley is detected first, then respectively in reverse
|
||||
int pos=ind,off,index;
|
||||
uint map; // intermediate bit-map for one extremum
|
||||
//---
|
||||
m_extr_map=0;
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
off=State(pos);
|
||||
if(off>0)
|
||||
{
|
||||
//--- minimum of the oscillator is detected
|
||||
pos+=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=TriX(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_low.MinValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]<m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]<m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_low.MinValue(pos-1,4,index);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- maximum of the oscillator is detected
|
||||
pos-=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=TriX(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]>m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]>m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-1,4,index);
|
||||
}
|
||||
}
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Comparing the bit-map of extremums with pattern. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalTriX::CompareMaps(int map,int count,bool minimax,int start)
|
||||
{
|
||||
int step =(minimax)?4:8;
|
||||
int total=step*(start+count);
|
||||
//--- check input parameters for a possible going out of range of the bit-map
|
||||
if(total>32)
|
||||
return(false);
|
||||
//--- bit-map of the patter is an "array" of 4-bit fields
|
||||
//--- each "element of the array" definitely describes the desired ratio
|
||||
//--- of current extremums of the oscillator and the price with previous ones
|
||||
//--- purpose of bits of an elements of the pattern of the bit-map pattern
|
||||
//--- bit 3 - is equal to if the ratio of extremums of the oscillator is insignificant for us
|
||||
//--- is equal to 0 if we want to "find" the ratio of extremums of the oscillator determined by the value of bit 2
|
||||
//--- bit 2 - is equal to 1 if we want to "discover" the situation when the current extremum of the "oscillator" is "more extreme" than the previous one
|
||||
//--- (current peak is higher or current valley is deeper)
|
||||
//--- is equal to 0 if we want to "discover" the situation when the current extremum of the oscillator is "less extreme" than the previous one
|
||||
//--- (current peak is lower or current valley is less deep)
|
||||
//--- bit 1 - is equal to 1 if the ratio of extremums is insignificant for us
|
||||
//--- it is equal to 0 if we want to "find" the ratio of price extremums determined by the value of bit 0
|
||||
//--- bit 0 - is equal to 1 if we want to "discover" the situation when the current price extremum is "more extreme" than the previous one
|
||||
//--- (current peak is higher or current valley is deeper)
|
||||
//--- it is equal to 0 if we want to "discover" the situation when the current price extremum is "less extreme" than the previous one
|
||||
//--- (current peak is lower or current valley is less deep)
|
||||
uint inp_map,check_map;
|
||||
int i,j;
|
||||
//--- loop by extremums (4 minimums and 4 maximums)
|
||||
//--- price and the oscillator are checked separately (thus, there are 16 checks)
|
||||
for(i=step*start,j=0;i<total;i+=step,j+=4)
|
||||
{
|
||||
//--- "take" two bits - patter of the corresponding extremum of the price
|
||||
inp_map=(map>>j)&3;
|
||||
//--- if the higher-order bit=1, then any ratio is suitable for us
|
||||
if(inp_map<2)
|
||||
{
|
||||
//--- "take" two bits of the corresponding extremum of the price (higher-order bit is always 0)
|
||||
check_map=(m_extr_map>>i)&3;
|
||||
if(inp_map!=check_map)
|
||||
return(false);
|
||||
}
|
||||
//--- "take" two bits - pattern of the corresponding oscillator extremum
|
||||
inp_map=(map>>(j+2))&3;
|
||||
//--- if the higher-order bit=1, then any ratio is suitable for us
|
||||
if(inp_map>=2)
|
||||
continue;
|
||||
//--- "take" two bits of the corresponding oscillator extremum (higher-order bit is always 0)
|
||||
check_map=(m_extr_map>>(i+2))&3;
|
||||
if(inp_map!=check_map)
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalTriX::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- check direction of the oscillator
|
||||
if(DiffTriX(idx)>0.0)
|
||||
{
|
||||
//--- the oscillator is directed upwards confirming the possibility of price growth
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0; // "confirming" signal number 0
|
||||
//--- if the model 1 is used, search for a reverse of the oscillator
|
||||
if(IS_PATTERN_USAGE(1) && DiffTriX(idx)>0.0 && DiffTriX(idx+1)<0.0)
|
||||
result=m_pattern_1; // signal number 1
|
||||
//--- if the model 2 is used, search for an intersection of the oscillator line and the zero level
|
||||
if(IS_PATTERN_USAGE(2) && TriX(idx)>0.0 && TriX(idx+1)<0.0)
|
||||
result=m_pattern_2; // signal number 2
|
||||
//--- if the model 3 is used, and the oscillator turned up below the zero level, search for the divergence
|
||||
if(IS_PATTERN_USAGE(3) && TriX(idx)<0.0)
|
||||
{
|
||||
//--- perform the extended analysis of the oscillator state
|
||||
ExtState(idx);
|
||||
//--- search for the "divergence" signal
|
||||
if(CompareMaps(1,1)) // 0000 0001b
|
||||
{
|
||||
if(m_extr_osc[0]<0.0 && m_extr_osc[1]<0.0 && m_extr_osc[2]<0.0)
|
||||
{
|
||||
//--- both valleys of the oscillator are below zero and the peak between them hasn't raised above zero
|
||||
result=m_pattern_3; // signal number 3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalTriX::ShortCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//--- check direction of the main line
|
||||
if(DiffTriX(idx)<0.0)
|
||||
{
|
||||
//--- main line is directed downwards, confirming a possibility of falling of price
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0; // "confirming" signal number 0
|
||||
//--- if the model 1 is used, search for a reverse of the main line
|
||||
if(IS_PATTERN_USAGE(1) && DiffTriX(idx)<0.0 && DiffTriX(idx+1)>0.0)
|
||||
result=m_pattern_1; // signal number 1
|
||||
//--- if the model 2 is used, search for an intersection of the main line and the zero level
|
||||
if(IS_PATTERN_USAGE(2) && TriX(idx)<0.0 && TriX(idx+1)>0.0)
|
||||
result=m_pattern_2; // signal number 2
|
||||
//--- if the model 3 is used and the main line turned down above the zero level, search for the divergence
|
||||
if(IS_PATTERN_USAGE(3) && TriX(idx)>0.0)
|
||||
{
|
||||
//--- perform the extended analysis of the oscillator state
|
||||
ExtState(idx);
|
||||
//--- search for the "divergence" signal
|
||||
if(CompareMaps(1,1)) // 0000 0001b
|
||||
{
|
||||
if(m_extr_osc[0]>0.0 && m_extr_osc[1]>0.0 && m_extr_osc[2]>0.0)
|
||||
{
|
||||
//--- both peaks of the oscillator are above zero and the valley between them hasn't fallen below zero
|
||||
result=m_pattern_3; // signal number 3
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,371 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalWPR.mqh |
|
||||
//| Copyright 2000-2024, MetaQuotes Ltd. |
|
||||
//| https://www.mql5.com |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals of oscillator 'Williams Percent Range' |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=Williams Percent Range |
|
||||
//| ShortName=WPR |
|
||||
//| Class=CSignalWPR |
|
||||
//| Page=signal_wpr |
|
||||
//| Parameter=PeriodWPR,int,8,Period of calculation |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalWPR. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| the 'Williams Percent Range' oscillator. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalWPR : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiWPR m_wpr; // object-oscillator
|
||||
//--- adjusted parameters
|
||||
int m_period_wpr; // the "period of calculation" parameter of the oscillator
|
||||
//--- "weights" of market models (0-100)
|
||||
int m_pattern_0; // model 0 "the oscillator has required direction"
|
||||
int m_pattern_1; // model 1 "reverse behind the level of overbuying/overselling"
|
||||
int m_pattern_2; // model 2 "divergence of the oscillator and price"
|
||||
//--- variables
|
||||
double m_extr_osc[10]; // array of values of extremums of the oscillator
|
||||
double m_extr_pr[10]; // array of values of the corresponding extremums of price
|
||||
int m_extr_pos[10]; // array of shifts of extremums (in bars)
|
||||
uint m_extr_map; // resulting bit-map of ratio of extremums of the oscillator and the price
|
||||
|
||||
public:
|
||||
CSignalWPR(void);
|
||||
~CSignalWPR(void);
|
||||
//--- methods of setting adjustable parameters
|
||||
void PeriodWPR(int value) { m_period_wpr=value; }
|
||||
//--- methods of adjusting "weights" of market models
|
||||
void Pattern_0(int value) { m_pattern_0=value; }
|
||||
void Pattern_1(int value) { m_pattern_1=value; }
|
||||
void Pattern_2(int value) { m_pattern_2=value; }
|
||||
//--- method of verification of settings
|
||||
virtual bool ValidationSettings(void);
|
||||
//--- method of creating the indicator and timeseries
|
||||
virtual bool InitIndicators(CIndicators *indicators);
|
||||
//--- methods of checking if the market models are formed
|
||||
virtual int LongCondition(void);
|
||||
virtual int ShortCondition(void);
|
||||
|
||||
protected:
|
||||
//--- method of initialization of the oscillator
|
||||
bool InitWPR(CIndicators *indicators);
|
||||
//--- methods of getting data
|
||||
// double WPR(int ind);
|
||||
double WPR(int ind) { return(m_wpr.Main(ind)); }
|
||||
double Diff(int ind) { return(WPR(ind)-WPR(ind+1)); }
|
||||
int State(int ind);
|
||||
bool ExtState(int ind);
|
||||
bool CompareMaps(int map,int count,bool minimax=false,int start=0);
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalWPR::CSignalWPR(void) : m_period_wpr(14),
|
||||
m_pattern_0(80),
|
||||
m_pattern_1(70),
|
||||
m_pattern_2(90)
|
||||
{
|
||||
//--- initialization of protected data
|
||||
m_used_series=USE_SERIES_HIGH+USE_SERIES_LOW;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor |
|
||||
//+------------------------------------------------------------------+
|
||||
CSignalWPR::~CSignalWPR(void)
|
||||
{
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalWPR::ValidationSettings(void)
|
||||
{
|
||||
//--- validation settings of additional filters
|
||||
if(!CExpertSignal::ValidationSettings())
|
||||
return(false);
|
||||
//--- initial data checks
|
||||
if(m_period_wpr<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": period of the WPR oscillator must be greater than 0");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalWPR::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL)
|
||||
return(false);
|
||||
//--- initialization of indicators and timeseries of additional filters
|
||||
if(!CExpertSignal::InitIndicators(indicators))
|
||||
return(false);
|
||||
//--- create and initialize WPR oscillator
|
||||
if(!InitWPR(indicators))
|
||||
return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialize WPR oscillators. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalWPR::InitWPR(CIndicators *indicators)
|
||||
{
|
||||
//--- check pointer
|
||||
if(indicators==NULL) return(false);
|
||||
//--- add object to collection
|
||||
if(!indicators.Add(GetPointer(m_wpr)))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
return(false);
|
||||
}
|
||||
//--- initialize object
|
||||
if(!m_wpr.Create(m_symbol.Name(),m_period,m_period_wpr))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check of the oscillator state. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalWPR::State(int ind)
|
||||
{
|
||||
int res=0;
|
||||
double var;
|
||||
//---
|
||||
for(int i=ind;;i++)
|
||||
{
|
||||
if(WPR(i+1)==EMPTY_VALUE)
|
||||
break;
|
||||
var=Diff(i);
|
||||
if(res>0)
|
||||
{
|
||||
if(var<0)
|
||||
break;
|
||||
res++;
|
||||
continue;
|
||||
}
|
||||
if(res<0)
|
||||
{
|
||||
if(var>0)
|
||||
break;
|
||||
res--;
|
||||
continue;
|
||||
}
|
||||
if(var>0)
|
||||
res++;
|
||||
if(var<0)
|
||||
res--;
|
||||
}
|
||||
//---
|
||||
return(res);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Extended check of the oscillator state consists |
|
||||
//| in forming a bit-map according to certain rules, |
|
||||
//| which shows ratios of extremums of the oscillator and price. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalWPR::ExtState(int ind)
|
||||
{
|
||||
//--- operation of this method results in a bit-map of extremums
|
||||
//--- practically, the bit-map of extremums is an "array" of 4-bit fields
|
||||
//--- each "element of the array" definitely describes the ratio
|
||||
//--- of current extremums of the oscillator and the price with previous ones
|
||||
//--- purpose of bits of an element of the analyzed bit-map
|
||||
//--- bit 3 - not used (always 0)
|
||||
//--- bit 2 - is equal to 1 if the current extremum of the oscillator is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- bit 1 - not used (always 0)
|
||||
//--- bit 0 - is equal to 1 if the current extremum of price is "more extreme" than the previous one
|
||||
//--- (a higher peak or a deeper valley), otherwise - 0
|
||||
//--- in addition to them, the following is formed:
|
||||
//--- array of values of extremums of the oscillator,
|
||||
//--- array of values of price extremums and
|
||||
//--- array of "distances" between extremums of the oscillator (in bars)
|
||||
//--- it should be noted that when using the results of the extended check of state,
|
||||
//--- you should consider, which extremum of the oscillator (peak or valley)
|
||||
//--- is the "reference point" (i.e. was detected first during the analysis)
|
||||
//--- if a peak is detected first then even elements of all arrays
|
||||
//--- will contain information about peaks, and odd elements will contain information about valleys
|
||||
//--- if a valley is detected first, then respectively in reverse
|
||||
int pos=ind,off,index;
|
||||
uint map; // intermediate bit-map for one extremum
|
||||
//---
|
||||
m_extr_map=0;
|
||||
for(int i=0;i<10;i++)
|
||||
{
|
||||
off=State(pos);
|
||||
if(off>0)
|
||||
{
|
||||
//--- minimum of the oscillator is detected
|
||||
pos+=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=WPR(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_low.MinValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]<m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]<m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_low.MinValue(pos-1,4,index);
|
||||
}
|
||||
else
|
||||
{
|
||||
//--- maximum of the oscillator is detected
|
||||
pos-=off;
|
||||
m_extr_pos[i]=pos;
|
||||
m_extr_osc[i]=WPR(pos);
|
||||
if(i>1)
|
||||
{
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-2,5,index);
|
||||
//--- form the intermediate bit-map
|
||||
map=0;
|
||||
if(m_extr_pr[i-2]>m_extr_pr[i])
|
||||
map+=1; // set bit 0
|
||||
if(m_extr_osc[i-2]>m_extr_osc[i])
|
||||
map+=4; // set bit 2
|
||||
//--- add the result
|
||||
m_extr_map+=map<<(4*(i-2));
|
||||
}
|
||||
else
|
||||
m_extr_pr[i]=m_high.MaxValue(pos-1,4,index);
|
||||
}
|
||||
}
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Comparing the bit-map of extremums with pattern. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalWPR::CompareMaps(int map,int count,bool minimax,int start)
|
||||
{
|
||||
int step =(minimax)?4:8;
|
||||
int total=step*(start+count);
|
||||
//--- check input parameters for a possible going out of range of the bit-map
|
||||
if(total>32)
|
||||
return(false);
|
||||
//--- bit-map of the patter is an "array" of 4-bit fields
|
||||
//--- each "element of the array" definitely describes the desired ratio
|
||||
//--- of current extremums of the oscillator and the price with previous ones
|
||||
//--- purpose of bits of an elements of the pattern of the bit-map pattern
|
||||
//--- bit 3 - is equal to if the ratio of extremums of the oscillator is insignificant for us
|
||||
//--- is equal to 0 if we want to "find" the ratio of extremums of the oscillator determined by the value of bit 2
|
||||
//--- bit 2 - is equal to 1 if we want to "discover" the situation when the current extremum of the "oscillator" is "more extreme" than the previous one
|
||||
//--- (current peak is higher or current valley is deeper)
|
||||
//--- is equal to 0 if we want to "discover" the situation when the current extremum of the oscillator is "less extreme" than the previous one
|
||||
//--- (current peak is lower or current valley is less deep)
|
||||
//--- bit 1 - is equal to 1 if the ratio of extremums is insignificant for us
|
||||
//--- it is equal to 0 if we want to "find" the ratio of price extremums determined by the value of bit 0
|
||||
//--- bit 0 - is equal to 1 if we want to "discover" the situation when the current price extremum is "more extreme" than the previous one
|
||||
//--- (current peak is higher or current valley is deeper)
|
||||
//--- it is equal to 0 if we want to "discover" the situation when the current price extremum is "less extreme" than the previous one
|
||||
//--- (current peak is lower or current valley is less deep)
|
||||
uint inp_map,check_map;
|
||||
int i,j;
|
||||
//--- loop by extremums (4 minimums and 4 maximums)
|
||||
//--- price and the oscillator are checked separately (thus, there are 16 checks)
|
||||
for(i=step*start,j=0;i<total;i+=step,j+=4)
|
||||
{
|
||||
//--- "take" two bits - patter of the corresponding extremum of the oscillator
|
||||
inp_map=(map>>i)&3;
|
||||
//--- if the higher-order bit=1, then any ratio is suitable for us
|
||||
if(inp_map<2)
|
||||
{
|
||||
//--- "take" two bits of the corresponding extremum of the oscillator (higher-order bit is always 0)
|
||||
check_map=(m_extr_map>>j)&3;
|
||||
if(inp_map!=check_map)
|
||||
return(false);
|
||||
}
|
||||
//--- "take" two bits - pattern of the corresponding price extremum
|
||||
inp_map=(map>>(i+2))&3;
|
||||
//--- if the higher-order bit=1, then any ratio is suitable for us
|
||||
if(inp_map>=2)
|
||||
continue;
|
||||
//--- "take" two bits of the corresponding price extremum (higher-order bit is always 0)
|
||||
check_map=(m_extr_map>>(j+2))&3;
|
||||
if(inp_map!=check_map)
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will grow. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalWPR::LongCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//---
|
||||
if(Diff(idx)>0.0)
|
||||
{
|
||||
//--- the oscillator is directed upwards confirming the possibility of price growth
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0; // "confirming" signal number 0
|
||||
//--- if the model 1 is used, search for a reverse of the oscillator upwards behind the level of overselling
|
||||
if(IS_PATTERN_USAGE(1) && Diff(idx+1)<0.0 && WPR(idx+1)>-80.0)
|
||||
result=m_pattern_1; // signal number 1
|
||||
//--- if the model 2 or 3 is used, search for the divergences
|
||||
if(IS_PATTERN_USAGE(2))
|
||||
{
|
||||
//--- perform the extended analysis of the oscillator state
|
||||
ExtState(idx);
|
||||
//--- if the model 2 is used, search for the "divergence" signal
|
||||
if(CompareMaps(1,1)) // 00000001b
|
||||
result=m_pattern_2; // signal number 2
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| "Voting" that price will fall. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSignalWPR::ShortCondition(void)
|
||||
{
|
||||
int result=0;
|
||||
int idx =StartIndex();
|
||||
//---
|
||||
if(Diff(idx)<0.0)
|
||||
{
|
||||
//--- the oscillator is directed downwards confirming the possibility of falling of price
|
||||
if(IS_PATTERN_USAGE(0))
|
||||
result=m_pattern_0; // "confirming" signal number 0
|
||||
//--- if the model 1 is used, search for a reverse of the oscillator downwards behind the level of overbuying
|
||||
if(IS_PATTERN_USAGE(1) && Diff(idx+1)>0.0 && WPR(idx+1)<-20.0)
|
||||
result=m_pattern_1; // signal number 1
|
||||
//--- if the model 2 or 3 is used, search for the divergences
|
||||
if(IS_PATTERN_USAGE(2))
|
||||
{
|
||||
//--- perform the extended analysis of the oscillator state
|
||||
ExtState(idx);
|
||||
//--- if the model 2 is used, search for the "divergence" signal
|
||||
if(CompareMaps(1,1)) // 00000001b
|
||||
result=m_pattern_2; // signal number 2
|
||||
}
|
||||
}
|
||||
//--- return the result
|
||||
return(result);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,278 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SuperTrendSignal.mqh |
|
||||
//| Copyright © 2011, Nikolay Kositsin |
|
||||
//| Khabarovsk, farria@mail.redcom.ru |
|
||||
//+------------------------------------------------------------------+
|
||||
#property copyright "Copyright © 2011, Nikolay Kositsin"
|
||||
#property link "farria@mail.redcom.ru"
|
||||
//+------------------------------------------------------------------+
|
||||
//| Included files |
|
||||
//+------------------------------------------------------------------+
|
||||
#property tester_indicator "SuperTrend.ex5"
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
//--- wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Declaration of constants |
|
||||
//+------------------------------------------------------------------+
|
||||
#define OPEN_LONG 80 // The constant for returning the buy command to the Expert Advisor
|
||||
#define OPEN_SHORT 80 // The constant for returning the sell command to the Expert Advisor
|
||||
#define CLOSE_LONG 40 // The constant for returning the command to close a long position to the Expert Advisor
|
||||
#define CLOSE_SHORT 40 // The constant for returning the command to close a short position to the Expert Advisor
|
||||
#define REVERSE_LONG 100 // The constant for returning the command to reverse a long position to the Expert Advisor
|
||||
#define REVERSE_SHORT 100 // The constant for returning the command to reverse a short position to the Expert Advisor
|
||||
#define NO_SIGNAL 0 // The constant for returning the absence of a signal to the Expert Advisor
|
||||
//+---------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=The signals based on SuperTrend indicator |
|
||||
//| Type=SignalAdvanced |
|
||||
//| Name=SuperTrend |
|
||||
//| Class=CSuperTrendSignal |
|
||||
//| Page= |
|
||||
//| Parameter=BuyPosOpen,bool,true,Permission to buy |
|
||||
//| Parameter=SellPosOpen,bool,true,Permission to sell |
|
||||
//| Parameter=BuyPosClose,bool,true,Permission to exit a long position |
|
||||
//| Parameter=SellPosClose,bool,true,Permission to exit a short position|
|
||||
//| Parameter=Ind_Timeframe,ENUM_TIMEFRAMES,PERIOD_H4,Timeframe |
|
||||
//| Parameter=CCIPeriod,uint,50, CCI indicator period |
|
||||
//| Parameter=ATRPeriod,uint,5,ATR indicator period |
|
||||
//| Parameter=Level,uint,0,CCI activation level |
|
||||
//| Parameter=SignalBar,uint,1,Bar index for entry signal |
|
||||
//+---------------------------------------------------------------------+
|
||||
//--- wizard description end
|
||||
//+---------------------------------------------------------------------+
|
||||
//| CSuperTrendSignal class. |
|
||||
//| Purpose: Class of generator of trade signals based on |
|
||||
//| SuperTrend indicator values http://www.mql5.com/ru/code/527/. |
|
||||
//| Is derived from the CExpertSignal class. |
|
||||
//+---------------------------------------------------------------------+
|
||||
class CSuperTrendSignal : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiCustom m_indicator; // the object for access to SuperTrend values
|
||||
|
||||
//--- adjusted parameters
|
||||
bool m_BuyPosOpen; // permission to buy
|
||||
bool m_SellPosOpen; // permission to sell
|
||||
bool m_BuyPosClose; // permission to exit a long position
|
||||
bool m_SellPosClose; // permission to exit a short position
|
||||
ENUM_TIMEFRAMES m_Ind_Timeframe; // indicator chart timeframe
|
||||
uint m_CCIPeriod; // CCI indicator period
|
||||
uint m_ATRPeriod; // ATR indicator period
|
||||
uint m_Level; // CCI activation level
|
||||
uint m_SignalBar; // bar index for getting entry signal
|
||||
|
||||
public:
|
||||
CSuperTrendSignal();
|
||||
|
||||
//--- methods of setting adjustable parameters
|
||||
void BuyPosOpen(bool value) { m_BuyPosOpen=value; }
|
||||
void SellPosOpen(bool value) { m_SellPosOpen=value; }
|
||||
void BuyPosClose(bool value) { m_BuyPosClose=value; }
|
||||
void SellPosClose(bool value) { m_SellPosClose=value; }
|
||||
//--- indicator input parameters
|
||||
void Ind_Timeframe(ENUM_TIMEFRAMES value) { m_Ind_Timeframe=value; }
|
||||
void CCIPeriod(uint value) { m_CCIPeriod=value; }
|
||||
void ATRPeriod(uint value) { m_ATRPeriod=value; }
|
||||
void Level(uint value) { m_Level=value; }
|
||||
//---
|
||||
void SignalBar(uint value) { m_SignalBar=value; }
|
||||
|
||||
//--- adjustable parameters validation method
|
||||
virtual bool ValidationSettings();
|
||||
//--- adjustable parameters validation method
|
||||
virtual bool InitIndicators(CIndicators *indicators); // indicators initialization
|
||||
//--- market entry signals generation method
|
||||
virtual int LongCondition();
|
||||
virtual int ShortCondition();
|
||||
|
||||
bool InitSuperTrend(CIndicators *indicators); // SuperTrend indicator initializing method
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| CSuperTrendSignal constructor. |
|
||||
//| INPUT: no. |
|
||||
//| OUTPUT: no. |
|
||||
//| REMARK: no. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CSuperTrendSignal::CSuperTrendSignal()
|
||||
{
|
||||
//--- setting default parameters
|
||||
m_BuyPosOpen=true;
|
||||
m_SellPosOpen=true;
|
||||
m_BuyPosClose=true;
|
||||
m_SellPosClose=true;
|
||||
|
||||
//--- indicator input parameters
|
||||
m_Ind_Timeframe=PERIOD_H4;
|
||||
m_CCIPeriod=50;
|
||||
m_ATRPeriod=5;
|
||||
m_Level=0;
|
||||
//---
|
||||
m_SignalBar=1;
|
||||
m_used_series=USE_SERIES_OPEN+USE_SERIES_HIGH+USE_SERIES_LOW+USE_SERIES_CLOSE;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Checking adjustable parameters. |
|
||||
//| INPUT: no. |
|
||||
//| OUTPUT: true if the settings are valid, false - if not. |
|
||||
//| REMARK: no. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSuperTrendSignal::ValidationSettings()
|
||||
{
|
||||
//--- checking parameters
|
||||
if(m_CCIPeriod<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": CCI indicator period must be greater than zero");
|
||||
return(false);
|
||||
}
|
||||
|
||||
if(m_ATRPeriod<=0)
|
||||
{
|
||||
printf(__FUNCTION__+": ATR indicator period must be greater than zero");
|
||||
return(false);
|
||||
}
|
||||
//--- successful completion
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Initialization of indicators and time series. |
|
||||
//| INPUT: indicators - pointer to an object-collection |
|
||||
//| of indicators and time series. |
|
||||
//| OUTPUT: true - in case of successful, otherwise - false. |
|
||||
//| REMARK: no. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSuperTrendSignal::InitIndicators(CIndicators *indicators)
|
||||
{
|
||||
//--- check of pointer
|
||||
if(indicators==NULL) return(false);
|
||||
|
||||
//--- indicator initialization
|
||||
if(!InitSuperTrend(indicators)) return(false);
|
||||
|
||||
//--- successful completion
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| SuperTrend indicator initialization. |
|
||||
//| INPUT: indicators - pointer to an object-collection |
|
||||
//| of indicators and time series. |
|
||||
//| OUTPUT: true - in case of successful, otherwise - false. |
|
||||
//| REMARK: no. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSuperTrendSignal::InitSuperTrend(CIndicators *indicators)
|
||||
{
|
||||
//--- check of pointer
|
||||
if(indicators==NULL) return(false);
|
||||
|
||||
//--- adding an object to the collection
|
||||
if(!indicators.Add(GetPointer(m_indicator)))
|
||||
{
|
||||
printf(__FUNCTION__+": error of adding the object");
|
||||
return(false);
|
||||
}
|
||||
|
||||
//--- setting the indicator parameters
|
||||
MqlParam parameters[5];
|
||||
|
||||
parameters[0].type=TYPE_STRING;
|
||||
parameters[0].string_value="SuperTrend.ex5";
|
||||
|
||||
parameters[1].type=TYPE_UINT;
|
||||
parameters[1].integer_value=m_CCIPeriod;
|
||||
|
||||
parameters[2].type=TYPE_UINT;
|
||||
parameters[2].integer_value=m_ATRPeriod;
|
||||
|
||||
parameters[3].type=TYPE_UINT;
|
||||
parameters[3].integer_value=m_Level;
|
||||
|
||||
parameters[4].type=TYPE_UINT;
|
||||
parameters[4].integer_value=m_Level;
|
||||
//---
|
||||
if(!m_indicator.Create(m_symbol.Name(),m_Ind_Timeframe,IND_CUSTOM,5,parameters))
|
||||
{
|
||||
printf(__FUNCTION__+": object initialization error");
|
||||
return(false);
|
||||
}
|
||||
|
||||
//--- number of buffers
|
||||
if(!m_indicator.NumBuffers(4)) return(false);
|
||||
|
||||
//--- SuperTrend indicator initialized successfully
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Checking conditions for opening a long position and |
|
||||
//| closing a short one |
|
||||
//| INPUT: no |
|
||||
//| OUTPUT: Vote weight from 0 to 100 |
|
||||
//| REMARK: no. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSuperTrendSignal::LongCondition()
|
||||
{
|
||||
//--- buy signal is determined by buffer 2 of the SuperTrend indicator
|
||||
double Signal=m_indicator.GetData(2,m_SignalBar);
|
||||
|
||||
//--- getting a trading signal
|
||||
if(Signal && Signal!=EMPTY_VALUE)
|
||||
{
|
||||
if(m_BuyPosOpen)
|
||||
{
|
||||
if(m_SellPosClose) return(REVERSE_SHORT);
|
||||
else return(OPEN_LONG);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_SellPosClose) return(CLOSE_SHORT);
|
||||
}
|
||||
}
|
||||
|
||||
//--- searching for signals for closing a short position
|
||||
if(!m_SellPosClose) return(NO_SIGNAL);
|
||||
|
||||
//--- trend signal is determined by buffer 0 of the SuperTrend indicator
|
||||
Signal=m_indicator.GetData(0,m_SignalBar);
|
||||
if(Signal && Signal!=EMPTY_VALUE) return(CLOSE_SHORT);
|
||||
|
||||
//--- no trading signal
|
||||
return(NO_SIGNAL);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Checking conditions for opening a short position and |
|
||||
//| closing a long one |
|
||||
//| INPUT: no |
|
||||
//| OUTPUT: Vote weight from 0 to 100 |
|
||||
//| REMARK: no. |
|
||||
//+------------------------------------------------------------------+
|
||||
int CSuperTrendSignal::ShortCondition()
|
||||
{
|
||||
//--- sell signal is determined by buffer 3 of the SuperTrend indicator
|
||||
double Signal=m_indicator.GetData(3,m_SignalBar);
|
||||
|
||||
//--- getting a trading signal
|
||||
if(Signal && Signal!=EMPTY_VALUE)
|
||||
{
|
||||
if(m_SellPosOpen)
|
||||
{
|
||||
if(m_BuyPosClose) return(REVERSE_LONG);
|
||||
else return(OPEN_SHORT);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_BuyPosClose) return(CLOSE_LONG);
|
||||
}
|
||||
}
|
||||
|
||||
//--- searching for signals for closing a short position
|
||||
if(!m_BuyPosClose) return(NO_SIGNAL);
|
||||
|
||||
//--- trend signal is determined by buffer 1 of the SuperTrend indicator
|
||||
Signal=m_indicator.GetData(1,m_SignalBar);
|
||||
if(Signal && Signal!=EMPTY_VALUE) return(CLOSE_LONG);
|
||||
|
||||
//--- no trading signal
|
||||
return(NO_SIGNAL);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
@@ -0,0 +1,246 @@
|
||||
//+------------------------------------------------------------------+
|
||||
//| SignalCrossEMA.mqh |
|
||||
//| Copyright © 2010, MetaQuotes Software Corp. |
|
||||
//| http://www.metaquotes.net |
|
||||
//| Revision 2010.10.12 |
|
||||
//+------------------------------------------------------------------+
|
||||
#include <Expert\ExpertSignal.mqh>
|
||||
// wizard description start
|
||||
//+------------------------------------------------------------------+
|
||||
//| Description of the class |
|
||||
//| Title=Signals based on crossover of two EMA |
|
||||
//| Type=Signal |
|
||||
//| Name=CrossEMA |
|
||||
//| Class=CSignalCrossEMA |
|
||||
//| Page= |
|
||||
//| Parameter=FastPeriod,int,12 |
|
||||
//| Parameter=SlowPeriod,int,24 |
|
||||
//+------------------------------------------------------------------+
|
||||
// wizard description end
|
||||
//+------------------------------------------------------------------+
|
||||
//| Class CSignalCrossEMA. |
|
||||
//| Appointment: Class trading signals cross two EMA. |
|
||||
//| Derives from class CExpertSignal. |
|
||||
//+------------------------------------------------------------------+
|
||||
class CSignalCrossEMA : public CExpertSignal
|
||||
{
|
||||
protected:
|
||||
CiMA *m_FastEMA;
|
||||
CiMA *m_SlowEMA;
|
||||
//--- input parameters
|
||||
int m_fast_period;
|
||||
int m_slow_period;
|
||||
|
||||
public:
|
||||
CSignalCrossEMA();
|
||||
~CSignalCrossEMA();
|
||||
//--- methods initialize protected data
|
||||
void FastPeriod(int period) { m_fast_period=period; }
|
||||
void SlowPeriod(int period) { m_slow_period=period; }
|
||||
virtual bool InitIndicators(CIndicators* indicators);
|
||||
virtual bool ValidationSettings();
|
||||
//---
|
||||
virtual bool CheckOpenLong(double& price,double& sl,double& tp,datetime& expiration);
|
||||
virtual bool CheckCloseLong(double& price);
|
||||
virtual bool CheckOpenShort(double& price,double& sl,double& tp,datetime& expiration);
|
||||
virtual bool CheckCloseShort(double& price);
|
||||
|
||||
protected:
|
||||
bool InitFastEMA(CIndicators* indicators);
|
||||
bool InitSlowEMA(CIndicators* indicators);
|
||||
//---
|
||||
double FastEMA(int ind) { return(m_FastEMA.Main(ind)); }
|
||||
double SlowEMA(int ind) { return(m_SlowEMA.Main(ind)); }
|
||||
double StateFastEMA(int ind) { return(FastEMA(ind)-FastEMA(ind+1)); }
|
||||
double StateSlowEMA(int ind) { return(SlowEMA(ind)-SlowEMA(ind+1)); }
|
||||
double StateEMA(int ind) { return(FastEMA(ind)-SlowEMA(ind)); }
|
||||
};
|
||||
//+------------------------------------------------------------------+
|
||||
//| Constructor CSignalCrossEMA. |
|
||||
//| INPUT: no. |
|
||||
//| OUTPUT: no. |
|
||||
//| REMARK: no. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CSignalCrossEMA::CSignalCrossEMA()
|
||||
{
|
||||
//--- initialize protected data
|
||||
m_FastEMA =NULL;
|
||||
m_SlowEMA =NULL;
|
||||
//--- set default inputs
|
||||
m_fast_period =12;
|
||||
m_slow_period =24;
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Destructor CSignalCrossEMA. |
|
||||
//| INPUT: no. |
|
||||
//| OUTPUT: no. |
|
||||
//| REMARK: no. |
|
||||
//+------------------------------------------------------------------+
|
||||
void CSignalCrossEMA::~CSignalCrossEMA()
|
||||
{
|
||||
//---
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Validation settings protected data. |
|
||||
//| INPUT: no. |
|
||||
//| OUTPUT: true-if settings are correct, false otherwise. |
|
||||
//| REMARK: no. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalCrossEMA::ValidationSettings()
|
||||
{
|
||||
if(m_fast_period>=m_slow_period)
|
||||
{
|
||||
printf(__FUNCTION__+": period of slow EMA must be greater than period of fast EMA");
|
||||
return(false);
|
||||
}
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create indicators. |
|
||||
//| INPUT: indicators -pointer of indicator collection. |
|
||||
//| OUTPUT: true-if successful, false otherwise. |
|
||||
//| REMARK: no. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalCrossEMA::InitIndicators(CIndicators* indicators)
|
||||
{
|
||||
//--- check
|
||||
if(indicators==NULL) return(false);
|
||||
//--- create and initialize fast EMA indicator
|
||||
if(!InitFastEMA(indicators)) return(false);
|
||||
//--- create and initialize slow EMA indicator
|
||||
if(!InitSlowEMA(indicators)) return(false);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create fast EMA indicators. |
|
||||
//| INPUT: indicators -pointer of indicator collection. |
|
||||
//| OUTPUT: true-if successful, false otherwise. |
|
||||
//| REMARK: no. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalCrossEMA::InitFastEMA(CIndicators* indicators)
|
||||
{
|
||||
//--- create fast EMA indicator
|
||||
if(m_FastEMA==NULL)
|
||||
if((m_FastEMA=new CiMA)==NULL)
|
||||
{
|
||||
printf(__FUNCTION__+": error creating object");
|
||||
return(false);
|
||||
}
|
||||
//--- add fast EMA indicator to collection
|
||||
if(!indicators.Add(m_FastEMA))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
delete m_FastEMA;
|
||||
return(false);
|
||||
}
|
||||
//--- initialize fast EMA indicator
|
||||
if(!m_FastEMA.Create(m_symbol.Name(),m_period,m_fast_period,0,MODE_EMA,PRICE_CLOSE))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
m_FastEMA.BufferResize(1000);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Create slow EMA indicators. |
|
||||
//| INPUT: indicators -pointer of indicator collection. |
|
||||
//| OUTPUT: true-if successful, false otherwise. |
|
||||
//| REMARK: no. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalCrossEMA::InitSlowEMA(CIndicators* indicators)
|
||||
{
|
||||
//--- create slow EMA indicator
|
||||
if(m_SlowEMA==NULL)
|
||||
if((m_SlowEMA=new CiMA)==NULL)
|
||||
{
|
||||
printf(__FUNCTION__+": error creating object");
|
||||
return(false);
|
||||
}
|
||||
//--- add slow EMA indicator to collection
|
||||
if(!indicators.Add(m_SlowEMA))
|
||||
{
|
||||
printf(__FUNCTION__+": error adding object");
|
||||
delete m_SlowEMA;
|
||||
return(false);
|
||||
}
|
||||
//--- initialize slow EMA indicator
|
||||
if(!m_SlowEMA.Create(m_symbol.Name(),m_period,m_slow_period,0,MODE_EMA,PRICE_CLOSE))
|
||||
{
|
||||
printf(__FUNCTION__+": error initializing object");
|
||||
return(false);
|
||||
}
|
||||
m_SlowEMA.BufferResize(1000);
|
||||
//--- ok
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check conditions for long position open. |
|
||||
//| INPUT: price - refernce for price, |
|
||||
//| sl - refernce for stop loss, |
|
||||
//| tp - refernce for take profit, |
|
||||
//| expiration - refernce for expiration. |
|
||||
//| OUTPUT: true-if condition performed, false otherwise. |
|
||||
//| REMARK: no. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalCrossEMA::CheckOpenLong(double& price,double& sl,double& tp,datetime& expiration)
|
||||
{
|
||||
if(!(StateEMA(2)<0 && StateEMA(1)>0)) return(false);
|
||||
//---
|
||||
price=0.0;
|
||||
sl =0.0;
|
||||
tp =0.0;
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check conditions for long position close. |
|
||||
//| INPUT: price - refernce for price. |
|
||||
//| OUTPUT: true-if condition performed, false otherwise. |
|
||||
//| REMARK: no. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalCrossEMA::CheckCloseLong(double& price)
|
||||
{
|
||||
if(!(StateEMA(2)>0 && StateEMA(1)<0)) return(false);
|
||||
//---
|
||||
price=0.0;
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check conditions for short position open. |
|
||||
//| INPUT: price - refernce for price, |
|
||||
//| sl - refernce for stop loss, |
|
||||
//| tp - refernce for take profit, |
|
||||
//| expiration - refernce for expiration. |
|
||||
//| OUTPUT: true-if condition performed, false otherwise. |
|
||||
//| REMARK: no. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalCrossEMA::CheckOpenShort(double& price,double& sl,double& tp,datetime& expiration)
|
||||
{
|
||||
if(!(StateEMA(2)>0 && StateEMA(1)<0)) return(false);
|
||||
//---
|
||||
price=0.0;
|
||||
sl =0.0;
|
||||
tp =0.0;
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
//| Check conditions for short position close. |
|
||||
//| INPUT: price - refernce for price. |
|
||||
//| OUTPUT: true-if condition performed, false otherwise. |
|
||||
//| REMARK: no. |
|
||||
//+------------------------------------------------------------------+
|
||||
bool CSignalCrossEMA::CheckCloseShort(double& price)
|
||||
{
|
||||
if(!(StateEMA(2)<0 && StateEMA(1)>0)) return(false);
|
||||
//---
|
||||
price=0.0;
|
||||
//---
|
||||
return(true);
|
||||
}
|
||||
//+------------------------------------------------------------------+
|
||||
Reference in New Issue
Block a user