Prevendo o Mercado Financeiro com Redes Neurais Artificiais — Parte I

Interessado em começar a investir? Esse post é o primeiro de uma série voltada à previsão do mercado financeiro usando técnicas de Inteligência Artificial

Arthur Oliveira
6 min readAug 19, 2019

Introdução

Esse é um post que inicia uma série de artigos sobre investimentos utilizando Redes Neurais Artificiais. Acesse aqui a Parte 2.

Existem inúmeros artigos na literatura acadêmica que tratam sobre a possibilidade da previsão do mercado financeiro. Alguns autores argumentam que o mercado financeiro possui uma trajetória aleatória, outros que o mercado reflete as informações novas assim que elas são disponibilizadas, sendo impossível “vencer” o mercado e obter ganhos absurdos.

No entanto, o fato é que existem também muitos trabalhos na literatura que mostram que existe uma possibilidade de previsão do mercado, mesmo que de forma parcial. Alguns trabalhos utilizam dados de séries temporais do mercado financeiro (como valores de ações) na tentativa de compreender padrões e esperar que se repitam no futuro. Aqui se encaixa uma forma de análise do mercado financeiro chamada Análise Técnica.

Por outro lado, também existem trabalhos que utilizam dados que são oriundos de notícias, com o objetivo de realizar tarefas de Análise de Sentimentos sobre as mesmas, na esperança de captar novas tendências no mercado para guiar os futuros investimentos. Já abordamos sobre Análise de Sentimentos com uma técnica simples e efetiva nesse post. Nesse ponto, temos uma análise de mercado chamada Análise Fundamentalista.

Descrevendo o Problema

Nesse post, vou atacar a previsão do valor de ações no mercado financeiro brasileiro por meio do índice Bovespa (iBovespa). Ou seja, vamos partir dos valores do índice que mede a tendência da bolsa de valores no Brasil entre os anos de 2015 e 2019 para treinar uma Rede Neural Artificial do tipo Multilayer Perceptron (MLP), a qual tratamos nesse post, para que ela nos ajude a fazer previsões sobre o mercado financeiro.

Lembrando que aqui iremos apenas esboçar o início de uma aplicação com RNAs para previsão do mercado financeiro. Esse post não possui o intuito de esgotar o assunto.

Implementando

Agora que há um entendimento do nosso contexto, do problema e das técnicas que serão utilizadas, vamos implementá-la em Python usando a biblioteca Keras, que se trata (no meu ponto de vista) da melhor biblioteca para iniciantes em Redes Neurais Artificiais e Deep Learning.

Para repetir o nosso experimento, você pode baixar a base de dados de séries temporais do iBovespa por meio de um arquivo CSV nesse link.

Primeiramente, vamos carregar os dados do arquivo CSV e exibí-lo em um gráfico, nos restringindo apenas ao preço de fechamento da ação no dia (Close).

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
#Carregando os dados
data = pd.read_csv("BVSP.csv")
#Plotting...
data.plot(x='Date', y = 'Close')
plt.show()

Agora que possuímos alguma informação visual dos dados, vamos ver como o arquivo CSV se apresenta.

Portanto, temos as seguintes colunas: data, preço de abertura, de alta, baixa e fechamento, além do volume de transações do dia.

Neste problema, iremos então prever o preço de fechamento de um dia dados os demais valores. Com isso, tentaremos sempre prever qual o valor do day trade no momento de seu encerramento, com o objetivo de fazer alguma transação financeira nesse momento levando-se em consideração todo o valor passado da série financeira.

Agora, vamos preparar nossos dados para o nosso modelo (RNA). Como vamos prever o preço de fechamento, a idéia a seguir é retirar o preço de fechamento dos dados (features) que irão treinar a nossa rede e adicioná-los aos rótulos (labels) que iremos tentar prever. Afinal, uma RNA sempre parte de um conjunto de dados para prever um conjunto de dados alvo. A isso damos o nome de treinamento supervisionado.

Além disso, vamos remover a coluna de data, pois, para o nosso intuito inicial, ela não será relevante. Nossa previsão será realizada com base em valores anteriores das ações, independentemente do dia em que elas se apresentem.

#Extracting Features
labels = np.array( data['Close']).reshape(-1,1)
features = data.drop('Close', axis = 1)
features = data.drop('Date', axis = 1)
features = np.array(features)

Aqui, um passo importante. Redes Neurais Artificiais necessitam de receber dados normalizados, comumente abrangendo uma faixa de 0 a 1. Isso porque elas apresentam melhores resultados quando recebem dados em uma faixa de valores pré-definidos, evitando uma série de problemas na previsão ao receber dados cujos valores podem ser muito discrepantes.

Para normalizar em Python, é muito simples:

#Normalizing
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
features = scaler.fit_transform(features)
labels = scaler.fit_transform( labels )

A seguir, dividimos nossos dados em conjunto de treinamento e testes. Enquanto o conjunto de treinamento irá gerar o nosso modelo (RNA), o conjunto de testes é utilizado para validar o modelo gerado, ou seja, para verificar se o modelo atende ao esperado ou se devemos modificá-lo.

#Splitting the data
from sklearn.model_selection import train_test_split
train_x, test_x, train_y, test_y = train_test_split(features, labels, test_size = 0.20, random_state = 42)

Finalmente, vamos criar nossa Rede Neural Artificial do tipo Multilayer Perceptron para realizar nosso treinamento. A nossa RNA possuirá a camada de entrada, duas camadas intermediárias com 30 neurônios e uma camada de saída com apenas 1 neurônio. Nesse ponto, diferentes arquiteturas e modelos de RNAs podem ser testadas, para verificar quais se adequam melhor ao nosso problema.

#Model
from keras import models
from keras import layers
from keras.layers import Dense
model = models.Sequential()
model.add(layers.Dense(30, input_dim = features.shape[1], activation = "relu"))
model.add(layers.Dense(30, activation ="relu"))
model.add(layers.Dense(1))
model.summary()

Por fim, vamos compilar nossa rede e treiná-la. Validando os nossos resultados.

Aqui, o mais importante é destacar a função de erro (loss), que é o erro quadrático médio, ou seja, uma espécie de distância entre os valores previstos pela nossa RNA e os valores reais que estão contidos no vetor de labels da nossa rede. Como no nosso caso queremos prever o valor de ações, é importante saber qual a distância o cálculo do nosso modelo está em comparação ao valor real das ações.

model.compile(
optimizer = ‘adam’,
loss = “mean_squared_error”, #mean_squared_error
)
results = model.fit(
train_x, train_y,
epochs= 100,
batch_size = 128,
validation_data = (test_x, test_y)
)

A Figura a seguir mostra um breve resumo da nossa rede, seus parâmetros e os resultados de execução das três primeiras épocas (passagens de todos os dados pela rede)

Avaliando a nossa função de erro ao longo das 100 épocas, temos:

plt.plot(results.history["loss"], label="loss")
plt.plot(results.history["val_loss"], label="val_loss")
plt.legend()
plt.show()

Pelo gráfico, podemos ver como a função de erro apresentou melhora (ou seja, diminuição em seu valor) à medida em que a RNA foi treinada. Visualmente falando, seu valor estabilizou por volta da época 20.

Conclusão

Com esse processo, foi possível visualizar todas as etapas, desde a coleta de dados, até a criação e treinamento de um modelo de RNA para previsão do mercado financeiro. Note que ainda não fizemos a previsão e análise do modelo em si, que ficará para futuros posts.

Aqui tratamos apenas de uma versão inicial dessa árdua tarefa que é a previsão do mercado financeiro. No entanto, esse processo necessita ser complementado, o que tentaremos fazer em posts futuros. Por exemplo, é necessário uma análise da viabilidade dos resultados apresentados pela função de erro, além de realizarmos de fato previsões no mercado com o modelo proposto, visto que até o momento apenas treinamos o modelo. Além disso, também é interessante utilizar a estratégia delineada pela RNA para simular uma carteira de investimentos no mercado financeiro para avaliar qual seria o nosso retorno.

Ainda, podemos melhorar o modelo proposto, testando diferentes arquiteturas e número de nós e camadas na rede.

Enfim, temos muito trabalho à frente e pontos que serão abordados a fundo em futuras postagens.

Acesse aqui a Parte 2 deste artigo.

Obrigado pela leitura!

--

--

Arthur Oliveira

Professor da área de computação. Doutor pela UNICAMP. Graduado em Ciências da Computação e mestre pela USP.