Você está na página 1de 10

Previsão do valor de ações utilizando Redes Perceptron Multicamadas

(PMC)
Yan Uynitu Seles Correa

Resumo— Este trabalho tem como finalidade demonstrar a investimento procuram continuamente soluções desse tipo,
aplicação de Redes Neurais Artificiais, mais especificamente as visando obter altos retornos financeiros [1].
redes Perceptron Multicamadas ou Multilayer Perceptron (MLP)
na previsão de preços no mercado de ações. Com a capacidade II. DEFINIÇÃO DO PROBLEMA
de descobrir padrões em sistemas não-lineares e caóticos, alguns
tipos de redes neurais oferecem a possibilidade de prever as Uma rede neural é um programa de computador que pode
direções do mercado com precisões consideráveis, servindo reconhecer padrões nos dados, aprender com isso e, no caso
como apoio à tomada de decisões no processo de compra e de dados de séries temporais, fazer previsões de valores
venda de ações.
futuros. O uso de uma rede neural demanda tempo para
compreender e limpar os dados, remover erros, pré-processar
I. I NTRODUÇÃO
e pós-processar [2].
Desde os primórdios, o homem sempre buscou por Tudo que é observado e medido, seja uma variável física
soluções ou meios que facilitassem a sua vida. O fogo, a como a temperatura ou o preço de uma ação da bolsa de
roda, as ferramentas e todas as invenções que, de alguma valores são diferentes em pontos distintos do tempo. O
forma, resolveram algum problema da época ou contribuíram reconhecimento clássico de padrões e, com ele, grande parte
para solucionar e criar novos artefatos décadas ou séculos das aplicações das redes neurais, tem sido principalmente
depois e até hoje são utilizados, como exemplo a internet, preocupado em detectar padrões sistemáticos em uma série
talvez uma das maiores invenções da humanidade e que de medições que não mudam no tempo (padrões estáticos).
possibilitou um grande avanço para a raça humana. Aplicações típicas envolvem a classificação dos vetores de
Nos dias atuais, novos problemas surgem todos os dias e entrada em uma classe (problema de classificação) ou a
a busca por suas soluções são incessáveis. Afinal, evoluímos descrição aproximada do valor saída esperado para uma
e o mundo que nos cerca hoje, certamente, sofrerá grandes dada variável ou variáveis (problema de regressão). Quando
variações nos próximos anos. Décadas atrás era inimaginável as mudanças ao longo do tempo também são levadas em
uma pessoa comum conseguir investir seu dinheiro em consideração, a dimensão temporal é inserida. A análise
alguma empresa ou ação, porém, hoje, todos podem e grande desses dados espaço-temporais, ou seja, dados com dimensão
parte da população o faz, necessitando ter apenas um celular espacial e temporal, é geralmente denominada processamento
ou computador com conexão à internet. E é aqui onde está de séries temporais[3]. A Figura 1 serve como exemplo de
o divisor de águas para muita gente: todos podem investir uma série temporal que descreve o valor de uma ação com
mas qual é a maneira correta de se fazer? Com certeza não o decorrer do tempo.
há uma resposta simples e objetiva para esta pergunta, mas
existem ferramentas que podem ajudar na tomada de decisão.
Os investidores têm a difícil tarefa de acompanhar, de
forma contínua, as oscilações do mercado para que suas
estratégias resultem em melhores retornos financeiros. Não
é uma tarefa simples acompanhar as diversas informações
veiculadas em jornais, revistas, televisão, Internet ou outros
canais, depois filtrá-las e analisá-las para tomar uma decisão.
Muitas vezes são utilizadas ferramentas gráficas para acom-
panhar e até mesmo tentar antecipar os riscos do mercado.
Muitos sistemas eletrônicos, disponibilizados por corretoras
e instituições bancárias para seus clientes, baseiam-se nas
informações de liquidez diária das empresas participantes da
Bolsa e em gráficos de tendências. Figura 1. Variação do preço de uma ação ao decorrer dos anos.
Existem várias motivações para tentar prever os preços do
mercado de ações. O mais básico deles é o ganho financeiro. Um tipo de rede neural chamado Multilayer Perceptron
Qualquer sistema que possa sempre escolher vencedores e (MLP) foi introduzido em 1957 para resolver diferentes
perdedores frente a um mercado dinâmico e inconstante problemas combinatoriais [4]. A rede MLP foi utilizada
fará com que seu proprietário fique muito rico. Assim, no problema não linear XOR, também conhecido como ou
muitos indivíduos, incluindo pesquisadores e profissionais de exclusivo, e foi aplicada com sucesso a diferentes problemas
combinatórios. É agora muito usada para processamento de i m p o r t p a n d a s a s pd
informações e reconhecimento de padrões. Por se tratar de i m p o r t numpy a s np
import m a t p l o t l i b . pyplot as p l t
um classificador não linear, várias publicações têm apre-
sentado a rede MLP como uma aproximadora universal de d a t a = pd . r e a d _ c s v ( " . / BVSP . c s v " , u s e c o l s = [ ’
funções, como em [5] e [6], sendo constantemente utilizada D a t e ’ , ’ Open ’ , ’ High ’ , ’Low ’ , ’ C l o s e ’ , ’
Volume ’ ] )
e testada em problemas de predição de séries temporais d a t a [ ’ D a t e ’ ] = pd . t o _ d a t e t i m e ( d a t a [ ’ D a t e ’ ] )
[7]. A Figura 2 mostra a estrutura de uma rede MLP com d a t a . s e t _ i n d e x ( ’ Date ’ , i n p l a c e =True )
6 neurônios na camada de entrada, 4 na primeira camada print ( data . describe () )
oculta, 3 na segunda camada oculta e 1 na camada de saída. Código 1. Importando dados do CSV

