How To Predict The Next H4 Candle Using Elman Neural Network?

As a professional trader, I know candlestick patterns are important signals. I mostly trade candlestick patterns on H4 timeframe. I also a programmer who wants to build an automated trading system using neural networks. If you have read my previous post then you must have an idea how important candlestick patterns are especially on higher timeframes like daily and weekly. Gold is an important commodity that many traders love to trade. In this post I discussed my analysis of why I think gold rally will reverse now. Did the rally then reverse as predicted by me? A long legged doji appeared on the weekly chart, which was a signal that the rally was not over. So you can see how strong candlestick patterns like doji, harami, engulfing etc are. Doji is an indecision candle that signals that the bulls and bears don’t know what to do.

Having realized the importance of candlestick patterns can we build a neural network model that can predict the next candle? Predicting the next candle means predicting the Open, High, Low and Close. In this post we are going to precisely do that. First we need to download the H4 data from MT4. Download H4 data for any currency pair in csv file is simple and easy. Click on Tools >History Center and you can now click on the currency pair that you want to download the data. So first we read GBPUSDH240 csv file in R:

quotes <- read.csv(“E:/MarketData/GBPUSD240.csv”, header=FALSE)

In the above R command we give R the path of the csv file so that it then reads it. How many rows are in this file:


[1] 9599    7

The file has got 9599 rows and 7 columns. Each row represents a 4 hour candle. So in fact the data comprises of 9599 H4 candles. Do we need these many candles? Most probably not. What we will be doing is using the lastest 4000 candles and discarding the older 5000 candles.

What Neural Network Model To Use To Make The Prediction?

There are a number of neural network models. We need to decide which model is best suited to our needs. We have a time series data. We need a neural network that is best suited to deal with a time series data as we plan to use the lagged values of the time series as input data. Multi Layer Perceptron aka MLP is not suited to our needs. In the same manner Probabistic Neural Network aks PNN and the Generalized Regression Neural Network aka GRNN are also not suited.

What we should try is the Recurrent Neural Network. We will apply the Elman Neural Network to our price data and check how good the predictions are. On the first try we may not get a very good fit. We will be using RSNNS package. It is essentially a wrapper for R for the powerful SNNS software.

RSNNS provides a convenient interface to the popular Stuttgart Neural Network Simulator SNNS. The main features are (a) encapsulation of the relevant SNNS parts in a C++ class, for sequential and parallel usage of di erent networks, (b) accessibility of all of the SNNS algorithmic functionality from R using a low-level interface, and (c) a high-level interface for convenient, R-style usage of many standard neural network procedures. The package also includes functions for visualization and analysis of the models and the training procedures, as well as functions for data input/output from/to the original SNNS le formats.

So we are lucky we don’t need to program our own Elman Neural Network using C++.  We will be using  the R to connect to the powerful Stuttgart Neural Network Simulator SNNS that is already programmed in C++.

Data science is all about trying and trying again until you get a good fit. Of course we should avoid over fitting the data. This is what we propose to do. We will use Open, High, Low and Close lagged values to predict Open, High, Low and Close. So we will be building a multi output model. How many lagged values we need? This also depends on trial and error. We will start by lagging Open, high, Low and Close 10 times and then combining these 10 vectors into our input vector. So let’s start the pre-processing of data.

Data Pre-Processing

Data pre-processing is very important. Data pre-processing means preparing the data for building the model. We have read the csv file above in a data frame. The data has got 9599 rows and 7 columns. Now the first thing that we need to do is scale the data. Scaling is very important for neural network data as unsealed data can cause convergence problems. Unscaled data can cause the network to calculate wrong weights. So we need to first scale the data. We use this formula to scale the data.

quotes1 <- scale(quotes[, 3:7],  center=T, scale=T)

Now the data has been scaled. The above command calculates the mean and standard deviation for each column and then subtracts each column value with the mean and divides it with the standard deviation so that the data is between the [0,1] range which is suited for calculations in the back propagation algorithm.

Convert The Data Into A Time Series

We are dealing with a financial time series. Price is being recorded after regular intervals. After scaling the data, we need to convert the data frame into a time series. It is very easy to do. Use the following R command:

quotes1 <- as.ts(quotes1)

You can check what is the class of this object with the following R command:


[1] “mts”   “ts”    “matrix”

Now we need to load the Quantmod library.


