Skip to content

Repository files navigation

Fund Analytics Lab

Risk-adjusted performance analysis of Brazilian investment funds

Python DuckDB License


Executive Summary

This project provides a comprehensive analytical framework for evaluating Brazilian investment funds (fundos de investimento) through the lens of risk-adjusted performance. Rather than simply ranking funds by raw return, we decompose performance into its risk, consistency, and alpha components to answer a fundamental investment question:

"Quais fundos brasileiros realmente entregaram retorno ajustado ao risco superior ao benchmark — e de onde veio essa performance?"

The analysis covers ~30-50 multimarket funds (multimercado) over the 2019-2025 period, spanning pre-COVID, the March 2020 crash, the recovery rally, and multiple interest rate cycles.

Key Deliverables

  • 15+ quantitative metrics per fund (Sharpe, Sortino, Calmar, VaR, CVaR, rolling alpha, etc.)
  • Fund Quality Score — proprietary composite scoring methodology
  • Fund Selection Simulator — profile-based fund recommendation engine
  • Out-of-sample backtest validating scoring methodology's predictive power
  • Power BI dashboard with 7 interactive pages
  • Research-grade report (8-15 pages)

Investment Question

The core research question drives every analytical decision:

After controlling for volatility, drawdown, and factor exposure, which Brazilian multimarket funds have consistently delivered superior risk-adjusted returns relative to their benchmark, and what explains this performance?

Sub-questions:

  1. Is the outperformance persistent (rolling metrics) or concentrated in few periods (attribution)?
  2. Does the Fund Quality Score have out-of-sample predictive power?
  3. Which risk profile (conservative/moderate/aggressive) has the most attractive risk-return tradeoff?

Data Sources & Universe

Universe Definition

Parameter Value
Fund class Multimercado (ANBIMA)
Minimum AUM R$100M (average over period)
Minimum history 5 years
Status Active only
Period January 2019 — August 2025
Expected universe size 30–50 funds

Data Sources

Data Source Method
Daily NAV (cotas) CVM Dados Abertos HTTP/CSV monthly ZIPs
AUM & shareholders CVM Dados Abertos HTTP/CSV
Fund registry CVM Dados Abertos HTTP/CSV
CDI BCB SGS (série 12) python-bcb API
IPCA BCB SGS (série 433) python-bcb API
Dólar PTAX BCB SGS (série 1) python-bcb API
Ibovespa Yahoo Finance (^BVSP) yfinance
IMA-B Yahoo Finance (IMAB11.SA) yfinance

Database Schema

funds ──┬── fund_prices    (daily NAV + returns)
        ├── fund_aum       (PL + cotistas)
        └── [benchmark] ── benchmark_prices

5 tables in DuckDB (columnar, analytical-optimized). See src/database/schema.sql.


Methodology

Return Metrics

Metric Formula Purpose
Cumulative return ∏(1 + rᵢ) - 1 Total performance
Annualized return (1 + r_cum)^(252/n) - 1 Comparable across periods
Rolling 12M/36M Moving window (252/756 days) Temporal stability
Alpha Annualized excess vs benchmark Skill measurement

Risk Metrics

Metric Formula Purpose
Annualized volatility σ(r) × √252 Total risk
Downside deviation σ(min(r - MAR, 0)) × √252 Downside-only risk
VaR 95% Percentile 5% of returns Tail risk (1-day)
CVaR 95% E[r | r ≤ VaR] Expected shortfall

Performance Ratios

Ratio Formula Interpretation
Sharpe (r_p - r_f) / σ_p Return per unit of total risk
Sortino (r_p - r_f) / σ_down Return per unit of downside risk
Calmar r_annual / |MaxDD| Return per unit of drawdown
Information Ratio α / σ(α) Active return per tracking error

Drawdown Analysis

Each drawdown episode is decomposed into:

Peak → Queda → Fundo (trough) → Recuperação (recovery)

With metrics: maximum drawdown, duration (trading days), and recovery time.

Fund Quality Score

Proprietary composite score (0-100) with configurable weights:

Component Weight Metric
Risk-adjusted return 30% Annualized Sharpe
Drawdown 20% Max Drawdown (inverted)
Consistency 15% % months above benchmark
Alpha 15% Annualized excess return
Downside risk 10% Downside deviation (inverted)
AUM stability 10% Inverse CV of AUM

Normalization: Min-max within universe, with 5th/95th percentile winsorization.

