3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于 QMT 平台 API 编写的 Parabolic SAR (抛物线转向指标) 交易策略。
# -*- coding: gbk -*-
import pandas as pd
import numpy as np
import talib
def init(ContextInfo):
"""
策略初始化函数
"""
# 设置资金账号 (请替换为您真实的资金账号)
ContextInfo.accID = '6000000000'
ContextInfo.set_account(ContextInfo.accID)
# 设置标的股票 (示例:浦发银行)
ContextInfo.stock_code = '600000.SH'
ContextInfo.set_universe([ContextInfo.stock_code])
# 策略参数设置
ContextInfo.sar_acceleration = 0.02 # 加速因子初始值和步长
ContextInfo.sar_maximum = 0.2 # 加速因子最大值
# 每次交易数量
ContextInfo.trade_vol = 100
print("SAR 策略初始化完成")
def handlebar(ContextInfo):
"""
K线周期运行函数
"""
# 获取当前图表的当前K线索引
index = ContextInfo.barpos
# 获取当前时间戳
realtime = ContextInfo.get_bar_timetag(index)
# 获取标的代码
stock = ContextInfo.stock_code
# 获取历史行情数据 (High, Low, Close)
# 为了计算 SAR,我们需要一定长度的历史数据,这里取 100 根 K 线
# 使用 get_market_data_ex 接口
data_map = ContextInfo.get_market_data_ex(
['high', 'low', 'close'],
[stock],
period=ContextInfo.period,
count=100,
dividend_type='front' # 前复权
)
if stock not in data_map:
return
df = data_map[stock]
# 确保数据量足够计算指标
if len(df) < 50:
return
# 提取 High 和 Low 用于计算 SAR
high_prices = df['high'].values
low_prices = df['low'].values
close_prices = df['close'].values
# 使用 talib 计算 SAR 指标
# 注意:talib 接收 numpy array
sar_values = talib.SAR(
high_prices,
low_prices,
acceleration=ContextInfo.sar_acceleration,
maximum=ContextInfo.sar_maximum
)
# 获取当前和上一根K线的数据
current_close = close_prices[-1]
current_sar = sar_values[-1]
prev_close = close_prices[-2]
prev_sar = sar_values[-2]
# 在图表上绘制 SAR 指标 (方便回测观察)
ContextInfo.paint('SAR', current_sar, -1, 0, 'yellow')
# ----------------------------------------------------------------
# 交易逻辑判断
# ----------------------------------------------------------------
# 只有在最后一根K线或者是回测模式下才执行交易逻辑
if not ContextInfo.is_last_bar():
return
# 获取当前持仓
position = get_position(ContextInfo, stock)
# 信号 1: 买入 (价格上穿 SAR)
# 逻辑: 上一根K线收盘价在SAR下方,当前K线收盘价在SAR上方
buy_signal = (prev_close < prev_sar) and (current_close > current_sar)
# 信号 2: 卖出 (价格下穿 SAR)
# 逻辑: 上一根K线收盘价在SAR上方,当前K线收盘价在SAR下方
sell_signal = (prev_close > prev_sar) and (current_close < current_sar)
# 执行买入
if buy_signal:
if position == 0:
print(f"[{stock}] 触发买入信号: 价格({current_close}) 上穿 SAR({current_sar})")
# 23: 买入, 1101: 单股单账号普通交易
passorder(23, 1101, ContextInfo.accID, stock, 5, -1, ContextInfo.trade_vol, ContextInfo)
# 执行卖出
elif sell_signal:
if position > 0:
print(f"[{stock}] 触发卖出信号: 价格({current_close}) 下穿 SAR({current_sar})")
# 24: 卖出, 1101: 单股单账号普通交易
passorder(24, 1101, ContextInfo.accID, stock, 5, -1, position, ContextInfo)
def get_position(ContextInfo, stock_code):
"""
辅助函数:获取指定股票的持仓数量
"""
# 获取持仓对象列表
# 'STOCK' 代表股票账户, 'POSITION' 代表持仓
positions = get_trade_detail_data(ContextInfo.accID, 'STOCK', 'POSITION')
for pos in positions:
if pos.m_strInstrumentID + '.' + pos.m_strExchangeID == stock_code:
return pos.m_nVolume
return 0
数据获取 (get_market_data_ex):
high) 和最低价 (low)。talib.SAR 函数有足够的数据进行收敛计算。dividend_type='front'(前复权),这在回测和实盘中对于技术指标计算非常重要,可以避免分红派息导致的价格跳空影响指标准确性。指标计算 (talib.SAR):
talib 库进行计算,效率高且准确。acceleration (加速因子) 和 maximum (最大值) 是 SAR 的核心参数。信号逻辑:
prev_close < prev_sar 且 current_close > current_sar。这意味着趋势由跌转涨。prev_close > prev_sar 且 current_close < current_sar。这意味着趋势由涨转跌。绘图 (ContextInfo.paint):
ContextInfo.paint 函数,这样在回测或模型运行时,主图上会画出黄色的 SAR 点位,方便您直观验证策略信号是否正确。交易执行 (passorder):
opType=23,卖出使用 opType=24。prType=5 (最新价),价格填 -1 表示跟随最新价。get_position 函数检查持仓,避免在没有持仓时卖出(虽然系统会报错,但逻辑上处理更好)。init 函数中的 ContextInfo.accID 为您的真实或模拟资金账号。Q: 为什么 SAR 指标在盘整震荡行情中表现不佳?
A: SAR 是典型的趋势跟踪指标。在明显的单边上涨或下跌趋势中,它能很好地锁住利润。但在横盘震荡时,价格频繁上下穿过 SAR 点位,会导致频繁发出买卖信号(来回止损),从而产生连续的小额亏损。通常建议结合 ADX (平均趋向指标) 来判断当前是否有趋势,只有在趋势明显时才使用 SAR。
Q: 如何修改 SAR 的灵敏度?
A: 可以调整 init 函数中的 ContextInfo.sar_acceleration (加速因子)。
Q: passorder 函数中的 1101 是什么意思?
A: 1101 是 orderType(下单方式)的代码,代表:单股、单账号、普通、股/手方式下单。这是最常用的股票交易下单模式。如果您需要按金额下单(例如买入 1 万元),可以使用 1102。