Open High Low Close Volume


count 2586.00 2586.00 2586.000 2586.00 2.586000e03
mean 66034.19 66673.7 65395.29 66045.95 3.724617e06
std 16921.00 17038.68 16804.33 16939.42 1.985539e06
min 37501.00 38031.00 37046.00 37497.00 0.000000e00
25% 53836.25 54298.50 53257.25 53833.25 2.631500e06
50% 61806.00 62283.50 61300.00 61805.00 3.395450e06
75% 72742.75 73585.75 71931.25 72748.50 4.318875e06
max 119528.00 119593.00 118108.00 119528.0 1.675150e07
Tabela I
D ESCRIÇÃO DOS DADOS OBTIDOS

Figura 2. Estrutura de uma rede MLP.

Posto isso, tem-se que a variação do preço de uma dada


Continuando a exploração dos dados, o método info()
ação da bolsa de valores é uma série temporal, onde sua
também traz uma informação importante (Tabela II). Ob-
cotação oscila ao decorrer dos dias e, com isso, é possível
serve que existem 2595 entradas de dados, condizentes com
treinar uma rede MLP para aprender e se ajustar à curva
o número de dias no período analisado em que a bolsa
gerada ao longo do tempo, tentando aproximar a função que
disponibilizou dados para BVSP. Porém, 2586 entradas são
descreveu tal oscilação até o momento e, assim, tentar prever
não nulas (por coluna), ou seja, 9 entradas são nulas e, por
um valor futuro.
isso, serão descartadas do conjunto de treinamento, pois não
Por fim, este trabalho tem como objetivo treinar uma rede
oferecem informação nenhuma e podem ser um obstáculo
MLP que se ajuste aos dados de uma determinada ação da
no treinamento da RNA. Para tal, pode-se aplicar o método
bolsa e, após isso, predizer seu valor de fechamento para
dropna().
uma data futura, criando uma ferramenta de apoio que pode
Após isso, é possível plotar o gráfico do valor de
ser utilizada como uma segunda opinião antes de se tomar a
fechamento da ação em função do tempo, conforme Figura
decisão final.
3 e, utilizando o MPLFinance (Código 2), obter os Candle-
III. SOLUÇÃO DO PROBLEMA sticks, um método de análise gráfica de mercado. Na Figura 4
Tendo em vista o exposto, será utilizada a linguagem pode-se encontrar o gráfico para um período reduzido, apenas
Python na implementação deste trabalho. Também serão os últimos 2 meses, afim de não poluir a visualização.
empregados alguns frameworks como o Pandas, Keras e
Sklearn para auxiliar no tratamento e maninpulação dos
dados.
B. TRATAMENTO DOS DADOS
A. OBTENÇÃO E EXPLORAÇÃO DOS DADOS Após finalizada a obtenção e a exploração dos dados,
Existem inúmeras maneiras de se adquirir dados sobre a parte-se ao tratamento dos dados, onde será necessário
bolsa de valores. Algumas delas inclusive oferecem APIs
para tornar esse processo mais fácil e transparente. Para isso,
serão utilizados os dados da IBOVESPA, que podem ser Non-Null Total From To
Open 2586 2595 04/01/2010 18/06/2020
adquiridos no Yahoo Finance, que disponibiliza a exportação
High 2586 2595 04/01/2010 18/06/2020
dos dados em um arquivo CSV no período escolhido, no caso Low 2586 2595 04/01/2010 18/06/2020
04/01/2010 à 18/06/2020. Após adquirir os dados, utiliza- Close 2586 2595 04/01/2010 18/06/2020
se o Pandas para carregar o arquivo, conforme o código Volume 2586 2595 04/01/2010 18/06/2020
1. Também é possível descrever os dados que acabaram de Tabela II
ser carregados, extraindo algumas informações importantes I NFORMAÇÃO SOBRE OS DADOS OBTIDOS
como o máximo, mínimo, média, desvio padrão e também a
distribuição sobre alguns quartis, indicados na tabela I.
from s k l e a r n . p r e p r o c e s s i n g i m p o r t S t a n d a r d S c a l e r

