DEV Community

Cover image for Automatizando Análises de Ações da Bolsa com Python e Inteligência Artificial
Matheus Ronelle
Matheus Ronelle

Posted on

1

Automatizando Análises de Ações da Bolsa com Python e Inteligência Artificial

Introdução

Em um mundo onde a análise de dados e a automação de processos são cada vez mais essenciais, entender como integrar ferramentas tecnológicas pode ser um grande diferencial. Este projeto foi desenvolvido como uma iniciativa didática para treinar a utilização de APIs e inteligência artificial (IA), explorando ferramentas tecnológicas que podem simplificar processos complexos.

Objetivo do Projeto

  1. Coletar dados financeiros de ações em tempo real;
  2. Gerar gráficos e análises técnicas;
  3. Automatizar a criação de um relatório em PDF;
  4. Enviar o relatório por e-mail para stakeholders.

Ferramentas Utilizadas

  • Python: Para a lógica de programação e automação.
  • Alpha Vantage API: Para coleta de dados financeiros.
  • Pandas e Matplotlib: Para análise e visualização de dados.
  • FPDF: Para geração de PDFs.
  • OpenAI API: Para gerar insights automatizados com IA.
  • SMTP: Para envio de e-mails automatizados.

Passo a Passo do Projeto

1. Coleta de Dados com a Alpha Vantage API

A primeira etapa foi coletar dados financeiros em tempo real. Para isso, utilizei a API da Alpha Vantage, que fornece dados históricos e em tempo real de ações. A biblioteca requests foi utilizada para fazer as chamadas à API.

2. Análise e Visualização de Dados

Com os dados em mãos, utilizei o Pandas para manipulação e o Matplotlib para criar gráficos de preços de fechamento e médias móveis.

3. Geração de Relatórios em PDF

Para criar o relatório em PDF, utilizei a biblioteca FPDF. O relatório inclui o gráfico gerado e insights obtidos com a OpenAI API.

4. Automação de E-mails

Por fim, utilizei a biblioteca smtplib para enviar o relatório por e-mail automaticamente.

Conclusão

Este projeto foi uma excelente oportunidade para aprofundar meus conhecimentos em Python e APIs. Ao longo do desenvolvimento, pude explorar conceitos importantes, como o protocolo HTTP, status codes, estrutura de requisições HTTP, tipos de autenticação de APIs e muito mais.

Vale ressaltar que o objetivo principal deste projeto foi didático. As recomendações de compra ou venda geradas no relatório são baseadas em análises técnicas automatizadas e não devem ser utilizadas como única fonte para decisões de investimento. A análise de mercado exige uma abordagem mais abrangente, considerando fatores fundamentais, macroeconômicos e contextuais.

Aqui está um exemplo do relatório gerado para as ações da Apple no dia 30/01/2025, juntamente com o código utilizado:

Image description

import os
from dotenv import load_dotenv
import requests
import pandas as pd
import matplotlib.pyplot as plt
from fpdf import FPDF, enums
import openai
import time
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.base import MIMEBase
from email import encoders
import re

# Carregar variáveis de ambiente do arquivo .env
load_dotenv()

# Obter as chaves da API e senha do e-mail
api_key = os.getenv('ALPHA_VANTAGE_API_KEY')
openai_api_key = os.getenv('OPENAI_API_KEY')
email_app_password = os.getenv('EMAIL_APP_PASSWORD')

# Verificar se as chaves foram carregadas corretamente
if not api_key:
    raise ValueError("Chave da API Alpha Vantage não encontrada. Verifique o arquivo .env.")

if not openai_api_key:
    raise ValueError("Chave da API OpenAI não encontrada. Verifique o arquivo .env.")

if not email_app_password:
    raise ValueError("Senha do aplicativo de e-mail não encontrada. Verifique o arquivo .env.")

# Inicializa o cliente OpenAI corretamente
client = openai.OpenAI(api_key=openai_api_key)

# Função para remover emojis e caracteres especiais
def remover_emoji(texto):
    return re.sub(r'[^\x00-\x7F]+', '', texto)

# Função para obter insights da IA
def obter_insights(dados):
    prompt = f"""
    A seguir estão os dados financeiros recentes para as ações monitoradas:
    {dados}

    Com base nesses dados e utilizando exclusivamente análise grafista, sem considerar fatores externos, você recomendaria a compra ou venda dessas ações? 
    Explique brevemente utilizando apenas uma análise grafista, e sendo puramente técnico. Pode utilizar conceitos avançados da análise grafista, como linhas de tendência, suporte e resistência, fibonacci, etc.
    Somado a isso, gere um texto sem caracteres especiais, exemplo: Ao invés de escrever Relatório, escreva Relatorio. Por fim, elabore um texto de, no mínimo, 200 palavras com uma análise completa.
    """
    try:
        response = client.chat.completions.create(
            model="gpt-3.5-turbo",
            messages=[
                {"role": "system", "content": "Você é um analista financeiro."},
                {"role": "user", "content": prompt}
            ]
        )
        insights = response.choices[0].message.content.strip()
        insights = remover_emoji(insights)  # Remove emojis
        print("\n🔍 **Insights Gerados pela IA:**\n")
        print(insights)  # Exibir insights na tela
        return insights
    except Exception as e:
        return f"Erro ao obter insights: {str(e)}"

