news 2026/7/31 17:06:08

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
可直接回测!Ptrade 强势 ETF 周度轮动程序化交易策略全解

文章简介

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

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

平台: Ptrade Python 量化接口

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

一、策略核心逻辑

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

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

二、完整策略代码

# 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 初始化函数

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

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

3.3 before_trading_start 盘前选股函数

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

  1. 调用is_first_trading_day_of_week标记周初交易日;
  2. 遍历候选池 ETF,拉取 20 日收盘价计算动量涨幅,降序排序选出前 2 只强势标的存入全局变量;

注意:此函数仅做数据计算,不会发起交易下单。

3.4 buy_function 买入下单函数

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

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

3.5 sell_function 清仓卖出函数

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

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

3.6 交易日判断辅助函数

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

  1. is_first_trading_day_of_week:向前回溯查找上一个交易日,对比周数,自动识别节后首个交易日;
  2. 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 回测优先,谨慎实盘

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

五、策略优化拓展思路

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

六、总结

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

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/31 17:04:04

3个关键阶段:手把手教你用OpenCore在普通PC上安装macOS黑苹果系统

3个关键阶段&#xff1a;手把手教你用OpenCore在普通PC上安装macOS黑苹果系统 【免费下载链接】Hackintosh 国光的黑苹果安装教程&#xff1a;手把手教你配置 OpenCore 项目地址: https://gitcode.com/gh_mirrors/hac/Hackintosh 想要体验苹果macOS的流畅优雅&#xff0…

作者头像 李华
网站建设 2026/7/31 17:03:47

Steam成就管理器:轻松掌控你的游戏成就解锁之旅

Steam成就管理器&#xff1a;轻松掌控你的游戏成就解锁之旅 【免费下载链接】SteamAchievementManager A manager for game achievements in Steam. 项目地址: https://gitcode.com/gh_mirrors/st/SteamAchievementManager 你是否曾为那些永远无法完成的Steam成就而烦恼…

作者头像 李华
网站建设 2026/7/31 17:03:14

用Three.js构建沉浸式室内导航:indoor3D库的技术探索

用Three.js构建沉浸式室内导航&#xff1a;indoor3D库的技术探索 【免费下载链接】indoor3D a js lib based on three.js to show 3D indoor map 项目地址: https://gitcode.com/gh_mirrors/in/indoor3D 想象一下&#xff0c;当你走进一座现代化的购物中心&#xff0c;手…

作者头像 李华
网站建设 2026/7/31 17:02:19

怎样高效使用暗黑破坏神2角色编辑器:3个实用技巧掌握角色定制

怎样高效使用暗黑破坏神2角色编辑器&#xff1a;3个实用技巧掌握角色定制 【免费下载链接】diablo_edit Diablo II Character editor. 项目地址: https://gitcode.com/gh_mirrors/di/diablo_edit 还在为暗黑破坏神2中刷不到理想装备而烦恼吗&#xff1f;想自由定制角色属…

作者头像 李华
网站建设 2026/7/31 16:59:53

AAV靶向心脏选型全攻略:HFpEF新靶点Sub1机制深度解析

核心亮点&#xff1a;复旦大学附属中山医院团队利用AAV9载体首次证实转录辅因子Sub1是连接心脏衰老与射血分数保留型心力衰竭&#xff08;HFpEF&#xff09;的关键分子开关。该研究发表于《Nature Communications》&#xff0c;揭示Sub1通过双重调控p53翻译后修饰驱动心肌细胞衰…

作者头像 李华