scaler = StandardScaler ()
f o r c i n d a t a . columns :
d a t a [ c+ ’ _Norm ’ ] = s c a l e r . f i t _ t r a n s f o r m ( d a t a [ c ] .
to_numpy ( ) . r e s h a p e ( −1 , 1 ) )
Código 4. Normalização dos dados de entrada

a implementação do modelo, mais à frente. Nessa tabela


Figura 3. Valor da BVSP no período de 04/01/2010 à 18/06/2020. também é possível obter outra informação importante, por
exemplo caso no dia 04/01/2010 fosse feito um investimento
de R$70.045,00 e vendido no dia seguinte, o investidor teria
i m p o r t m p l f i n a n c e a s mpf
um retorno R$195,00 pois a BVSP valorizou entre esses
mpf . p l o t ( d a t a [ pd . t o _ d a t e t i m e ( ’ 18−04−2020 ’ ) : pd . dois dias. Já se o investimento tivesse sido feito no dia
t o _ d a t e t i m e ( ’ 18−06−2020 ’ ) ] , t y p e = ’ c a n d l e ’ , 07/01/2010, haveria um prejuízo de R$188,00. Essa técnica
f i g s c a l e = 1 . 0 , volume = F a l s e , s t y l e = ’ c h a r l e s ’
, y l a b e l = ’BVSP ( R$ ) ’ )
de investimentos é conhecida como Day Trade, onde ações
são comercializadas em curtíssimos prazos, geralmente no
Código 2. Plotando Candlesticks
mesmo dia ou no seguinte, com o objetivo de ganhar dinheiro
na variação do preço de forma rápida com as oscilações.
Date Open High Low Close Volume Close_Tomorrow Return
identificar as características que o modelo da RNA utilizará 2010-01-04 68587.0 70081.0 68587.0 70045.0 1655400.0 70240.0 195.0
2010-01-05 70046.0 70595.0 69928.0 70240.0 1984200.0 70729.0 489.0
no treinamento. Todo o processamento será feito sobre o 2010-01-06 70237.0 70937.0 70016.0 70729.0 2243600.0 70451.0 -278.0
2010-01-07 70723.0 70723.0 70045.0 70451.0 1555000.0 70263.0 -188.0
DataFrame que contém os dados de da BVSP. 2010-01-08 70455.0 70766.0 70158.0 70263.0 1634400.0 70433.0 170.0
... ... ... ... ... ... ... ...
Primeiramente, deslocar-se-á o valor de fechamento do 2020-06-10 96747.0 97646.0 94665.0 94686.0 11739600.0 92795.0 -1891.0
dia n + 1 para o dia n, ou seja, durante o treinamento 2020-06-12
2020-06-15
94677.0
92780.0
94703.0
93112.0
90811.0
90148.0
92795.0
92376.0
12785600.0
13317500.0
92376.0
93531.0
-419.0
1155.0
será possível saber o valor de fechamento da ação no dia 2020-06-16
2020-06-17
92387.0
93531.0
95216.0
96611.0
92387.0
93531.0
93531.0
95547.0
12034200.0
11134700.0
95547.0
96125.0
2016.0
578.0
seguinte. Isso possibilita o cálculo do retorno financeiro, isto 2020-06-18 95547.0 97110.0 94698.0 96125.0 10008500.0

é, a diferença entre o valor final do dia n + 1 e do dia n. Tabela III


O Código 3 demonstra como realizar essa operação uti- DATA F RAME APÓS APLICAR - SE shift
lizando o DataFrame.

Vale destacar que a última linha, ou seja, o último dia


Com isso, agora o DataFrame tem não somente o dados do conjunto de dados possui valores nulos para o valor de
do dia, mas também informações do dia seguinte como o fechamento e retorno de investimento, causado pelo shift ou
valor de fechamento e o retorno financeiro, como pode- deslocamento de um dia realizado no conjunto de dados.
se observar na Tabela III. Isso será muito útil e facilitará O próximo passo é de suma importância. As Redes Neu-
rais Artificiais precisam receber dados normalizados em sua
entrada, ou seja, todos os valores devem estar confinados em
uma faixa pré-definida, geralmente entre 0 e 1 ou entre -1 e
1. Isso evita uma série de problemas na previsão ao receber
dados contendo valores muito discrepantes. O Código 4 é
uma alternativa dentre as várias maneiras de se normalizar
os números em Python, onde cada coluna do DataFrame é
normalizada e adicionada aos dados com o mesmo nome,
porém adicionando o sufixo "_Norm" para indicar que ali
estão os dados maipulados. Com isso, os dados originais são
mantidos, evitando a perda de informações.

Figura 4. Candlesticks do valor da BVSP sobre o período de 18/04/2020


à 18/06/2020.
Feito isso, chega-se a um momento crucial deste trabalho:
a divisão dos dados para treinamento, validação e teste da
RNA. Mas, o que são essas divisões de dados?
d a t a [ ’ Close_Tomorrow ’ ] = d a t a [ ’ C l o s e ’ ] . s h i f t ( −1)
d a t a [ ’ R e t u r n ’ ] = d a t a [ ’ Close_Tomorrow ’ ]− d a t a [ ’ C l o s e ’ ] • Treinamento: são aqueles que fazem o modelo com-

