GBPUSD Rallies Hard On Early Election News

Today UK Prime Minster Theresa May was scheduled to speak in the parliament. Now if you have been reading my Forex Signals Blog posts, you should know by now that currency market is highly fickle when it comes to speeches by the Prime Minsters or the Presidents. Just last week, US Dollar fell sharply when President Trump said that Dollar has become too strong and is hurting the US economy. This time it was UK PM Theresa May. Theresa May election announcement has stunned the financial markets and the reaction was very volatile. In the end, market seems to have liked the idea of an early election. British Pound has rallied hard. Did you read the post on USDJPY trade that made 400 pips with a small 20 pips stop loss? Take a look at the following GBPUSD M15 screenshot.

GBPUSD M15 Chart

Whenever the market moves fast, the first signs appear on the lower timeframe like M15. So we start with the lower timeframe. I use candlestick patterns a lot in my trading. DId you read the post on Fuzzy Logic Candlestick Trading System? This was the first post. I will write the next post soon. Fuzzy logic is a concept that is very useful in trading because everything is vague when we are trading. I have developed a course on Fuzzy Logic for Traders. You can take a look at my course. In this course I start from the very beginning and show you how you are going to use fuzzy logic in trading. Can you see the red arrow in the above screenshot? This is the time when the market is worried what Theresa May is going to say in her speech. So GBPUSD starts falling sharply.

Can We Predict GBPUSD Price With An AR Model?

Can we predict this move? In this post we will use a simple autoregressive AR model and see if we can predict GBPUSD price. Now you should keep this in mind that currency market is very dynamic. We will try to predict the market after every 15 minutes and see if we do well. Let’s start with just the candle that is below the red arrow in the above screenshot. Closing price is at 1.26013.

> #autoregressive model
> # Import the csv file
> quotes <- read.csv("D:/MarketData/GBPUSD15.csv", header=FALSE)
> colnames(quotes) <- c("Date", "Time", "Open", "High", "Low", "Close", "Volume")
> tail(quotes)
           Date  Time    Open    High     Low   Close Volume
2200 2017.04.18 13:45 1.26393 1.26595 1.26360 1.26525   5019
2201 2017.04.18 14:00 1.26523 1.26710 1.26521 1.26631   5243
2202 2017.04.18 14:15 1.26632 1.26772 1.26626 1.26705   5059
2203 2017.04.18 14:30 1.26704 1.26776 1.26615 1.26732   3654
2204 2017.04.18 14:45 1.26731 1.26789 1.26671 1.26687   2805
2205 2017.04.18 15:00 1.26688 1.26735 1.26619 1.26629   2446
> #number of rows 
> x <- nrow(quotes)
> quotes1 <- as.ts(quotes$Close)
> 
> N <-4
> quotes1[x-12-N]
[1] 1.26013
> #fit an autoregessive model
> model <- ar(quotes1[(x-32-N):(x-12-N)], aic=TRUE, method='mle')
> pred <- predict(model, n.ahead=15)
> pred
$pred
Time Series:
Start = 22 
End = 36 
Frequency = 1 
 [1] 1.260052 1.259976 1.259903 1.259833 1.259765 1.259699 1.259636 1.259575 1.259516
[10] 1.259460 1.259405 1.259352 1.259301 1.259252 1.259205

$se
Time Series:
Start = 22 
End = 36 
Frequency = 1 
 [1] 0.0004526688 0.0006289369 0.0007569344 0.0008590669 0.0009442241 0.0010170734
 [7] 0.0010804520 0.0011362507 0.0011858117 0.0012301325 0.0012699814 0.0013059663
[13] 0.0013385791 0.0013682250 0.0013952426

You can see the model is predicting price is go down. But by not much. We have predicted the price for the next 15 candles. So we move to the next candle and once again make predictions for the next 15 candles. GBPUSD is prone to violent behavior. Did you read the post on GBPUSD Flash Crash? Algorithmic trading is being used widely now. You should start learning algorithmic trading if you want to succeed as a trader. I have developed a few courses that can help you. Java is a very powerful modern object oriented language. I have developed 3 part series course on Java. First is the Java for Traders. In this course I teach you the basics of Java language. Second course is the Java Machine Learning For Traders. In this course I teach you how to use Java machine learning and make predictions about price action that can be used in trading. The last course is Algorithmic Trading with Java. In this course I teach you how to actually build your algorithmic trading system using Java. There are many brokers who provide Java APIs for building algorithmic trading systems. So by taking these 3 courses, you will become a professional algorithmic trader.

> N <-3
> quotes1[x-12-N]
[1] 1.25924
> #fit an autoregessive model
> model <- ar(quotes1[(x-32-N):(x-12-N)], aic=TRUE, method='mle')
> pred <- predict(model, n.ahead=15)
> pred
$pred
Time Series:
Start = 22 
End = 36 
Frequency = 1 
 [1] 1.259147 1.259058 1.258975 1.258896 1.258821 1.258751 1.258685 1.258622 1.258562
[10] 1.258506 1.258453 1.258403 1.258356 1.258311 1.258269

$se
Time Series:
Start = 22 
End = 36 
Frequency = 1 
 [1] 0.0004830080 0.0006644925 0.0007921168 0.0008907258 0.0009703209 0.0010362200
 [7] 0.0010916900 0.0011389257 0.0011794940 0.0012145634 0.0012450341 0.0012716173
[13] 0.0012948860 0.0013153092 0.0013332759

You  can see price is going down but by not much. We again move to the next 15 minute candle and make the prediction for the next 15 candles. Now you should keep this in mind the behavior of market when it goes down is very different from the behavior of market when it goes up. This has been studied out in volatility modelling in which it has been observed that when price falls volatility behaves differently and when price goes up, volatility behaves differently. Did you read the post on how to use Support Vector Machine in daily trading?

> N <-2
> quotes1[x-12-N]
[1] 1.25851
> #fit an autoregessive model
> model <- ar(quotes1[(x-32-N):(x-12-N)], aic=TRUE, method='mle')
> pred <- predict(model, n.ahead=15)
> pred
$pred
Time Series:
Start = 22 
End = 36 
Frequency = 1 
 [1] 1.258423 1.258343 1.258271 1.258206 1.258146 1.258092 1.258042 1.257998 1.257957
[10] 1.257920 1.257886 1.257855 1.257827 1.257802 1.257779

$se
Time Series:
Start = 22 
End = 36 
Frequency = 1 
 [1] 0.0004901858 0.0006625506 0.0007767061 0.0008597282 0.0009227548 0.0009717892
 [7] 0.0010105406 0.0010414958 0.0010664145 0.0010865883 0.0011029916 0.0011163735
[13] 0.0011273191 0.0011362905 0.0011436558

Our model is predicting price to go down. But as usual by not much. But we know from the prediction that price is going down and not up. Do you know how to trade with harmonic price patterns?

> N <-1
> quotes1[x-12-N]
[1] 1.25855
> #fit an autoregessive model
> model <- ar(quotes1[(x-32-N):(x-12-N)], aic=TRUE, method='mle')
> pred <- predict(model, n.ahead=15)
> pred
$pred
Time Series:
Start = 22 
End = 36 
Frequency = 1 
 [1] 1.258205 1.256695 1.256355 1.255994 1.255699 1.255754 1.255479 1.256532 1.256470
[10] 1.257016 1.258154 1.258274 1.258335 1.258774 1.259340

$se
Time Series:
Start = 22 
End = 36 
Frequency = 1 
 [1] 0.0001404474 0.0001625751 0.0001720661 0.0002073619 0.0002389041 0.0002629828
 [7] 0.0002651808 0.0002686534 0.0002703579 0.0002892005 0.0003395126 0.0003704289
[13] 0.0003936169 0.0004090275 0.0004117391

You can see above that the model is predicting price to reverse. Instead of building a regression model we can also build classification models as well in which we are only interested in knowing how much the price is going to move. In this post I have used R language. R is a powerful data science and machine learning language that is being used extensively in the academia. You can read the post on how to use R in currency trading.

> N <-0
> quotes1[x-12-N]
[1] 1.25183
> #fit an autoregessive model
> model <- ar(quotes1[(x-32-N):(x-12-N)], aic=TRUE, method='mle')
> pred <- predict(model, n.ahead=15)
> pred
$pred
Time Series:
Start = 22 
End = 36 
Frequency = 1 
 [1] 1.253707 1.254914 1.255690 1.256189 1.256510 1.256717 1.256850 1.256935 1.256990
[10] 1.257025 1.257048 1.257063 1.257072 1.257078 1.257082

$se
Time Series:
Start = 22 
End = 36 
Frequency = 1 
 [1] 0.001496653 0.001779489 0.001884117 0.001925737 0.001942693 0.001949664
 [7] 0.001952541 0.001953730 0.001954221 0.001954424 0.001954508 0.001954543
[13] 0.001954558 0.001954564 0.001954566

Now this was the point when GBPUSD made a reversal and shot up. Our model is predicting that well. The last candle close was 1.25183. Our autoregressive model predicts the next candle close as 1.25370. Now this was the prediction on M15 timeframe. Let’s shift to H4 timeframe and check if we can make a good prediction. Read the post on EURUSD falling 450 pips on QE announcement.

GBPUSD H4 chart

As you can see in the above screenshot, price make big candles after the announcement of early elections by Theresa May. As said above we shift to H4 timeframe and check if we can make a good prediction.

> #autoregressive model
> # Import the csv file
> quotes <- read.csv("D:/MarketData/GBPUSD240.csv", header=FALSE)
> colnames(quotes) <- c("Date", "Time", "Open", "High", "Low", "Close", "Volume")
> tail(quotes)
            Date  Time    Open    High     Low   Close Volume
11163 2017.04.17 20:00 1.25861 1.25902 1.25584 1.25646  18312
11164 2017.04.18 00:00 1.25648 1.25710 1.25501 1.25637  19013
11165 2017.04.18 04:00 1.25638 1.25764 1.25562 1.25639  18721
11166 2017.04.18 08:00 1.25638 1.26081 1.25612 1.25855  25805
11167 2017.04.18 12:00 1.25856 1.27309 1.25149 1.27190  87657
11168 2017.04.18 16:00 1.27191 1.27469 1.27099 1.27453  16057
> #number of rows 
> x <- nrow(quotes)
> quotes1 <- as.ts(quotes$Close)
> 
> quotes1[x-3]
[1] 1.25639
> #fit an autoregessive model
> model <- ar(quotes1[(x-25):(x-1)], aic=TRUE, method='mle')
> pred <- predict(model, n.ahead=15)
> pred
$pred
Time Series:
Start = 26 
End = 40 
Frequency = 1 
 [1] 1.276778 1.276860 1.274551 1.271333 1.268051 1.265132 1.262745 1.260910 1.259571
[10] 1.258638 1.258020 1.257633 1.257407 1.257288 1.257237

$se
Time Series:
Start = 26 
End = 40 
Frequency = 1 
 [1] 0.002979770 0.005068990 0.006559625 0.007527771 0.008108958 0.008432810
 [7] 0.008600107 0.008679814 0.008714498 0.008728043 0.008732635 0.008733894
[13] 0.008734124 0.008734135 0.008734144

In the above code you can see that the model did predict price to shoot up. The last closing price that we had used was 1.25639. The first predicted price by our model is 1.276778. Actual price is 1.25855. Then GBPUSD started falling down sharply. It then reversed and shot up again. So the model is predicting price to shoot up. Somehow the market knows what is going to happen. But our model is not that good. We have to refine this model if we want to use it in trading.  But this is for sure, past prices can be used to predict the future price. We can improve the model by building a Kalman Filter that will correct the autoregressive model after each prediction. More on that in a future post. Read the post on how to trade with Awesome Oscillator.

The crux of this post is on the currency market being fickle. Currency market responds too much to breaking news. You should keep this in mind when you are trading. Always start your trading day by taking a look at the economic news calendar. This should give you a fair idea of what is going to happen. In the the case of GBPUSD, price first went down. Then it reversed and changed direction. So we should be careful when trading. Stop loss can get tripped easily. It is always a good idea to keep the stop loss as small as possible. Predictions are always predictions. They can be wrong. This is for sure predictions are never accurate. You only get a rough idea of what can happen. So it is always a good idea to keep the stop loss small. By keeping risk small, you can always ensure that your loss is always small. The trick lies in keeping the risk small and catching the big moves in the market. If you can do that you will make a lot of money in the market. The key is developing a model that integrates the lower timeframes with the higher timeframes. Watch the interview with the #2 ranked forex trader in the world.

Now coming back to the topic of financial market machine learning, I have tried to show you in this post how difficult it is predict the financial market. Currency market prediction is one of the most challenging artificial intelligence. If you can solve this challenging task, you will then never worry about making money. You will be able to make as much as you want. I started off with time series autoregressive model. I showed you autoregressive model does have some predictive power but it cannot follow the speed of price change. In auto-regression, we regress the past values and predict the future value. This makes sense. This is precisely what we do when we do technical analysis. We look at the chart of the past price action and try to predict the future price action. I am a firm believer of technical analysis. Below is the chart of GPBUSD H4 chart that shows how much price moved.

GBPUSD H4 Chart

Now you can see from the above chart, GBPUSD price touched 1.2905 level before it retraced. It seems that 1.2905 is a resistance level. Our auto-regression model was not able to predict price as fast as it moved. It did predict the turning point well. Can we improve our AR model? I think we can by using some Bayesian analysis and building a Kalman Filter. This we will do in the future post.

Can We Predict GBPUSD Price With GARCH Model?

In all Time Series Analysis textbooks, you will taught the GARCH model in  depth. But does it works in practice. Take a look at the following results:

> #GARCH model
> # Import the csv file
> quotes <- read.csv("D:/MarketData/GBPUSD1440.csv", header=FALSE)
> colnames(quotes) <- c("Date", "Time", "Open", "High", "Low", "Close", "Volume")
> tail(quotes)
           Date  Time    Open    High     Low   Close Volume
2046 2017.04.12 00:00 1.24900 1.25486 1.24806 1.25373 253346
2047 2017.04.13 00:00 1.25387 1.25743 1.25004 1.25054 231645
2048 2017.04.14 00:00 1.25085 1.25351 1.25009 1.25283 168341
2049 2017.04.17 00:00 1.25325 1.25962 1.25250 1.25646  85714
2050 2017.04.18 00:00 1.25648 1.29059 1.25149 1.28412 240045
2051 2017.04.19 00:00 1.28410 1.28606 1.28095 1.28536 103219
> #number of rows 
> x <- nrow(quotes)
> quotes1 <- as.ts(quotes$Close)
> 
> library(fGarch)
Loading required package: timeDate
Loading required package: timeSeries
Loading required package: fBasics


Rmetrics Package fBasics
Analysing Markets and calculating Basic Statistics
Copyright (C) 2005-2014 Rmetrics Association Zurich
Educational Software for Financial Engineering and Computational Science
Rmetrics is free software and comes with ABSOLUTELY NO WARRANTY.
https://www.rmetrics.org --- Mail to: info@rmetrics.org
> garchModel <- garchFit(~ arma(4,4) + garch(2, 2),
+                            data = quotes1[(x-125):(x-2)], trace = FALSE)
> 
> predict(garchModel, n.ahead = 2, plot = TRUE)
  meanForecast   meanError standardDeviation lowerInterval upperInterval
1     1.254672 0.005038828       0.005038828      1.244796      1.264548
2     1.252095 0.005582340       0.005048046      1.241154      1.263036
Warning message:
In predict.Arima(ARMA, n.ahead) : MA part of model is not invertible

We have used a GARCH model to predict the next daily candle. You can see GARCH(2,2) model predicts the price to be 1.2546 whereas actual price is 1.2850. Below is a GARCH prediction plot. GARCH model miserably fails to predict rapidly moving markets.

GBPUSD GARCH Model

Now we try the exponential EGARCH model below and see if we can have a good prediction.

> #eGARCH Model
> # Import the csv file
> quotes <- read.csv("D:/MarketData/GBPUSD1440.csv", header=FALSE)
> colnames(quotes) <- c("Date", "Time", "Open", "High", "Low", "Close", "Volume")
> tail(quotes)
           Date  Time    Open    High     Low   Close Volume
2046 2017.04.12 00:00 1.24900 1.25486 1.24806 1.25373 253346
2047 2017.04.13 00:00 1.25387 1.25743 1.25004 1.25054 231645
2048 2017.04.14 00:00 1.25085 1.25351 1.25009 1.25283 168341
2049 2017.04.17 00:00 1.25325 1.25962 1.25250 1.25646  85714
2050 2017.04.18 00:00 1.25648 1.29059 1.25149 1.28412 240045
2051 2017.04.19 00:00 1.28410 1.28606 1.28095 1.28536 103219
> #number of rows 
> x <- nrow(quotes)
> quotes1 <- as.ts(quotes$Close)
> #load rugarch library
> library(rugarch)

Attaching package: ‘rugarch’

The following object is masked from ‘package:stats’:

    sigma

> 
> spec = ugarchspec(variance.model = list(model = 'eGARCH', garchOrder = c(2, 1)), 
+                   distribution = 'std')
> 
> egarch1<- ugarchfit(spec, quotes1[(x-125):(x-2)], solver = 'hybrid')
> egarch1

*---------------------------------*
*          GARCH Model Fit        *
*---------------------------------*

Conditional Variance Dynamics 	
-----------------------------------
GARCH Model	: eGARCH(2,1)
Mean Model	: ARFIMA(1,0,1)
Distribution	: std 

Optimal Parameters
------------------------------------
         Estimate  Std. Error     t value Pr(>|t|)
mu       1.219514    0.001120 1089.220517 0.000000
ar1      0.988453    0.016541   59.758686 0.000000
ma1     -0.142465    0.030703   -4.640081 0.000003
omega   -9.942181    3.090857   -3.216642 0.001297
alpha1   0.034126    0.096972    0.351911 0.724905
alpha2   0.422871    0.078430    5.391664 0.000000
beta1    0.001000    0.308524    0.003241 0.997414
gamma1   0.565470    0.184712    3.061367 0.002203
gamma2  -0.688925    0.118777   -5.800171 0.000000
shape   99.999709  227.876955    0.438832 0.660783

Robust Standard Errors:
         Estimate  Std. Error    t value Pr(>|t|)
mu       1.219514    0.001436 849.364810 0.000000
ar1      0.988453    0.012914  76.539529 0.000000
ma1     -0.142465    0.017990  -7.919099 0.000000
omega   -9.942181    4.021448  -2.472289 0.013425
alpha1   0.034126    0.066198   0.515505 0.606200
alpha2   0.422871    0.073248   5.773114 0.000000
beta1    0.001000    0.399901   0.002501 0.998005
gamma1   0.565470    0.229096   2.468272 0.013577
gamma2  -0.688925    0.234418  -2.938869 0.003294
shape   99.999709   44.488914   2.247744 0.024592

LogLikelihood : 439.8295 

Information Criteria
------------------------------------
                    
Akaike       -6.9327
Bayes        -6.7053
Shibata      -6.9445
Hannan-Quinn -6.8403

Weighted Ljung-Box Test on Standardized Residuals
------------------------------------
                        statistic p-value
Lag[1]                    0.05787 0.80990
Lag[2*(p+q)+(p+q)-1][5]   4.29546 0.03012
Lag[4*(p+q)+(p+q)-1][9]   7.40787 0.09353
d.o.f=2
H0 : No serial correlation

Weighted Ljung-Box Test on Standardized Squared Residuals
------------------------------------
                         statistic p-value
Lag[1]                       1.973  0.1601
Lag[2*(p+q)+(p+q)-1][8]      5.924  0.2428
Lag[4*(p+q)+(p+q)-1][14]     7.566  0.4348
d.o.f=3

Weighted ARCH LM Tests
------------------------------------
            Statistic Shape Scale P-Value
ARCH Lag[4]    0.1785 0.500 2.000  0.6726
ARCH Lag[6]    2.9402 1.461 1.711  0.3168
ARCH Lag[8]    3.6667 2.368 1.583  0.4269

Nyblom stability test
------------------------------------
Joint Statistic:  2.7614
Individual Statistics:              
mu     0.12188
ar1    0.34245
ma1    0.06640
omega  0.13363
alpha1 0.01101
alpha2 0.05246
beta1  0.16386
gamma1 0.11497
gamma2 0.20266
shape  0.89901

Asymptotic Critical Values (10% 5% 1%)
Joint Statistic:     	 2.29 2.54 3.05
Individual Statistic:	 0.35 0.47 0.75

Sign Bias Test
------------------------------------
                   t-value   prob sig
Sign Bias           1.2960 0.1975    
Negative Sign Bias  1.1208 0.2646    
Positive Sign Bias  0.3114 0.7561    
Joint Effect        2.9958 0.3923    


Adjusted Pearson Goodness-of-Fit Test:
------------------------------------
  group statistic p-value(g-1)
1    20     15.35       0.6998
2    30     25.03       0.6766
3    40     29.55       0.8631
4    50     39.71       0.8256


Elapsed time : 12.72658 

> 
> forecast <- ugarchforecast(egarch1, n.ahead = 1)
> forecast

*------------------------------------*
*       GARCH Model Forecast         *
*------------------------------------*
Model: eGARCH
Horizon: 1
Roll Steps: 0
Out of Sample: 0

0-roll forecast [T0=1970-05-05 05:00:00]:
    Series    Sigma
T+1  1.255 0.008436


> sigma(forecast);
    1970-05-05 05:00:00
T+1         0.008435753
> fitted(forecast)
    1970-05-05 05:00:00
T+1            1.255413

Now EGARCH model  daily price prediction is almost the same as the GARCH model daily price prediction. Both GARCH and EGARCH model fail to predict any volatility in the market. In my view GARCH model is useless. GARCH stands for Generalized Auto Regressive Conditionally Heteroscedastic. After reading this post you should release the difficulty of predicting currency market. When price moves it moves very fast. We call this high volatility. When the price ranges it ranges for many hours. The challenge is to predict when price is going to move very fast and when it is going to move slow.