关于 portfolio
portfolio 是面向资产收益数据分析的 Python 量化组合构建技能,提供 Markowitz、Black-Litterman 和层次方法,并支持命令行及库调用。
主要功能
- 01使用 Markowitz 方法优化组合
- 02结合市场先验与投资者观点
- 03通过 HRP、HERC 和 NCO 构建组合
- 04估算协方差矩阵
- 05计算组合风险指标
适用场景
- 01求解最大夏普或最小方差配置
- 02将投资观点纳入市场隐含收益
- 03用层次聚类构建投资组合
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ gauss314/ skills --skill portfolio安装后在 Claude Code 中输入/portfolio确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/defaults.jsonsample_classes.csvsample_constraints.csvsample_mcaps.jsonsample_prices_16.csvsample_prices.csvsample_returns_16.csvsample_returns.csvreferences/BLACK_LITTERMAN.mdHIERARCHICAL.mdPORTFOLIO_THEORY.mdRISK_MEASURES.mdscripts/__init__.pyblack_litterman.pycli.pycovariance.pyhierarchical.pyportfolio.pyrisk_measures.pytests/__init__.pytest_portfolio.py详细介绍
投资组合——投资组合定量优化
此技能基于课程资料(notebook Clase_08_teoria_2025_portafolio.ipynb 和 PDF Portafolios 2025 Ucema.pdf),实现了 3 种投资组合优化方法:
- Markowitz / 均值-方差 — 通过
scipy.optimize进行凸优化- 蒙特卡洛模拟 + 有效前沿 + CML。
- Black-Litterman — 将市场均衡收益(反向 CAPM)与投资者观点进行贝叶斯组合,其中包括不确定性矩阵 Ω(Idzorek 方法)。
- HRP / HERC / NCO — 通过聚类(single/complete/average/ward)、风险平价和带约束的 NCO 构建层次化投资组合。
所有脚本仅使用 numpy、pandas 和 scipy。无需繁重依赖。
此技能独立运行:无需 skills/backtesting。
如需了解优化后的绩效比率(Sharpe、Sortino、VaR、回撤等),请参阅姊妹技能:
skills/backtesting。
属于 Gauss314 Skills Repository 的一部分。
文件概览
skills/portfolio/
├── SKILL.md ← Este archivo
├── references/
│ ├── PORTFOLIO_THEORY.md ← MPT, Markowitz, frontera eficiente (ES)
│ ├── BLACK_LITTERMAN.md ← BL: prior, views, posterior, omega (ES)
│ ├── HIERARCHICAL.md ← HRP, HERC, NCO, clustering (ES)
│ └── RISK_MEASURES.md ← VaR, CVaR, MAD, MSV, DR, MDD (ES)
├── assets/
│ ├── sample_prices.csv ← Precios multi-activo para ejemplos
│ ├── sample_returns.csv ← Retornos multi-activo
│ ├── sample_mcaps.json ← Market caps para Black-Litterman
│ └── defaults.json ← Parámetros default
├── scripts/
│ ├── __init__.py
│ ├── portfolio.py ← Core: Markowitz, Sharpe, Monte Carlo, frontera
│ ├── black_litterman.py ← BL: prior, posterior, omega, views
│ ├── hierarchical.py ← HRP/HERC/NCO: clustering, risk parity, constraints
│ ├── risk_measures.py ← VaR, CVaR, MAD, MSV, MDD, DR
│ ├── covariance.py ← Covarianza: hist, ledoit-wolf, oas, ewma
│ └── cli.py ← CLI unificada (12 modos)
└── tests/
├── __init__.py
└── test_portfolio.py ← Tests + validación contra notebook
各脚本的功能
| 脚本 | 作用 | 主要函数 |
|---|---|---|
portfolio.py | Markowitz 优化核心 | max_sharpe_optim、min_variance_optim、random_portfolios、efficient_frontier、cml_portfolio、asset_stats |
black_litterman.py | 完整的 Black-Litterman 实现 | market_implied_risk_aversion、market_implied_prior_returns、bl_posterior_returns、omega_idzorek |
hierarchical.py | HRP / HERC / NCO | hrp_portfolio、herc_portfolio、nco_portfolio、nco_with_constraints、hrp_constraints |
risk_measures.py | 风险度量 | var_historic、cvar、max_drawdown、cdar、diversification_ratio、risk_contribution |
covariance.py | 协方差估计 | cov_hist、cov_ledoit_wolf、cov_oas、cov_ewma |
快速开始
Markowitz(scipy.optimize)
# Max Sharpe con 3 activos
py scripts/cli.py markowitz --assets assets/sample_returns.csv
# Con tasa libre de riesgo personalizada
py scripts/cli.py markowitz --assets assets/sample_returns.csv --rf 0.05
# Estadísticas individuales
py scripts/cli.py stats --assets assets/sample_returns.csv
蒙特卡洛
# Simular 10.000 carteras aleatorias
py scripts/cli.py montecarlo --assets assets/sample_returns.csv
# Guardar frontera a CSV
py scripts/cli.py montecarlo --assets assets/sample_returns.csv --save frontier.csv
有效前沿
py scripts/cli.py frontier --assets assets/sample_returns.csv --n 50
CML——杠杆与去杠杆
将切点投资组合(最大 Sharpe)与无风险资产组合,即可在保持相同 Sharpe 比率的前提下,得到资本市场线(CML)上的任意点。
# Portafolio tangente puro (w=1)
py scripts/cli.py cml --assets assets/sample_returns.csv --weight 1.0
# Deleverage: 60% en tangencia, 40% en Rf (menos riesgo, mismo Sharpe)
py scripts/cli.py cml --assets assets/sample_returns.csv --weight 0.6
# Leverage: pide prestado 50% a Rf, invierte 150% en tangencia (más riesgo, mismo Sharpe)
py scripts/cli.py cml --assets assets/sample_returns.csv --weight 1.5
Black-Litterman
# Prior: retornos implícitos de mercado (CAPM inverso)
py scripts/cli.py bl-prior --assets assets/sample_returns.csv --market-prices assets/sample_prices.csv --mcaps assets/sample_mcaps.json
# BL completo con views + optimización
py scripts/cli.py bl --assets assets/sample_returns.csv --market-prices assets/sample_prices.csv --mcaps assets/sample_mcaps.json --views '{"BMA": 0.25, "LOMA": 0.4, "MELI": -0.1}' --confidences "0.3,0.5,0.8" --optimize
HRP / HERC / NCO
# Hierarchical Risk Parity
py scripts/cli.py hrp --assets assets/sample_returns.csv
# Nested Clustered Optimization
py scripts/cli.py nco --assets assets/sample_returns.csv --clusters 3
# NCO con restricciones
py scripts/cli.py nco-con --assets assets/sample_returns.csv --constraints assets/sample_constraints.csv --classes assets/sample_classes.csv
风险
# Todas las medidas de riesgo
py scripts/cli.py risk --prices assets/sample_prices.csv
# Medida específica
py scripts/cli.py risk --prices assets/sample_prices.csv --measure var
作为库使用
from scripts.portfolio import *
from scripts.black_litterman import *
from scripts.hierarchical import *
import numpy as np
# --- Markowitz ---
rets = pd.read_csv('assets/sample_returns.csv', index_col=0)
result = max_sharpe_optim(rets, rf=0.045)
print(result['weights'], result['sharpe']) # pesos óptimos, Sharpe
# --- CML: leverage/deleverage ---
# 60% en tangencia, 40% en Rf (deleverage)
cml = cml_portfolio(rets, rf=0.045, weight_tangency=0.6)
print(cml['ret'], cml['vol'], cml['sharpe']) # mismo Sharpe que el tangente
# Leverage: 150% en tangencia (pide prestado 50% a Rf)
cml2 = cml_portfolio(rets, rf=0.045, weight_tangency=1.5)
print(cml2['ret'], cml2['vol'], cml2['sharpe']) # mismo Sharpe
# --- Monte Carlo ---
port_df = random_portfolios(rets, n_portfolios=10000, rf=0.045)
best = port_df.loc[port_df['sharpe'].idxmax()]
print(best['weights']) # mejor combinación Monte Carlo
# --- Black-Litterman ---
import json
with open('assets/sample_mcaps.json') as f:
mcaps = json.load(f)
spy = pd.read_csv('assets/sample_prices.csv')['SPY'].pct_change().dropna()
bl_result = bl_pipeline(rets, spy.values, mcaps,
view_dict={'BMA': 0.25, 'LOMA': 0.4},
view_confidences=[0.3, 0.5], rf=0.045)
print(bl_result['posterior']) # retornos a posteriori
# --- HRP ---
hrp_result = hrp_portfolio(rets, linkage_method='ward')
print(hrp_result['weights']) # pesos HRP
依赖项
| 库 | 必需 | 用途 |
|---|---|---|
numpy | ✅ | 向量化计算、线性代数 |
pandas | ✅ | CSV I/O、DataFrame |
scipy | ✅ | optimize(Markowitz)、cluster.hierarchy(HRP/NCO)、stats |
无需 Riskfolio-Lib、PyPortfolioOpt、sklearn、cvxpy 或 arch。
可选地使用 matplotlib 进行可视化(树状图、有效前沿)。绘图示例见参考 notebook。
理论参考
- Markowitz(1952):"Portfolio Selection",Journal of Finance。
- Black & Litterman(1992):"Global Portfolio Optimization",Financial Analysts Journal。
- Idzorek(2005):"A Step-by-Step Guide to the Black-Litterman Model"。
- Lopez de Prado(2016):"Building Diversified Portfolios that Outperform Out of Sample"(HRP)。
- De Prado(2019):"Nested Clustered Optimization",SSRN 3469961。
- Pfitzinger & Katzke(2019):"NCO with Constraints",SSRN 4409173。
- Meucci(2006):"Beyond Black-Litterman: Views on Non-Normal Markets",SSRN 1213325。
- Avramov(2004):"Bayesian Variable Selection in Portfolio Analysis",SSRN 3326617。
如需深入了解绩效比率(30 多项指标:Sharpe、Sortino、
VaR、cVaR、Kelly、Rachev、Profit Factor 等)和策略的回测:
skills/backtesting。
参考 Notebook
此技能的理论内容和数值示例基于:
temp/Clase_08_teoria_2025_portafolio.ipynb— Markowitz、Monte Carlo、NCO(Riskfolio-Lib)、Black-Litterman(PyPortfolioOpt)的 Python 实现。temp/Portafolios 2025 Ucema.pdf— 理论框架:MPT、CAPM、Fama-French、聚类、NCO、Black-Litterman。
/scripts/ 中的 flat numpy 实现复现了这些 Notebook 的结果,且无需依赖上述库。