Código 3. Cálculo do retorno financeiro


preender a distribuição dos dados, ou seja, o apren-
dizado da rede.
t r a i n = d a t a [ pd . t o _ d a t e t i m e ( ’ 04−01−2010 ’ ) : pd .
t o _ d a t e t i m e ( ’ 31−12−2017 ’ ) ]
t r a i n _ x = d a t a [ [ ’ Open_Norm ’ , ’ High_Norm ’ , ’ Low_Norm ’ ,
’ Close_Norm ’ , ’ Volume_Norm ’ ] ] . to_numpy ( )
t r a i n _ y = d a t a [ [ ’ Return_Norm ’ ] ] . to_numpy ( )
Código 5. Separando os dados de treinamento

• Validação: são os dados utilizados para ajustar o mod-


elo durante o treinamento.
• Teste: esses serão colocados na entrada da RNA,
visando a obtenção (predição) da saída da RNA, ou
seja, verificar a eficácia da rede em generalizar o Figura 5. Tangente hiperbólica.
conhecimento adquirido para dados novos.
Existem diferentes proporções indicadas para essa divisão. from k e r a s i m p o r t m o d e l s
Aqui, os dados possuem dependência temporal, isto é, a from k e r a s i m p o r t l a y e r s
from k e r a s . l a y e r s i m p o r t Dense
ordem ou sequência dos dados importa e essa dependência
deve ser mantida no treinamento da rede. Assim, os primeiros model = m o d e l s . S e q u e n t i a l ( )
sete anos serão para treinamento (04/01/2010 - 31/12/2017), model . add ( l a y e r s . Dense ( 3 0 , input_dim = t r a i n _ x .
shape [ 1 ] , a c t i v a t i o n = " tanh " ) )
um ano para validação (01/01/2018 - 31/12/2018) e o restante model . add ( l a y e r s . Dense ( 3 0 , a c t i v a t i o n =" tanh " ) )
para teste. O Código 5 mostra como fazer essa separação em model . add ( l a y e r s . Dense ( 3 0 , a c t i v a t i o n =" tanh " ) )
Python. Analogamente, são obtidos os dados de validação e model . add ( l a y e r s . Dense ( 1 ) )
model . summary ( )
teste, alterando o período para o descrito anteriormente.
model . c o m p i l e (
o p t i m i z e r = ’ adam ’ ,
loss = ’ mean_squared_error ’ ,
)
C. DEFINIÇÃO E TREINAMENTO DA REDE r e s u l t s = model . f i t (
train_x , train_y ,
Após toda a manipulação feita nos dados, tem-se que epochs= 5000 ,
definir a topologia da rede. No caso da MLP significa definir b a t c h _ s i z e = 128 ,
a quantidade de camadas, o número de neurônios em cada v a l i d a t i o n _ d a t a = ( val_x , val_y ) ,
verbose = 0
uma delas, a função de ativação e a função de erro utilizada )
para mensurar a convergência da rede.
Código 6. Criação da RNA (MLP) utilizando Keras
As entradas da rede são os valores de abertura,
fechamento, alta, baixa e volume da ação do dia atual, todos
normalizados na etapa anterior. Com isso, tem-se 5 neurônios
na camada de entrada. A saída desejada da rede é o valor do Na Figura 6 é possível observar o erro durante o treina-
retorno financeiro caso seja feito investimento naquele dia, mento e a validação da RNA. Note que a tendência é que
o que implica em 1 neurônio na camada de saída. Foram ele diminua cada vez mais no decorrer das épocas.
adicionadas 3 camadas ocultas, cada uma com 30 neurônios.
Logo, a topologia da rede pode ser escrita como (5, 30, 30,
30, 1).

sinh(x) ex − e−x
tanh(x) = = x (1)
cosh(x) e + e−x

Para a função de ativação, foi escolhida a tangente hiper-


