Based on statistics, what is the range in which Bitcoin may move?
Let's use returns since 2014 as a reasonable estimate of what will happen in the future.
avg <- mean(ClCl(rawdailyohlc['2014-01-01/']), na.rm = TRUE)
sdev <- sd(ClCl(rawdailyohlc['2014-01-01/']), na.rm = TRUE)
The average daily return is 0.0026 and the standard deviation is 0.0375.
For plotting purposes get the first and last value.
lval <- as.numeric(last(Cl(rawdailyohlc['2017-08-01/'])))
fval <- as.numeric(first(Cl(rawdailyohlc['2017-08-01/'])))
Intitialize some variables and then store the already realized Bitcoin values.
N <- 50
tval <- 1:N
oldval <- c(as.numeric(Cl(rawdailyohlc['2017-08-01/'])), rep(NA, N))
Define the confidence level that we are interested in and calculate the upper and lower ranges that the value may deviate to with that confidence level
qval <- qnorm(0.99, mean = 0, sd = 1, log.p = FALSE)
newvalu <- lval*exp((avg - 0.5 * sdev^2)*tval + qval * sdev * sqrt(tval))
newvalu <- c(rep(NA, length(oldval)-N-1), lval, newvalu)
newvald <- lval*exp((avg - 0.5 * sdev^2)*tval - qval * sdev * sqrt(tval))
newvald <- c(rep(NA, length(oldval)-N-1), lval, newvald)
Plot the results.
png(filename = "btc_plot_daily_futurerange.png")
plot(oldval, type = 'l', ylim = c(0, lval*2))
lines(newvalu, col = 'green')
lines(newvald, col = 'red')
dev.off()
This is a different way of thinking about it. We plot the range around the already existing time series.
avg <- mean(ClCl(rawdailyohlc['2014-01-01/2017-01-01']), na.rm = TRUE)
sdev <- sd(ClCl(rawdailyohlc['2014-01-01/2017-01-01']), na.rm = TRUE)
lval <- as.numeric(Cl(rawdailyohlc['2017-01-01']))
N <- 365
oldval <- c(as.numeric(Cl(rawdailyohlc['2017-01-01/'])), rep(NA, N-nrow(rawdailyohlc['2017-01-01/'])))
tval <- 1:N
qval <- qnorm(0.99, mean = 0, sd = 1, log.p = FALSE)
newvalu <- lval*exp((avg - 0.5 * sdev^2)*tval + qval * sdev * sqrt(tval))
newvalu <- c(lval, newvalu)
newvald <- lval*exp((avg - 0.5 * sdev^2)*tval - qval * sdev * sqrt(tval))
newvald <- c(lval, newvald)
png(filename = "btc_plot_daily_concurrentrange.png")
plot(oldval, type = 'l', ylim = c(0, max(newvalu, oldval, na.rm = TRUE)))
lines(newvalu, col = 'green')
lines(newvald, col = 'red')
dev.off()
In the plot we can see that the price has exceeded all expectations, how confident are we about our assumptions?
A slightly different version of the above plot, comparing to an even longer history. Demonstrates merging with xts series and a different plotting interface from quantmod.
refdatea <- as.Date('2016-01-01')
refdate <- as.Date('2017-01-01')
oldval <- Cl(rawdailyohlc['2016-01-01/'])
n <- nrow(oldval)
# redefine dates otherwise they will not merge
oldval <- xts(oldval, order.by = as.Date(as.POSIXct(refdatea + 1:n, tz = 'UTC')))
newvalu <- lval*exp((avg - 0.5 * sdev^2)*tval + qval * sdev * sqrt(tval))
newvalu <- xts(newvalu, order.by = as.Date(as.POSIXct(refdate + 1:N, tz = 'UTC')))
newvald <- lval*exp((avg - 0.5 * sdev^2)*tval - qval * sdev * sqrt(tval))
newvald <- xts(newvald, order.by = as.Date(as.POSIXct(refdate + 1:N, tz = 'UTC')))
forplot <- merge(oldval, newvalu, newvald)
png(filename = "btc_plot_daily_concurrentrangelong.png")
chart_Series(forplot$Close, name = 'Bitcoin USD')
add_TA(forplot$newvalu, on = 1, col = 'Green')
add_TA(forplot$newvald, on = 1, col = 'Red')
dev.off()
But how confident are we about the assumptions of the returns and standard deviations? Especially after looking at the different outcomes throughout history.
The following commands show some tables about the changing returns and standard deviations.
table.CalendarReturns(ClCl(rawdailyohlc))
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ClCl.rawdailyohlc
2011 NA NA NA NA NA NA NA NA 0.0 -5.7 17.3 8.8 20.3
2012 -5.0 2.3 0.4 1.8 0.6 1.4 3.1 -4.6 -0.5 1.9 0.5 0.3 1.8
2013 5.2 7.1 4.4 -2.4 0.9 0.6 1.8 2.5 -0.6 3.0 -1.1 -0.6 22.4
2014 0.4 -5.3 -1.1 0.2 1.1 6.9 3.2 -4.4 4.5 -2.4 0.4 3.2 6.2
2015 -5.3 0.3 -1.5 4.8 -1.4 2.5 -1.3 0.4 -0.3 -5.6 1.4 1.2 -5.2
2016 -1.9 0.8 0.2 -1.8 0.8 5.3 -4.7 -0.9 0.4 0.0 1.5 0.7 0.2
2017 4.8 -0.3 3.5 1.3 4.3 -3.0 4.1 3.5 3.9 5.1 1.3 2.8 35.9
cbind(apply.yearly(ClCl(rawdailyohlc), mean), apply.yearly(ClCl(rawdailyohlc), sd))
ClCl.rawdailyohlc ClCl.rawdailyohlc.1
2011-12-31 NA NA
2012-12-31 0.003895785 0.04419571
2013-12-31 0.014032751 0.07576909
2014-12-31 -0.001477679 0.03945913
2015-12-31 0.001501913 0.03679823
2016-12-31 0.002526586 0.02510439
2017-12-03 0.008324553 0.04574109
You could even try the different monthly return and standard deviation values from:
cbind(apply.monthly(ClCl(rawdailyohlc), mean), apply.monthly(ClCl(rawdailyohlc), sd))
Now that we understand the range of possible outcomes, and what the caveats regarding the inputs mighe be we can see what portion of our portfolio Bitcoin should be: Evaluating a portfolio
You can also jump to each section directly from here:
- Introduction to Bitcoin analysis with R
- Retrieving Bitcoin transaction data
- Part 2 - Reading the bitcoin data in to R
- Using the xts package and dates
- Using xts to summarize Bitcoin transaction data
- Setting up Bitcoin data in OHLC format
- Charting Bitcoin data
- Prliminary return analysis with plots
- Preliminary return analysis with rolling windows
- Technical analysis plots of Bitcoin
- Bitcoin's future price path
- Evaluating a portfolio
- Evaluating a stock portfolio
- Copulas and extreme values with Bitcoin
- Copulas and extreme value, many assets