Neste tutorial, você vai aprender a criar um Rastreador de Ações Profissional em Python, com interface gráfica moderna, gráficos interativos e suporte a diferentes moedas. Vamos usar CustomTkinter, tkcalendar, yfinance e matplotlib.

Funcionalidades do App

  • Seleção de ações populares ou entrada de um símbolo customizado.
  • Escolha de período e moeda.
  • Médias móveis MA20 e MA50 para análise técnica.
  • Gráfico interativo integrado à interface.
  • Exibição automática da variação percentual do período.
  • Salvar gráficos como PNG.

Passo 1: Instalar Dependências

Antes de começar, você precisa instalar algumas bibliotecas Python. Abra o terminal ou prompt de comando e execute:

pip install customtkinter tkcalendar yfinance matplotlib pandas

  • customtkinter → Interface moderna para Tkinter.
  • tkcalendar → Para selecionar datas facilmente.
  • yfinance → Para baixar dados históricos de ações.
  • matplotlib → Para plotar gráficos de preço.
  • pandas → Para manipulação e análise de dados.

Passo 2: Configurar o App e Tema

Começamos configurando o tema e aparência do aplicativo:

import customtkinter as ctk

ctk.set_appearance_mode("dark")        # Modo escuro
ctk.set_default_color_theme("blue")    # Tema azul

Isso garante que todos os widgets tenham um visual moderno e consistente.

Passo 3: Criar a Classe Principal do App

Usamos Programação Orientada a Objetos para organizar o app.

class StockApp(ctk.CTk):
    def __init__(self):
        super().__init__()
        self.title("📈 Rastreador de Ações Profissional")
        self.geometry("1100x650")
        self.minsize(1000, 600)
  • self.title() → Define o título da janela.
  • self.geometry() → Define o tamanho inicial da janela.
  • self.minsize() → Define tamanho mínimo da janela para evitar cortes nos elementos.

Passo 4: Criar a Sidebar com Controles

A sidebar é onde o usuário escolhe ações, datas e moeda.

self.sidebar = ctk.CTkFrame(self, width=300, corner_radius=0)
self.sidebar.pack(side="left", fill="y")

Elementos da Sidebar

1. Título e ComboBox de Ações

ctk.CTkLabel(self.sidebar, text="📊 Escolha uma Ação", font=("Roboto", 16, "bold")).pack(pady=(20, 15))

self.stock_list = ["AAPL", "MSFT", "AMZN", "GOOGL", "META", "TSLA", "NVDA", "NFLX"]
self.selected_stock = ctk.CTkComboBox(self.sidebar, values=self.stock_list, width=260, height=35)
self.selected_stock.pack(pady=10, padx=20)
self.selected_stock.set(self.stock_list[0])

2. Entrada para Ação Customizada

self.custom_stock = ctk.CTkEntry(self.sidebar, placeholder_text="Ou digite outro símbolo", width=260, height=35)
self.custom_stock.pack(pady=10, padx=20)

3. Escolha da Moeda

self.currency_symbols = {"USD ($)":"$", "EUR (€)":"€", "AOA (Kz)":"Kz"}
self.currency_combo = ctk.CTkComboBox(self.sidebar, values=list(self.currency_symbols.keys()), width=260, height=35)
self.currency_combo.pack(pady=10, padx=20)
self.currency_combo.set("USD ($)")

4. Seleção de Datas

from tkcalendar import DateEntry
self.start_date = DateEntry(self.sidebar, width=18)
self.start_date.pack(pady=5, padx=20)
self.end_date = DateEntry(self.sidebar, width=18)
self.end_date.pack(pady=5, padx=20)

5. Botões para Gerar e Salvar Gráficos

self.fetch_btn = ctk.CTkButton(self.sidebar, text="Gerar Gráfico", command=self.generate_chart)
self.fetch_btn.pack(pady=20, padx=20)

self.save_btn = ctk.CTkButton(self.sidebar, text="💾 Salvar Gráfico", command=self.save_chart)
self.save_btn.pack(pady=5, padx=20)

6. Label de Variação Percentual

self.percentage_label = ctk.CTkLabel(self.sidebar, text="")
self.percentage_label.pack(pady=(20,0), padx=20)

Passo 5: Criar o Frame do Gráfico

No lado direito, teremos o gráfico interativo do preço da ação:

self.chart_frame = ctk.CTkFrame(self)
self.chart_frame.pack(side="right", fill="both", expand=True, padx=10, pady=10)
self.canvas = None
self.fig = None

Passo 6: Formatação de Moeda

Para exibir preços com o símbolo correto:

def format_currency(self, value, currency):
    currency_formats = {
        "USD ($)": lambda x: f"${x:,.2f}",
        "AOA (Kz)": lambda x: f"Kz {x:,.0f}"
    }
    return currency_formats.get(currency, lambda x: f"{x:,.2f}")(value)

 

Passo 7: Gerar o Gráfico de Preço

A função principal generate_chart() faz o seguinte:

  1. Escolhe o ticker da ação.
  2. Baixa os dados com yfinance.
  3. Calcula médias móveis (MA20 e MA50).
  4. Converte preços para a moeda escolhida.
  5. Plota o gráfico com matplotlib.
  6. Mostra a variação percentual no período.
data = yf.download(ticker, start=start, end=end, auto_adjust=True)
data["MA20"] = data["Close"].rolling(20).mean()
data["MA50"] = data["Close"].rolling(50).mean()

Para plotar:

import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

self.fig, ax = plt.subplots(figsize=(8,5))
ax.plot(data["Date"], data["Close_converted"], color="#2D7DD2", label="Preço")
ax.plot(data["Date"], data["MA20_converted"], color="#F4A261", linestyle="--", label="MA20")
ax.plot(data["Date"], data["MA50_converted"], color="#E76F51", linestyle="--", label="MA50")
ax.set_title(f"{ticker} — Preço em {currency}")
ax.legend()

self.canvas = FigureCanvasTkAgg(self.fig, master=self.chart_frame)
self.canvas.draw()
self.canvas.get_tk_widget().pack(fill="both", expand=True)

 

Passo 8: Salvar o Gráfico

O botão de salvar chama:

def save_chart(self):
    if self.fig is None:
        messagebox.showwarning("Aviso", "Gere o gráfico antes de salvar.")
        return
    file_path = filedialog.asksaveasfilename(defaultextension=".png", filetypes=[("PNG", "*.png")])
    if file_path:
        self.fig.savefig(file_path)
        messagebox.showinfo("Sucesso", f"Gráfico salvo em:\n{file_path}")

 

Passo 9: Executar o App

Por fim, inicializamos a aplicação:

if __name__ == "__main__":
    app = StockApp()
    app.mainloop()