bólica, dada pela Equação 1 e seu gráfico pela Figura 5.
Para o erro foi escolhido o Erro Quadrático Médio (EQM)
e, no treinamento, o Gradiente Descendente com a taxa
de aprendizagem padrão do Keras, 0.001. O valor do erro
permitido também é o padrão, 10e−7 , porém também foi
colocado um limite de 5 mil épocas que encerra a execução
do treinamento caso o erro desejado ainda não tenha sido
alcançado. O Código 6 mostra como é feita a configuração
inicial do MLP em Python.
Figura 6. EQM durante o treinamento e validação.
Date Return_Norm Return (R$) Return_Predicted (R$) M_Predicted M_Real
p r e d = model . p r e d i c t ( t e s t _ x ) 2019-01-02 0.496973 552,00 234,84 Up Up
2019-01-03 0.243651 277,00 580,36 Up Up
pred = s c a l e r . i n v e r s e _ t r a n s f o r m ( pred ) 2019-01-04 -0.142321 -142,00 774,86 Up Down
t e s t _ y [ ’ Return_Predicted ’ ] = pred 2019-01-07 0.295236 333,00 -25,77 Down Up
2019-01-08 1.444860 1581,00 132,81 Up Up
Código 7. Predição e alteração da escala dos dados de saída ... ... ... ... Up Up
2020-06-10 -1.753453 -1891,00 -1893,59 Down Down
2020-06-12 -0.397486 -419,00 -553,66 Down Down
2020-06-15 1.052441 1155,00 1117,36 Up Up
Date Return_Norm Return (R$) Return_Predicted (R$) 2020-06-16 1.845571 2016,00 2014,65 Up Up
2020-06-17 0.520924 578,00 417,97 Up Up
2019-01-02 0.496973 552,00 234,84
2019-01-03 0.243651 277,00 580,36 Tabela V
2019-01-04 -0.142321 -142,00 774,86
DADOS MARCADOS COM O SENTIDO DO RETORNO
2019-01-07 0.295236 333,00 -25,77
2019-01-08 1.444860 1581,00 132,81
... ... ... ...
2020-06-10 -1.753453 -1891,00 -1893,59
2020-06-12 -0.397486 -419,00 -553,66 t e s t _ y [ ’ H i t ’ ] = [ 1 i f m[ 1 ] [ ’ Movement_Real ’ ] == m
2020-06-15 1.052441 1155,00 1117,36 [ 1 ] [ ’ Movement_Predicted ’ ] e l s e 0 f o r m in
2020-06-16 1.845571 2016,00 2014,65 test_y . iterrows () ]
2020-06-17 0.520924 578,00 417,97
Código 9. Anotação dos acertos (hits) entre a previsão e a realidade
Tabela IV
P REDIÇÃO DOS DADOS DE TESTE

Neste momento, é possível realizar uma comparação entre


o sentido real do mercado financeiro e o previsto pela RNA.
D. REALIZANDO PREDIÇÕES DE MERCADO Como exemplo, nos dias 2, 3 e 8 de Janeiro de 2019 o
modelo foi capaz de acertar o movimento para cima do
Todas os passos realizados até o momento foram respon- mercado financeiro e, nos dias 10 e 12 de Junho de 2020, o
sáveis por formar a base, ou seja, o modelo que será utilizado movimento para baixo. Isso é ótimo pois, quanto mais a rede
na predição dos valores de retorno dos investimentos. Por acertar, maior sua acurácia e, consequentemente, maior será o
conseguinte, o próximo passo é realizar a predição e, após lucro pois seria possível saber quando investir e quando não.
obtido o resultado, voltar à escala original. Essa etapa é Porém, também houveram erros, como no dia 04/01/2019,
necessária pois a escala dos dados foi alterada durante a quando a rede previu um possível lucro e, na verdade, houve
normalização realizada em III-B. Esse resultado pode ser prejuízo.
facilmente obtido aplicando-se o Código 7. Uma nova coluna
contendo a predição também é adicionada ao DataFrame. E. ESTRATÉGIA DE INVESTIMENTO
Será utilizada uma abordagem simples e intuitiva para
decidir quando investir: caso a previsão seja de lucro haverá
Desse modo, obtem-se a Tabela IV que agora contém o investimento, caso contrário nada será feito. Para tanto,
retorno normalizado, que é o valor de saída esperado pela percorre-se o DataFrame analisando as predições e marcando
rede e também sua correspondência na escala original. A com um acerto (hit) sempre que a previsão e a realidade
última coluna equivale ao valor do retorno previsto pela coincidirem, ou seja, os movimentos previstos e reais forem
RNA. Indo um pouco mais a fundo, alguns pontos podem iguais, conforme o Código 9.
ser observados como, por exemplo, a divergência ou de-
sigualdade entre o retorno esperado e o retorno previsto.
Tendo como exemplo, no dia 02/01/2019 o valor de retorno Por conseguinte, seguindo a estratégia de investimento
esperado era de R$552,00 mas a rede previu R$234,84. Isso proposta, será criada uma nova coluna no DataFrame,
não será um problema pois o investimento apenas será feito chamada Investment_Return, e adicionada a ela todos os
visando obter lucro, ou seja, retorno positivo. Logo, o valor valores de retorno que correspondem com o movimento Up,
em si não é um obstáculo pois o que interessa é saber o simulando que nesses períodos foi realizado investimento na
gradiente da aplicação, isto é, se deu lucro ou prejuízo. ação e obteve-se o resultado do retorno do dia (vide Código
Tendo isso em mente, é possível modificar a Tabela IV, 10). Essa coluna irá contabilizar o sucesso do investimento.
percorrendo seus valores previstos e reais e marcando-os com
Up quando obtiver lucro ou, caso contrário, com Down. Para
tal, aplica-se o Código 8, de onde obtém-se a Tabela V. Contudo, a acurácia da RNA pode ser calculada através da
média de acertos dos movimentos previstos já que a coluna

