How To Use NNET Multinomial Log Linear Models In Trading?

In a previous post we tried to use Elman Recurrent Neural Network in predicting four hourly candle. The problem with Elman Neural Network is that it takes a long time to do the calculations. Last night also when I started writing this post, I tried to train an Elman Neural Network. It took more than 30 minutes. So it can take more than 30 minutes to finish calculations and show the results. In intraday trading, 30 minutes is a pretty long time. We cannot afford to wait for 30 minutes for the predictions.

In another previous post we tried to fit a vector autoregressive model to predict price on intraday timeframe. This model does calculations pretty fast but the results were not that good. In this post we will try to use NNET Multinomial Log Linear Model via Feed Forward Neural Network in making predictions on weekly, daily and intraday timeframes. NNET can do the calculations in a few minutes. Sometimes it faces problem in convergence (more on that below). In recent years neural networks have become popular in making predictions on all sorts of things. You will be surprised to know that neural networks can read human hand writing pretty accurately and are used extensively in teller machines and in many more applications. Did you watch the video interview of a mathematician who became a billionaire hedge fund manager?

What Is A Multinomial Log Linear NNET Model?

Multinomial Log Linear model tries to fit a log linear model between one output and several inputs via a feed forward neural network. This is a simple neural network that has only 1 hidden layer. Instead of trying to fit highly complex models that use non linear mathematics and take a long time to train, we should focus on linear models that are quick to train and can give reasonably good approximation to our problems. One such model is this NNET model that tries to fit a multinomial log linear model using a neural network. It is pretty fast most of the time. Sometimes this model does face problem in converging. You can watch the video below that explains Multinomial Log Linear NNET model:

In the above video you can see a multinomial log linear model is an offshoot of a logistic regression model. Neural Networks are black boxes that were designed a few decades ago to mimic the neurons in our brain. They combine the inputs using sigmoid functions. These sigmoid functions have properties that mimic those of the neurons in our brains. Watch the video below that provides a good introduction to Artificial Neural Networks:

https://www.youtube.com/watch?v=IS-PeWbvqbs

Keep this in mind the neurons in our brain are much more complex than these models. These artificial neural networks are very crude and very simplistic approximations to how a biological neural network functions in our brains. However the name of neural network persists. In our view these are just mathematical models that have been misnamed as neural networks. These models don’t have anything common with biological neural networks. Below is another video that provides a somewhat advanced introduction to Neural Networks:

The choice of inputs matter a lot when it comes to making the predictions. Developing a model is like preparing a new recipe. We need to experiment a lot. Most of the time, we will not get good results but if we persist and don’t lose our focus we can ultimately develop a model that can provide good predictions. So let’s start with out first model and try to predict the closing price of the next daily candle.

> data <- read.csv("E:/MarketData/GBPUSD1440.csv", header = FALSE)
> 
> colnames(data) <- c("Date", "Time", "Open", "High",
+                     "Low", "Close", "Volume")
> 
> library(quantmod)
Loading required package: xts
Loading required package: zoo

Attaching package: ‘zoo’

The following objects are masked from ‘package:base’:

    as.Date, as.Date.numeric