We need this quantmod library because we want to convert the ts to a zoo object. Zoo is a time series object with many  that powerful functions and method that the Quantmod package uses. Use the following R command:

quotes1 <- as.zoo(quotes1)

Check what is the class of this object:


[1] “zooreg”, “zoo”

Lagging The Input Values

We need to lag the values. Lets start by lagging the Open, High, Low, Close and Volume 10 times and then using these 10 lagged values as input vectors. Use the following R command to lag the values!

x1 <- lag(quotes1, k=-1, na.pad=TRUE)

> tail(x1)
V3        V4        V5        V6         V7
9595 -2.673068 -2.722192 -2.663868 -2.697631 0.37004361
9596 -2.698602 -2.738616 -2.666239 -2.709204 0.01259432
9597 -2.709837 -2.737589 -2.710430 -2.742051 1.14537462
9598 -2.743201 -2.729378 -2.740737 -2.690993 1.85331186
9599 -2.690942 -2.606543 -2.664884 -2.601642 3.54481475
9600 -2.602254 -2.630836 -2.583274 -2.579347 0.29276273
> head(x1)
V3        V4        V5        V6          V7
1        NA        NA        NA        NA          NA
2 0.6235208 0.6617582 0.6587629 0.6968611 -0.66517714
3 0.6967178 0.6651798 0.6604561 0.6475053 -0.62895804
4 0.6456502 0.6566258 0.6113548 0.6389956 -0.06034833
5 0.6371389 0.6155668 0.5893439 0.5709186 -0.00496034
6 0.5707509 0.5402918 0.5504015 0.5266685 -0.19180654

x2 <- lag(quotes1, k=-2, na.pad=TRUE)
x3 <- lag(quotes1, k=-3, na.pad=TRUE)
x4 <- lag(quotes1, k=-4, na.pad=TRUE)
x5 <- lag(quotes1, k=-5, na.pad=TRUE)
x6 <- lag(quotes1, k=-6, na.pad=TRUE)
x7 <- lag(quotes1, k=-7, na.pad=TRUE)
x8 <- lag(quotes1, k=-8, na.pad=TRUE)
x9 <- lag(quotes1, k=-9, na.pad=TRUE)
x10 <- lag(quotes1, k=-10, na.pad=TRUE)

The rationale for lagging the values is that we know from experience that price has a memory and depends on the past prices. This is precisely what we do in technical analysis we study past prices to predict future prices. So we lag the prices and then combine them into a new matrix.

Quotes <- cbind(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, quotes1)

Let’s check what’s the class of this matix


[1]  “zooreg” , “zoo”

[1] 9609   55

So we have now a matrix with 9609 rows and 55 columns. As you might have guessed now.

Building The Elman Neural Network

To make things easy for us, we save the covariate attributes containing the 10 lagged price vectors into the input matrix and the response variable in the output object for training.

inputs_train <- Quotes[ 5000:9500,  1:50]

outputs_train <- Quotes[5000:9500, 51:55]

Now let’s fit an Elman Neural Network to the above data. First we need to laod the RSNNS package. Use the following R command.


Now that we have loaded the RSNNS package we can now build the model using the following R command. Maxit means the maximum number of epochs that are allowed. We have set the maxit in out case to 10000.

model <- elman( inputs_train, outputs_train, size =c(10 ,10) , learnFuncParams =c (0.1) , maxit =20000)

We have the model properly trained on the dataset with us. We are ready for the predictions now. First type this command to get a summary of the elman model:


It will be a large block of R output.

inputs_test <- Quotes[9501:9599, 1:50]

outputs_test <- Quotes[9501:9599, 51:55]

Now we test the model on the 98 candlesticks that we have.

pred <- predict(model , inputs_test)

This is our output matrix

outputs_test <- Quotes[9501:9599, 51:55]

We calculate the squared correlation coefficient for each column.

cor( outputs_test, pred )^2

This is the plot for the iteration errors.


This command tells you at which epoch the desired SSE was achieved.

head(which(abs(diff(model$IterativeFitError)) < 1e-20), 1)

Now as said above in the beginning doing data analysis and building a successful model is a tedious process with lots of frustrations and occasional success. This models needs to be worked a lot. Right now the results are not encouraging. So keep tuned. Nothing to get discouraged. Model building is an incremental process. First model is always very crude. The next models then get more and more refined as you learn to include the missing things in them.