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