Discussing the article: "Reimagining Classic Strategies (Part XI): Moving Average Cross Over (II)"

 

Check out the new article: Reimagining Classic Strategies (Part XI): Moving Average Cross Over (II).

The moving averages and the stochastic oscillator could be used to generate trend following trading signals. However, these signals will only be observed after the price action has occurred. We can effectively overcome this inherent lag in technical indicators using AI. This article will teach you how to create a fully autonomous AI-powered Expert Advisor in a manner that can improve any of your existing trading strategies. Even the oldest trading strategy possible can be improved.

We have previously covered the idea of forecasting moving average cross-overs, the article is linked here. We observed that moving average cross-overs are easier to forecast than price changes directly. Today we will revisit this familiar problem but with an entirely different approach.
 
We now want to thoroughly investigate how big of a difference this makes for our trading applications and how this fact can improve your trading strategies. Moving averages cross-overs are one of the oldest existing trading strategies. It is challenging to build a profitable strategy using such a widely known technique. Nevertheless, I hope to show you in this article that old dogs can indeed learn new tricks.

To be empirical in our comparisons, we will first build a trading strategy in MQL5 for the EURGBP pair using just the following indicators:

  1. 2 Exponential Moving Averages applied to the Close Price. One with a period of 20, and the other set to 60.
  2. The Stochastic oscillator with the default settings of 5,3,3 applied set to Exponential Moving Average Mode and set to make its calculations in the CLOSE_CLOSE mode
  3. The Average True Range indicator with a period of 14 to set our take-profit and stop-loss levels.

Our strategy will be intended to trade the Daily Time Frame. We will back test this strategy from the first of January 2022 until the beginning of June 2024. Our strategy will initially use classical trading rules. So, buy signals will be generated whenever the fast-moving average crosses above the slow-moving average and the stochastic reading is above 80. And the converse is true for our sell signals. We will register a sell signal when the fast-moving average is beneath the slow, and the stochastic oscillator is beneath 20.

Author: Gamuchirai Zororo Ndawana

 

Thank you Gamu . I enjoy your publications and try to learn by reproducing your steps.

I am having some issues hopefully this may help others.

1) my tests with you EURGBP_Stochastic daily using the script supplied only produces 2 orders and subsequently Sharpe ration of 0.02 . I believe I have the same settings as you but on 2 brokers it produces only 2 orders .

2) as a heads up for others you may need to modify the symbol settings to match your broker (e.g. EURGBP to EURGBP.i) if necessary 

3) next when I try to export the data I get an array out of range for the ATR this I believe is because I don't get 100000 records into my Array ( if I change it to 677 ) I can accordingly get a file with 677 rows  . for me the default for max bars in a chart is 50000, If I change that to 100000 my array size is only 677 , but possibly I have a bad set up . Maybe you could also include the data extract script in your download .

4)I copied the code from you article to  try in Python I get an error look_ahead not defined ----> 3 data.loc[data["Close"].shift(-look_ahead) > data["Close"],"Binary Target"] = 1

      4 data = data.iloc[:-look_ahead,:]


NameError: name 'look_ahead' is not defined

5) when I loaded your Juypiter notebook I find it needed to have look ahead set  #Let us forecast 20 steps into the future

look_ahead = 20 , After this I have used your included file only but I am stuck on the following error , possibly related to only having 677 rows .

I run #Scale the data before we start visualizing it

from sklearn.preprocessing import RobustScaler

scaler = RobustScaler()

data[['Open', 'High', 'Low', 'Close', 'MA Fast', 'MA Slow','Stoch Main']] = scaler.fit_transform(data[['Open', 'High', 'Low', 'Close', 'MA Fast', 'MA Slow','Stoch Main']])

which gives me an error that I don't understand how to resolve 

ipython-input-6-b2a044d397d0>:4: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy data[['Open', 'High', 'Low', 'Close', 'MA Fast', 'MA Slow','Stoch Main']] = scaler.fit_transform(data[['Open', 'High', 'Low', 'Close', 'MA Fast', 'MA Slow','Stoch Main']])

 
linfo2 #:

Thank you Gamu . I enjoy your publications and try to learn by reproducing your steps.

I am having some issues hopefully this may help others.

1) my tests with you EURGBP_Stochastic daily using the script supplied only produces 2 orders and subsequently Sharpe ration of 0.02 . I believe I have the same settings as you but on 2 brokers it produces only 2 orders .

