Is there a best time of day to trade Bitcoin?

Which hours of day do Bitcoin make biggest gains and losses? Is there a best time of the day to trade it? In this article I attempt to answer this question using statistics. This is an educational article, and is not investment or trading advice. Backtest performance never guarantees real-time trading performance.

For the analyses I used historical hourly Bitcoin prices between January 1st 2012 and May 5th 2021. I did not include slippage, commissions or taxes. I provide the R code I used to do the analyses so you can replicate it if you wanted to. However, you will have to get the data yourself.

There are a few packages we will use so I suggest you install them and load them.

install.packages("tidyverse","data.table","plyr","kableExtra","effsize")
library(ggplot2)
library(data.table)
library(plyr)
library(tidyverse)
library(kableExtra)
library(effsize)

Is there a best time of day to trade?

First let’s get the data and calculate descriptive statistics including mean, standard deviation, minimum, and maximum values for price percent change.

# read the data in to a data frame
hrs <- read_csv("hours.csv")
# create empty data frame to store descriptive statistics
hours <- data.frame("Hour" = character(),"Mean"=numeric(),"SD" = numeric(),"Min" = numeric(), "Max" = numeric(), stringsAsFactors = F)
hrs_distinct <-distinct(hrs,Hour)
# calculate descriptives for each day
for (i in 1:nrow(hrs_distinct)){
  hr <- hrs_distinct[i,"Hour"]$Hour
  now <- hrs %>%  filter (Hour == hr)
  meand <- round(mean(now$Percent), digits = 2)
  sdd <- round(sd(now$Percent), digits = 2)
  mind <- round(min(now$Percent), digits = 2)
  maxd <- round(max(now$Percent), digits = 2)
  hours[as.numeric(hr)+1,] <- c(hr,meand,sdd,mind,maxd)
}
# convert the columns to numeric
hours[,c(2:5)] <- sapply(hours[,c(2:5)], as.numeric)
# the descriptives table
hours %>% kbl(row.names=F) %>% kable_paper()

Let’s look at the descriptive statistics. The mean percent price change seems to fluctuate around zero, this doesn’t look significant. Standard deviation is also between 1 and 1.5, that seems similar across hours too. But look at the minimum and maximum price change percentages. Anything more than 25% happened at night hours or early in the morning. Day time seems much more stable.

Bitcoin price change with respect to hours of day descriptive statistics

Let’s see if we can detect a difference in price percentage changes with respect to hours.

# ANOVA
res.aov <- aov(Percent ~ Hour, data = hrs)
summary(res.aov)
# Tukey's test
kk<-TukeyHSD(res.aov, "Hour", ordered = TRUE)
kk$Hour
result<-data.frame( kk$Hour)
result["p.adj"]

I have not shown the comparisons table but there is nothing with p < 0.05. So not even statistical significance is detected. No need to look for practical significance.

Now I wonder if daytime and nighttime has an effect. I will define daytime as hour between 07:00 to 19:00 and nighttime as 20:00 to 06:00.

daytime <- hrs %>% mutate(is_day=ifelse(Hour < 20 | Hour > 6,"Day","Night"))
res.aov <- aov(Percent ~ is_day, data = daytime)
summary(res.aov)

The output shows:

               Df   Sum Sq Mean Sq F value Pr(>F)  
is_day          1      5   4.769   3.924 0.0476 *
Residuals   78324  95199   1.215                 
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Looks like there is a statistically significant difference between day and night. Let’s see how it is further.

TukeyHSD(res.aov)

The output:

                diff         lwr           upr     p adj
Night-Day -0.0208619 -0.04150426 -0.0002195331 0.0476128

But is this practically significant?

day <- daytime %>% filter(is_day == "Day")
night<- daytime %>% filter(is_day == "Night")
cohen.d(day$Percent,night$Percent)

The output says no, the difference is negligible in practice:

Cohen's d

d estimate: 0.01892282 (negligible)
95 percent confidence interval:
       lower        upper 
0.0001986041 0.0376470376 

Finally let’s visualize the two distributions:

# clean to show the differences in means
daytime <- daytime %>% filter(Percent > -5 & Percent < 5)
# create the plot for weekends and weekdays
mu <- ddply(daytime, "is_day", summarise, grp.mean=mean(Percent))
ggplot(daytime, aes(x=Percent, color=is_day, fill=is_day)) +
  geom_histogram(aes(y=..density..), position="identity", alpha=0.5, bins = 50)+
  geom_density(alpha=0.6)+
  geom_vline(data=mu, aes(xintercept=grp.mean, color=is_day),
             linetype="dashed")+
  scale_color_manual(values=c("#000000", "#ff0000", "#56B4E9"))+
  scale_fill_manual(values=c("#cccccc", "#fff000", "#56B4E9"))+
  labs(title="Day vs Night Price Change Percentage",x="Price Change %", y = "Density (Frequency)")+
  theme_classic()
Bitcoin day versus night price change distribution

I was led to think that there might be a difference between day and night in terms of price percentage change, but I found no practically significant difference. What does this mean? We can interpret it as, the Bitcoin market does not sleep, any time of day is equally likely for a price change to happen. Let me say it again, this is not trading or investment advice.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.