云计算百科
云计算领域专业知识百科平台

可直接回测!Ptrade 强势 ETF 周度轮动程序化交易策略全解

文章简介

本文基于 Ptrade 量化平台,搭建一套可直接回测、仿真运行的周度强势 ETF 轮动策略。核心逻辑:每周筛选 20 日涨幅最强 2 只 ETF,7:3 资金配比买入,每周最后一个交易日全部清仓,循环滚动做趋势短线。全文附带完整可运行代码、函数拆解、节假日自动适配逻辑与实操避坑要点,新手也能快速上手改造。

适用人群:Ptrade 量化学习者、ETF 趋势交易者、程序化自动化交易爱好者

平台: Ptrade Python 量化接口

策略类型:周度趋势轮动、动量策略

一、策略核心逻辑

整套策略极简易懂,完全贴合 A 股 ETF T+1 交易规则,无日内频繁交易风险:

  • 选股规则:每周首个交易日,遍历 ETF 候选池,计算所有标的近 20 个交易日涨跌幅,取涨幅前 2 名强势标的;
  • 资金分配:第一名分配 70% 可用资金,第二名分配 30%,可自行修改权重;
  • 卖出规则:每周最后一个交易日 14:55 统一清仓全部持仓,预留 5 分钟成交时间;
  • 循环执行:次周重复选股、买入、清仓流程,持续跟踪市场强势板块 ETF;
  • 特色适配:内置交易日判断函数,自动跳过周末、法定节假日,周一休市则顺延至节后首个交易日。
  • 二、完整策略代码

    # 1. 导入依赖库
    import datetime
    import pandas as pd
    from datetime import date
    from datetime import timedelta
    import numpy as np

    # 2. 策略初始化函数,程序启动仅执行一次
    def initialize(context):
    # ETF候选池,自行填充沪市/深市ETF代码,示例:["510300.SS","159915.SZ"]
    g.security_list = []
    set_universe(g.security_list)

    # 全局缓存变量
    g.trade_days_list = get_trade_days('2015-01-01', '2025-10-31') # 交易日期总表
    g.selected_stocks = [] # 每周筛选出的2只ETF
    g.weights = [0.7, 0.3] # 资金分配比例
    g.hold_positions = context.portfolio.positions # 当前持仓

    # 定时任务:每日固定时间执行对应函数
    run_daily(context, buy_function, time='9:31') # 周初9:31执行买入
    run_daily(context, sell_function, time='14:55') # 周末14:55执行清仓

    # 3. 每日盘前执行:筛选强势ETF、标记本周首尾交易日
    def before_trading_start(context, data):
    today = get_trading_day(0)
    # 判断是否本周第一个/最后一个交易日
    g.is_first = is_first_trading_day_of_week(today)
    g.is_last = is_last_trading_day_of_week(today)
    print('{}是否为本周首个交易日: {}'.format(today, g.is_first))
    print('{}是否为本周最后一个交易日: {}'.format(today, g.is_last))

    # 仅周初执行选股逻辑
    if g.is_first:
    returns = {}
    for stock in g.security_list:
    # 获取近20日收盘价
    history = get_history(20, '1d', 'close', stock, fq='pre')
    # 计算20日涨跌幅
    ret = (history.iloc[-1, 0] – history.iloc[0, 0]) / history.iloc[0, 0]
    returns[stock] = ret
    log.info("各ETF20日涨跌幅:", returns)
    # 按涨幅降序排序,取前2只
    sorted_returns = sorted(returns.items(), key=lambda x: x[1], reverse=True)
    g.selected_stocks = [item[0] for item in sorted_returns[:2]]
    else:
    pass

    # 4. 买入函数:周初开盘后按比例下单
    def buy_function(context):
    if g.is_first:
    total_available_cash = context.portfolio.cash
    for i in range(len(g.selected_stocks)):
    # 获取最新1分钟收盘价
    history_1 = get_history(1, '1m', 'close', g.selected_stocks[i], fq='pre')
    current_price = history_1.iloc[0]
    # 分配对应资金
    buy_cash = total_available_cash * g.weights[i]
    # A股ETF一手100份,计算可买整数手
    amount = int(buy_cash / current_price / 100) * 100
    if amount > 0:
    order(g.selected_stocks[i], amount)
    else:
    log.info('今日不是本周第一个交易日,不执行买入')

    # 5. 卖出函数:周末收盘前全部清仓
    def sell_function(context):
    if g.is_last:
    g.current_holdings = {}
    # 遍历全部持仓
    for sid, position in context.portfolio.positions.items():
    if position.amount > 0:
    g.current_holdings[sid] = position.amount
    sell_list = list(g.current_holdings.keys())
    # 清仓所有持仓
    for code in sell_list:
    if g.current_holdings[code] > 0:
    order_target(code, 0)
    log.info("卖出{},共{}份".format(code, g.current_holdings[code]))
    else:
    log.info('今日不是本周最后一个交易日,不执行卖出')

    # 辅助函数1:判断当日是否为本周第一个交易日(自动适配节假日)
    def is_first_trading_day_of_week(today):
    one_day = timedelta(days=1)
    yesterday = today – one_day
    # 向前寻找上一个有效交易日
    while yesterday.strftime('%Y-%m-%d') not in g.trade_days_list:
    yesterday -= one_day
    # 周数不同则代表今天是本周首个交易日
    return today.isocalendar()[1] > yesterday.isocalendar()[1] or today.year > yesterday.year

    # 辅助函数2:判断当日是否为本周最后一个交易日(自动适配节假日)
    def is_last_trading_day_of_week(today):
    one_day = timedelta(days=1)
    tomorrow = today + one_day
    # 向后寻找下一个有效交易日
    while tomorrow.strftime('%Y-%m-%d') not in g.trade_days_list:
    tomorrow += one_day
    # 周数不同则代表今天是本周最后一个交易日
    return today.isocalendar()[1] < tomorrow.isocalendar()[1] or today.year < tomorrow.year

    三、代码逐模块详细解析

    3.1 依赖库导入模块

    import datetime
    import pandas as pd
    from datetime import date
    from datetime import timedelta
    import numpy as np

    • datetime/timedelta:处理日期、交易日偏移、节假日判断;
    • pandas:行情数据表格处理;
    • numpy:数值计算、涨跌幅运算; 所有 Ptrade 策略必备基础库,缺失会导致行情获取、日期计算报错。

    3.2 initialize 初始化函数

    程序启动仅运行一次,负责全局变量、候选池、定时任务配置:

  • g.security_list:ETF 标的池,必须手动填充代码,沪市后缀.SS、深市后缀.SZ;
  • get_trade_days:拉取指定区间全部交易日,用于节假日判断;
  • run_daily:定时触发器,固定时间自动执行买卖函数,无需人工盯盘;
  • 3.3 before_trading_start 盘前选股函数

    每个交易日开盘前自动执行,核心完成两件事:

  • 调用is_first_trading_day_of_week标记周初交易日;
  • 遍历候选池 ETF,拉取 20 日收盘价计算动量涨幅,降序排序选出前 2 只强势标的存入全局变量;
  • 注意:此函数仅做数据计算,不会发起交易下单。

    3.4 buy_function 买入下单函数

    仅每周首个交易日 9:31 执行:

  • 获取账户可用现金,按 7:3 权重分配资金;
  • 读取实时 1 分钟收盘价,计算可买入份数;
  • int(xxx/100)*100强制保证下单数量为 100 的整数倍,符合 A 股 ETF 交易规则;
  • order(标的, 数量):Ptrade 原生限价下单接口。
  • 3.5 sell_function 清仓卖出函数

    仅每周最后一个交易日 14:55 执行:

  • 遍历账户全部持仓,筛选持有数量大于 0 的 ETF;
  • order_target(code, 0):一键清仓接口,目标持仓设为 0,无需手动计算卖出数量;
  • 14:55 操作预留 5 分钟收盘缓冲,避免尾盘流动性不足无法成交。
  • 3.6 交易日判断辅助函数

    策略核心适配工具,解决节假日、长假休市问题:

  • is_first_trading_day_of_week:向前回溯查找上一个交易日,对比周数,自动识别节后首个交易日;
  • is_last_trading_day_of_week:向后查找下一个交易日,识别节前最后一个交易日; 无需手动调整日期,回测、实盘均可自动适配。
  • 四、策略实操关键注意事项

    4.1 ETF 候选池配置

    g.security_list = []为空列表,必须填充标的,推荐宽基、行业 ETF 混合,建议 20~40 只,

    格式区分沪深市场,代码后缀写错会导致行情拉取失败。

    4.2 回测时间区间匹配

    代码内get_trade_days('2015-01-01', '2025-10-31'),回测起止时间不能超出该区间,可自行修改结束年份拓展数据范围。

    4.3 资金权重自定义

    g.weights = [0.7, 0.3],风险偏好保守可改为[0.5,0.5]均衡分配,仅支持 2 个数值,对应选出的 2 只 ETF。

    4.4 A 股交易规则适配

    ETF 实行 T+1 交易,本策略每周买入、次周卖出,完全规避日内交易限制,不存在当日买入无法卖出的逻辑 bug。

    4.5 回测优先,谨慎实盘

  • 先用 Ptrade 仿真终端长期回测,观察不同牛熊周期收益、最大回撤;
  • 可自行调参:20 日动量周期改为 10/30 日、增减持仓数量;
  • 实盘前小资金试运行 1~2 个月,验证成交滑点、手续费对收益的影响。
  • 五、策略优化拓展思路

  • 增加止损逻辑:在每日盘后增加持仓跌幅判断,单只 ETF 回撤超 5% 强制卖出;
  • 多周期动量过滤:叠加 60 日中长期趋势,仅在大盘上行时执行轮动;
  • 仓位动态调整:根据市场波动率自动调整总仓位,高位降仓、低位加仓;
  • 扩大持仓数量:修改代码选取前 3~4 只 ETF,分散单一标的风险;
  • 过滤低流动性标的:增加日均成交额筛选,剔除成交量低迷的小盘 ETF。
  • 六、总结

    本套 Ptrade ETF 周度动量轮动策略代码完整、逻辑轻量化,内置节假日自动适配、合规交易数量处理、定时自动交易能力,新手可直接复用平台回测。 策略核心依靠动量效应捕捉中期强势板块 ETF,每周调仓频率适中,不会产生过高交易手续费,适合中长期自动化定投 + 趋势交易结合的投资者。

    风险提示:本文仅为量化代码教学分享,不构成任何投资建议。量化策略存在历史回测不代表未来收益,市场波动、流动性风险、手续费滑点均会影响实际收益,请谨慎使用。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 可直接回测!Ptrade 强势 ETF 周度轮动程序化交易策略全解
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!