//+------------------------------------------------------------------+ //| StrategiesList.mqh | //| Copyright 2016, Vasiliy Sokolov, St-Petersburg, Russia | //| https://www.mql5.com/en/users/c-4 | //+------------------------------------------------------------------+ #property copyright "Copyright 2016, Vasiliy Sokolov." #property link "https://www.mql5.com/en/users/c-4" #ifdef SHOW_BASE_SETTINGS input string StrategiesXMLFile="Strategies.xml"; // Upload strategies from the file input bool LoadOnlyCurrentSymbol=false; // Upload only for the current symbol #endif #include #include "Strategy.mqh" #include "StrategyParamsBase.mqh" #include "EquityListener.mqh" #include ".\Panel\Panel.mqh" #include "RSquare.mqh" #include "Panel\Events\EventChartListChanged.mqh" //+------------------------------------------------------------------+ //| Determines the type of custom criterion calculated after         | //| optimization. | //+------------------------------------------------------------------+ enum ENUM_CUSTOM_TYPE { CUSTOM_NONE, // Custom criterion is not calculated CUSTOM_R2_BALANCE, // R^2 based on the strategy balance CUSTOM_R2_EQUITY, // R^2 based on the strategy equity }; //+------------------------------------------------------------------+ //| Container class to manage strategies of the CStrategy type | //+------------------------------------------------------------------+ class CStrategyList { private: CEquityListener m_equity_exp; CLog* Log; // Logging CArrayObj m_strategies; // Strategies of the CStrategy type ENUM_CUSTOM_TYPE m_custom_type; // Custom optimization criterion ENUM_CORR_TYPE m_corr_type; // Type of correlation for R^2 void ParseStrategies(CXmlElement *xmlStrategies,bool load_curr_symbol); void ParseLimits(CXmlElement *xmlLimits); CStrBtn StrButton; void AddEquityExpert(ENUM_TIMEFRAMES tf, string symbol); public: CStrategyList(void); ~CStrategyList(void); void LoadStrategiesFromXML(string xml_name,bool load_curr_symbol); bool AddStrategy(CStrategy *strategy); int Total(); void Clear(); void SetCustomOptimizeR2Balance(ENUM_CORR_TYPE corr_type); void SetCustomOptimizeR2Equity(ENUM_CORR_TYPE corr_type); CStrategy *At(int index); void OnTick(); void OnTimer(); void OnBookEvent(string symbol); void OnDeinit(const int reason); double OnTester(void); void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam); }; //+------------------------------------------------------------------+ //| Default constructor. | //+------------------------------------------------------------------+ CStrategyList::CStrategyList(void) : StrButton(GetPointer(this)) { Log=CLog::GetLog(); StrButton.Show(); m_strategies.Sort(0); m_corr_type = CORR_PEARSON; m_custom_type = CUSTOM_R2_EQUITY; } //+------------------------------------------------------------------+ //| Note: this is the only place where CLog is deleted. In other | //| places no need to delete it. | //+------------------------------------------------------------------+ CStrategyList::~CStrategyList(void) { CLog::DeleteLog(); } //+------------------------------------------------------------------+ //| Clear the list of strategies | //+------------------------------------------------------------------+ CStrategyList::Clear(void) { m_strategies.Clear(); } //+------------------------------------------------------------------+ //| Sets R^2 as the optimization criterion. The coeffi cient is      | //| calculated for the trades made.        | //+------------------------------------------------------------------+ void CStrategyList::SetCustomOptimizeR2Balance(ENUM_CORR_TYPE corr_type) { m_custom_type = CUSTOM_R2_BALANCE; m_corr_type = corr_type; } //+------------------------------------------------------------------+ //| Sets R^2 as the optimization criterion. The coefficient is      | //| calculated based on the recorded equity. | //+------------------------------------------------------------------+ void CStrategyList::SetCustomOptimizeR2Equity(ENUM_CORR_TYPE corr_type) { m_custom_type = CUSTOM_R2_EQUITY; m_corr_type = corr_type; } //+------------------------------------------------------------------+ //| Sends the OnTick event to all listed strategies | //+------------------------------------------------------------------+ void CStrategyList::OnTick(void) { for(int i=0; i PERIOD_H1) m_equity_exp.Timeframe(tf); else m_equity_exp.Timeframe(PERIOD_H1); m_equity_exp.ExpertSymbol(symbol); m_equity_exp.ExpertMagic(1029384); m_equity_exp.ExpertName("Equity Listener Expert"); m_strategies.InsertSort(&m_equity_exp); } //+------------------------------------------------------------------+ //| Adds monitoring of equity                                        | //+------------------------------------------------------------------+ double CStrategyList::OnTester(void) { switch(m_custom_type) { case CUSTOM_NONE: return 0.0; case CUSTOM_R2_BALANCE: return CustomR2Balance(m_corr_type); case CUSTOM_R2_EQUITY: { double equity[]; m_equity_exp.GetEquityArray(equity); int total = ArrayResize(equity, ArraySize(equity)+1); equity[total-1] = AccountInfoDouble(ACCOUNT_EQUITY); return CustomR2Equity(equity, m_corr_type); } } return 0.0; } //+------------------------------------------------------------------+ //| Loads strategies from the passed XML file "xml_name" | //| If the load_curr_symbol flag is set to true, it will only load | //| the strategies in which symbol corresponds to the current | //| symbol CurrentSymbol() | //+------------------------------------------------------------------+ void CStrategyList::LoadStrategiesFromXML(string xml_name,bool load_curr_symbol) { CXmlDocument doc; string err; bool res=doc.CreateFromFile(xml_name,err); if(!res) printf(err); CXmlElement *global=GetPointer(doc.FDocumentElement); for(int i=0; i