3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于宏观经济数据(PMI)进行择时的策略设计。
# -*- coding: utf-8 -*-
from jqdata import *
def initialize(context):
"""
初始化函数
"""
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
# 设置交易标的:沪深300ETF
g.security = '510300.XSHG'
# 设置手续费:股票类每笔交易时的手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
# 设置滑点
set_slippage(PriceRelatedSlippage(0.002), type='stock')
# 设定按月运行,在每月第一个交易日的开盘时运行
run_monthly(trade_func, 1, time='open')
def trade_func(context):
"""
月度调仓函数
"""
# 获取当前的日期
current_date = context.current_dt.date()
# 查询宏观数据:制造业PMI (MAC_MANUFACTURING_PMI)
# 按照统计月份降序排列,取最近的一条数据
# 注意:macro.run_query 会自动根据回测时间 context.current_dt 过滤掉未来数据
q = query(
macro.MAC_MANUFACTURING_PMI
).order_by(
macro.MAC_MANUFACTURING_PMI.stat_month.desc()
).limit(1)
df = macro.run_query(q)
# 如果没有获取到数据,则不进行操作
if df.empty:
log.warn("未获取到PMI数据,跳过本月操作")
return
# 获取PMI数值
current_pmi = df['pmi'][0]
stat_month = df['stat_month'][0]
log.info("当前时间: %s, 获取到的最新PMI数据月份: %s, PMI数值: %s" % (current_date, stat_month, current_pmi))
# 获取当前持仓
position = context.portfolio.positions[g.security]
# 策略逻辑:荣枯线 50
if current_pmi > 50:
# 扩张区间,买入
if position.total_amount == 0:
log.info("PMI > 50 (扩张区间),全仓买入")
order_target_value(g.security, context.portfolio.available_cash)
else:
log.info("PMI > 50 (扩张区间),继续持有")
elif current_pmi <= 50:
# 收缩区间,卖出
if position.total_amount > 0:
log.info("PMI <= 50 (收缩区间),清仓卖出")
order_target(g.security, 0)
else:
log.info("PMI <= 50 (收缩区间),继续空仓")
宏观数据获取 (macro.run_query):
macro.MAC_MANUFACTURING_PMI 表。macro.run_query 时,系统只会返回在 context.current_dt 之前已经公布的数据。交易逻辑:
order_target_value 进行全仓买入,使用 order_target 进行清仓。标的选择:
510300.XSHG (沪深300ETF) 作为交易对象,这比直接交易指数(如 000300.XSHG,不可交易)更符合实盘逻辑。Q: 为什么回测时有时候会发现 PMI 数据获取不到?
A: 宏观数据的发布有时间滞后。虽然 PMI 发布较快,但如果回测时间设置得过早(例如2005年以前),可能数据库中缺乏当时的数据。代码中加入了 if df.empty 判断来防止程序报错。
Q: 可以使用财新 PMI 吗?
A: 可以。财新 PMI 通常更能反映中小企业的状况。在聚宽数据库中,可以通过查询 macro.MAC_CAIXIN_PMI 表来获取财新 PMI 数据,逻辑与上述代码完全一致,只需更改查询的表名即可。
Q: 如何避免频繁买卖?
A: 单纯以 50 为界限可能会在 50 附近频繁震荡导致磨损。可以优化策略,例如: