338 lines
27 KiB
MQL5
338 lines
27 KiB
MQL5
//+------------------------------------------------------------------+
|
|
//| EngineBase.mqh |
|
|
//| Copyright 2023 - Dev.Solve LTDA |
|
|
//+------------------------------------------------------------------+
|
|
#property copyright "Copyright 2023 - Dev.Solve LTDA"
|
|
#property version "1.00"
|
|
//+------------------------------------------------------------------+
|
|
//| Macro definitions. |
|
|
//+------------------------------------------------------------------+
|
|
#include "ExpertError.mqh"
|
|
//+------------------------------------------------------------------+
|
|
//| Includes. |
|
|
//+------------------------------------------------------------------+
|
|
#include <Trade\Trade.mqh>
|
|
#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>
|
|
#include "Enum.mqh"
|
|
#include "ExpertFilter.mqh"
|
|
//--- 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(...))
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| Class CEngineBase. |
|
|
//| Purpose: Base class of component of Expert Advisor. |
|
|
//| Derives from class CObject. |
|
|
//+------------------------------------------------------------------+
|
|
class CEngineBase
|
|
{
|
|
protected:
|
|
//--- global variables
|
|
ENUM_TIMEFRAMES m_period; // timeframe
|
|
CSymbolInfo *m_symbol; // symbol info object
|
|
string m_other_ticker; // ticker para cáclulo de indicadores (vazio = vigente)
|
|
ENUM_INIT_PHASE m_init_phase; // the phase (stage) of initialization of object
|
|
ulong m_magic; // magic
|
|
ENUM_ACCOUNT_MARGIN_MODE m_margin_mode; // netting or hedging
|
|
double m_adjusted_point; // "weight" 2/4 of a point
|
|
bool m_every_tick; // flag of starting the analysis from current (incomplete) bar
|
|
ENUM_TYPE_OPERATION m_type_operation; // type operation (byu and sell) (only buy) (only sell)
|
|
CIndicators m_indicators; // indicator collection to fast recalculations
|
|
CExpertFilter m_filters; // filters collection
|
|
ENUM_TYPE_DIRECTION m_direction; // direction of the strategy
|
|
double m_ticksize; // tick size of the current symbol
|
|
|
|
|
|
public:
|
|
CEngineBase();
|
|
~CEngineBase();
|
|
|
|
|
|
void EveryTick(bool value) { m_every_tick=value; };
|
|
//--- methods of initialization of the object
|
|
virtual bool Init(CSymbolInfo *symbol,ENUM_TIMEFRAMES period,double point,ulong magic,string other_ticket,ENUM_TYPE_OPERATION operation,ENUM_TYPE_DIRECTION direction);
|
|
void Magic(ulong value) { m_magic=value; };
|
|
bool Period(ENUM_TIMEFRAMES value);
|
|
ENUM_TIMEFRAMES GetPeriod(void) { return(m_period); };
|
|
void SetMarginMode(void) { m_margin_mode=(ENUM_ACCOUNT_MARGIN_MODE)AccountInfoInteger(ACCOUNT_MARGIN_MODE); };
|
|
void SetOtherTicker(string value) { m_other_ticker=value; };
|
|
string GetOtherTicker(void) const { return(m_other_ticker); };
|
|
void SetTypeOperation(ENUM_TYPE_OPERATION value) { m_type_operation=value; };
|
|
int GetTypeOperation(void) const { return(m_type_operation); };
|
|
void SetTypeDirection(ENUM_TYPE_DIRECTION value) { m_direction=value; };
|
|
//---
|
|
virtual bool IsNewBar(void);
|
|
virtual bool IsNewBar(bool flag);
|
|
virtual bool IsNewBar(ENUM_TIMEFRAMES period);
|
|
virtual bool IsNewDay(void);
|
|
//--- method of verification of settings
|
|
virtual bool ValidationSettings(void);
|
|
//--- method of creating the collection filters
|
|
virtual bool InitFilters(CExpertFilter *_filters);
|
|
//--- methods of creating the indicator and timeseries
|
|
virtual bool InitIndicators(CIndicators *indicators=NULL);
|
|
|
|
protected:
|
|
//--- deinit
|
|
void DeInit(void);
|
|
};
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
CEngineBase::CEngineBase() : m_magic(0),
|
|
m_margin_mode(ACCOUNT_MARGIN_MODE_RETAIL_NETTING),
|
|
m_init_phase(INIT_PHASE_FIRST),
|
|
m_adjusted_point(1.0),
|
|
m_every_tick(false)
|
|
{
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| |
|
|
//+------------------------------------------------------------------+
|
|
CEngineBase::~CEngineBase()
|
|
{
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Initialization of object. |
|
|
//+------------------------------------------------------------------+
|
|
bool CEngineBase::Init(CSymbolInfo *symbol,ENUM_TIMEFRAMES period,double point,ulong magic,string other_ticket,ENUM_TYPE_OPERATION operation,ENUM_TYPE_DIRECTION direction)
|
|
{
|
|
//--- check init 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_ticksize =m_symbol.TickSize();
|
|
SetMarginMode();
|
|
m_magic =magic;
|
|
m_other_ticker =other_ticket;
|
|
m_type_operation=operation;
|
|
m_direction =direction;
|
|
//--- primary initialization is successful, pass to the phase of tuning
|
|
m_init_phase=INIT_PHASE_TUNING;
|
|
//--- ok
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Validation Settings |
|
|
//+------------------------------------------------------------------+
|
|
bool CEngineBase::ValidationSettings(void)
|
|
{
|
|
//--- 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, pass to the phase of validation
|
|
m_init_phase=INIT_PHASE_VALIDATION;
|
|
//--- ok
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Changing work timeframe. |
|
|
//+------------------------------------------------------------------+
|
|
bool CEngineBase::Period(ENUM_TIMEFRAMES value)
|
|
{
|
|
//--- check the initialization phase
|
|
if(m_init_phase!=INIT_PHASE_TUNING)
|
|
{
|
|
Print(__FUNCTION__+" Erro: é proibida a mudança de Time Frame nessa fase.");
|
|
return(false);
|
|
}
|
|
//--- update period
|
|
if(value==PERIOD_CURRENT)
|
|
value=::Period();
|
|
//---
|
|
if(m_period==value)
|
|
return(true);
|
|
//--- change work timeframe
|
|
m_period=value;
|
|
//--- ok
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Initialization of filters. |
|
|
//+------------------------------------------------------------------+
|
|
bool CEngineBase::InitFilters(CExpertFilter *_filters)
|
|
{
|
|
//--- check the initialization phase
|
|
if(m_init_phase!=INIT_PHASE_VALIDATION)
|
|
{
|
|
Print(__FUNCTION__+": parameters of setting are not checked");
|
|
return(false);
|
|
}
|
|
//--- check pointers
|
|
if(_filters==NULL)
|
|
return(false);
|
|
//---
|
|
m_filters=_filters;
|
|
//--- ok
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Initialization of indicators and timeseries. |
|
|
//+------------------------------------------------------------------+
|
|
bool CEngineBase::InitIndicators(CIndicators *indicators)
|
|
{
|
|
//--- check the initialization phase
|
|
if(m_init_phase!=INIT_PHASE_VALIDATION)
|
|
{
|
|
Print(__FUNCTION__+": parameters of setting are not checked");
|
|
return(false);
|
|
}
|
|
//--- check pointers
|
|
if(m_symbol==NULL)
|
|
return(false);
|
|
if(indicators==NULL)
|
|
return(false);
|
|
//--- now it's impossible to change anything in the settings
|
|
m_init_phase=INIT_PHASE_COMPLETE;
|
|
//--- ok
|
|
return(true);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| De Init |
|
|
//+------------------------------------------------------------------+
|
|
void CEngineBase::DeInit(void)
|
|
{
|
|
//--- delete symbol object
|
|
if(m_symbol!=NULL)
|
|
{
|
|
delete m_symbol;
|
|
m_symbol=NULL;
|
|
}
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Verify is New Day |
|
|
//+------------------------------------------------------------------+
|
|
bool CEngineBase::IsNewDay(void)
|
|
{
|
|
//--- reset last price
|
|
MqlDateTime time;
|
|
TimeToStruct(TimeLocal(),time);
|
|
static int current_day=0;
|
|
//--- first call
|
|
if(current_day==0)
|
|
{
|
|
current_day=time.day;
|
|
return(true);
|
|
}
|
|
//--- reset status if is new day
|
|
if(current_day!=time.day)
|
|
{
|
|
current_day=time.day;
|
|
return(true);
|
|
}
|
|
return(false);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Verify is New Bar |
|
|
//+------------------------------------------------------------------+
|
|
bool CEngineBase::IsNewBar(void)
|
|
{
|
|
//--- memorize the time of opening of the last bar in the static variable
|
|
static datetime last_time=0;
|
|
//--- current time
|
|
datetime lastbar_time=(datetime)SeriesInfoInteger(m_symbol.Name(),m_period,SERIES_LASTBAR_DATE);
|
|
//--- if it is the first call of the function
|
|
if(last_time==0)
|
|
{
|
|
//--- set the time and exit
|
|
last_time=lastbar_time;
|
|
return(true);
|
|
}
|
|
//--- if the time differs
|
|
if(last_time!=lastbar_time)
|
|
{
|
|
//--- memorize the time and return true
|
|
last_time=lastbar_time;
|
|
return(true);
|
|
}
|
|
//--- if we passed to this line, then the bar is not new; return false
|
|
return(false);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Verify is New Bar by Flag |
|
|
//+------------------------------------------------------------------+
|
|
bool CEngineBase::IsNewBar(bool flag)
|
|
{
|
|
//--- execute logic if flag is false
|
|
if(!flag)
|
|
{
|
|
//--- memorize the time of opening of the last bar in the static variable
|
|
static datetime last_time=0;
|
|
//--- current time
|
|
datetime lastbar_time=(datetime)SeriesInfoInteger(m_symbol.Name(),m_period,SERIES_LASTBAR_DATE);
|
|
//--- if it is the first call of the function
|
|
if(last_time==0)
|
|
{
|
|
//--- set the time and exit
|
|
last_time=lastbar_time;
|
|
return(true);
|
|
}
|
|
//--- if the time differs
|
|
if(last_time!=lastbar_time)
|
|
{
|
|
//--- memorize the time and return true
|
|
last_time=lastbar_time;
|
|
return(true);
|
|
}
|
|
//--- if we passed to this line, then the bar is not new; return false
|
|
return(false);
|
|
}
|
|
else
|
|
return(flag);
|
|
}
|
|
//+------------------------------------------------------------------+
|
|
//| Verify is New Bar |
|
|
//+------------------------------------------------------------------+
|
|
bool CEngineBase::IsNewBar(ENUM_TIMEFRAMES period)
|
|
{
|
|
//--- memorize the time of opening of the last bar in the static variable
|
|
static datetime last_time=0;
|
|
//--- current time
|
|
datetime lastbar_time=(datetime)SeriesInfoInteger(m_symbol.Name(),period,SERIES_LASTBAR_DATE);
|
|
|
|
//--- if it is the first call of the function
|
|
if(last_time==0)
|
|
{
|
|
//--- set the time and exit
|
|
last_time=lastbar_time;
|
|
return(true);
|
|
}
|
|
//--- if the time differs
|
|
if(last_time!=lastbar_time)
|
|
{
|
|
//--- memorize the time and return true
|
|
last_time=lastbar_time;
|
|
return(true);
|
|
}
|
|
//--- if we passed to this line, then the bar is not new; return false
|
|
return(false);
|
|
}
|
|
//+------------------------------------------------------------------+
|