投资组合的仓位分配直接决定了实盘的风险收益比。本文将结合 scipy 的数学优化模块与 QuantDash 清晰的多市场历史行情数据,手把手带你计算一个包含多市场资产的马科维茨有效前沿(Efficient Frontier),并输出最优权重分配与历史最大回撤(Max Drawdown)。
许多个人投资者或策略开发者在构建跨市场股票投资组合时,往往通过经验分配仓位(例如简单的等权重分配)。这在工程与数学上面临以下弊端:
利用 SciPy 的优化模块(scipy.optimize)配合 QuantDash 标准格式的多市场收盘价,可以快速实现投资组合配置的科学优化。
本实例拉取港股腾讯控股(00700.HK)和A股贵州茅台(600519.SH)的历史行情,在 Pandas 中对齐日期后,通过数学方法求解“波动率最小”的最优持仓权重。
pip install pandas numpy scipy quantdashimport numpy as np
import pandas as pd
from scipy.optimize import minimize
import quantdash as qd
# 初始化公共Token(支持免注册拉取测试标的)
qd.set_token("demo_public_token")
def get_aligned_returns(symbols: list, start: str, end: str):
"""
拉取多市场标的历史收盘价,并在 Pandas 中对齐日期计算收益率
"""
prices = {}
for sym in symbols:
df = qd.get_kline(symbol=sym, start_date=start, end_date=end, adjust="qfq")
if df is not None and not df.empty:
df['timestamp'] = pd.to_datetime(df['timestamp'])
# 将收盘价按时间戳存入 dict
prices[sym] = df.set_index('timestamp')['close']
# 利用 Pandas 的 join 机制进行跨市场日期对齐,缺失值向前填充 (ffill)
price_df = pd.DataFrame(prices).ffill().dropna()
# 计算每日收益率
returns_df = price_df.pct_change().dropna()
return returns_df
def optimize_portfolio(returns_df: pd.DataFrame):
"""
使用 SciPy 优化求解:在保证权重大于0且和为1的前提下,求解波动率(风险)最小的组合权重
"""
num_assets = len(returns_df.columns)
cov_matrix = returns_df.cov() * 252 # 年化协方差矩阵
# 定义优化目标函数:投资组合的年化波动率(标准差)
def portfolio_volatility(weights):
return np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))
# 约束条件1:权重之和必须等于 1
constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
# 约束条件2:每个资产的权重范围限制在 0 ~ 1 之间(不允许做空)
bounds = tuple((0, 1) for _ in range(num_assets))
# 初始等权重猜测
init_guess = num_assets * [1. / num_assets]
# 调用 SciPy 优化求解器
opt_result = minimize(
portfolio_volatility,
init_guess,
method='SLSQP',
bounds=bounds,
constraints=constraints
)
return opt_result.x
def calculate_max_drawdown(returns_series: pd.Series):
"""
计算投资组合历史最大回撤
"""
cumulative = (1 + returns_series).cumprod()
running_max = cumulative.cummax()
drawdown = (cumulative - running_max) / running_max
return drawdown.min()
if __name__ == "__main__":
test_tickers = ["00700.HK", "600519.SH"]
# 1. 抓取并对齐多市场收益率数据
returns = get_aligned_returns(test_tickers, "2026-01-01", "2026-06-30")
# 2. 求解最低波动率的最优分配权重
optimized_weights = optimize_portfolio(returns)
# 3. 计算最优权重下的组合收益及最大回撤
portfolio_daily_ret = (returns * optimized_weights).sum(axis=1)
max_dd = calculate_max_drawdown(portfolio_daily_ret)
# 4. 打印量化评估结果
weight_report = pd.DataFrame({
"资产代码": test_tickers,
"最优配置比例 (最小波动)": [f"{w*100:.2f}%" for w in optimized_weights]
})
print("\n=== 跨市场资产配置权重优化报告 ===")
print(weight_report)
print(f"\n[=] 优化组合历史最大回撤: {max_dd*100:.2f}%")=== 跨市场资产配置权重优化报告 ===
资产代码 最优配置比例 (最小波动)
0 00700.HK 42.15%
1 600519.SH 57.85%
[=] 优化组合历史最大回撤: -7.42%当您准备让 AI 助手基于现代投资组合理论(MPT)构建更为复杂的风控系统时,可以使用以下 Prompt:
Role: 金融工程算法专家
Context: 我需要构建一个基于均值-方差优化(Mean-Variance Optimization)的组合调仓系统,历史 K 线由 QuantDash 提供。
Task:
1. 编写一段 Python 函数,输入包含多个股票收益率的 DataFrame。
2. 使用 scipy.optimize 寻找“夏普比率最大”(Maximize Sharpe Ratio)的持仓权重(假设无风险利率为 3% 年化)。
3. 将优化出的最优权重与等权重组合进行对比,输出两者在夏普比率和最大回撤(Max Drawdown)上的对比指标。参考文档:
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。