Skip to content

Instantly share code, notes, and snippets.

@vishalinp
Last active March 15, 2018 10:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vishalinp/b0916c06455ec0e39d6bd69eff70786d to your computer and use it in GitHub Desktop.
Save vishalinp/b0916c06455ec0e39d6bd69eff70786d to your computer and use it in GitHub Desktop.
Bitcoin Automated Alert Mock-up (SatRday 2018)

Hi!

This gist contains all of the necessary files to set up an automated alert on the price of Bitcoin, as covered in my talk at SatRday 2018.

You should be able to pop these files into a folder, fill out the necessary config at the top of 'Analysis_template.R' and have a working Rscript and Rmarkdown pair. In order to get this running on a schedule, you will need to hook 'BitcoinAlert_template.bat' to a task in Windows Task Scheduler. And that's it! If you experience any issues, please feel free to ask questions at vishalin.pillay@outlook.com.

library(jsonlite)
library(dplyr)
library(tidyr)
library(ggplot2)
library(RcppRoll)
library(mailR)
library(knitr)
setwd("directory/of/your/Rscript")
#---------------------------------Define Parameters----------------------------------------------
currentDate <- Sys.Date()
anchorDate <- as.Date('2016-01-01')
currency <- 'ZAR'
retro <- 1 #how far back to compare the price in days
#Email Config
sender <- 'example@example.com'
recipients <- c('abc@example.com','def@example.com')
smtp.hostname <- 'smtp.gmail.com'
smtp.port <- 465
smtp.username <- 'example@example.com'
emailpass <- 'you may want to put this elsewhere'
#---------------------------------Define Parameters----------------------------------------------
coindeskURL <- paste('https://api.coindesk.com/v1/bpi/historical/close.json',
'?currency=', currency,
'&start=', anchorDate,
'&end=', currentDate, sep='')
coindesk <- fromJSON(coindeskURL)
bpi <- as.data.frame(coindesk[1]) %>%
gather('Day', 'Price') %>%
mutate(Day = as.Date(gsub('bpi.', '', Day), format='%Y.%m.%d'), Price = as.numeric(Price)) %>%
arrange(Day) %>%
mutate(Index = seq.int(nrow(.)))
#12, 26, 50, 200 ema
emamult <- function(period)
{
2/(period + 1)
}
EmafromSma <- function(data)
{
data <- as.matrix(data)
for(i in 2:nrow(data))
{
if(!is.na(data[i-1, 'EMA12']))
{
data[i, 'EMA12'] <- (as.numeric(data[i, 'Price']) - as.numeric(data[i-1, 'EMA12'])) * emamult(12) + as.numeric(data[i-1, 'EMA12'])
}
if(!is.na(data[i-1, 'EMA26']))
{
data[i, 'EMA26'] <- (as.numeric(data[i, 'Price']) - as.numeric(data[i-1, 'EMA26'])) * emamult(26) + as.numeric(data[i-1, 'EMA26'])
}
if(!is.na(data[i-1, 'EMA50']))
{
data[i, 'EMA50'] <- (as.numeric(data[i, 'Price']) - as.numeric(data[i-1, 'EMA50'])) * emamult(50) + as.numeric(data[i-1, 'EMA50'])
}
if(!is.na(data[i-1, 'EMA200']))
{
data[i, 'EMA200'] <- (as.numeric(data[i, 'Price']) - as.numeric(data[i-1, 'EMA200'])) * emamult(200) + as.numeric(data[i-1, 'EMA200'])
}
}
data
}
bpitechnical <-
mutate(bpi,
SMA12 = roll_mean(Price, 12, align='right', fill=NA),
SMA26 = roll_mean(Price, 26, align='right', fill=NA),
SMA50 = roll_mean(Price, 50, align='right', fill=NA),
SMA200 = roll_mean(Price, 200, align='right', fill=NA)
) %>%
mutate(EMA12 = ifelse(Index == 12, SMA12, NA),
EMA26 = ifelse(Index == 26, SMA26, NA),
EMA50 = ifelse(Index == 50, SMA50, NA),
EMA200 = ifelse(Index == 200, SMA200, NA),
)
bpitechnical <- as.data.frame(EmafromSma(bpitechnical)) %>% mutate(Day = as.Date(as.character(Day)))
numericcolumns <- 2:11
bpitechnical[,numericcolumns] <- apply(bpitechnical[,numericcolumns], 2, function(x) {as.numeric(as.character(x))})
saveRDS(bpitechnical, 'bpitechnical.rda')
emastatus <- function(data, ema, lag)
{
yesterdayabove <- ifelse(data[nrow(data)-lag, 'Price'] > data[nrow(data)-lag, ema], T, F)
todayabove <- ifelse(data[nrow(data), 'Price'] > data[nrow(data), ema], T, F)
if(yesterdayabove != todayabove)
{
ifelse(yesterdayabove, 'FALL', 'RISE')
}else
{
'UNCHANGED'
}
}
ema12status <- emastatus(bpitechnical, 'EMA12', retro)
ema26status <- emastatus(bpitechnical, 'EMA26', retro)
ema50status <- emastatus(bpitechnical, 'EMA50', retro)
ema200status <- emastatus(bpitechnical, 'EMA200', retro)
if(ema12status != 'UNCHANGED' || ema26status != 'UNCHANGED' || ema50status != 'UNCHANGED' || ema200status != 'UNCHANGED')
{
markdown <- paste(readLines('BitcoinAlert_template.Rmd', warn = FALSE), collapse = "\n")
message <- knitr::knit2html(text=markdown, options=c("use_xhtml", "smartypants","mathjax","highlight_code"))
send.mail(from = sender,
to = recipients,
subject = "Bitcoin Alert",
body = message,
html = TRUE,
inline = TRUE,
smtp = list(host.name = smtp.hostname, port = smtp.port, user.name = smtp.port, passwd = emailpass, ssl = TRUE),
authenticate = TRUE,
send = TRUE)
}
Rscript path\to\your\script\Analysis_template.R
pause
```{r setup, include=FALSE}
knitr::opts_chunk$set(
echo = FALSE,
message = FALSE,
warning = FALSE,
fig.width = 12,
fig.height = 6
)
```
## Bitcoin Price Alert
The bitcoin price has broken through one or more resistance levels. Please see below for details:
</br>
```{r}
library(ggplot2)
library(dplyr)
bpitechnical <- readRDS('bpitechnical.rda')
emastatus <- function(data, ema, lag)
{
yesterdayabove <- ifelse(data[nrow(data)-lag, 'Price'] > data[nrow(data)-lag, ema], T, F)
todayabove <- ifelse(data[nrow(data), 'Price'] > data[nrow(data), ema], T, F)
if(yesterdayabove != todayabove)
{
ifelse(yesterdayabove, 'FALL', 'RISE')
}else
{
'UNCHANGED'
}
}
ema12status <- emastatus(bpitechnical, 'EMA12', 3)
ema26status <- emastatus(bpitechnical, 'EMA26', 3)
ema50status <- emastatus(bpitechnical, 'EMA50', 3)
ema200status <- emastatus(bpitechnical, 'EMA200', 3)
ema12colour <- ifelse(ema12status == 'RISE', 'green', 'red')
ema26colour <- ifelse(ema26status == 'RISE', 'green', 'red')
ema50colour <- ifelse(ema50status == 'RISE', 'green', 'red')
ema200colour <- ifelse(ema200status == 'RISE', 'green', 'red')
ema12message <- ifelse(ema12status ==
'RISE', 'The price has risen through the 12 day resistance level.',
ifelse(ema12status ==
'FALL', 'The price has fallen through the 12 day resistance level.\n', '')
)
ema26message <- ifelse(ema26status ==
'RISE', 'The price has risen through the 26 day resistance level.',
ifelse(ema26status ==
'FALL', 'The price has fallen through the 26 day resistance level.\n', '')
)
ema50message <- ifelse(ema50status ==
'RISE', 'The price has risen through the 50 day resistance level.',
ifelse(ema50status ==
'FALL', 'The price has fallen through the 50 day resistance level.\n', '')
)
ema200message <- ifelse(ema200status ==
'RISE', 'The price has risen through the 200 day resistance level.',
ifelse(ema200status ==
'FALL', 'CRITICAL: The price has fallen through the 200 day resistance level.\n', '')
)
risesig <- ifelse(ema200status=='RISE', 4, ifelse(ema50status=='RISE', 3, ifelse(ema26status=='RISE', 2, ifelse(ema12status=='RISE', 1, 0))))
fallsig <- ifelse(ema200status=='FALL', 4, ifelse(ema50status=='FALL', 3, ifelse(ema26status=='FALL', 2, ifelse(ema12status=='FALL', 1, 0))))
positivenews <- ifelse(risesig > fallsig, T, F)
```
<span style="color:`r ema12colour `"> `r ema12message `</span>
<span style="color:`r ema26colour `"> `r ema26message `</span>
<span style="color:`r ema50colour `"> `r ema50message `</span>
<span style="color:`r ema200colour `"> `r ema200message `</span>
### Historical Views
```{r}
ggplot(bpitechnical, aes(x=Day)) +
geom_line(aes(y=Price), colour='black') +
geom_line(aes(y=EMA12), colour='green', size=1.3, alpha=0.3) +
geom_line(aes(y=EMA26), colour='yellow', size=1.3, alpha=0.3) +
geom_line(aes(y=EMA50), colour='orange', size=1.3, alpha=0.3) +
geom_line(aes(y=EMA200), colour='red', size=1.3, alpha=0.3) +
ylab('ZAR') +
theme(axis.title.x = element_blank()) +
ggtitle('All Time')
ggplot(filter(bpitechnical, Index > nrow(bpitechnical) - 365), aes(x=Day)) +
geom_line(aes(y=Price), colour='black') +
geom_line(aes(y=EMA12), colour='green', size=1.3, alpha=0.3) +
geom_line(aes(y=EMA26), colour='yellow', size=1.3, alpha=0.3) +
geom_line(aes(y=EMA50), colour='orange', size=1.3, alpha=0.3) +
geom_line(aes(y=EMA200), colour='red', size=1.3, alpha=0.3) +
ylab('ZAR') +
theme(axis.title.x = element_blank()) +
ggtitle('1 Year')
ggplot(filter(bpitechnical, Index > nrow(bpitechnical) - 92), aes(x=Day)) +
geom_line(aes(y=Price), colour='black') +
geom_line(aes(y=EMA12), colour='green', size=1.3, alpha=0.3) +
geom_line(aes(y=EMA26), colour='yellow', size=1.3, alpha=0.3) +
geom_line(aes(y=EMA50), colour='orange', size=1.3, alpha=0.3) +
geom_line(aes(y=EMA200), colour='red', size=1.3, alpha=0.3) +
ylab('ZAR') +
theme(axis.title.x = element_blank()) +
ggtitle('3 Months')
ggplot(filter(bpitechnical, Index > nrow(bpitechnical) - 31), aes(x=Day)) +
geom_line(aes(y=Price), colour='black') +
geom_line(aes(y=EMA12), colour='green', size=1.3, alpha=0.3) +
geom_line(aes(y=EMA26), colour='yellow', size=1.3, alpha=0.3) +
geom_line(aes(y=EMA50), colour='orange', size=1.3, alpha=0.3) +
geom_line(aes(y=EMA200), colour='red', size=1.3, alpha=0.3) +
ylab('ZAR') +
theme(axis.title.x = element_blank()) +
ggtitle('1 Month')
```
</br>
`r if(positivenews){'[comment]: # '}` EVERYTHING WILL BE FINE, JUST <span style="color:green"> HODL </span>
</br>
Trading in cryptocurrencies is a high risk venture. Consult with a financial advisor before making investment decisions. This should not be treated as expert financial advice.
</br>
`Powered by coindesk.com`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment