//+------------------------------------------------------------------+ //| 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 #include #include #include #include #include #include #include #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); } //+------------------------------------------------------------------+