枢轴点反转策略
一、交易策略解释
核心思想
枢轴点反转策略基于价格围绕关键支撑位和阻力位波动的市场特性。该策略认为,当价格达到计算出的支撑位或阻力位后,有较大概率发生反转。 具体而言,当价格下跌至支撑位附近并开始回升时,可能是做多信号;当价格上涨至阻力位附近并开始下跌时,可能是做空信号。这种策略特别适合震荡市场,能够捕捉价格在一定区间内的波动。
该策略通过前一交易日的高点、低点和收盘价计算枢轴点,并衍生出多个支撑位和阻力位,这些价格水平共同构成了一个完整的交易系统,能够捕捉市场中的价格反转信号。
理论基础
枢轴点策略的理论基础主要来自于市场微观结构和价格行为理论:
-
供需平衡点理论:枢轴点代表了市场参与者认为的价格公允水平,价格围绕这一水平波动。
-
价格记忆效应:市场对历史价格水平有"记忆",昨日的高低点对今日交易有重要影响。
-
市场惯性与反转:市场在短期内往往遵循惯性运动原则,但达到极限点后会发生反转。
多项学术研究表明,支撑位和阻力位在短期内对价格走势具有显著影响。Lo和MacKinlay(1999)的研究表明,市场在短期内存在可预测性,这为反转策略提供了理论支持。同时,专业交易者长期经验也证实,在震荡市场中,价格往往在关键水平附近发生反转。
策略适用场景
-
市场类型:震荡市或区间震荡市场,价格在一定范围内波动。
-
波动特征:日内波动较大,但总体趋势不明显的市场。
-
流动性:流动性充足的市场,如主力合约期货。
-
交易时间框架:短线交易,特别是日内交易。
-
品种选择:波动较大的商品期货,如螺纹钢、铜、原油等。
二、天勤介绍
天勤平台概述
天勤(TqSdk)是一个由信易科技开发的开源量化交易系统,为期货、期权等衍生品交易提供专业的量化交易解决方案。平台具有以下特 点:
- 丰富的行情数据: 提供所有可交易合约的全部Tick和K线数据,基于内存数据库实现零延迟访问。
- 一站式的解决方案: 从历史数据分析到实盘交易的完整工具链,打通开发、回测、模拟到实盘的全流程。
- 专业的技术支持: 近百个技术指标源码,深度集成pandas和numpy,采用单线程异步模型保证性能。
策略开发流程
- 环境准备
- 安装Python环境(推荐Python 3.6或以上版本)
- 安装tqsdk包:pip install tqsdk
- 注册天勤账户获取访问密钥
- 数据准备
- 订阅近月与远月合约行情
- 获取历史K线或者Tick数据(用于分析与行情推进)
- 策略编写
- 设计信号生成逻辑(基于价差、均值和标准差)
- 编写交易执行模块(开仓、平仓逻辑)
- 实现风险控制措施(止损、资金管理)
- 回测验证
- 设置回测时间区间和初始资金
- 运行策略获取回测结果
- 分析绩效指标(胜率、收益率、夏普率等)
- 策略优化
- 调整参数(标准差倍数、窗口大小等)
- 添加过滤条件(成交量、波动率等)
- 完善风险控制机制
三、天勤实现策略
策略原理
枢轴点反转策略基于前一交易日的高点、低点和收盘价计算出关键价格水平:
枢轴点(Pivot) = (High + Low + Close) / 3
第一支撑位(S1) = (2 × P) - High
第一阻力位(R1) = (2 × P) - Low
第二支撑位(S2) = P - (High - Low)
第二阻力位(R2) = P + (High - Low)
在实际应用中,我们还可以增加更多支撑位和阻力位:
第三支撑位(S3) = S1 - (High - Low)
第三阻力位(R3) = R1 + (High - Low)
这些价格水平构成了交易信号的基础:
-
反转情景:当价格接近支撑位或阻力位并出现反转迹象时入场
-
反弹交易:从支撑位附近做多,目标价格为枢轴点或阻力位
-
回落交易:从阻力位附近做空,目标价格为枢轴点或支撑位
交易逻辑
做多信号:
-
当价格下跌到第一支撑位(S1)附近并开始反弹时,开仓做多。
-
当价格下跌到第二支撑位(S2)附近并开始反弹时,开仓做多。
做空信号:
-
当价格上涨到第一阻力位(R1)附近并开始回落时,开仓做空。
-
当价格上涨到第二阻力位(R2)附近并开始回落时,开仓做空。
入场确认:
-
可结合K线形态(如上升锤形线、吞没形态等)确认反转信号。
-
可使用RSI等指标确认超买超卖状态,增强信号可靠性。
平仓规则:
-
反向位置平仓:做多单在接近阻力位时平仓,做空单在接近支撑位时平仓。
-
日内交易在收盘前15分钟平仓。
-
或者当价格达到预设止损水平时平仓。
止损设置:
-
做多止损设置在支撑位下方10-20个点。
-
做空止损设置在阻力位上方10-20个点。
回测
回测初始设置
- 测试周期: 2023 年 2 月 10 日 - 2023 年 3 月 15 日
- 交易品种: SHFE.cu2309
- 初始资金: 1000万元
回测结果
上述回测累计收益走势图
完整代码示例
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = "Chaos"
from datetime import date
from tqsdk import TqApi, TqAuth, TqBacktest, TargetPosTask, BacktestFinished
from tqsdk.tafunc import time_to_str
# ===== 全局参数设置 =====
SYMBOL = "SHFE.cu2309"
POSITION_SIZE = 100
START_DATE = date(2023, 2, 10) # 回测开始日期
END_DATE = date(2023, 3, 15) # 回测结束日期
# 策略参数
REVERSAL_CONFIRM = 50 # 反转确认点数
STOP_LOSS_POINTS = 100 # 止损点数
# ===== 全局变量 =====
current_direction = 0 # 当前持仓方向:1=多头,-1=空头,0=空仓
entry_price = 0 # 开仓价格
stop_loss_price = 0 # 止损价格
prev_high = 0 # 前一日最高价
prev_low = 0 # 前一日最低价
prev_close = 0 # 前一日收盘价
# ===== 策略开始 =====
print("开始运行枢轴点反转策略...")
# 创建API实例
api = TqApi(backtest=TqBacktest(start_dt=START_DATE, end_dt=END_DATE),
auth=TqAuth("快期账号", "快期密码"))
# 订阅合约的K线数据
klines = api.get_kline_serial(SYMBOL, 60 * 60 * 24) # 日线数据
# 创建目标持仓任务
target_pos = TargetPosTask(api, SYMBOL)
def calculate_pivot_points(high, low, close):
"""计算枢轴点及支撑阻力位"""
pivot = (high + low + close) / 3
r1 = (2 * pivot) - low
s1 = (2 * pivot) - high
r2 = pivot + (high - low)
s2 = pivot - (high - low)
r3 = r1 + (high - low)
s3 = s1 - (high - low)
return pivot, r1, r2, r3, s1, s2, s3
try:
while True:
# 等待更新
api.wait_update()
# 如果K线有更新
if api.is_changing(klines.iloc[-1], "datetime"):
# 确保有足够的数据
if len(klines) < 2:
continue
# 获取当前价格和前一日数据
current_price = klines.close.iloc[-1].item()
current_high = klines.high.iloc[-1].item()
current_low = klines.low.iloc[-1].item()
prev_close = klines.close.iloc[-2].item()
# 如果是新的一天,更新前一日数据
if klines.datetime.iloc[-1] != klines.datetime.iloc[-2]:
prev_high = klines.high.iloc[-2].item()
prev_low = klines.low.iloc[-2].item()
prev_close = klines.close.iloc[-2].item()
print(f"\n新的一天开始:")
print(f"前一日数据 - 最高价: {prev_high:.2f}, 最低价: {prev_low:.2f}, 收盘价: {prev_close:.2f}")
# 计算枢轴点及支撑阻力位
pivot, r1, r2, r3, s1, s2, s3 = calculate_pivot_points(prev_high, prev_low, prev_close)
# 获取最新数据
current_timestamp = klines.datetime.iloc[-1]
current_datetime = time_to_str(current_timestamp)
# 打印当前状态
print(f"\n日期: {current_datetime}")
print(f"当前价格: {current_price:.2f}")
print(f"枢轴点: {pivot:.2f}")
print(f"支撑位: S1={s1:.2f}, S2={s2:.2f}, S3={s3:.2f}")
print(f"阻力位: R1={r1:.2f}, R2={r2:.2f}, R3={r3:.2f}")
# 打印信号条件
print("\n多头信号条件:")
print(f"1. 价格在S1附近: {current_price <= s1 + REVERSAL_CONFIRM and current_price > s1 - REVERSAL_CONFIRM}")
print(f"2. 价格高于当日最低价: {current_price > klines.low.iloc[-1].item()}")
print(f"3. 价格高于前一日收盘价: {current_price > prev_close}")
print("\n空头信号条件:")
print(f"1. 价格在R1附近: {current_price >= r1 - REVERSAL_CONFIRM and current_price < r1 + REVERSAL_CONFIRM}")
print(f"2. 价格低于当日最高价: {current_price < klines.high.iloc[-1].item()}")
print(f"3. 价格低于前一日收盘价: {current_price < prev_close}")
# ===== 交易逻辑 =====
# 空仓状态 - 寻找开仓机会
if current_direction == 0:
# 多头开仓条件:价格低于S1
if current_price < s1:
current_direction = 1
target_pos.set_target_volume(POSITION_SIZE)
entry_price = current_price
stop_loss_price = entry_price - STOP_LOSS_POINTS
print(f"\n多头开仓信号! 开仓价: {entry_price:.2f}, 止损价: {stop_loss_price:.2f}")
# 空头开仓条件:价格高于R1
elif current_price > r1:
current_direction = -1
target_pos.set_target_volume(-POSITION_SIZE)
entry_price = current_price
stop_loss_price = entry_price + STOP_LOSS_POINTS
print(f"\n空头开仓信号! 开仓价: {entry_price:.2f}, 止损价: {stop_loss_price:.2f}")
# 多头持仓 - 检查平仓条件
elif current_direction == 1:
# 止盈条件:价格回到枢轴点或更高
if current_price >= pivot:
profit = (current_price - entry_price) * POSITION_SIZE
target_pos.set_target_volume(0)
current_direction = 0
print(f"多头止盈平仓: 价格={current_price:.2f}, 盈利={profit:.2f}")
# 止损条件
elif current_price <= stop_loss_price:
loss = (entry_price - current_price) * POSITION_SIZE
target_pos.set_target_volume(0)
current_direction = 0
print(f"多头止损平仓: 价格={current_price:.2f}, 亏损={loss:.2f}")
# 空头持仓 - 检查平仓条件
elif current_direction == -1:
# 止盈条件:价格回到枢轴点或更低
if current_price <= pivot:
profit = (entry_price - current_price) * POSITION_SIZE
target_pos.set_target_volume(0)
current_direction = 0
print(f"空头止盈平仓: 价格={current_price:.2f}, 盈利={profit:.2f}")
# 止损条件
elif current_price >= stop_loss_price:
loss = (current_price - entry_price) * POSITION_SIZE
target_pos.set_target_volume(0)
current_direction = 0
print(f"空头止损平仓: 价格={current_price:.2f}, 亏损={loss:.2f}")
except BacktestFinished as e:
print("回测结束")
api.close()