3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于威廉指标(Williams %R)的 QMT 量化交易策略。
# -*- coding: gbk -*-
import pandas as pd
import numpy as np
import talib
def init(ContextInfo):
"""
初始化函数,策略启动时执行一次
"""
# 1. 设置策略参数
ContextInfo.N = 14 # 威廉指标周期,通常为14
ContextInfo.buy_threshold = -80 # 买入阈值
ContextInfo.sell_threshold = -20 # 卖出阈值
# 2. 设置股票池(示例使用浦发银行,实盘请在界面设置或此处修改)
ContextInfo.stock_code = '600000.SH'
ContextInfo.set_universe([ContextInfo.stock_code])
# 3. 设置资金账号 (请替换为您真实的资金账号)
ContextInfo.account_id = 'YOUR_ACCOUNT_ID'
ContextInfo.account_type = 'STOCK' # 账号类型:STOCK股票,FUTURE期货
ContextInfo.set_account(ContextInfo.account_id)
print("策略初始化完成,监控标的: {}, 周期: {}".format(ContextInfo.stock_code, ContextInfo.N))
def handlebar(ContextInfo):
"""
K线处理函数,每根K线执行一次
"""
# 获取当前正在处理的K线对应的股票代码
# 如果是回测模式,ContextInfo.stockcode 会自动随主图变化
# 如果是实盘,建议明确指定代码
stock_code = ContextInfo.stock_code
# 1. 获取历史行情数据
# 我们需要 High, Low, Close 价格来计算威廉指标
# 获取数量 count 需要比 N 大,以确保有足够数据计算指标
count = ContextInfo.N + 5
# 使用 get_market_data_ex 获取数据 (推荐使用 ex 接口)
# period='1d' 表示日线,也可以改成 '1m', '5m' 等
data_map = ContextInfo.get_market_data_ex(
['high', 'low', 'close'],
[stock_code],
period='1d',
count=count,
dividend_type='front' # 前复权
)
# 数据校验:如果没取到数据,直接返回
if stock_code not in data_map or data_map[stock_code].empty:
return
df = data_map[stock_code]
# 确保数据长度足够
if len(df) < ContextInfo.N:
return
# 2. 计算威廉指标 (Williams %R)
# 转换数据为 numpy 数组,talib 需要 float 类型
high_prices = df['high'].values.astype(float)
low_prices = df['low'].values.astype(float)
close_prices = df['close'].values.astype(float)
# 调用 talib 库计算 WILLR
# 公式: %R = (Highest High - Close) / (Highest High - Lowest Low) * -100
wr_values = talib.WILLR(high_prices, low_prices, close_prices, timeperiod=ContextInfo.N)
# 获取最新的 WR 值 (数组最后一个)
current_wr = wr_values[-1]
# 打印当前指标值 (方便调试)
# print(f"时间: {df.index[-1]}, WR: {current_wr:.2f}")
# 3. 交易逻辑判断
# 获取当前持仓
positions = ContextInfo.get_trade_detail_data(ContextInfo.account_id, ContextInfo.account_type, 'POSITION')
current_holding = 0
for pos in positions:
if pos.m_strInstrumentID + '.' + pos.m_strExchangeID == stock_code:
current_holding = pos.m_nVolume
break
# 信号判断
# 只有在 K 线走完或者是最新一根 K 线时才进行交易判断
if not np.isnan(current_wr):
# --- 买入信号:WR < -80 (超卖) ---
if current_wr < ContextInfo.buy_threshold:
# 如果当前没有持仓,则买入
# 这里使用 order_target_percent 调整仓位到 100% (即满仓买入)
# 注意:实盘中请根据风控需求调整比例,例如 0.1 (10%)
if current_holding == 0:
print(f"触发买入信号: WR={current_wr:.2f} < {ContextInfo.buy_threshold}")
order_target_percent(stock_code, 1.0, ContextInfo, ContextInfo.account_id)
# --- 卖出信号:WR > -20 (超买) ---
elif current_wr > ContextInfo.sell_threshold:
# 如果有持仓,则卖出
# 调整仓位到 0% (即清仓)
if current_holding > 0:
print(f"触发卖出信号: WR={current_wr:.2f} > {ContextInfo.sell_threshold}")
order_target_percent(stock_code, 0.0, ContextInfo, ContextInfo.account_id)
# -*- coding: gbk -*-:
数据获取 (get_market_data_ex):
get_market_data_ex 接口,这是 QMT 推荐的新版数据接口。dividend_type='front' 设置为前复权,这对于技术指标计算非常重要,可以避免分红派息导致的价格跳空影响指标准确性。指标计算 (talib.WILLR):
talib 库,直接调用 WILLR 函数计算威廉指标,效率最高且准确。float 类型的 numpy 数组。交易函数 (order_target_percent):
order_target_percent(stock_code, target_percent, ...) 是一个非常方便的函数。1.0 代表买入直到该股票占账户总资产的 100%(满仓)。0.0 代表卖出直到持仓为 0(清仓)。1.0 改为较小的比例(如 0.1 或 0.2)以控制风险。账号设置:
ContextInfo.account_id = 'YOUR_ACCOUNT_ID' 需要替换为您实际的资金账号,否则无法下单。Q: 为什么威廉指标是负数?
A: 威廉指标的公式设计决定了其值域为 0 到 -100。0 代表收盘价处于过去 N 天的最高价(超买),-100 代表收盘价处于过去 N 天的最低价(超卖)。
Q: 如何在回测中查看效果?
A: 在 QMT 界面点击“模型回测”,设置好回测区间、基准和费率,然后点击“开始回测”。代码中的 print 语句会在日志中输出买卖信号。
Q: 这个策略可以直接实盘吗?
A: 代码逻辑是完整的,但实盘前请务必:
order_target_percent 的比例调整为合理的仓位控制(不要直接满仓)。