当前位置: 首页 > news >正文

可直接回测!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,每周调仓频率适中,不会产生过高交易手续费,适合中长期自动化定投 + 趋势交易结合的投资者。

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

http://www.cnnetsun.cn/news/3770248.html

相关文章:

  • 3个关键阶段:手把手教你用OpenCore在普通PC上安装macOS黑苹果系统
  • Steam成就管理器:轻松掌控你的游戏成就解锁之旅
  • 用Three.js构建沉浸式室内导航:indoor3D库的技术探索
  • 怎样高效使用暗黑破坏神2角色编辑器:3个实用技巧掌握角色定制
  • 告别杂乱桌面!免费开源桌面分区工具NoFences让你的Windows效率提升300%
  • AAV靶向心脏选型全攻略:HFpEF新靶点Sub1机制深度解析
  • 直接优化策略:策略梯度、Actor-Critic、Advantage 与重要性采样
  • RTOS-F429-HAL-任务状态查询API实验(2026/7/30)
  • OpenSCAP实战:Docker容器镜像安全扫描与CI/CD集成指南
  • 终极实战:Chaplin开源唇语识别技术深度解析与集成指南
  • 如何快速搭建跨平台交互模拟器:TUIOSimulator完整指南
  • 2026最新测评:16款降AI率网站测评,这款神器让论文秒过检测!
  • BepInEx完整入门指南:5步掌握Unity游戏插件开发框架
  • STM32定时器RCR与单脉冲模式实现步进电机精确脉冲控制
  • CTF杂项进阶:ZIP伪加密与Base64隐写原理与实战解析
  • OpenMetadata数据血缘追踪:企业级架构解析与实战部署指南
  • Unity游戏移植微信小游戏:核心挑战、性能优化与实战指南
  • 如何快速修复损坏视频:Untrunc开源工具的完整实战指南
  • AI会议效率跃迁实战手册(2024最新版):从日均3.2小时无效会议压缩至47分钟的完整路径
  • 51单片机RS-485通信实战:从硬件电路到多机协议完整指南
  • 真空共晶炉行业深度分析:技术演进、市场格局与未来趋势
  • 【Gartner认证AI协同框架】:基于237家企业的A/B测试数据,重构会议ROI的4层智能过滤模型
  • 强烈推荐配镜的机构
  • 基于Raft分布式Kv存储:Clerk
  • AI驱动项目交付提速40%的关键配置,飞书管理员绝不会告诉你的6个参数
  • 3分钟解锁《鸣潮》120FPS高帧率:WaveTools终极工具箱完整指南
  • C语言关键字深度解析:从语法基础到高级应用
  • Akagi雀魂助手:你的智能麻将AI教练真的能提升游戏水平吗?
  • M4Markets:注重效率的使用者更在意的技术架构,这里做个视角盘点
  • 【单片机毕业设计推荐】基于 STM32 或 51 单片机的水质多参数监测与自动换水控制系统设计 基于 STM32 或 51 单片机的水体 pH、温度、浑浊度智能监测装置设计(021504)