Discussion of article "Cross-Platform Expert Advisor: Signals" - page 2

 

Thanks Enrico,

I'm trying to understand if I can use a signal as an additional filter to another signal...

For example I have a main signal and it gives entry signal Long. Then the second signal is checked. And if it also gives long the total signal would be long. But if the second signal gives Long but the first one is neutral the total signal must be neutral either since the 2nd signal is just an additional filter to the 1st signal and it is not entry signal by itself.

Also, is there any way to control money management basing on specific signal. For example with that signal lot would be 1, with another signal lot would be 2 and so on. In connection to my first question, default lot would be for 1st signal but in case there is a confirmation from the 2nd signal the lot would be doubled for example.

Thanks.

 
mbjen:

I'm trying to understand if I can use a signal as an additional filter to another signal...

For example I have a main signal and it gives entry signal Long. Then the second signal is checked. And if it also gives long the total signal would be long. But if the second signal gives Long but the first one is neutral the total signal must be neutral either since the 2nd signal is just an additional filter to the 1st signal and it is not entry signal by itself.

It is possible. The most straightforward way is to combine the two signals in a single instance of the CSignal descendant. You may also create an instance of CSignals within the CSignal descendant, and have the sub-filters modify the parent signal accordingly.

mbjen:

Also, is there any way to control money management basing on specific signal. For example with that signal lot would be 1, with another signal lot would be 2 and so on. In connection to my first question, default lot would be for 1st signal but in case there is a confirmation from the 2nd signal the lot would be doubled for example.

Yes, this is possible. The container of the CSignals instance is an instance of CExpertAdvisor, while each CSignal instance has the same instance of CSignals as its parent. You just need to keep getting the parent/container until you get to the CExpertAdvisor instance, get the pointer to its money manager, and then assign the desired money management method by index or name.

 
Enrico Lambino:

It is possible. The most straightforward way is to combine the two signals in a single instance of the CSignal descendant. You may also create an instance of CSignals within the CSignal descendant, and have the sub-filters modify the parent signal accordingly.

Yes, this is possible. The container of the CSignals instance is an instance of CExpertAdvisor, while each CSignal instance has the same instance of CSignals as its parent. You just need to keep getting the parent/container until you get to the CExpertAdvisor instance, get the pointer to its money manager, and then assign the desired money management method by index or name.


Thanks Enrico, I will try that.

 

I have just started out to use the cross platfrom EA framework.

I applied TEMA and MA indicators into a combined SignalTEMA_MA. The Calculate and the LongCondition and ShortCondition as below. I've attached the EA code also.


bool SignalTEMA_MA::Calculate(void)
{
   int   tema_ma_state_current=0;
   bool  ret;
   
   if(m_ma.Main(m_signal_bar) >= m_tema.Main(m_signal_bar))
      tema_ma_state_current = 1;
   else
      tema_ma_state_current = -1;

   if (m_tema_ma_state != tema_ma_state_current) {
      ret = m_tema_ma_state == 0 ? false : true;
      m_tema_ma_state = tema_ma_state_current;
   }
   else {
      ret = false;
   }
   return ret;      
}