2) as a heads up for others you may need to modify the symbol settings to match your broker (e.g. EURGBP to EURGBP.i) if necessary 

3) next when I try to export the data I get an array out of range for the ATR this I believe is because I don't get 100000 records into my Array ( if I change it to 677 ) I can accordingly get a file with 677 rows  . for me the default for max bars in a chart is 50000, If I change that to 100000 my array size is only 677 , but possibly I have a bad set up . Maybe you could also include the data extract script in your download .

4)I copied the code from you article to  try in Python I get an error look_ahead not defined ----> 3 data.loc[data["Close"].shift(-look_ahead) > data["Close"],"Binary Target"] = 1

      4 data = data.iloc[:-look_ahead,:]


NameError: name 'look_ahead' is not defined

5) when I loaded your Juypiter notebook I find it needed to have look ahead set  #Let us forecast 20 steps into the future

look_ahead = 20 , After this I have used your included file only but I am stuck on the following error , possibly related to only having 677 rows .

I run #Scale the data before we start visualizing it

from sklearn.preprocessing import RobustScaler

scaler = RobustScaler()

data[['Open', 'High', 'Low', 'Close', 'MA Fast', 'MA Slow','Stoch Main']] = scaler.fit_transform(data[['Open', 'High', 'Low', 'Close', 'MA Fast', 'MA Slow','Stoch Main']])

which gives me an error that I don't understand how to resolve 

ipython-input-6-b2a044d397d0>:4: SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc[row_indexer,col_indexer] = value instead See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy data[['Open', 'High', 'Low', 'Close', 'MA Fast', 'MA Slow','Stoch Main']] = scaler.fit_transform(data[['Open', 'High', 'Low', 'Close', 'MA Fast', 'MA Slow','Stoch Main']])

What's up Neil, I trust you're good. 

Let me see how I can help:

1) This error is quite weird, here's how I'd approach it: 

Our system only opens trades if both AI models give the same forecast. Train the models and evaluate their coefficients, this will tell you when each one will generate a signal, and what the signal will be. Then carefully monitor the back test to see if the conditions the model is under, explain the number of trades. 

2) This is a constant issue, and is hard to control for because each broker has their own naming convention, but solution you provided is valid.

3) This may indicate your broker only has 677 bars of Daily data you can use, excluding period calculations. It's normal, I experience it too. Sometimes I try fetch just 1 year of daily data but only retrieve 200 and something bars.

4) Try defining look ahead just above the statement causing issues, and then update it throughout the code if need be.

5) This may be an issue of us either using different library versions, Python versions etc..  I think the adjustment needs to be made before the assignment. So the line:

data[['Open', 'High', 'Low', 'Close', 'MA Fast', 'MA Slow','Stoch Main']] =

May need to be adjusted to:

data.loc[:,['Open','High',...,'Stoch Main']] =
 
Gamuchirai Zororo Ndawana #:
What's up Neil, I trust you're good. 

Let me see how I can help:

1) This error is quite weird, here's how I'd approach it: 

Our system only opens trades if both AI models give the same forecast. Train the models and evaluate their coefficients, this will tell you when each one will generate a signal, and what the signal will be. Then carefully monitor the back test to see if the conditions the model is under, explain the number of trades. 

2) This is a constant issue, and is hard to control for because each broker has their own naming convention, but solution you provided is valid.

3) This may indicate your broker only has 677 bars of Daily data you can use, excluding period calculations. It's normal, I experience it too. Sometimes I try fetch just 1 year of daily data but only retrieve 200 and something bars.

4) Try defining look ahead just above the statement causing issues, and then update it throughout the code if need be.

5) This may be an issue of us either using different library versions, Python versions etc..  I think the adjustment needs to be made before the assignment. So the line:

data[['Open', 'High', 'Low', 'Close', 'MA Fast', 'MA Slow','Stoch Main']] =

May need to be adjusted to:

data.loc[:,['Open','High',...,'Stoch Main']] =

Thank you Gamu Appreciate that , Yes I know there are many moving parts , I will see if this will resolve my issues 

 
linfo2 #:

Thank you Gamu Appreciate that , Yes I know there are many moving parts , I will see if this will resolve my issues 

Man right? So many, and this only a simple implementation