问题描述
解决方案
在 QMT 中,判断一只股票当前是否处于可交易状态,主要通过以下两个核心 API 来实现:
ContextInfo.is_suspended_stock(stockcode): 专门用于判断股票是否停牌。ContextInfo.get_instrumentdetail(stockcode): 获取合约的详细信息,包含是否可交易、上市状态、涨跌停价格等更全面的数据。
通常建议结合使用这两个接口,以确保交易的安全性。
核心代码实现
以下是一个完整的策略示例代码,展示了如何在 handlebar 中封装一个检查函数,在下单前判断股票状态。
# -*- coding: gbk -*-
def init(ContextInfo):
# 设置测试标的,这里以浦发银行为例
ContextInfo.stock_code = '600000.SH'
print("策略初始化完成")
def check_stock_tradable(stock_code, ContextInfo):
"""
检查股票是否处于可交易状态
返回: (bool, str) -> (是否可交易, 原因描述)
"""
# 1. 检查是否停牌
# is_suspended_stock 返回 True 表示停牌,False 表示未停牌
if ContextInfo.is_suspended_stock(stock_code):
return False, f"{stock_code} 当前处于停牌状态"
# 2. 检查合约详细状态
# get_instrumentdetail 返回一个字典,包含合约的详细属性
detail = ContextInfo.get_instrumentdetail(stock_code)
if not detail:
return False, f"无法获取 {stock_code} 的合约详情,可能代码错误或未上市"
# 检查 'IsTrading' 字段 (合约是否可交易)
# 注意:不同版本的QMT返回的可能是布尔值或数字(1/0),建议做真值判断
if not detail.get('IsTrading'):
return False, f"{stock_code} 合约详情显示当前不可交易 (IsTrading=False)"
# 3. (可选) 检查是否涨跌停
# 如果策略要求涨跌停不交易,可以在这里通过 get_full_tick 获取最新价对比 detail['UpStopPrice']
# 这里仅做状态检查,不做价格检查
return True, "状态正常"
def handlebar(ContextInfo):
# 仅在最后一根K线(实时行情或回测的当前帧)执行,避免历史数据重复打印
if not ContextInfo.is_last_bar():
return
target_stock = ContextInfo.stock_code
# 调用检查函数
is_tradable, message = check_stock_tradable(target_stock, ContextInfo)
if is_tradable:
print(f"【检查通过】: {target_stock} {message},准备执行交易逻辑...")
# 在这里写入下单逻辑,例如:
# order_shares(target_stock, 100, 'fix', 10.0, ContextInfo, 'account_id')
else:
print(f"【检查失败】: {message},跳过交易。")
代码详解
1. ContextInfo.is_suspended_stock(stockcode)
- 功能: 最基础的停牌检查。
- 返回值:
True(停牌) 或False(正常)。 - 适用场景: 快速过滤掉正在进行重大资产重组或临时停牌的股票。
2. ContextInfo.get_instrumentdetail(stockcode)
- 功能: 获取合约的静态属性数据。
- 关键字段:
IsTrading: 最关键的字段。如果为False(或 0),代表该合约当前不可交易(可能是未上市、已退市或暂停上市)。InstrumentStatus: 合约停牌状态(部分版本提供)。OpenDate: 上市日期。ExpireDate: 退市日或到期日。UpStopPrice/DownStopPrice: 当日的涨跌停价格。
常见问题 Q&A
Q: 为什么 is_suspended_stock 返回 False,但我还是无法下单?
A: is_suspended_stock 只检查“停牌”状态。如果股票已经退市,或者今天是新股申购日但还未上市交易,它可能不会被标记为“停牌”。此时需要通过 get_instrumentdetail 中的 IsTrading 字段或 OpenDate 来进一步判断。
Q: 如何判断股票是否涨停或跌停从而无法买入/卖出?
A: 涨跌停不属于“不可交易状态”(交易所仍接受委托,只是不一定成交),但策略通常需要规避。你可以通过 ContextInfo.get_full_tick(stock_code) 获取最新价 lastPrice,并与 get_instrumentdetail 返回的 UpStopPrice (涨停价) 和 DownStopPrice (跌停价) 进行比较。
Q: 回测模式下这些函数有效吗?
A: 有效。在回测模式下,QMT 会根据历史数据返回当时那个时间点的停牌状态和合约信息。