How To Make A Candlestick Chart For A Custom Timeframe?

If you have been trading on MT4 for sometime, you know this that you can only watch these timeframes: 1M, 5M, 15M, 30M, 1H, 4H, Daily, Weekly and Monthly. Sometimes you would like to take a look at 3M chart or for that matter 2 hour chart or 8 hour chart and maybe 15 hour chart but on MT4 you cannot do it. People have developed indicators in MQL4 that draw the custom candlestick charts in a window below the main window which doesn’t give a good feel when you look at those custom charts.

Candlestick patterns are very important. A candle on 4 hour chart is a powerful signal that encompasses price action for the last 4 hours. How about 8 hour timeframe candle? Obviously an 8 hour candle is 2 times more powerful than a 4 hour candlestick as it encompasses 8 hours of price action. In the same manner a 12 hour candle is more powerful than a 8 hour candle. Instead of waiting for the daily candle to close you can look at 12 hour candle and know what price action is planning to do in the next 24 hours. Did you download your Cash Flow Channels System FREE PDF plus indicators? The important question that comes to mind is how to draw candlestick charts on these custom timeframes?

How to draw 2 hour candlestick chart?

In this post we will be using R data analysis and machine learning software to write a script that will draw candlestick chart for any custom timeframe that we want. Last time we did a random walk with GBPUSD and found that this model cannot make good predictions. We promised in the last post to improve this model. We can improve this model by making a Kalman Filter that uses Bayesian analysis to closely follow price action. We will giving you the Kalman filter script in a new post in the near future.

Another problem that we face in making predictions is the fact that as we increase the number of steps ahead, predictive accuracy decreases. We can improve predictive accuracy by using the data to make predictions. You should have R and RStudio installed. You should be familiar with R language. Below is the screenshot of 2 hour candle. Did you see the long tail candle? This is the candle that was formed when GBPUSD crashed 1000 pips from 1.24000 to 1.14000 in just 1 minute. You can look at the chart and see that the candles are telling about the downtrend. In a future post we will show you how everything was written on the charts for a big downward move on GBPUSD after it broke the support found after the Brexit referendum. This chart has been made using R Quantmod library.

2 Hour Candle Plot

> #import the data
> 
> data <- read.csv("E:/MarketData/GBPUSD60.csv", header = FALSE)
> 
> 
> 
> colnames(data) <- c("Date", "Time", "Open", "High",
+                     "Low", "Close", "Volume")
> 
> str(data)
'data.frame':	9727 obs. of  7 variables:
 $ Date  : Factor w/ 408 levels "2015.03.18","2015.03.19",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ Time  : Factor w/ 32 levels "00:00","01:00",..: 8 10 11 12 13 14 15 16 18 20 ...
 $ Open  : num  1.48 1.48 1.48 1.48 1.48 ...
 $ High  : num  1.48 1.48 1.48 1.48 1.48 ...
 $ Low   : num  1.48 1.48 1.48 1.48 1.47 ...
 $ Close : num  1.48 1.48 1.48 1.48 1.48 ...
 $ Volume: int  1769 967 2207 2460 6785 9570 17085 10025 8877 7332 ...
> 
> x <- nrow(data)
> 
> 
> library(quantmod)
> 
> #convert this data to n timeframe
> 
> n=2
> 
> #define lookback
> 
> lb=300
> 
> data1 <-data.frame(matrix(0, ncol=6, nrow=300))
> 
> colnames(data1) <- c("Date", "Time", "Open", "High",
+                     "Low", "Close")
> 
> # run the sequence to convert to a new timeframe
> 
> for ( k in (1:lb))
+ {
+   data1[k,1] <- as.character(data[x-lb*n+n*(k-1),1])
+   data1[k,2] <- as.character(data[x-lb*n+n*(k-1),2])
+   data1[k,3] <- data[x-lb*n+n*(k-1)+1,3]
+   data1[k,6] <- data[x-lb*n+n*k,6]
+   data1[k,4] <- max(data[(x-lb*n+n*(k-1)+1):(x-lb*n+k*n), 4:5])
+   data1[k,5] <- min(data[(x-lb*n+n*(k-1)+1):(x-lb*n+k*n), 4:5])
+ }
> 
> tail(data1)
          Date  Time    Open    High     Low   Close