# Lista de símbolos das ações monitoradas
symbols = ['AAPL']

# Dicionário para armazenar os DataFrames de cada ação
dataframes = {}

# Coletar dados das ações
for symbol in symbols:
    url = f'https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol={symbol}&apikey={api_key}'

    response = requests.get(url)
    data = response.json()

    if "Time Series (Daily)" in data:
        print(f"Dados coletados com sucesso para {symbol}")
        time_series = data['Time Series (Daily)']
        df = pd.DataFrame.from_dict(time_series, orient='index')
        df.index = pd.to_datetime(df.index)
        df.columns = ['Open', 'High', 'Low', 'Close', 'Volume']
        df = df.astype(float)
        df['SMA_20'] = df['Close'].rolling(window=20).mean()
        dataframes[symbol] = df
    elif "Error Message" in data or "Note" in data:
        print(f"Erro na API para {symbol}: {data}")
        break

    time.sleep(15)  # Respeitar limite da API

# Criar o PDF
pdf = FPDF()
pdf.set_auto_page_break(auto=True, margin=15)

# Adicionar cabeçalho ao PDF
pdf.add_page()
pdf.set_font("Arial", 'B', 16)
pdf.cell(200, 10, "Relatório Diário: Desempenho das Ações", new_x=enums.XPos.LMARGIN, new_y=enums.YPos.NEXT, align='C')
pdf.ln(10)  # Aumentar o espaçamento após o cabeçalho

# Gerar gráficos e adicionar ao PDF
for symbol, df in dataframes.items():
    plt.figure(figsize=(10, 5))
    plt.plot(df.index, df['Close'], label='Preço de Fechamento', color='#1f77b4')
    plt.plot(df.index, df['SMA_20'], label='Média Móvel 20 dias', color='orange')
    plt.title(f'Preço de Fechamento da Ação {symbol}', fontsize=14, fontweight='bold')
    plt.xlabel('Data', fontsize=12)
    plt.ylabel('Preço de Fechamento (USD ou BRL)', fontsize=12)
    plt.legend(loc='upper left')
    plt.grid(True, linestyle='--', alpha=0.7)

    image_path = f"{symbol}.png"
    plt.savefig(image_path)
    plt.close()

    # Adicionar título do gráfico
    pdf.set_font("Arial", 'B', 14)
    pdf.cell(200, 10, f'Desempenho da Ação: {symbol}', new_x=enums.XPos.LMARGIN, new_y=enums.YPos.NEXT, align='C')
    pdf.ln(5)  # Ajuste o espaçamento após o título do gráfico

    # Adicionar gráfico ao PDF
    pdf.image(image_path, x=10, y=pdf.get_y(), w=190)
    pdf.ln(100)  # Aumentar o espaçamento após o gráfico

    os.remove(image_path)

    # Obter e adicionar insights da IA
    dados_para_ia = f"{symbol}: Preço de Fechamento: {df['Close'].iloc[-1]:.2f}, Média Móvel 20 dias: {df['SMA_20'].iloc[-1]:.2f}"
    insights = obter_insights(dados_para_ia)

    # Adicionar os insights abaixo do gráfico
    pdf.set_font("Arial", 'B', 12)
    pdf.set_xy(10, pdf.get_y())  # Definir a posição x e y para o texto
    pdf.multi_cell(w=190, h=8, text=f"Insights da IA para {symbol}:")

    pdf.set_font("Arial", size=11)
    pdf.set_xy(10, pdf.get_y())  # Definir a posição x e y para o texto
    pdf.multi_cell(w=190, h=6, text=insights)

# Salvar o PDF
pdf_output_path = "desempenho_acoes_corrigido.pdf"
pdf.output(pdf_output_path)

print(f"📄 PDF gerado com sucesso: {pdf_output_path}")

# **Envio de E-mail**
from_address = "matheusronelle1@gmail.com"
to_address = "matheusronelle@hotmail.com"
subject = "Relatório Diário: Desempenho das Ações"
body = """
<html>
  <body>
    <h2>Relatório Diário: Desempenho das Ações</h2>
    <p>Por favor, encontre em anexo o relatório diário com o desempenho das ações monitoradas.</p>
    <p>Atenciosamente,<br>Matheus</p>
  </body>
</html>
"""

msg = MIMEMultipart()
msg['From'] = from_address
msg['To'] = to_address
msg['Subject'] = subject
msg.attach(MIMEText(body, 'html'))

with open(pdf_output_path, "rb") as attachment:
    part = MIMEBase('application', 'octet-stream')
    part.set_payload(attachment.read())
    encoders.encode_base64(part)
    part.add_header('Content-Disposition', f'attachment; filename= {os.path.basename(pdf_output_path)}')
    msg.attach(part)

server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(from_address, email_app_password)
server.sendmail(from_address, to_address, msg.as_string())
server.quit()

print("📧 E-mail enviado com sucesso!")
Enter fullscreen mode Exit fullscreen mode

Heroku

This site is built on Heroku

Join the ranks of developers at Salesforce, Airbase, DEV, and more who deploy their mission critical applications on Heroku. Sign up today and launch your first app!

Get Started

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more