-
-
Save gomesfellipe/357af0735d2aedca60146a7655e33929 to your computer and use it in GitHub Desktop.
Bot para coleta de cotações da bolsa e analise para desmontagem da carteira que envia mensagem no telegram
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#' 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