3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
传统固定间距网格策略在单边行情或波动剧烈变大时易面临破网风险或资金利用率低的问题。本文将介绍如何在 PTrade 量化交易平台上,利用 ATR (Average True Range,真实波幅指标) 实现动态调整网格间距的自适应网格策略,并引入资金管理与风险控制机制。
间距 = ATR * 倍数),波动率大时扩大间距防止频繁触网,波动率小时缩小间距捕捉微小震荡。# PTrade 动态网格交易策略示例
import numpy as np
def initialize(context):
# 1. 设置标的与操作股票池
g.security = '600570.SS' # 示例标的:恒生电子
set_universe(g.security)
# 2. 网格参数配置
g.atr_period = 14 # ATR 计算周期
g.atr_multi = 1.5 # ATR 间距倍数
g.base_price = None # 网格基准价
g.grid_levels = 5 # 单边网格层数
g.position_limit = 0.5 # 最大仓位限制(占总资产比例)
g.order_ratio = 0.1 # 每次交易使用可用资金比例
# 运行时段设置:每天盘前重置/更新网格参数
run_daily(context, daily_update, time='9:31')
def daily_update(context):
"""每日开盘更新 ATR 及动态网格间距"""
# 获取过去 N 天的 K 线数据计算 ATR
df = get_history(g.atr_period + 10, '1d', ['high', 'low', 'close'], g.security, fq='pre')
if df.empty or len(df) < g.atr_period + 1:
log.warning("数据不足,跳过 ATR 计算")
return
# 计算 TR (True Range)
highs = df['high'].values
lows = df['low'].values
closes = df['close'].values
tr_list = []
for i in range(1, len(df)):
tr = max(highs[i] - lows[i], abs(highs[i] - closes[i-1]), abs(lows[i] - closes[i-1]))
tr_list.append(tr)
# 计算 ATR
g.current_atr = np.mean(tr_list[-g.atr_period:])
g.grid_step = round(g.current_atr * g.atr_multi, 2)
# 初始化/更新基准价
current_price = closes[-1]
if g.base_price is None:
g.base_price = current_price
log.info("当日 ATR: %.3f, 动态网格间距: %.3f, 当前基准价: %.2f" % (g.current_atr, g.grid_step, g.base_price))
def handle_data(context, data):
if g.base_price is None or g.grid_step <= 0:
return
sid = g.security
current_price = data[sid]['close']
# 获取当前持仓及资产信息
pos = get_position(sid)
current_amount = pos.amount if pos else 0
portfolio_value = context.portfolio.portfolio_value
cash = context.portfolio.cash
position_value = context.portfolio.positions_value
# 仓位比例风控
current_pos_ratio = position_value / portfolio_value if portfolio_value > 0 else 0
# 1. 买入逻辑:价格低于基准价 - 网格间距
if current_price <= g.base_price - g.grid_step:
if current_pos_ratio < g.position_limit:
buy_cash = cash * g.order_ratio
if buy_cash >= current_price * 100:
order_value(sid, buy_cash)
g.base_price = current_price # 更新基准价
log.info("触发向下网格买入,买入金额: %.2f,新基准价: %.2f" % (buy_cash, g.base_price))
# 2. 卖出逻辑:价格高于基准价 + 网格间距
elif current_price >= g.base_price + g.grid_step:
if current_amount > 0:
sell_amount = min(current_amount, int((cash + position_value) * g.order_ratio / current_price / 100) * 100)
if sell_amount <= 0:
sell_amount = 100 # 最少卖出1手
order(sid, -sell_amount)
g.base_price = current_price # 更新基准价
log.info("触发向上网格卖出,卖出数量: %d,新基准价: %.2f" % (sell_amount, g.base_price))
get_history 时,务必开通前复权 (fq='pre'),确保 ATR 计算的连续性。