★ 代表實作
横截面动量(赢家-输家组合)官方示例
python
在多标的横截面上按动量排序构建赢家/输家多空组合,含月度再平衡与净值曲线。
實作程式碼 python
# =====================================================================
# 量化策略流派 · 官方教学示例(横截面动量 / Cross-sectional Momentum)
# 策略:按月调仓,做多过去 N 日收益最高的「赢家」组合、做空最低的「输家」
# 说明:本代码为社区教学示例,由站点整理发布,仅供学习交流。
# 示例代码由站点提供,站点不对代码的安全性、合规性与收益
# 表现作任何明示或默示担保;据此交易风险自负。
# 依赖:numpy(pip install numpy)
# 运行:python cross_sectional_momentum.py
# =====================================================================
import numpy as np
def gen_assets(n_assets=20, n_days=756, seed=11):
"""生成多资产收益:共同市场因子 + 个股漂移 + 部分序列相关(动量)。"""
rng = np.random.default_rng(seed)
drift = rng.normal(0.0003, 0.0008, n_assets)
market = rng.normal(0, 0.008, n_days)
rets = np.zeros((n_days, n_assets))
for a in range(n_assets):
ar = rng.uniform(-0.04, 0.08) # 部分资产带自相关
prev = 0.0
for t in range(n_days):
prev = ar * prev
rets[t, a] = drift[a] + 0.6 * market[t] + prev + rng.normal(0, 0.012)
prices = np.exp(np.cumsum(rets, axis=0))
return prices
def backtest(prices, look=126, hold=21, top=0.3, cost=0.0005):
n_days, n_assets = prices.shape
pos = np.zeros_like(prices)
for start in range(0, n_days - hold, hold):
end = start + look
if end >= n_days:
break
mom = prices[end - 1] / prices[start] - 1.0 # 过去 look 日收益
order = np.argsort(mom)
k = int(n_assets * top)
w = 1.0 / (2 * k)
for a in order[-k:]:
pos[start:start + hold, a] = w # 赢家做多
for a in order[:k]:
pos[start:start + hold, a] = -w # 输家做空
asset_ret = np.zeros_like(prices)
asset_ret[1:] = prices[1:] / prices[:-1] - 1
port = np.sum(pos * asset_ret, axis=1)
chg = np.abs(np.diff(pos, axis=0)).sum(axis=1) # 调仓换手成本
port[1:] -= chg * cost
eq = np.cumprod(1 + port)
sharpe = port[1:].mean() / (port[1:].std() + 1e-9) * np.sqrt(252)
mdd = (eq - np.maximum.accumulate(eq)).min()
return dict(total=eq[-1] - 1, sharpe=sharpe, mdd=mdd)
if __name__ == "__main__":
px = gen_assets()
m = backtest(px)
print("横截面动量(赢家-输家组合)回测")
print(f" 资产数 / 交易日 : {px.shape[1]} / {px.shape[0]}")
print(f" 累计收益 : {m['total'] * 100:8.1f}%")
print(f" 年化夏普 : {m['sharpe']:8.2f}")
print(f" 最大回撤 : {m['mdd'] * 100:8.1f}%")
範例程式碼由使用者自行提供,網站不對其安全性與適用性負責。
💬 實作點評
🔵 登入 / 註冊