{"id":51476527,"url":"https://github.com/henrywen98/portfolio-optimizer-skill","last_synced_at":"2026-07-06T21:30:50.289Z","repository":{"id":312981928,"uuid":"1049532581","full_name":"henrywen98/portfolio-optimizer-skill","owner":"henrywen98","description":"No-API-key multi-market portfolio optimizer as a Claude Code skill — US stocks, China A-shares \u0026 Hong Kong. Max Sharpe / min variance / risk parity, full risk report, free data auto-fallback.","archived":false,"fork":false,"pushed_at":"2026-06-28T14:51:03.000Z","size":247,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-28T16:22:07.193Z","etag":null,"topics":["a-shares","agent-skills","akshare","algorithmic-trading","anthropic","asset-allocation","claude-code","claude-code-skill","efficient-frontier","fintech","hong-kong-stocks","portfolio-optimization","python","quantitative-finance","risk-parity","sharpe-ratio","us-stocks","yfinance"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/henrywen98.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-03T05:54:13.000Z","updated_at":"2026-06-28T14:50:59.000Z","dependencies_parsed_at":"2025-09-03T08:18:22.682Z","dependency_job_id":"7a2ee8c0-2a79-49bf-b946-6dd36f48ee79","html_url":"https://github.com/henrywen98/portfolio-optimizer-skill","commit_stats":null,"previous_names":["henrywen98/investment_portfolio_optimizer","henrywen98/portfolio-optimizer-skill"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/henrywen98/portfolio-optimizer-skill","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/henrywen98%2Fportfolio-optimizer-skill","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/henrywen98%2Fportfolio-optimizer-skill/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/henrywen98%2Fportfolio-optimizer-skill/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/henrywen98%2Fportfolio-optimizer-skill/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/henrywen98","download_url":"https://codeload.github.com/henrywen98/portfolio-optimizer-skill/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/henrywen98%2Fportfolio-optimizer-skill/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35206987,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-06T02:00:07.184Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["a-shares","agent-skills","akshare","algorithmic-trading","anthropic","asset-allocation","claude-code","claude-code-skill","efficient-frontier","fintech","hong-kong-stocks","portfolio-optimization","python","quantitative-finance","risk-parity","sharpe-ratio","us-stocks","yfinance"],"created_at":"2026-07-06T21:30:49.740Z","updated_at":"2026-07-06T21:30:50.274Z","avatar_url":"https://github.com/henrywen98.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Portfolio Optimizer Skill\n\n\u003e A **no-API-key, multi-market portfolio optimizer** that runs as a [Claude Code](https://claude.com/claude-code) skill — turn a list of tickers into an optimal weight allocation plus a full risk report, across **US stocks, China A-shares, and Hong Kong stocks**, with free data and zero setup.\n\n![License](https://img.shields.io/badge/license-MIT-blue.svg)\n![Python](https://img.shields.io/badge/python-3.9%2B-blue.svg)\n![Claude Code Skill](https://img.shields.io/badge/Claude%20Code-Skill-d97757.svg)\n![No API key](https://img.shields.io/badge/data-no%20API%20key-brightgreen.svg)\n\n**English** · [简体中文](README.zh-CN.md)\n\n\u003e ⚠️ For **education / research only**. Nothing here is investment advice.\n\n---\n\n## What it is\n\nThis repo **is** a Claude Code skill. Once installed, you drive it in plain language — Claude reads your intent, runs the bundled engine, and explains the result:\n\n- *\"Optimize my portfolio of AAPL, MSFT, NVDA for max Sharpe\"*\n- *\"帮我把 600519,000858,600036 做个最小方差配置，单只不超过 30%\"*\n- *\"Compare a few allocation strategies for these tickers and tell me which has the best Sharpe\"*\n\nNo command memorization, no data plumbing, no exchange/API keys. It works the same whether you point it at Apple or at Kweichow Moutai.\n\n## Why this exists\n\nAsking a general-purpose LLM to \"write some PyPortfolioOpt code\" gets you the *math* — but it stalls the moment you need **real prices**. Free US data gets rate-limited from cloud IPs; A-share and Hong Kong tickers need exchange-prefix / `secid` resolution that's fiddly to get right; and every ad-hoc script reinvents the fallback logic. This skill is the part that's annoying to reproduce:\n\n| | This skill | Plain \"ask Claude to write code\" | A typical GitHub optimizer |\n|---|:---:|:---:|:---:|\n| Runs as a Claude Code skill (natural language) | ✅ | — | — |\n| **US + A-shares + HK**, auto market detection | ✅ | ⚠️ you wire it | usually one market |\n| **No API key**, multi-source auto-fallback | ✅ | ❌ stalls on data | varies |\n| 5 strategies + side-by-side compare | ✅ | ⚠️ partial | usually 1–2 |\n| Full risk report (Sharpe/Sortino/Calmar/VaR/CVaR/drawdown/concentration) | ✅ | ⚠️ partial | varies |\n| Rolling-rebalance backtest with trading costs | ✅ | ❌ | sometimes |\n| Offline CSV mode (any market, no network) | ✅ | ❌ | rare |\n\nThe data layer is the moat: `auto` mode picks a source by market and falls back through **yfinance → akshare → East Money (direct) → local CSV** until one works — no key, anywhere.\n\n## Install\n\nIt's a standard Claude Code skill — drop it in your skills directory:\n\n```bash\ngit clone https://github.com/henrywen98/portfolio-optimizer-skill \\\n  ~/.claude/skills/portfolio-optimizer\ncd ~/.claude/skills/portfolio-optimizer\npip install -r requirements.txt\n```\n\nRestart Claude Code and just ask it to optimize a portfolio — the skill triggers on intent. You can also run the engine directly (below) without Claude at all.\n\n## Quick start (CLI / no Claude needed)\n\n```bash\n# US stocks, max Sharpe\npython scripts/optimize.py --tickers AAPL,MSFT,NVDA,JPM,KO --strategy max_sharpe --years 3\n\n# A-shares, min variance, cap any single name at 30%\npython scripts/optimize.py --tickers 600519,000858,600036 --strategy min_variance --max-weight 0.3\n\n# Compare every strategy side by side (JSON out)\npython scripts/optimize.py --tickers AAPL,MSFT,GOOGL,AMZN,META --compare --format json\n\n# Offline: feed your own price CSV (any market)\npython scripts/optimize.py --csv prices.csv --strategy risk_parity\n```\n\nRolling-rebalance backtest with trading costs (advanced):\n\n```bash\npython scripts/backtest.py --tickers AAPL,MSFT,NVDA,JPM,KO --years 5 \\\n    --strategy max_sharpe --lookback 252 --rebalance 63\n```\n\n## Strategies\n\n| Strategy | `--strategy` | In one line |\n|---|---|---|\n| Max Sharpe | `max_sharpe` | Highest excess return per unit of risk (default) |\n| Min Variance | `min_variance` | Lowest portfolio volatility on the feasible set |\n| Risk Parity | `risk_parity` | Every holding contributes equal risk (convex risk-budgeting) |\n| Max Diversification | `max_diversification` | Maximize the diversification ratio |\n| Equal Weight | `equal_weight` | Naive 1/N benchmark |\n\n## Data sources (no API key)\n\n`auto` mode chooses by market and falls back until one succeeds:\n\n| Market | Ticker example | Source order |\n|---|---|---|\n| US | `AAPL`, `MSFT` | yfinance → akshare → East Money |\n| China A-share | `600519`, `000858` | akshare → East Money → yfinance |\n| Hong Kong | `00700`, `09988` | akshare → East Money → yfinance |\n| Any (offline) | `--csv prices.csv` | local CSV, no network |\n\n## Python API\n\n```python\nfrom portfolio_engine import PortfolioOptimizer\n\nopt = PortfolioOptimizer(strategy=\"max_sharpe\", max_weight=0.3)\nweights, perf = opt.optimize_portfolio(tickers=[\"AAPL\", \"MSFT\", \"NVDA\"], years=3)\n\nprint(weights)               # {'AAPL': 0.31, ...}\nprint(perf[\"sharpe_ratio\"])  # plus Sortino / Calmar / VaR / CVaR / drawdown / concentration\n```\n\n## Project structure\n\n| Path | Role |\n|---|---|\n| `SKILL.md` | **Skill entry** — triggering, usage, guidance for Claude |\n| `portfolio_engine/` | Engine: optimizer, data fetch, market detection, constraints, backtest |\n| `scripts/optimize.py` | CLI — single strategy + `--compare` |\n| `scripts/backtest.py` | CLI — rolling-window optimize + periodic rebalance |\n| `references/` | Deep-dive docs (strategies / metrics / data / constraints / backtesting) |\n| `tests/` | Offline pytest suite (no network) |\n\n## How it was built\n\nThis skill was refactored from a single-market A-share tool and then **hardened with an evaluation loop** (Claude-with-skill vs. a from-scratch baseline, graded across many prompts). That loop earned its keep: on a low-correlation portfolio the baseline *beat* the skill because the old iterative risk-parity routine was zeroing out valid assets on ill-conditioned covariance. The fix — switching to the convex Spinu/Maillard risk-budgeting formulation (`minimize ½·wᵀΣw − (1/n)·Σ ln wᵢ`) — now keeps every asset long-only with equalized risk contributions, and ships with a regression test. A skill is only worth triggering if it's never *worse* than just asking the model directly.\n\nSee [`references/`](references/) for the strategy math, risk-metric definitions, the multi-source data design, and the backtest model.\n\n## Roadmap\n\n- More markets (LSE / TSE) behind the same auto-fallback\n- Black-Litterman / views-based allocation\n- Factor-tilt constraints\n\nContributions welcome — open an issue or PR.\n\n## License\n\n[MIT](LICENSE) · © 2025 Henry Wen\n\n---\n\nIf this saved you from wiring up yet another data fetcher, a ⭐ helps other people find it.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhenrywen98%2Fportfolio-optimizer-skill","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhenrywen98%2Fportfolio-optimizer-skill","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhenrywen98%2Fportfolio-optimizer-skill/lists"}