3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
在 QMT 平台进行实盘或模拟交易时,如果下单价格(如限价单价格)不符合该品种的最小变价单位(PriceTick),柜台系统会直接拒绝该笔委托,产生废单。例如,某股票的最小变价单位是 0.01 元,若算法计算出的下单价为 10.005 元,直接报单就会导致废单。
为了提高策略的鲁棒性,我们需要在下单前通过 QMT API 动态获取目标品种的 PriceTick,并对计算出的理论价格进行合规舍入。
QMT 提供了 ContextInfo.get_instrumentdetail(stockcode) 接口,可以获取指定合约的详细信息,其中就包含了 PriceTick(最小变价单位)。
detail = ContextInfo.get_instrumentdetail(stockcode)
price_tick = detail['PriceTick'] # 获取最小变价单位
我们可以编写一个通用的辅助函数,将任意计算出来的理论价格,舍入到最接近的 PriceTick 整数倍上,并处理 Python 浮点数精度问题。
PriceTick,并进行四舍五入取整。PriceTick。PriceTick 的小数位数,对最终结果进行精确保留。以下是一个完整的 QMT 策略模板,展示了如何在 handlebar 中获取 PriceTick 并对下单价格进行合规舍入后安全下单:
#coding:gbk
import math
def init(ContextInfo):
# 设定交易账号
ContextInfo.accid = '6000000248'
ContextInfo.set_account(ContextInfo.accid)
# 设定股票池
ContextInfo.set_universe(['600000.SH', '000001.SZ'])
def round_price_by_tick(ContextInfo, stock_code, target_price):
"""
根据合约的 PriceTick 对目标价格进行合规舍入
"""
# 获取合约详情
detail = ContextInfo.get_instrumentdetail(stock_code)
if not detail or 'PriceTick' not in detail:
return target_price # 若获取失败,返回原价格
price_tick = detail['PriceTick']
if price_tick <= 0:
return target_price
# 1. 舍入到最接近的 PriceTick 倍数
rounded_price = round(target_price / price_tick) * price_tick
# 2. 动态获取 PriceTick 的小数位数,消除 Python 浮点数精度误差
tick_str = str(price_tick)
if '.' in tick_str:
decimals = len(tick_str.split('.')[1])
else:
decimals = 0
return round(rounded_price, decimals)
def handlebar(ContextInfo):
# 仅在最后一根 K 线执行下单逻辑
if not ContextInfo.is_last_bar():
return
stock = '600000.SH' # 浦发银行
# 假设策略通过某种算法(如均线、指标)计算出一个理论买入价
# 例如:当前最新价的 0.98 倍作为限价单买入价
full_tick = ContextInfo.get_full_tick([stock])
if stock in full_tick:
last_price = full_tick[stock]['lastPrice']
raw_target_price = last_price * 0.98
# 进行 PriceTick 自动舍入
safe_price = round_price_by_tick(ContextInfo, stock, raw_target_price)
print(f"[交易优化] 原始计算价: {raw_target_price:.4f} | 舍入后合规价: {safe_price} | 最小变价单位: {ContextInfo.get_instrumentdetail(stock)['PriceTick']}")
# 使用合规价格安全下单,避免废单
passorder(23, 1101, ContextInfo.accid, stock, 11, safe_price, 100, 'PriceTick优化策略', 1, 'remark', ContextInfo)
PriceTick 差异巨大。例如 A 股股票通常是 0.01,科创板/创业板也是 0.01,但某些债券、ETF 或期权(如 0.0001)的变价单位各不相同。使用 get_instrumentdetail 可以动态适配所有品种。ContextInfo.get_option_detail_data(optioncode) 获取 PriceTick 进行相同的舍入处理。0.1 + 0.2 不等于 0.3。直接使用 round(price / tick) * tick 可能会产生类似 10.010000000000002 的浮点数,因此必须配合 round(rounded_price, decimals) 限制小数位数,确保报单价格绝对合规。