Discussion of article "Universal Expert Advisor: Integration with Standard MetaTrader Modules of Signals (Part 7)"
Thank Vasiliy for your contribution. I learned a lot. I downloaded all the code but it has a compiling error in file Panel.mqh:
'At' - object pointer expected Panel.mqh 210 39
'At' - object pointer expected Panel.mqh 228 37
Can you please check it?
Hi Amy. I have just completed reading through Vasiliy Sokolov articles. If you are still interested in finding out the solution. Please post the error log here. I recall coming across that error and realised that there is an ".\Panel\Panel.mqh" in declarations in StrategiesList file. Panel.mqh does not exist. Instead, try going to https://www.mql5.com/en/articles/2411 and download the Panel File from there. I believe it has the Panel.mqh file.
This series by Vasiliy's is really good as a framework. I learn't a lot too,but when there are issues with a library, if the author does not offer support, you could be left stuck if you are not a good programmer. Which is the point Alain Verleyen made in your other discussions. But those spending time to share their knowledge and skill here are completely amazing. I am eternally grateful.
- 2016.06.16
- Vasiliy Sokolov
- www.mql5.com
Hi, Vasily.
Thanks for all of your articles.
The Universal Expert Advisor is really impressive in terms of complexity and Software architecture.
For this particular version, I'd like to raise a point in this piece of code here:
CAdapterMACD::CAdapterMACD(void) { m_params.symbol = Symbol(); m_params.period = Period(); m_params.every_tick = false; m_params.signal_type = SIGNAL_MACD; m_params.magic = 1234; m_params.point = 1.0; m_params.usage_pattern = 2; CSignalMACD* macd = m_signal.CreateSignal(m_params); macd.PeriodFast(15); macd.PeriodSlow(32); macd.PeriodSignal(6); }
Actually, the MacD parameters (15, 32 and 6) are taking no effect here, since CreateSignal() method initializes the MacD signal before the params are updated.
In this case, I'd suggest to split the CSignalAdapter::CreateSignal() method in two parts, where in the first one, the signal is in fact created and returned just like it is, and the second part would be the signal initialization, after all "Signal Dependant" parameters (in this case, PeriodFast, PeriodSlow and PeriodSignal) are set:
CExpertSignal* CSignalAdapter::CreateSignal(MqlSignalParams& params) { DeleteSignal(); switch(params.signal_type) { case SIGNAL_AO: m_signal = new CSignalAO(); break; case SIGNAL_AC: m_signal = new CSignalAC(); break; case SIGNAL_ADAPTIVE_MA: m_signal = new CSignalAMA(); break; case SIGNAL_CCI: m_signal = new CSignalCCI(); break; case SIGNAL_DeMARKER: m_signal = new CSignalDeM(); break; case SIGNAL_DOUBLE_EMA: m_signal = new CSignalDEMA(); break; case SIGNAL_ENVELOPES: m_signal = new CSignalEnvelopes(); break; case SIGNAL_FRAMA: m_signal = new CSignalFrAMA(); break; case SIGNAL_MA: m_signal = new CSignalMA(); break; case SIGNAL_MACD: m_signal = new CSignalMACD(); break; case SIGNAL_PARABOLIC_SAR: m_signal = new CSignalSAR(); break; case SIGNAL_RSI: m_signal = new CSignalRSI(); break; case SIGNAL_RVI: m_signal = new CSignalRVI(); break; case SIGNAL_STOCHASTIC: m_signal = new CSignalStoch(); break; case SIGNAL_TRIPLE_EA: m_signal = new CSignalTriX(); break; case SIGNAL_TRIPLE_EMA: m_signal = new CSignalTEMA(); break; case SIGNAL_WILLIAMS_PER_RANGE: m_signal = new CSignalWPR(); break; } if(CheckPointer(m_signal)!= POINTER_INVALID) m_params = params; return m_signal; } bool CSignalAdapter::Init() { if(m_params.symbol == "") /* CreateSignal method should be called first in order to update m_params */ return false; m_info.Name(m_params.symbol); if(!m_signal.Init(GetPointer(m_info), m_params.period, m_params.point)) return false; if(!m_signal.InitIndicators(GetPointer(m_indicators))) return false; m_signal.EveryTick(m_params.every_tick); m_signal.Magic(m_params.magic); m_open.Create(m_params.symbol, m_params.period); m_high.Create(m_params.symbol, m_params.period); m_low.Create(m_params.symbol, m_params.period); m_close.Create(m_params.symbol, m_params.period); m_times.Create(m_params.symbol, m_params.period); m_spread.Create(m_params.symbol, m_params.period); m_tik_vol.Create(m_params.symbol, m_params.period); m_real_vol.Create(m_params.symbol, m_params.period); m_signal.SetPriceSeries(GetPointer(m_open), GetPointer(m_high), GetPointer(m_low), GetPointer(m_close)); //m_signal.SetOtherSeries(GetPointer(m_spread), GetPointer(m_times), GetPointer(m_tik_vol), GetPointer(m_real_vol)); int mask = 1; mask = mask << m_params.usage_pattern; m_signal.PatternsUsage(mask); return true; }
And of course, the newly created Init method needs to be called:
CAdapterMACD::CAdapterMACD(void) { m_params.symbol = Symbol(); m_params.period = Period(); m_params.every_tick = false; m_params.signal_type = SIGNAL_MACD; m_params.magic = 1234; m_params.point = 1.0; m_params.usage_pattern = 2; CSignalMACD* macd = m_signal.CreateSignal(m_params); macd.PeriodFast(15); macd.PeriodSlow(32); macd.PeriodSignal(6); m_signal.Init(); /* This call is going to create the CSignalMACD object with the custom parameters */ }
Thank you for the great work, and even more for sharing it, Vasily!
Cheers,
Rodrigo Haller
How it is possible to use class CSignalMACD in script?
I've tried to get signal result just inplace, but always got 0:
void OnStart() { CSignalMACD m_signal_macd; CSymbolInfo m_info; CiOpen m_open; CiHigh m_high; CiLow m_low; CiClose m_close; CIndicators m_indicators; m_signal_macd.Pattern_0(0); m_signal_macd.Pattern_1(0); m_signal_macd.Pattern_2(0); m_signal_macd.Pattern_3(100); m_signal_macd.Pattern_4(0); m_signal_macd.Pattern_5(0); m_info.Name(Symbol()); // Initializing the object that represents the trading symbol of the strategy m_signal_macd.Init(GetPointer(m_info), Period(), 10); // Initializing the signal module by the trading symbol and timeframe m_signal_macd.InitIndicators(GetPointer(m_indicators)); // creating required indicators in the signal module based on the empty list of indicators m_indicators //m_signal_macd.EveryTick(true); // Testing mode m_signal_macd.Magic(42); // Magic number m_signal_macd.PatternsUsage(8); // Pattern mask m_open.Create(Symbol(), Period()); // Initializing the timeseries of Open prices m_high.Create(Symbol(), Period()); // Initializing the timeseries of High prices m_low.Create(Symbol(), Period()); // Initializing the timeseries of Low prices m_close.Create(Symbol(), Period()); // Initializing the timeseries of Close prices m_signal_macd.SetPriceSeries(GetPointer(m_open), // Initializing the signal module by timeseries objects GetPointer(m_high), GetPointer(m_low), GetPointer(m_close)); m_indicators.Refresh(); m_signal_macd.SetDirection(); int power_sell = m_signal_macd.ShortCondition(); int power_buy = m_signal_macd.LongCondition(); printf("PowerSell: " + (string)power_sell + " PowerBuy: " + (string)power_buy); }
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use
New article Universal Expert Advisor: Integration with Standard MetaTrader Modules of Signals (Part 7) has been published:
This part of the article describes the possibilities of the CStrategy engine integration with the signal modules included into the standard library in MetaTrader. The article describes how to work with signals, as well as how to create custom strategies on their basis.
The below diagram shows the general scheme of vertical inheritance of classes used in the process of automatic generation of strategies:
Fig. 1. Inheritance of standard classes of the strategy generator
The figure only shows basic and some derived classes. The scheme does not feature all indicators inherited from CIndicators. Separate trailing, money management and signal modules are not included into the scheme. Instead, only the basic relationships are outlined. One of the featured groups is of interest to us: the signal classes CExpertSignal and its child classes. In Figure 1, the group is highlighted by a green dotted line.
Author: Vasiliy Sokolov