O intuito desse estudo é implementar nas cotações diárias da VALE3 um modelo matemático chamado de Naive Bayes e assim criar uma predição.

Modelo Naive Bayes

*Baseando-se no Teorema de Bayes, o classificador NB assume independencia condicional entre as classes (Gerlein et al., 2016; Patel et al., 2015a, p.264, p. 199). O Teorema de Bayes, expresso na Equação abaixo demenosta o calculo da probabilidade a posteriori de uma classe A dada a ocorrencia das características dos dados no vetor B.

Baixando os pacotes que irei usar:

library("quantmod")
library("lubridate")
library("e1071")
library(data.table)
library(gridExtra)
library(fTrading)
library(TTR)
library(fastDummies)
library(dplyr)
library(ncar)
library(pracma)
library(scales)
library(ggplot2)
library(useful)

Selecionado o ativo da VALE3:

#Seleção do ativo para análise:
ticker <- c("VALE3.SA")

#Período de análise:
stardate <- as.Date("2014-01-01")
enddate <- as.Date("2022-07-15")

#Carregando o dataset:
getSymbols(ticker, src = "yahoo", from = stardate, to = enddate)
VALE3.SA <- data.frame(VALE3.SA)
VALE3.SA <- na.omit(VALE3.SA)

#Renomeando o data frame:
names(VALE3.SA) <- c("Open", "High", "Low", "Close", "Volume", "Ajustado")
#Calculando os retornos:
VALE3.SA$Ret <- (VALE3.SA$Close - VALE3.SA$Open)
VALE3.SA <- shift.column(data = VALE3.SA, columns = 'Ret', len = 1)


# Alvo
VALE3.SA$Dir <- ifelse(VALE3.SA$Ret > 0,"Alta","Baixa")
VALE3.SA$Rsi <- RSI(VALE3.SA$Close, 9, "SMA")

# Status
VALE3.SA$Rsi_status <- as.factor(ifelse(VALE3.SA$Rsi > 70,"Sobrecomprado",ifelse(VALE3.SA$Rsi < 30,"Sobrevendido","Neutro")))

table(VALE3.SA$Dir, VALE3.SA$Rsi_status)

        Neutro Sobrecomprado Sobrevendido
  Alta     592           275          113
  Baixa    736           154          240

Divisão da base em treino e teste: 70% treino e 30% teste:

VALE_train <- VALE3.SA[1:1484,]
VALE_test <- VALE3.SA[1485:dim(VALE3.SA)[1],]

# Modelo em treino:
bayes <- naiveBayes(as.factor(Dir) ~ Rsi_status, data = VALE_train, na.action = na.omit,method="class")
bayes

Naive Bayes Classifier for Discrete Predictors

Call:
naiveBayes.default(x = X, y = Y, laplace = laplace, method = "class")

A-priori probabilities:
Y
     Alta     Baixa 
0.4657627 0.5342373 

Conditional probabilities:
       Rsi_status
Y          Neutro Sobrecomprado Sobrevendido
  Alta  0.6055313     0.2678311    0.1266376
  Baixa 0.6535533     0.1319797    0.2144670


# Modelo em teste:
VALE_test$Pred <- predict(bayes,VALE_test)

table(VALE_test$Pred, VALE_test$Dir, dnn = list('Previsto', 'Real'))

        Real
Previsto Alta Baixa
   Alta    91    50
   Baixa  202   292


(table(VALE_test$Pred, VALE_test$Dir, dnn = list('Previsto', 'Real'))[4] 
  + table(VALE_test$Pred, VALE_test$Dir, dnn = list('Previsto', 'Real'))[1])/dim(VALE_test)[1]
   
   0.6031496

Resultado do modelo:

VALE_test$Resultado <- ifelse(as.character(VALE_test$Pred) == 'Baixa', -1 * VALE_test$Ret.Shifted, VALE_test$Ret.Shifted)
cumulative_buy_Reais <- cumsum(VALE_test$Resultado)


plot(cumulative_buy_Reais, type = 'l', 
     xlab = 'Dias', 
     ylab = '%', 
     main = 'Modelo Naive Bayes',
     col = 'blue')

Simulando um stop no modelo de 2%:

stop = -2 

cumulative_buy_Reais <- ifelse(cumulative_buy_Reais < stop, stop, cumulative_buy_Reais)
retorno_modelo_acumulado <- cumsum(cumulative_buy_Reais)

retorno_modelo_acumulado

plot(retorno_modelo_acumulado, type = 'l', col = 'Blue')

Conclusão

Sendo assim, com a utilização do modelo matemático Naive Bayes, implementei ele com a variável RSI(IFR) e conseguiu obter um retorno de 1700%, porém, com o uso de um stop de 2% a cada operação, facilitando o aumento dos ganhos e diminuindo os prejuízos.