bool SignalTEMA_MA::LongCondition(void)
  {
   return m_tema.Main(m_signal_bar) > m_ma.Main(m_signal_bar);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool SignalTEMA_MA::ShortCondition(void)
  {
   return m_tema.Main(m_signal_bar) < m_ma.Main(m_signal_bar);
  }


The EA seems to work however I get an unwanted delay between the crossing of the TEMA/MA indicator and the order as can be seen below.
This example was done with MT5 EURUSD 15 min period from Dec 4th to 6th 2017.

My question is how I can get the order to be entered as close as possible to the crossing as possible?

Once I get passed this I will continue to implement the EA strategy to hopefully become profitable with additional enter/exit conditions and filters as well as money management.

/Karl


Files:
 

Hi Karl,

You can use >= and <= rather than < and > on your trade conditions:

bool SignalTEMA_MA::LongCondition(void)
  {
   return m_tema.Main(m_signal_bar) >= m_ma.Main(m_signal_bar);
  }
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
bool SignalTEMA_MA::ShortCondition(void)
  {
   return m_tema.Main(m_signal_bar) <= m_ma.Main(m_signal_bar);

On the third highlighted circle on your screen shot, the EA took the short trade too late. The code above will make that sell trade enter 1 bar earlier.

If you want it to trade on the cross itself (2 bars back, the candle where the highlighted circle is), then you can use the same settings but with m_signal_bar = 0 (current bar). This would ensure that the trade would be entered as close as possible to the cross, but the data at this bar are often repainting. The indicators may have crossed while the bar is forming, it may keep that until the close of that bar, or it may not.

 
Enrico Lambino:

Hi Karl,

You can use >= and <= rather than < and > on your trade conditions:

On the third highlighted circle on your screen shot, the EA took the short trade too late. The code above will make that sell trade enter 1 bar earlier.

If you want it to trade on the cross itself (2 bars back, the candle where the highlighted circle is), then you can use the same settings but with m_signal_bar = 0 (current bar). This would ensure that the trade would be entered as close as possible to the cross, but the data at this bar are often repainting. The indicators may have crossed while the bar is forming, it may keep that until the close of that bar, or it may not.


Hi Enrico,

Thanks very much for the quick response.I will try you recommendations.

/Karl

 
Karl Klang:


Hi Enrico,

Thanks very much for the quick response.I will try you recommendations.

/Karl

Hi again Enrico,

I've made some testin this weekend. I've changed the trade conditions to >= and <= as you stated, but the trade doesn't move 1 bar earlier unfortunately (see snip below)


I have also tried to set the signal_bar=0. Now it trades on the cross itself, but I get a lot of unwanted trades eventhough one_trade_per_candle=true and position_reverse=true in the expert.Init call (see snip below).

The current Expert source file is attached.

 

Maybe the following condition in the CExpertAdvisorBase::OnTick(void) is wrong?

   if((checkopenlong || checkopenshort)
      && (m_every_tick || IsNewBar(m_symbol_name,m_period))
      && (!CheckPointer(m_times) || m_times.Evaluate()) 
      && (!m_one_trade_per_candle || m_last_trade_time<Time(0))
   )

Should it be like this?

   if((checkopenlong || checkopenshort)
      && (m_every_tick || m_last_trade_time<Time(0))
      && (!CheckPointer(m_times) || m_times.Evaluate()) 
      && (!m_one_trade_per_candle || IsNewBar(m_symbol_name,m_period))
   )


Then I get the following :



 
Karl Klang:

Maybe the following condition in the CExpertAdvisorBase::OnTick(void) is wrong?

Should it be like this?


Then I get the following :



Hi Karl,

This is often a problem with indicators such as TEMA. The values given by such indicators are so flat that sometimes it is quite hard to confirm a crossover. For example, on your first screen shot (white background), the first and second trades, if you look closely, two bars ago before these trades, the signal is still on the opposite direction. This makes the bar 1 candle ago to be the first candle to give a signal reversal (which resulted in the trade in the bar after that). As for the third trade, I cannot confirm unless we have the indicator values printed on the logs. Visually, the indicators appear continuous, but in reality, the data are discrete.

Regarding CExpertAdvisorBase::OnTick(void), make sure that if you set the signal bar = 0, the expert advisor has m_every_tick = true. Checking for new candle is different from maintaining a single trade per candle.

 

Hi Enrico,

I have found a way to handle the Calculate function now including a hysteresis feature which seems to work when the MA and the TEMA indicator crosses.

However I have run into a problem with the Order Manager. It happens when I have run the strategy tester for some loops during optimization. For the first loops it work fine but after some loops an order is placed for every candle.

Here it works fine:


But here the Order Manager starts to place multiple orders:


When I debugged the following code part of the COrderManager, the statement orders_total = OrdersTotal(); becomes 1 when it works but becomes 0 when it fails, which leads to that the if condition m_max_order>orders_total always evaluates to true.

bool COrderManager::TradeOpen(const string symbol,ENUM_ORDER_TYPE type,double price,bool in_points=true)
  {
   bool ret=false;
   double lotsize=0.0;
   int trades_total =TradesTotal();
   int orders_total = OrdersTotal();
   m_symbol=m_symbol_man.Get(symbol);
   if(!IsPositionAllowed(type))
      return true;
   if(m_max_orders>orders_total && (m_max_trades>trades_total || m_max_trades<=0))

Hopefully you can help to figure this out.

Best Regards/
Karl

Reason: