In this post we are going to forward test a simple binary options trading strategy. In this simple binary options trading strategy we are going to bet in the direction of the previous candle. For example, if the previous candle is bullish on 5 minute chart, we will buy a call option with expiry 5 minute. And in case if the previous candle is bearish, we are going to buy a put option with expiry 5 minutes. Did you read the previous post on how to use regressions splines in trading binary options? We can use this bet as previous binary options strategy in all timeframes. We need to measure its average winrate and check much profitable this strategy is. Below is the R script that we will use. You should have R and RStudio installed on your computer.
> ###########Bet As Previous Strategy######### > ###########Strategy Forward Test######## > > data <- read.csv("E:/MarketData/EURUSD5.csv", header = FALSE) > > > > colnames(data) <- c("Date", "Time", "Open", "High", + "Low", "Close", "Volume") > > x1 <- nrow(data) > > > #define lookback > > lb=500 > > Results <-data.frame(matrix(0, ncol=2, nrow=500)) > > > > #Results$Predicted <- factor(Results$Predicted, levels=c(-1, 1)) > > for (i in (1:lb)) + { + + Results[i, 1] <- data[x1-lb+i,6] - data[x1-lb+i-1,6] + + } > > Results[,2] <- ifelse(Results[ ,1] > 0, 1,-1 ) > > > Results[,2] <- factor(Results[ ,2]) > > for (i in (1:lb-1)) + { + + Results[i, 3] <- Results[i+1, 2] + + } > > colnames(Results) <- c("Direction", "Predicted", "Actual") > > Results <- Results[-500, ] > > table(Results$Predicted, Results$Actual) -1 1 -1 137 131 1 131 100 > > library(gmodels) > CrossTable(Results$Predicted, Results$Actual) Cell Contents |-------------------------| | N | | Chi-square contribution | | N / Row Total | | N / Col Total | | N / Table Total | |-------------------------| Total Observations in Table: 499 | Results$Actual Results$Predicted | -1 | 1 | Row Total | ------------------|-----------|-----------|-----------| -1 | 137 | 131 | 268 | | 0.334 | 0.388 | | | 0.511 | 0.489 | 0.537 | | 0.511 | 0.567 | | | 0.275 | 0.263 | | ------------------|-----------|-----------|-----------| 1 | 131 | 100 | 231 | | 0.388 | 0.450 | | | 0.567 | 0.433 | 0.463 | | 0.489 | 0.433 | | | 0.263 | 0.200 | | ------------------|-----------|-----------|-----------| Column Total | 268 | 231 | 499 | | 0.537 | 0.463 | | ------------------|-----------|-----------|-----------| > > library(caret) Loading required package: lattice Loading required package: ggplot2 > confusionMatrix(Results$Predicted, Results$Actual) Confusion Matrix and Statistics Reference Prediction -1 1 -1 137 131 1 131 100 Accuracy : 0.4749 95% CI : (0.4304, 0.5198) No Information Rate : 0.5371 P-Value [Acc > NIR] : 0.9976 Kappa : -0.0559 Mcnemar's Test P-Value : 1.0000 Sensitivity : 0.5112 Specificity : 0.4329 Pos Pred Value : 0.5112 Neg Pred Value : 0.4329 Prevalence : 0.5371 Detection Rate : 0.2745 Detection Prevalence : 0.5371 Balanced Accuracy : 0.4720 'Positive' Class : -1 > > library(vcd) Loading required package: grid > Kappa(table(Results$Predicted, Results$Actual)) value ASE z Pr(>|z|) Unweighted -0.05591 0.04467 -1.252 0.2107 Weighted -0.05591 0.04467 -1.252 0.2107 > > > #calculate the profit made by this Bet As Previous Strategy > #we start with $100 and bet $1 on each trade > > > > > Results$Profit <- ifelse (Results[, 2] == Results[,3], 0.8, -1) > > sum(Results$Profit) [1] -72.4 > > profit <- 100 > > for (i in (1:100)) + { + ifelse(Results[i,1]==Results[i,3], (profit= profit+0.8), (profit= profit-1)) + + } > > profit [1] 0
Now after running the R script, we can check the accuracy of this bet as previous binary options strategy. It is only 47% which is very poor. If we have started with a sum of $100. After 500 $1 trades, we will end up with a loss of $72. If we do 100 $1 trades then we will end up with a balance of zero. What this means is that this strategy is not profitable at all. Can we increase the winrate of this bet as previous binary options trading strategy?
Did you check our course on Quantitative Trading Fundamentals? In this course we teach you the fundamentals of quantitative trading in simple step by step manner. If you have never studied quantitative trading, this is the course for you. Quantitative trading methods are now increasingly being used in algorithmic trading. If you don’t learn quantitative trading now, you will left behind in the next few years.
Let’s use 1 minute timeframe and bet in the previous direction of 5 minute and see if we have a better winrate. This is what we are going to do. At the end of each 1 minute, we are going to reframe the data into 5 minute candles and bet in the direction of the previous 5 minute candle. In essence we will have a binary options signal after every 1 minute. Did you read the post on this 30 minute binary options trading strategy with 90% average winrate?
> ####################################### > ############################################################### > ###########Bet As Previous Strategy######### > ###########Strategy Forward Test######## > > data <- read.csv("E:/MarketData/EURUSD1.csv", header = FALSE) > > > > colnames(data) <- c("Date", "Time", "Open", "High", + "Low", "Close", "Volume") > > > x11 <- nrow(data) > > x12 <- x11-500 > > #convert this data to n timeframe > > n=5 > > #define lookback > > lb=500 > > > #define a new data frame > > data1 <-data.frame(matrix(0, ncol=7, nrow=300)) > > colnames(data1) <- c("Date", "Time", "Open", "High", + "Low", "Close", "Pips") > > Results <-data.frame(matrix(0, ncol=2, nrow=500)) > > colnames(Results) <- c("Predicted", "Actual") > > Results$Predicted <- factor(Results$Predicted, levels=c(-1, 1)) > > # run the sequence to convert to a new timeframe > > for (j in (1:500)) + { + x1 <- x12-1000-j+1 + + for ( k in (1:lb)) + { + data1[k,1] <- as.character(data[x1-lb*n+n*k-1,1]) + data1[k,2] <- as.character(data[x1-lb*n+n*k-1,2]) + data1[k,3] <- data[x1-lb*n+n*(k-1),3] + data1[k,6] <- data[x1-lb*n+n*k-1,6] + data1[k,4] <- max(data[(x1-lb*n+n*(k-1)):(x1-lb*n+k*n-1), 4:5]) + data1[k,5] <- min(data[(x1-lb*n+n*(k-1)):(x1-lb*n+k*n-1), 4:5]) + } + + + + + + for (i in (1:(lb-1))) + { + data1[i+1, 7] <- 10000*(data1[i+1, 6]-data1[i,6]) + data1[i,7] <- data1[i+1,7] + } + + data1$Direction <- ifelse(data1[ ,7] > 0, 1,-1 ) + + + data1$Direction <- factor(data1$Direction) + + + + Results[j,1] <- data1[j, 8] + Results[j,2] <- 10000*(data[x1+n,6]-data[x1,6]) + + } > > Results$Direction <- factor(ifelse(Results[ ,2] > 0, 1, -1)) > > table(Results$Predicted, Results$Direction) -1 1 -1 131 136 1 87 146 > > library(gmodels) > CrossTable(Results$Predicted, Results$Direction) Cell Contents |-------------------------| | N | | Chi-square contribution | | N / Row Total | | N / Col Total | | N / Table Total | |-------------------------| Total Observations in Table: 500 | Results$Direction Results$Predicted | -1 | 1 | Row Total | ------------------|-----------|-----------|-----------| -1 | 131 | 136 | 267 | | 1.828 | 1.413 | | | 0.491 | 0.509 | 0.534 | | 0.601 | 0.482 | | | 0.262 | 0.272 | | ------------------|-----------|-----------|-----------| 1 | 87 | 146 | 233 | | 2.095 | 1.619 | | | 0.373 | 0.627 | 0.466 | | 0.399 | 0.518 | | | 0.174 | 0.292 | | ------------------|-----------|-----------|-----------| Column Total | 218 | 282 | 500 | | 0.436 | 0.564 | | ------------------|-----------|-----------|-----------| > > library(caret) > confusionMatrix(Results$Predicted, Results$Direction) Confusion Matrix and Statistics Reference Prediction -1 1 -1 131 136 1 87 146 Accuracy : 0.554 95% CI : (0.5092, 0.5981) No Information Rate : 0.564 P-Value [Acc > NIR] : 0.690548 Kappa : 0.1157 Mcnemar's Test P-Value : 0.001308 Sensitivity : 0.6009 Specificity : 0.5177 Pos Pred Value : 0.4906 Neg Pred Value : 0.6266 Prevalence : 0.4360 Detection Rate : 0.2620 Detection Prevalence : 0.5340 Balanced Accuracy : 0.5593 'Positive' Class : -1 > > library(vcd) > Kappa(table(Results$Predicted, Results$Direction)) value ASE z Pr(>|z|) Unweighted 0.1157 0.0435 2.66 0.007818 Weighted 0.1157 0.0435 2.66 0.007818 > > library(irr) Loading required package: lpSolve > Results1 <- Results[, -2] > > kappa2(Results1[, 1:2]) Cohen's Kappa for 2 Raters (Weights: unweighted) Subjects = 500 Raters = 2 Kappa = 0.116 z = 2.64 p-value = 0.00836 > > #calculate the profit made by this Bet As Previous Strategy > #we start with $100 and bet $1 on each trade > > > Results$Profit <- ifelse (Results[, 1] == Results[,3], 0.8, -1) > > sum(Results$Profit) [1] -1.4 > > profit <- 100 > > for (i in (1:lb)) + { + ifelse(Results[i,1]==Results[i,3], (profit=profit+0.8), (profit= profit-1)) + + } > > profit [1] 98.6
Now we have a slightly better winrate of 55%. But still we don’t have an edge against the market. In the future posts I am going to show how we can use ensemble learning on weak learners like above and take the winrate above 80%. In binary options trading we need to have at least 80% winrate if we want our account to grow. If we lose a trade, we need 2 trades to recover the loss and make some profit. So we need to have a binary options strategy that has got a high winrate. Did you read the post on 3 exponential moving average binary options strategy?