295 2016.10.07 02:00 1.23892 1.24843 1.23490 1.23974
296 2016.10.07 04:00 1.23980 1.24438 1.23848 1.24293
297 2016.10.07 06:00 1.24294 1.24696 1.24231 1.24626
298 2016.10.07 08:00 1.24622 1.24776 1.24185 1.24587
299 2016.10.07 10:00 1.24590 1.24607 1.23141 1.23153
300 2016.10.07 12:00 1.23148 1.23969 1.22282 1.23529
> 
> #convert data1 into an xts object
> 
> data2 <- as.xts(data1[,-(1:2)], as.POSIXct(paste(data1[,1],data1[,2]),
+                                           format='%Y.%m.%d %H:%M'))
> 
> 
> candleChart(data2,
+             theme='white', type='candles', subset='last 3 days')

 

In the above script. n is the timeframe. We have read GBPUSD H1 csv. In the above script, n is 2.  This will make a 2 hour candle. We could have selected n as 10 which would have made 10 hour candle. Above script calculated 300 candles based on the lookback variable lb. If we had selected lb as 500, it would have calculated 500 candles. We can read M1 csv candle and select n as 2 to draw a 2 minute candle. We can read M5 candle and select n as 2 which will make a 10 minute candle. Watch these video tutorials on forex breakout strategies.

How to draw 8 Hour Candlestick Chart?

In the same manner we could have read H4 csv and selected n as 2 which would have made 8 hour candle. Below is a 8 hour candlestick chart. Can you see the inverted hammer at the start of the chart which is signalling a strong downtrend.

8 Hour Candle Plot

You might be wondering why we need to draw different timeframe candles. The purpose is to predict the next candle using a neural network or a support vector machine. Read this post in which we explain how we made 270% in 1 week.  In the script below we made an 8 hour candle.

> #import the data
> 
> data <- read.csv("E:/MarketData/GBPUSD240.csv", header = FALSE)
> 
> 
> 
> colnames(data) <- c("Date", "Time", "Open", "High",
+                     "Low", "Close", "Volume")
> 
> str(data)
'data.frame':	10513 obs. of  7 variables:
 $ Date  : Factor w/ 1766 levels "2009.12.21","2009.12.22",..: 1 1 1 1 1 1 2 2 2 2 ...
 $ Time  : Factor w/ 13 levels "00:00","00:05",..: 1 3 5 7 9 11 1 3 5 7 ...
 $ Open  : num  1.61 1.62 1.61 1.61 1.61 ...
 $ High  : num  1.62 1.62 1.62 1.61 1.61 ...
 $ Low   : num  1.61 1.61 1.61 1.61 1.61 ...
 $ Close : num  1.62 1.61 1.61 1.61 1.61 ...
 $ Volume: int  5892 6251 11887 12436 10584 5136 6234 3828 12690 13307 ...
> 
> x <- nrow(data)
> 
> 
> 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.
> 
> #convert this data to n timeframe
> 
> n=2
> 
> #define lookback
> 
> lb=300
> 
> data1 <-data.frame(matrix(0, ncol=6, nrow=300))
> 
> colnames(data1) <- c("Date", "Time", "Open", "High",
+                     "Low", "Close")
> 
> # run the sequence to convert to a new timeframe
> 
> for ( k in (1:lb))
+ {
+   data1[k,1] <- as.character(data[x-lb*n+n*(k-1),1])
+   data1[k,2] <- as.character(data[x-lb*n+n*(k-1),2])
+   data1[k,3] <- data[x-lb*n+n*(k-1)+1,3]
+   data1[k,6] <- data[x-lb*n+n*k,6]
+   data1[k,4] <- max(data[(x-lb*n+n*(k-1)+1):(x-lb*n+k*n), 4:5])
+   data1[k,5] <- min(data[(x-lb*n+n*(k-1)+1):(x-lb*n+k*n), 4:5])
+ }
> 
> tail(data1)
          Date  Time    Open    High     Low   Close
295 2016.10.03 04:00 1.29403 1.29452 1.28460 1.28612
296 2016.10.03 12:00 1.28611 1.28718 1.28177 1.28410
297 2016.10.03 20:00 1.28363 1.28609 1.28166 1.28423
298 2016.10.04 04:00 1.28416 1.28494 1.27364 1.27632
299 2016.10.04 12:00 1.27634 1.27750 1.27196 1.27285
300 2016.10.04 20:00 1.27259 1.27459 1.27206 1.27326
> 
> #convert data1 into an xts object
> 
> data2 <- as.xts(data1[,-(1:2)], as.POSIXct(paste(data1[,1],data1[,2]),
+                                           format='%Y.%m.%d %H:%M'))
> 
> 
> candleChart(data2,
+             theme='white', type='candles', subset='last 3 days')

In the above scrip we read a GBPUSD 240 minute csv (240 minutes are equal to 4 hours). Now we need to make a predictive model using either fuzzy logic, neural network or support vector machines. Suppose we succeed in making a good predictive model that can predict the next candle. Using the above script, we can predict the 15 hour candle which will tell us the predicted price after 15 hours.

UPDATE: The above R code used a for loop which is inherently slow. It takes aboue 1.8 seconds for R to do the above calculations. So I vectorized the whole operation and optimized it. Now the whole code just takes 0.35 seconds to execute which is 9 times faster than the above code that used for loop.

> start.time <- Sys.time() 
> #define a new dataframe having candles n period long
> # Import the csv file
> data1 <- read.csv("D:/Shared/MarketData/GBPUSD30.csv",
 + header=FALSE) 
> colnames(data1) <- c("Date", "Time", "Open", "High", "Low",
 + "Close", "Volume") 
> x <-nrow(data1)-1 
> n <-30 
> k <- x-floor(x/n)*n 
> data3 <- as.data.frame(matrix(nrow=(x-k)/n, ncol=7, data=NA)) 
> colnames(data3) <- c("Date", "Time", "Open", "High", "Low",
 + "Close", "Volume") 
> x1 <-nrow(data3) 
> data3[ , 1] <- as.character(data1[seq(k+1, x-n+1, n),1]) 
> data3[ , 2] <- as.character(data1[seq(k+1, x-n+1,n),2]) 
> data3[ , 3] <- data1[seq(k+1, x-n+1,n),3] 
> data3[ , 6] <- data1[seq(k+n, x ,n), 6] 
> data3[ , 4] <- apply(suppressWarnings(matrix(nrow=x1, ncol=5,
 + data=data1[k+1:x,4], byrow=TRUE)), 1, FUN=max) 
> data3[ , 5] <- apply(suppressWarnings(matrix(nrow=x1, ncol=5,
 + data=data1[k+1:x,5], byrow=TRUE)), 1, FUN=min) 
> data3[ , 7] <- rowSums(suppressWarnings(matrix(nrow=x1, ncol=5,
 + data=data1[k+1:x,7], byrow=TRUE))) 
> data3[x1+1,1] <- as.character(data1[x+1, 1]) 
> data3[x1+1,2] <- as.character(data1[x+1, 2]) 
> data3[x1+1,3:7] <- data1[x+1,3:7] 
> tail(data3)
          Date  Time    Open    High     Low   Close Volume
427 2018.11.06 18:30 1.30866 1.34234 1.34130 1.31583   1287
428 2018.11.07 09:30 1.31584 1.34482 1.34208 1.31251   2123
429 2018.11.08 00:30 1.31250 1.34553 1.34381 1.31158   4432
430 2018.11.08 15:30 1.31157 1.34544 1.34294 1.30436   5021
431 2018.11.09 06:30 1.30435 1.34496 1.34301 1.29719   5886
432 2018.11.09 21:30 1.29716 1.29766 1.29673 1.29739    365
> end.time <- Sys.time() > time.taken <- end.time - start.time > time.taken
Time difference of 0.3599479 secs
> head(data3)
        Date  Time    Open    High     Low   Close Volume
1 2017.10.25 03:00 1.31314 1.31370 1.31251 1.32454   1863
2 2017.10.25 18:00 1.32455 1.31381 1.31091 1.32119   4875
3 2017.10.26 09:00 1.32116 1.32234 1.31174 1.31285   8850
4 2017.10.27 00:00 1.31282 1.32659 1.32177 1.31110   7739
5 2017.10.27 15:00 1.31106 1.32704 1.32234 1.31448   8301
6 2017.10.30 06:00 1.31445 1.32635 1.32430 1.32069   4927
> tail(data3)
          Date  Time    Open    High     Low   Close Volume
427 2018.11.06 18:30 1.30866 1.34234 1.34130 1.31583   1287
428 2018.11.07 09:30 1.31584 1.34482 1.34208 1.31251   2123
429 2018.11.08 00:30 1.31250 1.34553 1.34381 1.31158   4432
430 2018.11.08 15:30 1.31157 1.34544 1.34294 1.30436   5021
431 2018.11.09 06:30 1.30435 1.34496 1.34301 1.29719   5886
432 2018.11.09 21:30 1.29716 1.29766 1.29673 1.29739    365

You can see the whole code got executed in just 0.36 seconds. I was getting warning messages while doing the matrix operations.I am unable to figure out why the matrix operation is giving warnings so I have suppressed the warning messages. I double checked the matrix operation there was no error in it. So I fail to understand the warning messages that data is not multiple of row length. I leave it for another day to figure out the reason for the warning messages.