大家好,我是花姐~今天想和大家聊一个很实用的话题:怎么用 miniQMT 跑一个最小可用的实盘策略。
为什么说"最小"?因为很多同学刚入门量化,想要尝试实盘,但又担心成本太高、流程太复杂。其实没那么难,我们完全可以用 miniQMT + 一个极简策略 来跑起来,低成本、低门槛,验证下自己的想法。
今天这个策略超级简单,主要就是为了让大家搞明白量化的实盘流程。
策略为:查看是否持有某只股票,如果没有就直接开仓,开仓以后如果盈利5%以上就直接卖出,就这么简单。
为了让大家更直观地理解实盘运行的过程,我整理了一张流程图。

接下来是最小可用实盘策略源码分析:
初始化交易模块
首先是实盘策略的入口函数,这里需要配置上资金帐号和QMT软件userdata_mini文件夹的实际安装目录。
python
if __name__ == '__main__':
xtdata.enable_hello = False
path = r'G:\QMT交易端\userdata_mini'
accountID = '资金帐号'
xt_trader,acc = init_account(path,accountID)
if xt_trader is None or acc is None:
print("初始化失败")
else:
print("="*20+"初始化成功"+"="*20)
stock_list = ['510300.SH'] #要交易的标的
main(stock_list=stock_list,xt_trader=xt_trader,acc=acc)
在init_account
方法中对实盘模块进行初始化,返回XtQuantTrader和StockAccount2个对象,后期交易会用到。
初始化的时候我们会配置一个回调函数,它会在不同事件发生时触发,比如订单回报、成交回报、下单失败、撤单失败等。实盘操作中,我们可以基于这些回调做很多常规操作。
python
# 创建交易回调类对象,并声明接收回调
callback = MyXtQuantTraderCallback()
xt_trader.register_callback(callback)
1.连接管理
回调函数 :on_disconnected
常规操作:
- 记录断线时间和状态,方便后续分析
- 尝试自动重连或触发告警(邮件/钉钉/微信)
- 在断线期间暂停策略下单,避免风险 💡 实盘中断线处理很重要,避免策略在异常情况下疯狂下单
python
def on_disconnected(self):
print(datetime.datetime.now(),'连接断开回调')
# 自动重连
self.trader.reconnect()
# 发通知
notify_user("交易连接断开,已尝试重连")
2.委托相关
回调函数:
on_stock_order
(委托回报)on_order_error
(委托失败)on_order_stock_async_response
(异步委托回报)
常规操作:
- 更新本地订单状态(已报、已撤、报错等)
- 失败重试逻辑(如网络异常、风控失败等)
- 打印或记录委托日志,方便事后回溯
- 异步回报可以触发策略继续执行下一步操作
python
def on_stock_order(self, order):
print(datetime.datetime.now(), '委托回调', order.order_remark)
# 更新本地订单状态
local_order_manager.update(order)
def on_order_error(self, order_error):
print(f"委托报错回调 {order_error.order_remark} {order_error.error_msg}")
# 可以触发报警或重试逻辑
3. 成交相关
回调函数 :on_stock_trade
常规操作:
- 更新本地持仓(持仓数量、成本价等)
- 更新资金账户信息(可用资金、冻结资金)
- 判断策略是否达到止盈止损条件
- 可以触发策略下一步动作(比如分批止盈或反向建仓)
python
def on_stock_trade(self, trade):
print(datetime.datetime.now(), '成交回调', trade.order_remark, f"方向 {trade.offset_flag} 价格 {trade.traded_price} 数量 {trade.traded_volume}")
# 更新持仓
portfolio.update(trade)
# 判断是否触发止盈止损
strategy.check_exit(trade)
4.撤单相关
回调函数:
on_cancel_error
(撤单失败)on_cancel_order_stock_async_response
(异步撤单回报)
常规操作:
- 撤单失败记录日志,判断是否需要人工介入
- 异步撤单回报更新本地订单状态
- 在撤单失败时触发补救措施(如再次撤单或手动处理)
5. 账户状态
回调函数 :on_account_status
常规操作:
- 定期更新本地账户状态(可用资金、持仓情况、保证金)
- 判断资金是否满足策略下单要求
- 触发资金或持仓告警
python
def on_account_status(self, status):
print(datetime.datetime.now(), sys._getframe().f_code.co_name)
account_manager.update(status)
if status.available_cash < strategy.min_cash_required:
notify_user("可用资金不足,策略暂停下单")
下载历史行情
接下来我们需要预先下载历史行情数据 ,以便在策略运行过程中直接调用。比如我们要做一个双均线策略,就必须依赖历史K线来计算均线指标,因此盘前把所需的历史数据下载好是非常关键的。具体下载什么周期的数据,可以根据策略需求来决定:如果是基于分钟级别的策略,那就需要提前把分钟级别的历史数据落地保存,这样实盘时就能直接进行计算,避免因临时获取数据而影响策略执行效率。
python
def down_data_before_open(stock_list,period='1d'):
# 运行前下载历史数据 stock_list的数量不要超过500个
print("开始下载历史行情数据")
for stock in stock_list:
xtdata.download_history_data(stock, period=period, incrementally=True)
订阅行情
历史行情下载完成后,我们就需要对当天的行情进行订阅。这里的逻辑和历史行情类似:如果需要日线,就订阅日线;如果需要分钟线,就订阅分钟线。订阅完成后,就可以通过 xtdata.get_market_data_ex
获取行情数据。值得注意的是,通过订阅获取的数据,会自动把历史行情和最新行情拼接在一起,方便我们直接使用。
python
def subscribe_data(stock_list,period='1d'):
# 订阅行情
print(f"开始订阅 {period} 行情数据")
for stock in stock_list:
xtdata.subscribe_quote(stock,period=period)
有了数据,接下来就是策略的核心部分------策略逻辑的设计与实现了。这一步决定了你的策略能否真正发挥价值,是量化交易中最关键的一环。
策略核心逻辑
今天 Demo 里的策略非常简单,主要目的是帮助大家熟悉实盘操作的流程,了解从数据获取到策略执行的整体过程。
首先,我们定义一个死循环,每隔 100 秒执行一次(具体间隔可根据实际需求调整),在循环中定时检查账户状态、更新策略,并根据策略信号触发下单操作。
python
while True:
try:
# 策略核心逻辑
except Exception as e:
print(f"运行出错了{e}")
finally:
time.sleep(100) #休眠100s
在这个最小实盘 Demo 中,我们首先需要判断当前是否是周末。理想情况下,如果交易接口能直接返回当天是否为交易日,那就更方便了。这里我们用 Python 的 weekday()
简单判断周末:
python
weekday = now.weekday()
if weekday == 5 or weekday == 6:
print("今天是周末不交易")
continue
接下来是判断要交易的标的是否有持仓,没有持仓的情况下会返回None
python
p = xt_trader.query_stock_position(acc,stock)
if p:
# 有持仓 需要判断是否盈利大于5%
else:
# 没有持仓,可以开始交易了
有持仓的话比较方便,我们通过
python
tick_data = xtdata.get_market_data_ex(stock_list=[stock],period='tick',count=1)
获取股票最新价格,然后计算下收益率满足5%就调用order_stock
卖出持有的股票即可
python
xt_trader.order_stock(acc,stock,xtconstant.STOCK_SELL,
p.can_use_volume,price_type=xtconstant.FIX_PRICE
,price=bidPrice1,
strategy_name='hj_001',order_remark='test_001')
没有持仓会复杂一些
首先要检查当前是否存在未成交的委托单。如果还有未完成的订单,就不能重复下单。这是很多新手容易忽略的地方,一不小心就可能导致实盘重复下单的风险。
python
orders = xt_trader.query_stock_orders(acc)
is_ordered=False #股票是否已经下单了但是还没有成交
for o in orders:
stock_code = o.stock_code
order_status = o.order_status
# 委托状态是已撤、废单就继续下单
if order_status in [54,57]:
pass
else:
if stock == stock_code:
is_ordered = True #已经下单了
接下来需要判断账户可用资金是否充足。如果现金不足,下单就会失败,这也是实盘操作中必须提前检查的环节。
python
# 获取可用现金
asset = xt_trader.query_stock_asset(acc)
cash = asset.cash
print(f"可用现金:{cash}")
buycash = bidPrice1*1000
if buycash>cash:
print("可用现金不足")
continue
else:
# 没有持仓,买入1000股
# 以买1价格 限价买入1000股
print(f"{stock} 买入 ,报价:{bidPrice1}, 买入数量{1000}")
order_id = xt_trader.order_stock(acc,stock,xtconstant.STOCK_BUY,1000,price_type=xtconstant.FIX_PRICE,price=bidPrice1,
strategy_name='hj_001',order_remark='test_001')
print(f"订单号为{order_id}")
至此,一个简单但完整的收盘 Demo 就完成了。整个流程就是这样,实际应用中可以根据策略需求,增加更多判断条件和操作逻辑。
完整代码在这里