3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于 QMT 平台的 BIAS(乖离率) 量化交易策略。
BIAS (乖离率) 是测量股价偏离移动平均线程度的指标。
以下是完整的 Python 策略代码,您可以直接复制到 QMT 的策略编辑器中。
# -*- coding: gbk -*-
import pandas as pd
import numpy as np
def init(ContextInfo):
"""
初始化函数,设定策略参数和账户
"""
# 1. 策略参数设置
ContextInfo.N = 6 # 计算均线的周期 (如:6日均线)
ContextInfo.buy_threshold = -6 # 买入阈值:BIAS < -6%
ContextInfo.sell_threshold = 6 # 卖出阈值:BIAS > 6%
# 2. 设定交易标的 (示例:浦发银行)
# 实盘或回测时,也可以通过界面右侧的“股票池”设置,这里代码强制设定方便演示
ContextInfo.stock_list = ['600000.SH']
ContextInfo.set_universe(ContextInfo.stock_list)
# 3. 设定资金账号 (请修改为您自己的资金账号)
# 注意:回测模式下,这里可以填任意字符串;实盘模式下必须填写真实账号
ContextInfo.account_id = 'YOUR_ACCOUNT_ID'
ContextInfo.set_account(ContextInfo.account_id)
# 4. 设定回测细节 (仅回测有效)
ContextInfo.set_slippage(1, 0.0) # 设置滑点
ContextInfo.set_commission(0, [0.0003, 0.0003, 0.0003, 0.0003, 0, 5]) # 设置手续费
def handlebar(ContextInfo):
"""
K线逐根运行函数
"""
# 获取当前正在处理的 K 线索引
index = ContextInfo.barpos
# 获取当前图表的周期 (例如 '1d')
period = ContextInfo.period
# 遍历股票池中的每一只股票
for stock in ContextInfo.stock_list:
# 1. 获取历史行情数据
# 我们需要 N 个数据来计算均线,但为了稳健,多取一点数据
# count = ContextInfo.N + 2
# 使用 get_market_data_ex 获取数据,这是更推荐的新接口
# 注意:dividend_type='front' 使用前复权数据,避免分红造成指标失真
data_dict = ContextInfo.get_market_data_ex(
['close'],
[stock],
period=period,
count=ContextInfo.N + 5,
dividend_type='front',
subscribe=True
)
if stock not in data_dict:
continue
df = data_dict[stock]
# 如果数据长度不足以计算 N 日均线,则跳过
if len(df) < ContextInfo.N:
continue
# 2. 计算指标
# 获取最近的收盘价序列
close_prices = df['close']
# 获取当前最新收盘价 (Series的最后一个值)
current_close = close_prices.iloc[-1]
# 计算 N 日移动平均线 (取最后 N 个数据求平均)
# 注意:这里计算的是包含当前K线的 MA
ma_n = close_prices.iloc[-ContextInfo.N:].mean()
# 计算 BIAS 乖离率
# 公式:(收盘价 - 均线) / 均线 * 100
bias = (current_close - ma_n) / ma_n * 100
# 打印日志方便调试 (仅在回测或实盘日志窗口显示)
# print(f"代码: {stock}, 时间: {df.index[-1]}, 收盘: {current_close:.2f}, MA{ContextInfo.N}: {ma_n:.2f}, BIAS: {bias:.2f}%")
# 3. 获取当前持仓信息
# 使用 get_position 获取该股票的持仓数量
# 注意:回测模式下 QMT 会自动维护持仓;实盘需确保账号同步
position = ContextInfo.get_position(stock, ContextInfo.account_id)
current_holdings = position.m_nVolume if position else 0
# 4. 交易逻辑判断
# --- 信号 1: 买入 (BIAS 低于下限) ---
if bias < ContextInfo.buy_threshold:
# 如果当前没有持仓,则全仓买入 (目标仓位调整为 100%)
# 这里使用 order_target_percent 方便管理仓位
if current_holdings == 0:
print(f"买入信号触发: {stock}, BIAS: {bias:.2f}% < {ContextInfo.buy_threshold}%")
order_target_percent(stock, 1.0, ContextInfo, ContextInfo.account_id)
# --- 信号 2: 卖出 (BIAS 高于上限) ---
elif bias > ContextInfo.sell_threshold:
# 如果当前有持仓,则清仓卖出 (目标仓位调整为 0%)
if current_holdings > 0:
print(f"卖出信号触发: {stock}, BIAS: {bias:.2f}% > {ContextInfo.sell_threshold}%")
order_target_percent(stock, 0.0, ContextInfo, ContextInfo.account_id)
# 辅助函数:获取持仓 (兼容回测和实盘)
def get_position(stock_code, account_id):
# QMT 的 ContextInfo.get_position 有时返回对象,有时需通过 get_trade_detail_data 获取
# 这里直接使用 ContextInfo.get_position 即可,它是 QMT 封装好的便捷方法
pass
# -*- coding: gbk -*-:
数据获取 (get_market_data_ex):
dividend_type='front'(前复权)。计算技术指标(如均线、BIAS)时,必须使用复权数据,否则股票分红除权会导致价格跳空,产生错误的 BIAS 信号。count 设置为 N + 5 是为了确保有足够的数据计算均线,防止边界数据缺失。指标计算:
pandas 的 iloc 和 mean() 函数快速计算移动平均线。交易执行 (order_target_percent):
order_target_percent(stock, 1.0, ...): 表示将该股票的仓位调整至总资产的 100%(全仓买入)。order_target_percent(stock, 0.0, ...): 表示将该股票的仓位调整至 0%(清仓卖出)。passorder 更简单,因为它会自动计算需要买卖的股数,并处理买卖方向。ContextInfo.account_id = 'YOUR_ACCOUNT_ID' 中的 'YOUR_ACCOUNT_ID' 替换为您真实的资金账号(如果是回测,保持默认或随意填写即可)。600000.SH,您可以在 init 函数中修改 ContextInfo.stock_list,或者在界面右侧的属性栏中选择运行的股票。Q: 为什么我的 BIAS 计算结果和看盘软件不一样?
A: 可能有两个原因:
front),请检查看盘软件是否也是前复权。Q: 如何修改为多只股票同时运行?
A: 代码中的 ContextInfo.stock_list 是一个列表。您可以填入多个代码,例如 ['600000.SH', '000001.SZ']。handlebar 函数中的 for stock in ContextInfo.stock_list: 循环会自动处理列表中的每一只股票。注意资金分配,如果多只股票同时触发买入,order_target_percent(stock, 1.0) 会尝试全仓买入每一只,导致资金不足,建议改为 1.0 / len(ContextInfo.stock_list)。
Q: 实盘交易需要注意什么?
A: 实盘时,handlebar 会随行情 Tick 实时刷新。为了避免信号闪烁(即盘中价格波动导致信号一会有一会无),建议在逻辑中加入 if not ContextInfo.is_last_bar(): return 来只在历史K线上回测,或者在实盘逻辑中判断当前时间是否临近收盘(如 14:55 后)再执行信号。