t e s t _ y [ ’ M _ P r e d i c t e d ’ ] = [ ’Up ’ i f p > 0 e l s e ’Down ’ t e s t _ y [ ’ I n v e s t m e n t _ R e t u r n ’ ] = [m[ 1 ] [ ’ R e t u r n ’ ] i f m


for p in pred ] [ 1 ] [ ’ M o v e m e n t _ P r e d i c t e d ’ ] == ’Up ’ e l s e 0 f o r m
t e s t _ y [ ’ M_Real ’ ] = [ ’Up ’ i f m > 0 e l s e ’Down ’ f o r in test_y . iterrows () ]
m in t e s t _ y [ ’ Return ’ ] ] Código 10. Criação da coluna que guardará os valores do retorno financeiro
Código 8. Marcação do sentido do movimento dos valores reais e previstos das aplicações do dia
a c c u r a c y = t e s t _ y [ ’ H i t ’ ] . mean ( )
t o t a l _ r e t u r n = t e s t _ y [ ’ I n v e s t i m e n t _ R e t u r n ’ ] . sum ( ) i n i t i a l _ i n v e s t m e n t = d a t a [ pd . t o _ d a t e t i m e ( ’
Código 11. Cálculo da acurácia e do retorno financeiro dos investimentos 01−01−2019 ’ ) : ] . h e a d ( 1 ) [ ’ Open ’ ]
b u y _ a n d _ h o l d = t e s t _ y [ ’ R e t u r n ’ ] . sum ( ) +
initial_investment
Código 12. Cálculo da valorização da ação utilizando a técnica Buy and
Hold
Hit foi marcada com 1 para acertos e 0 para erros..O retorno
do investimento é a soma de todos os retornos financeiros,
obtidos na coluna Investment_Return. Logo, o Código 11 é Profit
responsável por computar esses valores. Initial Investment R$87.887,00 N/A
Buy & Hold Return R$103.961,00 18.29%
Investment Return (RNA) R$147.903,00 68.28%
Tabela VII
IV. RESULTADOS C OMPARAÇÃO ENTRE O RETORNO FINANCEIRO UTILIZANDO A RNA E A
TÉCNICA Buy & Hold

Após serem aplicadas todas as técnicas de manipulação


dos dados e implementada a estrátégia de investimento,
chegou o momento de verificar se realmente é possível obter
Com base nessas informações, é correto afirmar que a
lucro aplicando a RNA implementada. Para isso, todos os
RNA obteria um lucro superior ao de uma simples aplicação
algorítmos aqui descritos são compilados e executados sobre
utilizando Buy & Hold, já que a rede neural obteria um
os dados de teste, afim de tentar prever o mercado e obter
lucro de R$60.016,00 enquanto a outra técnica, embora mais
lucro. A Tabela VI demonstra o resultado da rede.
simples, atingiria um lucro de apenas R$16.074,00.

Accuracy Investment Return


70.39% R$147.903,00 V. CONCLUSÃO
Tabela VI Conforme os resultados obtidos e apresentados durante
ACURÁCIA E RETORNO FINANCEIRO APLICANDO A RNA SOBRE OS este trabalho, é plausível considerar o uso de uma rede neural
DADOS DE TESTE para predições do mercado financeiro, não só como simu-
lação mas também em um cenário real, visto que o desem-
penho da MLP mostrou-se bastante satisfatório, justificando
seu uso. Além disso, é possível utilizar outras topologias de
Foi possível acertar 70% das movimentações do mercado rede, por exemplo a TDNN - (Time Delay Neural Network)
no período de 01/01/2019 à 18/06/2020 , o que é mais que e até mesmo combinar diversas redes buscando uma melhor
suficiente para obter algum lucro. Além disso, a rede treinou performance. Uma boa alternativa seria acoplar a análise de
durante 3 mil épocas, número que poderia ser aumentado sentimentos, onde seriam obtidas informações oriundas de
para tentar diminuir ainda mais o erro na tentativa de notícias na esperança de captar novas tendências no mercado
aumentar a acurácia. Além disso, outros parâmetros como e guiar os futuros investimentos.
a taxa de aprendizagem poderiam ser alterados na busca de Ademais, é fato que as redes neurais tem um imenso leque
melhorar o desempenho da rede. de opções onde podem ser utilizadas e, com certeza, ainda
Ademais, é necessário comparar, de alguma forma, quão evoluirão muito e serão cada vez mais utilizadas e vistas no
boa foi a previsão da RNA. Neste caso, pode-se tomar como cotidiano das pessoas.
base uma outra estratégia de investimento conhecida, afim Todos os códigos implementados na resolução deste tra-
de confirmar que a rede realmente fez previsões coerentes balho encontram-se no Anexo A.
e não simplesmente se aproveitou de um período de alta do R EFERÊNCIAS
mercado, o que levaria ao lucro de qualquer forma. Para isso,
[1] R. Lawrence, Using neural networks to forecast stock market prices.
será utilizada a técnica Buy & Hold que consiste em adquirir Citeseer, 1997, vol. 333.
a ação no início do período e mantê-la até o fim, analisando [2] E. M. Azoff, Neural Network Time Series Forecasting of Financial
sua valorização. Markets, 1st ed. USA: John Wiley Sons, Inc., 1994.
[3] G. Dorffner, “Neural networks for time series processing,” Neural
Assim sendo, para obter a valorização da ação basta apenas Network World, vol. 6, pp. 447–468, 1996.
acumular todo o retorno financeiro do período e somar com o [4] F. Rosenblatt, “The perceptron: a probabilistic model for information
investimento inicial que é dado pelo valor de abertura da ação storage and organization in the brain.” Psychological review, vol. 65,
no. 6, p. 386, 1958.
no dia da compra, isto é, no primeiro dia do período. Dessa [5] G. Cybenko, “Approximation by superpositions of a sigmoidal func-
forma, basta aplicar o Código 12. Portanto, a técnica Buy & tion,” Mathematics of control, signals and systems, vol. 2, no. 4, pp.
Hold levaria a um lucro de R$16.074,00 o que resulta em 303–314, 1989.
[6] K. Hornik, M. Stinchcombe, H. White et al., “Multilayer feedforward
um retorno financeiro de R$103.961,00 conforme mostrado networks are universal approximators.” Neural networks, vol. 2, no. 5,
na Tabela VII. pp. 359–366, 1989.
[7] H. Shah, R. Ghazali, and N. M. Nawi, “Using artificial bee colony
algorithm for mlp training on earthquake time series data prediction,”
arXiv preprint arXiv:1112.4628, 2011.

