Objetivo Buscar e salvar os Tickers das ações integrantes no S&P100 no período pedido.
- as_of: Ano e mes desejado [yyyy-mm]
- save_csv: Salvar ou apenas retornar os dados [bool]
- csv_dir: Diretório [str]
Objetivo Descarregar as informações históricas de cada ticker préviamente salvo nas datas relevantes.
Script de uso único
Objetivo. Converter janelas da série em imagens usando um método específico
-
Série:
$S = {x_t}_{t=1}^T$ -
$S$ : série temporal completa -
$x_t$ : valor da série no tempo$t$ -
$T$ : comprimento total da série
-
-
Janela:
$W_t = (x_{t-w+1}, \ldots, x_t)$ -
$W_t$ : janela (subconjunto) da série que termina no tempo$t$ -
$w$ : tamanho da janela (número de observações)
-
-
Imagem:
$I_t^{(m)} = \text{Transform}_m(W_t)$ , para$t \in {w, w+s, w+2s, \ldots}$ -
$I_t^{(m)}$ : imagem gerada pelo método$m$ no tempo$t$ -
$\text{Transform}_m$ : função de transformação específica do método$m$ -
$s$ : stride (passo entre janelas consecutivas)
-
-
Stride:
$s$ -
$s = 1$ : janelas sobrepostas (cada novo ponto cria uma janela) -
$s = w$ : janelas sem sobreposição (janelas independentes) -
$s > w$ : janelas com lacunas entre elas
-
-
Número de janelas:
$N = \left\lfloor \frac{T-w}{s} \right\rfloor + 1$ (com$T \geq w$ )-
$N$ : quantidade total de janelas/imagens geradas -
$\lfloor \cdot \rfloor$ : função piso (arredonda para baixo)
-
Saída.
-
${I_t^{(m)}}$ : conjunto de todas as imagens geradas -
$\overline{m}$ : identificador do método usado
Método Implementado (GAF_RGB). A estratégia principal desenvolvida utiliza um único método composto, aqui identificado como m = "GAF_RGB". Este método gera uma imagem de 3 canais onde:
-
Canal R: GASF (Gramian Angular Summation Field)
-
Canal G: GADF (Gramian Angular Difference Field)
-
Canal B: MTF (Markov Transition Field)
O pipeline subsequente é, portanto, otimizado para este tipo de imagem de entrada.
-
Entrada:
$S$ (série temporal) -
Parâmetros:
$w$ (tamanho da janela),$s$ (stride), método fixo$m$ -
Saída: imagens
${I_t^{(m)}}$ para o método$m$
Objetivo. Padronizar as imagens do método
Onde:
-
$X_t^{(m)}$ : imagem pré-processada (tensor) pronta para a CNN -
$g$ : função de pré-processamento -
$I_t^{(m)}$ : imagem bruta gerada na etapa anterior -
$H$ : altura (height) da imagem em pixels -
$W$ : largura (width) da imagem em pixels -
$C$ : número de canais (ex: 1 para grayscale, 3 para RGB) -
$\theta$ : hiperparâmetros de normalização/transformação
- Limpeza: NaN/Inf/outliers → clip opcional
- Redimensionamento: As imagens são mantidas em seu formato (H, W, 3), conforme geradas na etapa anterior. O método GAF_RGB já representa o empilhamento dos canais GASF, GADF e MTF.
- Normalização (Delegada à CNN): Nenhuma normalização de pixel (ex: min-max para [0,1]) é aplicada nesta etapa. As imagens são passadas para o modelo com seus valores de ponto flutuante brutos (ex: GAFs em [-1, 1] e MTF em [0, 1]). A normalização será realizada dentro da arquitetura da CNN através de camadas de BatchNormalization, que aprendem as estatísticas de normalização adequadas durante o treinamento. Esta abordagem simplifica o pré-processamento e torna o modelo mais robusto.
- Splits temporais: sem vazamento
-
Empacotamento: tensores float32 + metadados, incluindo
$m$
Saída.
-
Entrada:
${I_t^{(m)}}$ (imagens brutas) -
Parâmetros:
$H, W, C, \theta$ (por$m$ ) -
Saída:
${X_t^{(m)}}$ (tensores normalizados por$m$ )
Objetivo. Treinar e otimizar uma CNN exclusiva para o método
Onde:
-
$\hat{p}_{t+h}^{(m)}$ : vetor de probabilidades previsto para o tempo futuro$t+h$ . -
$\hat{p} = [\hat{p}(Q_1), \hat{p}(Q_2), \dots, \hat{p}(Q_K)]$ , onde$K$ é o número de quartis. - A tarefa do modelo é classificar a imagem
$X_{t}^{(m)}$ na categoria de quintil de retorno futuro mais provável.
- Arquitetura: Conv/BN/ReLU/Pool, dropout, weight decay
- Perda: CategoricalCrossentropy. Essencial para treinar um modelo de classificação multiclasse.
- Métricas: Accuracy, AUC (One-vs-Rest), LogLoss (Cross-Entropy). Métricas financeiras são secundárias e calculadas em etapas posteriores.
- HPO: random/bayesiana, early stopping, time-series split
- Melhor par $(\theta^, \lambda^)$
-
$\theta^*$ : melhores parâmetros do modelo -
$\lambda^*$ : melhores hiperparâmetros (learning rate, regularização, etc.)
-
- Predições
$\hat{p}_{t+h}^{(m)}$ (vetores de probabilidade) em val/test. - Artefatos (pesos + configs) etiquetados com
$m$
-
Entrada:
${X_t^{(m)}}$ (imagens processadas), rótulos$y_{t+h}$ (valores reais) -
Parâmetros: arquitetura/treino/HPO para
$m$ -
Saída: modelo e predições do método
$m$
Objetivo. Consumir as previsões brutas de probabilidade da CNN, alinhá-las no tempo e transformá-las nos sinais quantitativos necessários para o modelo de portfólio Black-Litterman: o vetor de visões de retorno (
- Previsões brutas do modelo CNN (
probs_transfer_learning_pipe_2.csv): vetores de probabilidade sobre bins fixos de retorno $\hat{p}{t}^{(m)} = [p{bin0}, \ldots, p_{bin4}]$ para cada ativo e data. - Dados históricos de mercado (diretório
Séries_temp): preços diários de todo o universo de ativos S&P100 para calibração dinâmica dos bins e cálculo da matriz de covariância.
O modelo CNN classifica retornos futuros (horizonte de 63 dias ≈ 1 trimestre) em 5 bins fixos:
- Bin 0: retorno < -5%
- Bin 1: -5% ≤ retorno < -1%
- Bin 2: -1% ≤ retorno < 1%
- Bin 3: 1% ≤ retorno < 5%
- Bin 4: retorno ≥ 5%
- Sinais (
signals_black_litterman.csv): Tabela contendo os sinais prontos para obacktest.py:
| time | asset_id | mu_hat (Q) | omega_hat_sq (Ω) | method |
|---|---|---|---|---|
| AAPL | -0.02456 | 0.00236 | GAF_RGB | |
| MSFT | -0.01874 | 0.00198 | GAF_RGB |
- Matrizes de Covariância (diretório
covariance_matrices/):- Uma matriz por data de negociação:
cov_YYYY-MM-DD.csv - Resumo estatístico:
covariance_summary.csv
- Uma matriz por data de negociação:
-
Carregar Previsões da CNN:
- Carregar os vetores de probabilidade
$\hat{p}_{t}^{(m)}$ gerados pelo modelo para todos os ativos e datas. - Total: 2,808 sinais ao longo de 29 trimestres (2017-2024), cobrindo ~110 ativos.
- Carregar os vetores de probabilidade
-
Calibração Dinâmica dos Retornos de Bin (Online):
-
Abordagem adaptativa: Os retornos esperados para cada bin são recalibrados trimestralmente usando dados recentes:
- Q1 2017 (primeira previsão): Usa todos os retornos realizados de 2016 para calibrar os bins.
- Trimestres subsequentes: Usa os retornos realizados do trimestre anterior.
- Para cada bin
$b$ , calcular$E[R|bin_b]$ = média dos retornos que caíram naquele bin no período de calibração. - Resultado: vetor dinâmico $ER_{Bin} = [ER|bin_0, \ldots, ER|bin_4]$, que se adapta às condições de mercado.
-
Abordagem adaptativa: Os retornos esperados para cada bin são recalibrados trimestralmente usando dados recentes:
-
Construir o Vetor de Visões (
$Q$ ):- Para cada ativo
$i$ e tempo$\tau$ , calcular o retorno esperado ($\hat{\mu}{i,\tau}$) como a média dos retornos de bin calibrados, ponderada pelo vetor de probabilidades previsto pela CNN: $$ \hat{\mu}{i,\tau} = Q_i = \sum_{b=0}^{4} \hat{p}_{i,\tau}(bin_b) \cdot ER|bin_b $$ - Este vetor
$\hat{\mu}_{\tau}$ será usado como o vetor de visões$Q$ no modelo Black-Litterman.
- Para cada ativo
-
Construir a Matriz de Incerteza da Visão (
$\Omega$ ):- A confiança em cada visão é o inverso de sua incerteza. Calculamos a incerteza para o ativo
$i$ como a variância da distribuição de retorno prevista pela CNN: $$ \omega_{i,i} = \sum_{b=0}^{4} \hat{p}{i,\tau}(bin_b) \cdot (ER|bin_b - \hat{\mu}{i,\tau})^2 $$ - Uma previsão "confiante" (distribuição concentrada) resultará em uma variância
$\omega_{i,i}$ baixa. Uma previsão incerta (distribuição dispersa) resultará em uma variância alta. - A matriz
$\Omega_{\tau}$ é uma matriz diagonal contendo esses valores de variância.
- A confiança em cada visão é o inverso de sua incerteza. Calculamos a incerteza para o ativo
-
Estimar a Matriz de Covariância (
$\Sigma$ ) com Janela Móvel:-
Abordagem dinâmica: Para cada trimestre
$\tau$ , calcular$\Sigma_{\tau}$ usando os últimos 252 dias de negociação (≈ 1 ano). - Esta janela móvel captura a volatilidade recente e mudanças de regime de mercado, mantendo robustez estatística.
- Para robustez, aplicar Ledoit-Wolf shrinkage (20% em direção à matriz diagonal) para reduzir erro de estimação.
- Resultado: 29 matrizes de covariância, uma para cada data de rebalanceamento, capturando a evolução temporal do risco.
-
Abordagem dinâmica: Para cada trimestre
-
Consistência Temporal (Sem Vazamento):
- Período out-of-sample completo: Todo o período 2017-2025 é tratado como teste (out-of-sample).
-
Look-ahead bias evitado: Calibração de bins e covariância usam apenas dados até
$\tau^-$ (estritamente antes de$\tau$ ). - Adaptação online: O sistema se adapta trimestralmente às condições de mercado sem re-treinar o modelo CNN.
-
Serialização:
- Salvar sinais ($\hat{\mu}{\tau}$, $\omega{\tau}$) em
signals_black_litterman.csv. - Salvar cada matriz
$\Sigma_{\tau}$ emcovariance_matrices/cov_YYYY-MM-DD.csv. - Salvar resumo estatístico das matrizes de covariância em
covariance_summary.csv.
- Salvar sinais ($\hat{\mu}{\tau}$, $\omega{\tau}$) em
- Sinais: 2,808 sinais (110 ativos × 29 trimestres)
- Período: 2017-07-03 a 2024-10-01
- Retorno esperado médio: -2.46% (trimestral)
- Incerteza média: 0.00236
- Ativos por matriz de covariância: ~97 (média)
- Volatilidade capturada: Mínima 0.0059 (Jan/2018), Máxima 0.0342 (Out/2020 - COVID)
- Entrada: Previsões de probabilidade da CNN e dados históricos de mercado.
-
Parâmetros:
- Horizonte de previsão: 63 dias (1 trimestre)
- Janela de covariância: 252 dias (1 ano, móvel)
- Shrinkage: 20% (Ledoit-Wolf)
-
Saída: Sistema adaptativo completo gerando sinais financeiros prontos para Black-Litterman: retornos esperados (
$Q$ ), incerteza ($\Omega$ ) e covariância ($\Sigma$ ), todos recalibrados trimestralmente.
Objetivo. Implementar a estratégia de alocação Black-Litterman (definida em strategy.py) e testá-la em uma janela out-of-sample, usando os sinais do signal_generator.py e incorporando fricções de mercado realistas.
-
Sinais do
signal_generator.py:- Vetor de visões de retorno esperado
$Q_{\tau}$ . - Matriz diagonal de incerteza das visões
$\Omega_{\tau}$ . - Matriz de covariância histórica
$\Sigma_{\tau}$ .
- Vetor de visões de retorno esperado
-
Dados de Mercado:
- Pesos do portfólio de mercado
$w_{mkt}$ para o cálculo dos retornos de equilíbrio. - Preços e retornos realizados para execução do backtest.
- Pesos do portfólio de mercado
-
Parâmetros da Estratégia:
- Parâmetros Black-Litterman: aversão ao risco do mercado
$\lambda$ , escalar de incerteza$\tau$ . - Parâmetros de Otimização: aversão ao risco do investidor
$\gamma$ , penalidade de turnover$\kappa$ . - Parâmetros de Execução: custos, slippage, frequência de rebalanceamento e restrições.
- Parâmetros Black-Litterman: aversão ao risco do mercado
- Série de pesos
$w_{\tau}$ (alocação em cada ativo), PnL (lucro/perda), equity curve (evolução do capital), métricas de risco/retorno e diagnósticos de processo.
strategy.py define o modelo de alocação em duas etapas: primeiro o Black-Litterman para gerar os retornos esperados e, em seguida, a otimização de Média-Variância.
-
Cálculo dos Retornos de Equilíbrio
$\Pi_{\tau}$ : $$ \Pi_{\tau} = \lambda \Sigma_{\tau} w_{mkt} $$ -
Cálculo dos Retornos Esperados Posteriores (Black-Litterman)
$\hat{\mu}_{BL, \tau}$ : $$ \hat{\mu}{BL, \tau} = [(\tau \Sigma{\tau})^{-1} + P^T \Omega_{\tau}^{-1} P]^{-1} [(\tau \Sigma_{\tau})^{-1} \Pi_{\tau} + P^T \Omega_{\tau}^{-1} Q_{\tau}] $$ -
Otimização Final (Média-Variância com Retornos BL): O vetor $\hat{\mu}{BL, \tau}$ é então usado como input para um otimizador que resolve: $$ \max{w} \quad w^T \hat{\mu}{BL, \tau} - \frac{\gamma}{2} w^T \Sigma{\tau} w - \kappa | w - w_{\tau^-} |_1 $$ Sujeito a restrições como
$\sum w = 1$ , limites de peso, etc.
-
Calendário e Janelas:
- Definir período de warm-up e frequência de rebalanceamento.
-
Otimização (a cada data de rebalanceamento
$\tau$ ):-
Passo 2.1: Chamar
strategy.pypara executar o processo Black-Litterman, gerando o vetor de retornos final$\hat{\mu}_{BL,\tau}$ . -
Passo 2.2: Resolver a otimização de Média-Variância para encontrar os pesos alvo
$w_{\tau}$ , incluindo a penalidade de turnover$\kappa$ .
-
Passo 2.1: Chamar
-
Execução:
- Calcular as negociações necessárias e aplicar custos de transação (bps) e slippage.
-
Atualização de PnL:
- Calcular o retorno do portfólio para o próximo período: $r^{\text{pf}}{\tau+1} = w{\tau}^T r_{\tau+1} - \text{custos}$.
- Atualizar a equity curve.
-
Métricas e Diagnósticos:
- Calcular métricas de Risco/Retorno (Sharpe, Sortino, Drawdown) e de Processo (Turnover, Concentração).
-
Validação Temporal:
- Executar o backtest em uma janela out-of-sample, garantindo que todos os hiperparâmetros da estratégia foram definidos usando apenas dados de treino/validação.
-
Serialização:
- Salvar a trajetória completa dos pesos
$w_{\tau}$ , PnL, e métricas em arquivos parquet/json para análise noreport.py.
- Salvar a trajetória completa dos pesos
-
Entrada: Sinais para Black-Litterman (
$Q_{\tau}, \Omega_{\tau}, \Sigma_{\tau}$ ) e dados de mercado. -
Parâmetros: Parâmetros do modelo Black-Litterman (
$\lambda, \tau$ ), da otimização ($\gamma, \kappa$ ) e de execução (custos, rebalance). - Saída: Trajetória de portfólio (pesos, PnL), métricas de performance e risco.
Objetivo. Gerar visualizações, tabelas e métricas consolidadas a partir dos resultados do backtest para compor o relatório final de análise de performance.
-
Resultados do backtest: pesos
$w_\tau$ , PnL, equity curve-
$w_\tau$ : vetor de alocações ao longo do tempo - PnL: série de lucros e perdas realizados
- equity curve: evolução do patrimônio do portfólio
-
-
Métricas calculadas: CAGR, Sharpe, Sortino, max drawdown, turnover, etc.
-
Predições: $\widehat{Y}\tau^{(m)}$ e valores realizados $Y\tau$
-
$\widehat{Y}_\tau^{(m)}$ : predições do método$m$ no tempo$\tau$ -
$Y_\tau$ : valores reais observados
-
-
Sinais gerados: $\hat{\mu}\tau$, $\hat{\sigma}\tau^{(m)}$
-
$\hat{\mu}_\tau$ : retornos esperados ao longo do tempo -
$\hat{\sigma}_\tau^{(m)}$ : volatilidades estimadas
-
-
Metadados: método
$m$ , horizonte$h$ , período (train/val/test), configurações-
$m$ : identificador do método de transformação -
$h$ : horizonte de previsão usado - Períodos: divisões temporais do experimento
-
Relatório estruturado contendo:
- Visualizações principais (gráficos em PNG/PDF/HTML)
- Tabelas de métricas (CSV/Excel/LaTeX)
- Relatório narrativo (opcional, em Markdown/PDF)
- Dashboard interativo (opcional, em HTML/Plotly)
-
Sem vazamento: estatísticas e HPO definidos em train do método
$m$ e congelados em val/test -
Metadados completos: incluir sempre
$m$ (método), além deid_série,t,w,s,h,split,config_id - Reprodutibilidade: seeds, versões e hashes por método
-
Combinação entre métodos (se desejado): delegada ao
signal_generator.py, que pode consumir$\widehat{Y}_\tau^{(m)}$ e selecionar/combinar somente depois
- O
signal_generator.pyestá completo e operacional, gerando a interface $(\hat{\mu}\tau,\omega\tau,\Sigma_\tau)$ para questrategy.pyebacktest.pyfiquem desacoplados da origem do sinal- Implementa calibração dinâmica adaptativa (trimestral para bins, anual para covariância)
- Mantém consistência temporal rigorosa (sem vazamento de informação)
- Gera 2,808 sinais ao longo de 29 trimestres (2017-2024) para ~110 ativos
- Todo o pipeline mantém consistência temporal (sem vazamento) e metadados rastreáveis (
method,horizon,config_id)