🚀 AI 一键生成 ptrade 策略代码
立即体验

如何在 ptrade 中基于历史波动率实现动态网格交易策略?(附 Python 完整源码)

ptrade | 发布时间: 2026/7/26
以下内容由 EasyQuant 生成。

问题描述

请根据以下 SEO 主题生成完整页面内容:

Title: ptrade 网格交易策略:结合历史波动率构建动态网格区间

Question: 如何在 ptrade 中利用历史 K 线数据动态计算股票价格网格,并实现自动低买高卖?

解决方案

ptrade 动态网格交易策略:基于历史波动率构建动态区间

网格交易是一种常见的均值回归交易策略,通过在价格区间内拉网分批挂单,实现“低买高卖”。然而传统固定网格在面对趋势行情或波动率剧烈变化时容易出现破网或资金利用率低的问题。

在 ptrade 量化交易平台中,我们可以结合 get_history 获取历史 K 线数据,计算标的的价格中枢(如 N 日移动平均线)和历史波动率(如真实波动幅度 ATR 或标准差),从而动态调整网格基准价与网格间距


策略设计核心逻辑

  1. 确定基准价格中枢:利用过去 N 天的收盘价均线(SMA)作为网格的中轴线。
  2. 计算动态网格间距:利用过去 N 天的日收盘价标准差(Standard Deviation)或百分比计算网格间距,波动率大时放大网格,波动率小时缩小网格。
  3. 构建买卖档位:根据基准价与网格间距,划分出多层买入线与卖出线。
  4. 自动低买高卖:在盘中 handle_data 事件中监控价格,当触及网格线时执行买入或卖出委托。

核心 ptrade API 说明

  • set_universe(security):设置策略操作的股票池。
  • get_history(count, frequency, field, security_list):获取历史 K 线行情,用于计算移动均线和波动率。
  • order(security, amount) / order_target(security, amount):执行股票下单委托。
  • get_position(security):获取持仓信息,确认可用持仓量。

完整策略 Python 源码

import numpy as np

def initialize(context):
    # 1. 设置交易标的(以恒生电子 600570.SS 为例)
    g.security = '600570.SS'
    set_universe(g.security)
    
    # 2. 网格参数设置
    g.grid_levels = 3          # 上下各设 3 层网格
    g.history_days = 20        # 计算基准价与波动率的历史天数
    g.trade_unit = 200         # 每层网格交易股数
    
    # 记录当前已触发的网格层级
    g.current_level = 0

def before_trading_start(context, data):
    # 盘前计算动态基准价与网格间距
    df = get_history(g.history_days, '1d', 'close', g.security, fq='pre', include=False)
    if df is not None and not df.empty:
        close_prices = df['close'].values
        g.base_price = round(float(np.mean(close_prices)), 2)      # 20日均价作为价格中枢
        std_dev = float(np.std(close_prices))
        g.grid_step = max(round(std_dev * 0.5, 2), 0.1)           # 以0.5倍标准差作为网格间距(最小0.1元)
        log.info("【盘前更新】基准中枢价: %s, 动态网格间距: %s" % (g.base_price, g.grid_step))

def handle_data(context, data):
    sid = g.security
    if sid not in data:
        return
        
    current_price = data[sid]['close']
    position = get_position(sid)
    current_amount = position.amount
    
    # 计算当前价格偏离基准价的网格层级
    # 例如:价格下跌超过 1 个 grid_step,target_level 为 -1
    price_diff = current_price - g.base_price
    target_level = int(np.floor(price_diff / g.grid_step))
    
    # 限制网格层级在设定范围内
    target_level = max(min(target_level, g.grid_levels), -g.grid_levels)
    
    # 当网格层级发生变化时触发交易
    if target_level != g.current_level:
        level_diff = target_level - g.current_level
        
        # 触发向下网格:价格下跌,买入
        if level_diff < 0:
            buy_amount = abs(level_diff) * g.trade_unit
            order(sid, buy_amount)
            log.info("【网格买入】价格降至 %s,触发低吸,买入 %s 股" % (current_price, buy_amount))
            g.current_level = target_level
            
        # 触发向上网格:价格上涨,卖出
        elif level_diff > 0 and current_amount > 0:
            sell_amount = min(level_diff * g.trade_unit, current_amount)
            order(sid, -sell_amount)
            log.info("【网格卖出】价格涨至 %s,触发高抛,卖出 %s 股" % (current_price, sell_amount))
            g.current_level = target_level

策略实盘与回测注意事项

  1. 价格精度保留:股票下单价格通常保留 2 位小数(如 round(price, 2)),ETF 或可转债需根据交易规则调整位数(如 3 位或 4 位),避免报单因价格精度非法被柜台拒单。
  2. 最小交易单位限制:股票买入必须为 100 股的整数倍;卖出时若清仓则不受 100 股限制。
  3. 单边趋势风险:网格交易属于震荡市策略。若遇到单边下跌行情,可能导致资金快速建仓被套;若遇到单边上涨行情,可能导致持仓提早卖空。建议搭配止损线及最大建仓上限。