Loading required package: TTR
Version 0.4-0 included new data defaults. See ?getSymbols.
> 
> data2 <- as.xts(data[,-(1:2)], as.Date(paste(data[,1]),format='%Y.%m.%d'))
> 
> 
> 
> data2$rsi <- RSI(data2$Close)
> data2$MACD <- MACD(data2$Close)
> data2$will <- williamsAD(data2[,2:4])
> data2$cci <-  CCI(data2[,2:4])
> data2$STOCH <- stoch(data2[,2:4])
> data2$Aroon <- aroon(data2[, 2:3])
> data2$ATR <- ATR(data2[, 2:4])
> 
> 
> data2$Return <- diff(log(data2$Close))
> 
> 
> 
> x <- nrow(data2)
> 
> for (i in (x-2000):(x-1))
+ {
+   
+   data2[i,21] <- data2[i+1,21] 
+   
+   
+ }
> 
> 
> 
> library(nnet)
> fit1 <- nnet( Return~ Open+High+Low+Close+Volume+rsi+macd+
+                 MACD+will+cci+fastK+fastD+STOCH+aroonUp+aroonDn+
+                 Aroon+tr+atr+trueHigh+ATR, 
+               data = data2[(x-2000):(x-2), 1:21], maxit = 5000, 
+               size = 20, decay = 0.01, linout = 1)
# weights:  441
initial  value 22.108696 
iter  10 value 0.599465
iter  20 value 0.107927
iter  30 value 0.087783
iter  40 value 0.071157
iter  50 value 0.069920
iter  60 value 0.069712
iter  70 value 0.069529
iter  80 value 0.069319
iter  90 value 0.069090
iter 100 value 0.068952
iter 110 value 0.068849
iter 120 value 0.068812
iter 130 value 0.068591
iter 140 value 0.068387
iter 150 value 0.068357
iter 160 value 0.068318
iter 170 value 0.068145
iter 180 value 0.068024
iter 190 value 0.067988
iter 200 value 0.067961
iter 210 value 0.067926
iter 220 value 0.067902
iter 230 value 0.067881
iter 240 value 0.067853
iter 250 value 0.067831
iter 260 value 0.067827
iter 270 value 0.067818
iter 280 value 0.067778
iter 290 value 0.067772
iter 300 value 0.067760
iter 310 value 0.067705
iter 320 value 0.067572
iter 330 value 0.067481
iter 340 value 0.067404
iter 350 value 0.067363
iter 360 value 0.067352
iter 370 value 0.067351
iter 380 value 0.067344
iter 390 value 0.067330
iter 400 value 0.067307
iter 410 value 0.067284
iter 420 value 0.067268
iter 430 value 0.067237
iter 440 value 0.067176
iter 450 value 0.067130
iter 460 value 0.067101
iter 470 value 0.067082
iter 480 value 0.067066
iter 490 value 0.067036
iter 500 value 0.066994
iter 510 value 0.066963
iter 520 value 0.066933
iter 530 value 0.066904
iter 540 value 0.066885
iter 550 value 0.066877
iter 560 value 0.066869
iter 570 value 0.066859
iter 580 value 0.066852
iter 590 value 0.066835
iter 600 value 0.066798
iter 610 value 0.066742
iter 620 value 0.066698
iter 630 value 0.066665
iter 640 value 0.066649
iter 650 value 0.066641
iter 660 value 0.066633
iter 670 value 0.066626
iter 680 value 0.066620
iter 690 value 0.066615
iter 700 value 0.066608
iter 710 value 0.066601
iter 720 value 0.066594
iter 730 value 0.066589
iter 740 value 0.066583
iter 750 value 0.066578
iter 760 value 0.066573
iter 770 value 0.066569
iter 780 value 0.066565
iter 790 value 0.066563
iter 800 value 0.066560
iter 810 value 0.066557
iter 820 value 0.066555
iter 830 value 0.066554
iter 840 value 0.066554
iter 850 value 0.066553
iter 860 value 0.066553
iter 870 value 0.066552
iter 880 value 0.066552
iter 890 value 0.066551
iter 900 value 0.066550
iter 910 value 0.066549
iter 920 value 0.066549
iter 930 value 0.066548
iter 940 value 0.066546
iter 950 value 0.066533
iter 960 value 0.066479
iter 970 value 0.066445
iter 980 value 0.066427
iter 990 value 0.066413
iter1000 value 0.066405
iter1010 value 0.066400
iter1020 value 0.066395
iter1030 value 0.066391
iter1040 value 0.066388
iter1050 value 0.066386
iter1060 value 0.066384
iter1070 value 0.066383
iter1080 value 0.066382
iter1090 value 0.066379
iter1100 value 0.066371
iter1110 value 0.066364
iter1120 value 0.066358
iter1130 value 0.066353
iter1140 value 0.066349
iter1150 value 0.066346
iter1160 value 0.066344
iter1170 value 0.066342
iter1180 value 0.066341
iter1190 value 0.066340
iter1200 value 0.066339
iter1210 value 0.066339
iter1220 value 0.066338
iter1230 value 0.066338
iter1240 value 0.066338
iter1240 value 0.066338
final  value 0.066338 
converged
> pred <- predict(fit1, newdata = data2[x-1, 1:20])
> 
> 
> exp(pred[1])*data[x-1,6]
[1] 1.308139

In the above NNET model, you can see the number of iterations that the model made to reduce the error and achieve convergence. In the end it says converged and provides you with the predicted return that we convert into the predicted closing price of 1.308139 which is way off the mark. Actual close was 1.29694. Now let’s run the same model and see what it predicts for the weekly closing price.

> #import the data
> 
> data <- read.csv("E:/MarketData/GBPUSD10080.csv", header = FALSE)
> 
> colnames(data) <- c("Date", "Time", "Open", "High",
+                     "Low", "Close", "Volume")
> 
> library(quantmod)
> 
> data2 <- as.xts(data[,-(1:2)], as.Date(paste(data[,1]),format='%Y.%m.%d'))
> 
> 
> 
> data2$rsi <- RSI(data2$Close)
> data2$MACD <- MACD(data2$Close)
> data2$will <- williamsAD(data2[,2:4])
> data2$cci <-  CCI(data2[,2:4])
> data2$STOCH <- stoch(data2[,2:4])
> data2$Aroon <- aroon(data2[, 2:3])
> data2$ATR <- ATR(data2[, 2:4])
> 
> 
> data2$Return <- diff(log(data2$Close))
> 
> 
> x <- nrow(data2)
> 
> for (i in (x-1000):(x-1))
+ {
+   
+   data2[i,21] <- data2[i+1,21] 
+   
+   
+ }
> 
> 
> 
> library(nnet)
> fit1 <- nnet( Return~ Open+High+Low+Close+Volume+rsi+macd+
+                 MACD+will+cci+fastK+fastD+STOCH+aroonUp+aroonDn+
+                 Aroon+tr+atr+trueHigh+ATR, 
+               data = data2[(x-1000):(x-2), 1:21], maxit = 5000, 
+               size = 20, decay = 0.01, linout = 1)
# weights:  441
initial  value 6126.765336 
iter  10 value 0.830602
iter  20 value 0.177233
iter  30 value 0.176860
iter  40 value 0.175780
iter  50 value 0.173517
iter  60 value 0.172335
iter  70 value 0.170377
iter  80 value 0.164833
iter  90 value 0.157712
iter 100 value 0.154134
iter 110 value 0.151568
iter 120 value 0.150104
iter 130 value 0.149120
iter 140 value 0.148291
iter 150 value 0.148236
iter 160 value 0.147904
iter 170 value 0.147809
iter 180 value 0.147472
iter 190 value 0.146180
iter 200 value 0.144779
iter 210 value 0.143722
iter 220 value 0.143272
iter 230 value 0.142902
iter 240 value 0.142544
iter 250 value 0.141886
iter 260 value 0.141439
iter 270 value 0.141170
iter 280 value 0.141100
iter 290 value 0.140988
iter 300 value 0.140749
iter 310 value 0.140691
iter 320 value 0.140576
iter 330 value 0.139948
iter 340 value 0.139413
iter 350 value 0.138968
iter 360 value 0.138666
iter 370 value 0.138417
iter 380 value 0.138172
iter 390 value 0.138116
iter 400 value 0.138085
iter 410 value 0.138060
iter 420 value 0.138019
iter 430 value 0.137977
iter 440 value 0.137952
iter 450 value 0.137940
iter 460 value 0.137934
iter 470 value 0.137930
iter 480 value 0.137926
iter 490 value 0.137920
iter 500 value 0.137914
iter 510 value 0.137910
iter 520 value 0.137909
iter 530 value 0.137908
iter 540 value 0.137907
iter 550 value 0.137907
iter 560 value 0.137906
iter 570 value 0.137906
iter 580 value 0.137906
iter 590 value 0.137906
iter 600 value 0.137906
iter 600 value 0.137906
iter 600 value 0.137906
final  value 0.137906 
converged
> pred <- predict(fit1, newdata = data2[x-1, 1:20])
> 
> 
> exp(pred[1])*data[x-1,6]
[1] 1.297978

Above model predicts weekly close as 1.29797 while the actual weekly close was 1.29694. The predicted close and the actual close are pretty close. What this means is that the inputs that we have chosen work well on weekly but don’t work on the daily. We need to play around with the inputs on the daily and see if we get good results.You can see this model made a total of 600 iterations. We had chosen 20 neurons in the hidden layer ( the same number as the inputs).

Above modelling has been done in R, you can also do modelling using Python. R and Python these are 2 very powerful data analysis and machine learning languages that you should make some effort to learn. Take a look at this Quantopian platform that provides you the chances to develop algorithmic trading strategies using python. Best approach in our view is to combine these models with your manual system. Candlesticks are powerful signals. Use them for entry and exit. Use the above models to find the direction in which the market is going to move. The above models can give you approximate levels where market can turn. But these levels can be wrong as well. Keep this in mind. Always trade when you find confluence between your manual system and algorithmic system. Did you read the post on a EURUSD swing trade that made 400 pips in 3 days?

Published
Categorized as Forex Tagged