3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于 QMT (Quantitative Trading Platform) API 编写的自动投资组合再平衡策略。
该策略旨在实现一个经典的定期等权重再平衡(Equal-Weight Rebalancing)逻辑:
order_target_percent 函数。该函数会自动计算需要买入或卖出的数量,将仓位调整至目标比例。# -*- coding: gbk -*-
import pandas as pd
import time
def init(ContextInfo):
"""
初始化函数,策略启动时调用一次
"""
# 1. 设置资金账号 (请替换为您真实的资金账号)
# 格式如: '6000000248'
ContextInfo.account_id = 'YOUR_ACCOUNT_ID'
ContextInfo.set_account(ContextInfo.account_id)
# 2. 设置股票池 (示例:贵州茅台, 五粮液, 平安银行, 招商银行, 宁德时代)
# 用户可根据需求修改此列表
ContextInfo.stock_list = ['600519.SH', '000858.SZ', '000001.SZ', '600036.SH', '300750.SZ']
ContextInfo.set_universe(ContextInfo.stock_list)
# 3. 设置再平衡参数
# 记录上一次再平衡的月份,用于判断是否跨月
ContextInfo.last_rebalance_month = -1
# 4. 设置回测参数 (仅回测模式有效)
# 资金 100万
ContextInfo.capital = 1000000
# 费率设置:万分之三
ContextInfo.set_commission(0, [0.001, 0.001, 0.0003, 0.0003, 0.0003, 5])
# 滑点设置:0.01元
ContextInfo.set_slippage(1, 0.01)
print("策略初始化完成,标的池数量: {}".format(len(ContextInfo.stock_list)))
def handlebar(ContextInfo):
"""
行情事件函数,每根K线运行一次
"""
# 获取当前K线的时间戳
timetag = ContextInfo.get_bar_timetag(ContextInfo.barpos)
# 将时间戳转换为 datetime 格式的字符串
current_date_str = timetag_to_datetime(timetag, '%Y%m%d')
# 提取当前月份 (格式 YYYYMM)
current_month = int(current_date_str[0:6])
# 判断是否需要跳过 (例如未到最后一根K线,或者非交易时间)
# 在回测模式下,通常在日线周期的每一根Bar执行
# --- 再平衡逻辑判断 ---
# 如果当前月份与上一次记录的月份不同,说明进入了新的月份,执行再平衡
if current_month != ContextInfo.last_rebalance_month:
print(">>> 检测到月份变化,执行再平衡。当前日期: {}".format(current_date_str))
# 执行调仓函数
rebalance(ContextInfo)
# 更新记录的月份
ContextInfo.last_rebalance_month = current_month
def rebalance(ContextInfo):
"""
执行再平衡的核心逻辑
"""
stock_count = len(ContextInfo.stock_list)
if stock_count == 0:
return
# 计算每只股票的目标权重 (等权重)
# 如果有5只股票,每只权重为 1/5 = 0.2 (20%)
target_weight = 1.0 / stock_count
print("开始调仓,目标每只股票持仓权重: {:.2%}".format(target_weight))
# 遍历股票池中的每一只股票进行调整
for stock in ContextInfo.stock_list:
# 获取当前标的名称,用于日志输出
stock_name = ContextInfo.get_stock_name(stock)
# 使用 order_target_percent 进行下单
# 该函数会自动计算:(总资产 * 目标比例 - 当前持仓市值) / 股价
# 正数买入,负数卖出
# 注意:order_target_percent 依赖于账户的总资产数据
# 参数说明:
# stock: 代码
# target_weight: 目标比例 (0.2 表示 20%)
# order_type: 1101 (单股、单账号、普通、股/手方式下单) - 这里虽然是target_percent,但底层通常映射到具体的下单指令
# price: -1 (使用默认价格,通常是市价或最新价,取决于交易设置)
# ContextInfo: 上下文
# account_id: 账号
# 注意:QMT的 order_target_percent 封装在 Python API 中,
# 它会自动处理买卖方向。
order_target_percent(stock, target_weight, "LATEST", 0.0, ContextInfo, ContextInfo.account_id)
print("已发送调仓指令: {} ({}), 目标权重: {:.2%}".format(stock, stock_name, target_weight))
print("本次再平衡指令发送完毕。")
# -*- coding: gbk -*-:
init 函数:
ContextInfo.set_account: 必须设置真实的资金账号,否则无法获取持仓和资金信息,order_target_percent 也无法正确计算。ContextInfo.stock_list: 这里定义了投资组合的范围。handlebar 函数:
timetag_to_datetime 获取当前 K 线的时间。current_month 和 last_rebalance_month。如果不同,说明这是新月份的第一个交易 K 线,触发调仓。rebalance 函数:
target_weight = 1.0 / len(stock_list)。这是最简单的等权重模型。order_target_percent: 这是 QMT 提供的便捷交易函数。
target_weight。ContextInfo.account_id = 'YOUR_ACCOUNT_ID' 中的 'YOUR_ACCOUNT_ID' 替换为您实际的资金账号。Q: 如何将等权重改为按市值加权?
A: 您需要在 rebalance 函数中获取每只股票的总市值,计算总市值之和,然后计算每只股票的权重 weight = 个股总市值 / 所有股票总市值,最后将这个动态的 weight 传给 order_target_percent。
Q: 为什么回测时没有交易?
A: 请检查:1. ContextInfo.stock_list 中的股票在回测区间内是否已上市;2. 是否下载了对应的历史日线数据;3. 资金账号设置是否符合回测虚拟账号规则(回测模式下通常不需要真实账号,但代码逻辑中引用了 account_id,回测引擎会模拟一个)。
Q: order_target_percent 下单失败怎么办?
A: 可能是因为资金不足、股票停牌或跌停无法卖出。在实盘中,建议配合 get_trade_detail_data 查询委托状态,或者在 rebalance 前增加风控判断(如检查股票状态 ContextInfo.is_suspended_stock)。