This project now focuses on a direct comparison between:
- Fund A: A real-world mutual fund whose disclosed holdings all have publicly available ESG scores.
- Fund B: A user-constructed alternative mutual fund with the same NUMBER of holdings as Fund A, built from a candidate universe of securities that also have publicly available ESG scores.
The goal is to evaluate whether an alternative composition (Fund B) can improve ESG profile (and possibly risk/return characteristics) while holding constant the count of positions. Weighting schemes, selection rules, and ESG uplift are reported along with standard performance metrics and alerts.
- Ingestion of real mutual fund holdings (CSV:
ticker,weight). - Public ESG data collection (Yahoo Finance ESG endpoint; script + cache).
- Construction of Fund B by selecting N tickers (N = number of holdings in Fund A) from a universe file using a strategy (e.g. top ESG, random, user-supplied list).
- Weight assignment for Fund B (equal-weight, ESG-score-weighted, or market-cap proxy).
- Comparative analytics: annual return, volatility, Sharpe, alpha/beta vs baseline, correlation, max drawdown, tracking error, information ratio, active share, effective number, ESG uplift.
- Alerts: ESG downgrades (if prior year data supplied), volatility spikes, concentration.
- CLI workflow (will be updated) for: load Fund A, load ESG dataset, build Fund B, compute metrics, export comparison.
Synthetic large price generation has been removed to reduce scope and emphasize real data + ESG comparison. Mean-variance optimization remains optional but is not required for the A vs B comparison.
scripts/fetch_esg_yahoo.py– fetch & cache ESG scores.scripts/fetch_real_prices.py– pull historical prices for tickers.scripts/export_portfolios.py– export comparative weights & metrics.src/esg_fund/– core logic (data loading, portfolio, analytics, alerts).
- Provide Fund A holdings:
data/fund_a_holdings.csv(ticker,weight). - Provide ESG score file:
data/esg_scores_YYYY.csv(ticker,esg_scoreplus optional pillars). - Provide candidate universe for Fund B:
data/universe.csv(ticker[,mcap]). If omitted, use all tickers with ESG scores excluding Fund A holdings. - Choose Fund B selection strategy:
top_esg– pick highest ESG scoring tickers not in Fund A.random– random sample (for benchmarking diversity).custom– user provides an explicit list.
- Assign weights for Fund B:
equal– all weights = 1/N.esg– proportional to ESG score.mcap– proportional to provided market cap column (if present).
- Fetch prices (Yahoo) for union of tickers if price analytics desired.
- Run comparison & export metrics, weights, alerts.
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements.txt
Fetch ESG data (example):
python scripts\fetch_esg_yahoo.py --ticker-map data\ticker_map.csv --year 2025 --out data\esg_scores_2025.csv --metadata-file data\esg_scores_2025_meta.json
Export portfolio comparison (existing baseline vs ESG tilt – until CLI refactor lands):
python scripts\export_portfolios.py --holdings data\fund_a_holdings.csv --esg-current data\esg_scores_2025.csv --use-yf --start 2024-01-01 --end 2024-12-31 --out data\comparison.csv
By default the app fetches Indian equities and benchmark prices via these providers in order:
- NSElib (capital_market.price_volume_and_deliverable_position_data)
- Alpha Vantage (requires env var
ALPHAVANTAGE_API_KEY) - Yahoo Finance (yfinance)
Notes:
- For benchmark
^NSEI, the code proxies usingNIFTYBEESwhen needed. - Offline mode: set
PRICE_FETCH_MODE=offline. OptionalPRICE_OFFLINE_CSVcan point to a CSV with either:- Wide format:
date,<SYM1>,<SYM2>,... - Long format:
symbol,date,closeThe app will read from this file and skip network calls.
- Wide format:
- New CLI flags:
--fund-a-holdings,--fund-b-universe,--fund-b-selection {top_esg,random,custom},--fund-b-weights {equal,esg,mcap}. - Helper in
portfolio.py:build_alternative_portfolio()encapsulating selection + weighting. - Update
export_portfolios.pylogic to enforce matched holding count (|B| = |A|). - Remove synthetic price generation references from docs & CLI.
- Add validation: ensure all tickers in A and B have ESG scores; generate a coverage report.
Public ESG data (Yahoo) is partial; absence of a score ≠ poor ESG performance. Use this toolkit for exploratory comparison only. For formal analysis, integrate licensed data sources.
Open an issue describing enhancement (e.g., additional selection strategies like risk-adjusted ESG) before submitting PRs.
MIT (adjust if needed).