A NEXOS
A. CÓDIGO FONTE
• Código 13: tratamento dos dados.
• Código 14: criação, treinamento e predição da RNA.
i m p o r t p a n d a s a s pd
i m p o r t numpy a s np
import m a t p l o t l i b . pyplot as p l t
import warnings
i m p o r t m p l f i n a n c e a s mpf
from s k l e a r n . p r e p r o c e s s i n g i m p o r t S t a n d a r d S c a l e r
from k e r a s i m p o r t m o d e l s
from k e r a s i m p o r t l a y e r s
from k e r a s . l a y e r s i m p o r t Dense
warnings . f i l t e r w a r n i n g s ( " ignore " )

DEBUG = F a l s e # Change t o T r u e t o show a l i n f o r m a t i o n s

# Loading d a t a
d a t a = pd . r e a d _ c s v ( " . / BVSP . c s v " , u s e c o l s = [ ’ D a t e ’ , ’ Open ’ , ’ High ’ , ’Low ’ , ’ C l o s e ’ , ’ Volume ’ ] )
d a t a [ ’ D a t e ’ ] = pd . t o _ d a t e t i m e ( d a t a [ ’ D a t e ’ ] )
d a t a . s e t _ i n d e x ( ’ Date ’ , i n p l a c e =True )

i f DEBUG:
p r i n t ( " Describe " )
print ( data . describe () )
print ( data . info () )
# Remove N u l l
data = data . dropna ( )
mpf . p l o t ( d a t a [ pd . t o _ d a t e t i m e ( ’ 18−04−2020 ’ ) : pd . t o _ d a t e t i m e ( ’ 18−06−2020 ’ ) ] , t y p e = ’ c a n d l e ’ ,
f i g s c a l e = 1 . 0 , volume = F a l s e , s t y l e = ’ c h a r l e s ’ , y l a b e l = ’BVSP ( R$ ) ’ )

d a t a [ ’ Close_Tomorrow ’ ] = d a t a [ ’ C l o s e ’ ] . s h i f t ( −1)
d a t a [ ’ R e t u r n ’ ] = d a t a [ ’ Close_Tomorrow ’ ] − d a t a [ ’ C l o s e ’ ]

i f DEBUG:
print ( data )

data = data . dropna ( )


scaler = StandardScaler ()
f o r c i n d a t a . columns :
d a t a [ c+ ’ _Norm ’ ] = s c a l e r . f i t _ t r a n s f o r m ( d a t a [ c ] . to_numpy ( ) . r e s h a p e ( −1 , 1 ) )
data = data . dropna ( )

# S p l i t t i n g t h e d a t a ( t r a i n , v a l i d a t i o n and t e s t )
# Train
t r a i n = d a t a [ pd . t o _ d a t e t i m e ( ’ 04−01−2010 ’ ) : pd . t o _ d a t e t i m e ( ’ 31−12−2017 ’ ) ]
t r a i n _ x = d a t a [ [ ’ Open_Norm ’ , ’ High_Norm ’ , ’ Low_Norm ’ , ’ Close_Norm ’ , ’ Volume_Norm ’ ] ] . to_numpy ( )
t r a i n _ y = d a t a [ [ ’ Return_Norm ’ ] ] . to_numpy ( )

# Validation
v a l = d a t a [ pd . t o _ d a t e t i m e ( ’ 01−01−2018 ’ ) : pd . t o _ d a t e t i m e ( ’ 31−12−2018 ’ ) ]
v a l _ x = v a l [ [ ’ Open_Norm ’ , ’ High_Norm ’ , ’ Low_Norm ’ , ’ Close_Norm ’ , ’ Volume_Norm ’ ] ] . to_numpy ( )
v a l _ y = v a l [ [ ’ Return_Norm ’ ] ] . to_numpy ( )

# Test
t e s t = d a t a [ pd . t o _ d a t e t i m e ( ’ 01−01−2019 ’ ) : pd . t o _ d a t e t i m e ( ’ 18−06−2020 ’ ) ]
t e s t _ x = t e s t [ [ ’ Open_Norm ’ , ’ High_Norm ’ , ’ Low_Norm ’ , ’ Close_Norm ’ , ’ Volume_Norm ’ ] ]
t e s t _ y = t e s t [ [ ’ Return_Norm ’ , ’ R e t u r n ’ ] ]
Código 13. Código fonte da RNA implementada e utilizada neste trabalho - Tratamento dos dados
# C r e a t i n g MLP Model
model = m o d e l s . S e q u e n t i a l ( )
model . add ( l a y e r s . Dense ( 3 0 , i n p u t _ d i m = t r a i n _ x . s h a p e [ 1 ] , a c t i v a t i o n = " t a n h " ) )
model . add ( l a y e r s . Dense ( 3 0 , a c t i v a t i o n = " t a n h " ) )
model . add ( l a y e r s . Dense ( 3 0 , a c t i v a t i o n = " t a n h " ) )
model . add ( l a y e r s . Dense ( 1 ) )
model . summary ( )

model . c o m p i l e (
o p t i m i z e r = ’ adam ’ ,
loss = ’ mean_squared_error ’ ,
)

# T r a i n i n g MLP
r e s u l t s = model . f i t (
train_x , train_y ,
epochs= 1000 ,
b a t c h _ s i z e = 128 ,
v a l i d a t i o n _ d a t a = ( val_x , val_y ) ,
verbose = 0
)

# P l o t t i n g T r a i n i n g and V a l i d a t i o n E r r o r s
p l t . p l o t ( r e s u l t s . h i s t o r y [ " l o s s " ] , l a b e l =" l o s s " )
p l t . p l o t ( r e s u l t s . h i s t o r y [ " v a l _ l o s s " ] , l a b e l =" v a l _ l o s s " )
p l t . legend ( )
p l t . show ( )

# P r e d i c t a l l T e s t Data
p r e d = model . p r e d i c t ( t e s t _ x )
pred = s c a l e r . i n v e r s e _ t r a n s f o r m ( pred )

# Creating Investment Strategy


t e s t _ y [ ’ Return_Predicted ’ ] = pred
t e s t _ y [ ’ M o v e m e n t _ P r e d i c t e d ’ ] = [ ’Up ’ i f p > 0 e l s e ’Down ’ f o r p i n p r e d ]
t e s t _ y [ ’ Movement_Real ’ ] = [ ’Up ’ i f m > 0 e l s e ’Down ’ f o r m i n t e s t _ y [ ’ R e t u r n ’ ] ]
t e s t _ y [ ’ H i t ’ ] = [ 1 i f m[ 1 ] [ ’ Movement_Real ’ ] == m[ 1 ] [ ’ M o v e m e n t _ P r e d i c t e d ’ ] e l s e 0 f o r m i n
test_y . iterrows () ]
t e s t _ y [ ’ I n v e s t m e n t _ R e t u r n ’ ] = [m[ 1 ] [ ’ R e t u r n ’ ] i f m[ 1 ] [ ’ M o v e m e n t _ P r e d i c t e d ’ ] == ’Up ’ e l s e 0
for m in test_y . iterrows () ]

# Show R e s u l t s
p r i n t ( ’ Acc : ’ , t e s t _ y [ ’ H i t ’ ] . mean ( ) )
i n i t i a l _ i n v e s t m e n t = d a t a [ pd . t o _ d a t e t i m e ( ’ 01−01−2019 ’ ) : ] . h e a d ( 1 ) [ ’ Open ’ ]
p r i n t ( ’ I n i t i a l I n v e s t m e n t : R$ \ n ’ , d a t a [ pd . t o _ d a t e t i m e ( ’ 01−01−2019 ’ ) : ] . h e a d ( 1 ) [ ’ Open ’ ] )
p r i n t ( ’ R e t u r n o f S t r a t e g y (RNA) : R$ ’ , t e s t _ y [ ’ I n v e s t m e n t _ R e t u r n ’ ] . sum ( ) , ’ Buy & Hold : R$ ’ , (
t e s t _ y [ ’ R e t u r n ’ ] . sum ( ) + i n i t i a l _ i n v e s t m e n t ) )
Código 14. Código fonte da RNA implementada e utilizada neste trabalho - Criação da RNA treinamento e predição

Você também pode gostar