Skip to content

Instantly share code, notes, and snippets.

@gomesfellipe

gomesfellipe/bot_report_stocks.R Secret

Last active Mar 25, 2020
Embed
What would you like to do?
Bot para coleta de cotações da bolsa e analise para desmontagem da carteira que envia mensagem no telegram
#' Bot do telegram envia uma mensagem com status da carteira
#'
#' Inicia o bot do telegram que vai coletar os valores das últimas cotações
#' desejadas da Bovespa e do Bitcoin calculando uma tabela financeira e
#' informando quando o valor atual estiver superior ao valor de compra.
#' Atencao: Envie uma mensagem para bot no seu telegram para ativar!
#'
#' @param portifolio Ativos da carteira (ativos da Bovespa terminam com ".SA")
#' @param cot_inicio Cotacoes no momento da compra
#' @param qtd_inicio Quantidade adiquirida
#' @param frequencia Tempo (em segundos) para cara looping. Padrao 20 minutos
#' @author Fellipe Gomes <github.com/gomesfellipe>
#' @return Um looping infinito com uma rotina para importar dados da bolsa, analisar e reportar via telegram
#' @export
#' @example
#' bot_report_stocks(portifolio = c("TUPY3.SA","ELET3.SA", "BTC-USD"),
#' cot_inicio = c(34.83, 19.70, 32243.9),
#' qtd_inicio = c(200, 150, 0.032))
#'
#'
bot_report_stocks <- function(portifolio = NULL,
cot_inicio = NULL,
qtd_inicio = NULL,
frequencia = 60*20) {
# Configuracoes iniciais de acesso ===================================
require(dplyr)
require(purrr)
require(alphavantager)
require(jsonlite)
require(kableExtra)
require(telegram)
# Chaves de acesso do alphavantager e do telegram
# foram salvas no arquivo .Renviron por questoes
# de seguranca. Para obter suar chaves de acesso acesse:
# telegram: https://github.com/lbraglia/telegram
# alphavantage: https://www.alphavantage.co/
key = Sys.getenv("AV_API_KEY")
av_api_key(key)
# Definir bot (envie uma menssagem para o bot pela 1a vez no telegram para ativar)
bot <- TGBot$new(token = bot_token('fgstockbot'))
# Conectar ao R (Envie uma menssagem para o bot para ativar)
bot$set_default_chat_id(bot$getUpdates()$message$chat$id[1])
# Checagem de inputs =================================================
if(is.null(portifolio) | is.null(cot_inicio) | is.null(qtd_inicio)){
stop("Esta faltando algum dos inputs!")}
# Funcoes auxiliares ==================================================
porcentagem <- function(x){paste0(round(x,2), "%")}
moeda_real <- function(x){
paste0("R\\$", format(x, big.mark = ".", decimal.mark = ",",
nsmall = 2, digits = 2))}
cat("Conferir se a bolsa esta aberta\n") # ========================
while((Sys.time() > lubridate::hm("9:30") &
Sys.time() < lubridate::hm("17:55") )) {
cat("Importar dados da bolsa\n") # ===============================
portifolio_sem_btc <- portifolio %>% .[-grep("BTC", .)]
consulta_acoes <- map_df(portifolio_sem_btc, ~{
tryCatch({
av_get(symbol = .x,
av_fun = "TIME_SERIES_INTRADAY",
interval = "1min",
outputsize = "compact") %>%
bind_cols(stock = rep(.x, nrow(.)))
}, error = function(e){
Sys.sleep(1)
av_get(symbol = .x,
av_fun = "TIME_SERIES_INTRADAY",
interval = "1min",
outputsize = "compact") %>%
bind_cols(stock = rep(.x, nrow(.)))
})
})
cat("Impotar dados do bitcoin\n") # ==============================
coin <- "BTC"
method <- "ticker"
url <- glue::glue("https://www.mercadobitcoin.net/api/{coin}/{method}/")
safe_fromJSON <- safely(fromJSON, as.numeric(NA))
consulta_bitcoin <-
safe_fromJSON(url)$result$ticker %>%
as_tibble() %>%
transmute(timestamp = lubridate::ymd_hms(as.POSIXct(date, origin="1970-01-01")),
open, high, low, close = sell, volume = NA, stock = "BTC.BR") %>%
mutate_at(c('open', 'high', 'low', 'close'), ~as.numeric(.x))
cat("Combinar resultados das consultas\n") # =====================
consulta_atual <-
bind_rows(
consulta_acoes %>%
group_by(stock) %>%
filter(timestamp == last(timestamp)),
consulta_bitcoin
)
cat("Coleta concluida!\n") # ====================================
cat("Criar tabela financeira automatizada\n") # ================
financas <-
tibble(
ativo = portifolio,
cot_inicio = cot_inicio,
qtd_inicio = qtd_inicio,
vol_inicio = cot_inicio * qtd_inicio,
cot_atual = consulta_atual$close,
qtd_atual = qtd_inicio,
vol_atual = cot_atual * qtd_atual,
ganho_perda = vol_atual - vol_inicio,
resultado_bruto = ganho_perda / vol_inicio * 100
)
# Condicao:
# Caso o valor atual de alguma cotacao seja maior que o vaor inicial
cat("Verificar possibilidade de lucro\n")
if(any(financas$vol_atual > financas$vol_atual)){
cat("Preparar formatacao da tabela\n") # =====================
tabela <-
financas %>%
mutate(
cot_inicio = moeda_real(cot_inicio),
cot_atual = moeda_real(cot_atual),
vol_inicio = moeda_real(vol_inicio),
vol_atual = moeda_real(vol_atual),
qtd_inicio = round(qtd_inicio,4),
qtd_atual = round(qtd_atual,4),
`Vender?` = ifelse(ganho_perda > 0,"\u2713", "\u2718") ,
cot_atual = cell_spec(cot_atual, "html", color = "blue"),
ganho_perda = cell_spec(moeda_real(ganho_perda), "html",
color = ifelse(ganho_perda > 0,
"green", "red")),
resultado_bruto = cell_spec(porcentagem(resultado_bruto), "html",
color = ifelse(resultado_bruto > 0,
"green", "red"))) %>%
kable(format = "html", escape = F) %>%
kable_styling(c("striped", "bordered", "hover", "responsive"), full_width = F) %>%
add_header_above(c(" ", "Montagem" = 3,
"Desmontagem / Atual" = 3, "Resultado" = 3))
save_kable(tabela, file = "table.png", self_contained = F)
cat("Enviar menssagem...\n") # ================================
# bot$sendMessage("Resultados do último modelo ajustado:")
# bot$sendMessage("Projeção para próximo semestre:")
# bot$sendPhoto('phophet.png', caption = "ModeloProphet")
bot$sendPhoto('table.png', caption = paste0("Tabela de resultados - ",
format(Sys.time(), "%d/%m/%y %H:%M") ))
bot$sendMessage("Alerta na tabela financeira!")
cat("Menssagem enviada!!\n")
}else{
cat("Sem lucros por enquanto!\n")
}
# Aguardar liberacao da api =====================================
cat(paste0("Aguarde ", frequencia/60, " minuto(s)..\n"))
# create progress bar
pb <- txtProgressBar(min = 0, max = frequencia, style = 3)
for(i in 1:frequencia){
Sys.sleep(1)
# update progress bar
setTxtProgressBar(pb, i)
}
close(pb)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.