🚀 AI 一键生成 qmt 策略代码
立即体验
👉 AI 生成代码 👈

QMT策略交易:批量预埋单DBF文件写入指南与替代方案

qmt | 发布时间: 2026/6/2
以下内容由 EasyQuant 生成。

问题描述

请教大神,策略交易=》批量预埋单的问题

请教一下大神,这个功能对应的这俩 DBF 怎么写入啊?死活写不进去。

解决方案

在QMT(迅投极速量化交易平台)中,UI界面的“批量预埋单”功能有时会要求使用特定的DBF(dBase)格式文件。很多开发者在尝试用Python写入DBF时会遇到“死活写不进去”的问题。这通常是因为DBF是一种非常古老的数据库格式,对字段类型、长度和编码(通常要求GBK)有极其严格的限制。

以下是解决该问题的详细指南以及更推荐的替代方案:

方案一:使用 Python 第三方库正确写入 DBF

Python 标准库不支持直接写入 DBF 文件,你需要安装第三方库,例如 dbf。根据 QMT API 文档,你可以通过命令行将第三方库安装到 QMT 的目录下:

# 在 cmd 中执行,注意替换为你的实际路径
C:\Python36\Scripts\pip.exe install dbf --target=D:\QMT\bin.x64\Lib\site-packages

安装完成后,在 Python 脚本中严格按照 QMT 模板的字段定义来写入:

import dbf

# 假设 QMT 要求的预埋单 DBF 字段为:证券代码(C,6), 买卖方向(C,1), 价格(N,8,2), 数量(N,10,0)
# 注意:具体字段名和长度请务必参考 QMT 客户端内提供的模板!
table = dbf.Table(
    filename='pre_orders.dbf',
    field_specs='ZQDM C(6); MMFX C(1); JG N(8,2); SL N(10,0)',
    codepage='cp936' # 必须使用 GBK/cp936 编码,否则 QMT 无法识别中文
)

table.open(mode=dbf.READ_WRITE)
# 写入数据
table.append(('600000', 'B', 10.50, 1000))
table.append(('000001', 'S', 15.20, 2000))
table.close()
print("DBF 文件写入成功!")

常见写入失败原因排查:

  1. 编码错误:QMT 客户端通常只认 GBK(cp936)编码,如果用 UTF-8 写入会导致乱码或读取失败。
  2. 字段长度超限:DBF 对字符串(C)和数字(N)的长度是固定的,写入的数据如果超过定义的长度会直接报错。
  3. 文件被占用:如果 QMT 客户端正在读取该文件,Python 写入时会报权限错误。

方案二:使用 QMT 原生 API 替代(强烈推荐)

如果你是为了在量化策略中实现“批量下单”或“一篮子下单”,完全不需要死磕 DBF 文件。QMT 的 Python API 提供了非常完善的 CSV/TXT 读取和批量下单接口,这比操作 DBF 稳定且简单得多。

1. 准备 CSV 或 TXT 文件

你可以用任何方式(如 pandas)生成一个简单的 CSV 文件 list.csv,格式如下:
600000.SH,100,000001.SZ,200,
(注意:根据 QMT API 文档,成对存在,前面是合约代码,后面是数量,最后一个字段后需要增加分隔符)

2. 在策略中使用 load_stk_vol_list 读取并下单

#coding:gbk
def init(ContextInfo):
    ContextInfo.set_account('你的资金账号')

def handlebar(ContextInfo):
    # 1. 读取一篮子证券编码及数量数据
    # 返回格式类似字符串,需要自行解析或直接用于组合下单
    basket_data = ContextInfo.load_stk_vol_list('D:/data/', 'list.csv')
    
    # 2. 解析并批量下单 (示例解析逻辑)
    if basket_data:
        items = basket_data.split(',')
        for i in range(0, len(items)-1, 2):
            stock_code = items[i]
            volume = int(items[i+1])
            if volume > 0:
                # 使用 passorder 进行买入下单,23代表股票买入,1101代表单股普通股/手方式
                passorder(23, 1101, ContextInfo.accID, stock_code, 5, -1, volume, ContextInfo)
                print(f"已发送委托: {stock_code}, 数量: {volume}")

总结
如果必须走 UI 的批量预埋单,请使用 dbf 库并严格指定 cp936 编码和字段长度;如果是为了策略自动化,建议直接使用 ContextInfo.load_stk_vol_list 配合 CSV 文件,或者直接在 Python 代码中用 pandas 读取数据后循环调用 passorder,效率更高且不易出错。