3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于 QMT (Quant My Trading) 平台的 全天候(All-Weather)投资组合策略 的 Python 实现代码。
全天候策略由桥水基金(Bridgewater)创始人瑞·达利欧提出,旨在通过配置不同相关性的资产,在各种经济环境(通胀、通缩、经济增长、经济衰退)下都能获得相对稳定的收益。
针对中国市场的 ETF 配置示例(简化版):
order_target_percent 按照账户总资产比例下单。# -*- coding: gbk -*-
import pandas as pd
import time
def init(ContextInfo):
"""
策略初始化函数
"""
# 1. 设置资金账号 (请替换为您自己的实盘或模拟账号)
# 注意:回测模式下,此账号仅作为标识,资金由回测参数设定
ContextInfo.account_id = '6000000000'
ContextInfo.set_account(ContextInfo.account_id)
# 2. 定义全天候策略的资产组合及目标权重
# 键为ETF代码,值为目标百分比权重
ContextInfo.target_portfolio = {
'510300.SH': 0.30, # 股票:沪深300 ETF
'511260.SH': 0.40, # 长债:十年国债 ETF
'511010.SH': 0.15, # 中债:五年国债 ETF
'518880.SH': 0.15 # 商品/黄金:黄金 ETF
}
# 3. 设置股票池 (用于行情订阅和回测数据下载)
ContextInfo.set_universe(list(ContextInfo.target_portfolio.keys()))
# 4. 设置调仓参数
ContextInfo.rebalance_days = 20 # 每20个交易日调仓一次
ContextInfo.days_counter = 0 # 计数器
print("全天候策略初始化完成")
print("目标组合: ", ContextInfo.target_portfolio)
def handlebar(ContextInfo):
"""
K线周期运行函数
"""
# 仅在K线结束时运行策略逻辑,避免盘中Tick波动频繁触发
if not ContextInfo.is_last_bar():
return
# 获取当前K线索引
bar_index = ContextInfo.barpos
# 获取当前时间
current_time = ContextInfo.get_bar_timetag(bar_index)
current_date = timetag_to_datetime(current_time, '%Y%m%d')
# 计数器递增
ContextInfo.days_counter += 1
# 判断是否达到调仓周期
# 逻辑:每 rebalance_days 天,或者第一天运行的时候进行调仓
if ContextInfo.days_counter % ContextInfo.rebalance_days == 0 or ContextInfo.days_counter == 1:
print(f"日期: {current_date},触发调仓信号,开始执行再平衡...")
rebalance(ContextInfo)
def rebalance(ContextInfo):
"""
再平衡执行函数:将持仓调整至目标权重
"""
# 获取目标组合
targets = ContextInfo.target_portfolio
account_id = ContextInfo.account_id
# 遍历目标组合中的每个标的
for stock_code, target_weight in targets.items():
# 获取当前标的的最新价格,用于计算(虽然order_target_percent内部会自动处理,但为了日志记录可以获取一下)
# 注意:order_target_percent 是按照总资产(现金+持仓市值)的比例下单
# 检查标的是否停牌,停牌则跳过
if ContextInfo.is_suspended_stock(stock_code):
print(f"标的 {stock_code} 停牌,跳过调仓")
continue
# 执行下单:调整至目标比例
# order_target_percent 会自动计算买卖方向和数量
# 1101 代表单股/单账号/普通/股数下单方式 (此处函数内部会转换为按比例计算出的股数)
# 注意:QMT的 order_target_percent 在回测和实盘中表现一致
print(f"调整 {stock_code} 仓位至 {target_weight * 100}%")
# 调用 QMT 的目标比例下单函数
# 参数说明: 标的代码, 目标比例(0-1), 下单选价类型(5为最新价), 价格(-1为无效), ContextInfo, 账号
order_target_percent(stock_code, target_weight, 5, -1, ContextInfo, account_id)
def timetag_to_datetime(timetag, format_str):
"""
辅助函数:将时间戳转换为日期字符串
"""
import time
return time.strftime(format_str, time.localtime(timetag / 1000))
init(ContextInfo) 初始化:
ContextInfo.target_portfolio: 这里定义了核心资产配置。你可以根据实际需求修改 ETF 代码。例如,如果你想增加风险偏好,可以提高 510300.SH 的权重。ContextInfo.set_universe: 这一步至关重要,它告诉 QMT 系统需要准备哪些标的的历史数据。ContextInfo.rebalance_days: 设定为 20,意味着大约每个月进行一次仓位检查和调整。handlebar(ContextInfo) 核心循环:
ContextInfo.is_last_bar(): 确保逻辑只在 K 线走完时(或回测的每一天结束时)运行一次,防止盘中重复发单。% 来判断是否到达第 20 天。rebalance(ContextInfo) 交易执行:
order_target_percent: 这是 QMT 中非常强大的函数。
is_suspended_stock 防止对停牌股票下单导致报错或废单。数据补充:
实盘配置:
init 函数中,将 ContextInfo.account_id 修改为你真实的资金账号。ETF 最小交易单位:
费率设置:
Q: 为什么选择 ETF 而不是直接买股票或债券?
A: 在 QMT 量化中,ETF 是实现大类资产配置最便捷的工具。它们流动性好,交易费用低,且能通过一个代码覆盖一篮子资产(如沪深300),非常适合全天候策略。
Q: 如何修改调仓频率?
A: 修改 init 函数中的 ContextInfo.rebalance_days 变量。例如,改为 5 就是每周调仓,改为 60 就是每季度调仓。
Q: 这个策略能保证盈利吗?
A: 全天候策略的目标是降低波动率和最大回撤,而不是追求短期暴利。在股市大牛市中,它可能跑不赢纯股票策略;但在股市崩盘或经济衰退时,它的表现通常会优于纯股票策略。
Q: order_target_percent 是按什么基准计算的?
A: 它是按照账户总资产(可用资金 + 持仓市值)来计算的。例如账户总资产 100万,目标权重 0.3,系统会确保该标的持仓市值调整为 30万。