Add files via upload

This commit is contained in:
amirghadiri1987
2025-02-07 19:08:31 +03:30
committed by GitHub
parent c33ac55f2f
commit a9340e5d4e
85 changed files with 15214 additions and 0 deletions
+173
View File
@@ -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);
}
//+------------------------------------------------------------------+
+265
View File
@@ -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);
}
//+------------------------------------------------------------------+
+339
View File
@@ -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);
}
//+------------------------------------------------------------------+
+289
View File
@@ -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);
}
//+------------------------------------------------------------------+
+289
View File
@@ -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);
}
//+------------------------------------------------------------------+
+382
View File
@@ -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);
}
//+------------------------------------------------------------------+
+257
View File
@@ -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);
}
//+------------------------------------------------------------------+
+378
View File
@@ -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);
}
//+------------------------------------------------------------------+
+193
View File
@@ -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);
}
//+------------------------------------------------------------------+
+257
View File
@@ -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);
}
//+------------------------------------------------------------------+
+91
View File
@@ -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);
}
//+------------------------------------------------------------------+
+261
View File
@@ -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);
}
//+------------------------------------------------------------------+
+408
View File
@@ -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);
}
//+------------------------------------------------------------------+
+400
View File
@@ -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);
}
//+------------------------------------------------------------------+
+180
View File
@@ -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);
}
//+------------------------------------------------------------------+
+168
View File
@@ -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);
}
//+------------------------------------------------------------------+
+426
View File
@@ -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);
}
//+------------------------------------------------------------------+
+257
View File
@@ -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);
}
//+------------------------------------------------------------------+
+395
View File
@@ -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);
}
//+------------------------------------------------------------------+
+371
View File
@@ -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);
}
//+------------------------------------------------------------------+
+246
View File
@@ -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);
}
//+------------------------------------------------------------------+