⚠️ The Fund Quality Score is a proprietary methodology created for comparing funds within the analyzed universe. It does not constitute investment advice or recommendation.


Results

Results are generated dynamically by running the pipeline. See the dashboard and report for current findings.

Dashboard Pages

Page Content
Overview Universe summary — # funds, total AUM, average return vs CDI
Performance Cumulative return vs benchmark, comparative table
Risk Volatility, VaR, CVaR — heatmaps and scatter plots
Consistency Rolling Sharpe 12M/24M/36M, rolling alpha
Ranking Fund Quality Score — sortable table with component breakdown
Fund Deep Dive Single-fund analysis: "What explains this fund's performance?"
Simulator Fund Selection by risk profile (Conservador/Moderado/Agressivo)

Backtest & Validation

The Fund Quality Score is validated out-of-sample:

  1. Split: 70% training / 30% test
  2. Train: Compute FQS on training period only
  3. Select: Top-10 funds by FQS
  4. Test: Measure their Sharpe in the test period
  5. Compare: Top-10 vs universe median

Success criterion: Top-10 Sharpe > Universe median Sharpe in the test period.


Limitations

This section exists intentionally. Acknowledging limitations is not a weakness — it demonstrates analytical rigor and a market-oriented mindset.

Limitation Impact Mitigation
Survivorship bias Only active funds are analyzed; failed funds excluded Explicitly acknowledged; results may overstate average performance
Look-ahead bias Universe selection uses current AUM, not point-in-time Could be mitigated with historical AUM snapshots (future work)
Data availability CVM publishes D+1; some funds report with delays Gaps handled via forward-fill; funds with >5% missing data excluded
Transaction costs Not modeled (management fees are embedded in NAV) Performance fees vary; actual investor returns may differ
Liquidity Redemption periods (D+30, D+60) not considered Illiquid funds may appear more attractive than accessible alternatives
Model assumptions Normalization assumes returns are roughly symmetric Winsorization at 5th/95th percentile mitigates outlier distortion
Benchmark selection CDI as default benchmark may not suit all strategies Benchmark mismatch can inflate/deflate alpha for certain fund types

Reproducibility

Prerequisites

  • Python 3.10+
  • Internet connection (for data download)

Setup

# Clone the repository
git clone https://github.com/mvasss/fund-analytics-lab.git
cd fund-analytics-lab

# Create virtual environment
python -m venv venv
venv\Scripts\activate        # Windows
source venv/bin/activate     # Linux/macOS

# Install dependencies
pip install -r requirements.txt

Run the Pipeline

# Full pipeline (download → clean → load → metrics → score → export)
python scripts/run_pipeline.py

# Or run individual steps
python scripts/run_pipeline.py --step 1   # Download only
python scripts/run_pipeline.py --step 4   # Metrics only (requires DB)

# Export data for dashboard
python scripts/export_to_dashboard.py

Run Tests

pytest tests/ -v

Project Structure

fund-analytics-lab/
├── README.md
├── requirements.txt
├── config/
│   ├── settings.py                 # Global configuration
│   ├── fund_universe.yaml          # Universe definition
│   └── scoring_weights.yaml        # FQS weight configuration
├── data/
│   ├── raw/                        # Raw CVM/BCB CSVs
│   └── processed/                  # Processed Parquet files
├── src/
│   ├── ingestion/                  # Data download (CVM, BCB, yfinance)
│   ├── cleaning/                   # Validation & universe filtering
│   ├── database/                   # DuckDB schema, manager, queries
│   ├── features/                   # Metrics (returns, risk, performance, drawdown, rolling)
│   ├── scoring/                    # Fund Quality Score
│   ├── analysis/                   # Attribution & consistency
│   ├── backtesting/                # Out-of-sample validation
│   └── simulator/                  # Fund Selection Simulator
├── notebooks/                      # Exploratory analysis
├── dashboard/                      # Power BI files
├── reports/                        # Investment report PDF
├── tests/                          # pytest test suite
└── scripts/                        # Pipeline orchestration

Dashboard

The Power BI dashboard consumes pre-aggregated Parquet files from data/processed/dashboard/.

To regenerate dashboard data:

python scripts/export_to_dashboard.py

License

MIT


Author

Marcos — GitHub | LinkedIn

About

Institutional quantitative research platform and Power BI dashboard for risk-adjusted analysis of Brazilian multimarket funds.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages