3 分钟快速生成代码
输入想法,AI 即刻生成可运行代码
这是一个基于 QMT Python API 编写的自动申购新股和新债的策略脚本。
get_ipo_data() 函数分别获取当天的新股(STOCK)和新债(BOND)信息。get_new_purchase_limit() 获取当前账户的新股申购额度(市值配售额度)。passorder 函数进行委托。请将以下代码复制到 QMT 的策略编辑器中。
# -*- coding: gbk -*-
import time
def init(ContextInfo):
# ================= 配置区域 =================
# 请在此处填写您的资金账号
ContextInfo.acc_id = 'YOUR_ACCOUNT_ID'
# 账号类型:'STOCK' (股票), 'CREDIT' (信用)
ContextInfo.acc_type = 'STOCK'
# ===========================================
# 设置账号
ContextInfo.set_account(ContextInfo.acc_id)
# 定义全局变量,用于控制当天是否已经申购过
ContextInfo.has_ordered = False
print("策略初始化完成,等待行情驱动...")
def handlebar(ContextInfo):
# 1. 仅在最后一根K线(实时行情)运行,跳过历史回测阶段
if not ContextInfo.is_last_bar():
return
# 2. 控制每天只运行一次
# 如果需要盘中多次尝试(防止早上未开盘失败),可以结合时间判断,例如每隔1小时尝试一次
if ContextInfo.has_ordered:
return
# 3. 检查交易时间 (通常申购时间为 9:30 - 15:00)
current_time = time.strftime("%H%M%S", time.localtime())
if not ("093000" <= current_time <= "150000"):
# 非交易时间不执行,但也不置为True,以便交易时间到了再执行
return
print(f"开始执行自动申购任务,当前时间: {current_time}")
# 执行申购逻辑
subscribe_ipo_stocks(ContextInfo)
subscribe_convertible_bonds(ContextInfo)
# 标记为已执行
ContextInfo.has_ordered = True
print("当日申购任务执行完毕。")
def subscribe_ipo_stocks(ContextInfo):
"""
申购新股逻辑
"""
try:
# 获取当日新股信息
ipo_stocks = get_ipo_data("STOCK")
if not ipo_stocks:
print("今日无新股可申购。")
return
# 获取账户申购额度
# 返回格式示例: {'上海主板': 10000, '深圳市场': 5000, ...}
limits = get_new_purchase_limit(ContextInfo.acc_id)
print(f"当前账户新股额度: {limits}")
for code, info in ipo_stocks.items():
name = info.get('name', code)
price = info.get('price', 0.0)
# 证券最大申购数量
max_purchase_num = info.get('maxPurchaseNum', 0)
# 简单的额度匹配逻辑 (注意:实际市场分类可能需要更复杂的映射)
# 这里采用尝试顶格申购策略,如果额度不足,柜台通常会自动废单或按最大额度成交
# 但为了严谨,建议取 min(额度, 上限)
# 确定申购数量:这里默认尝试按新股允许的上限申购
# 实际交易中,如果超过账户额度,passorder 可能会报错或由柜台拒单
volume = max_purchase_num
print(f"正在申购新股: {code} ({name}), 价格: {price}, 数量: {volume}")
# 下单
# opType=23 (买入/申购), orderType=1101 (单股单账号普通股数下单)
# prType=11 (指定价/模型价), price=发行价
passorder(23, 1101, ContextInfo.acc_id, code, 11, price, volume, ContextInfo)
except Exception as e:
print(f"申购新股时发生错误: {e}")
def subscribe_convertible_bonds(ContextInfo):
"""
申购新债逻辑
"""
try:
# 获取当日新债信息
ipo_bonds = get_ipo_data("BOND")
if not ipo_bonds:
print("今日无新债可申购。")
return
for code, info in ipo_bonds.items():
name = info.get('name', code)
price = info.get('price', 100.0) # 可转债一般面值100
# 可转债通常顶格申购为 10000 张 (1000手) 或者 1000000 元
# maxPurchaseNum 单位通常是“张”或“手”,需根据券商接口实际返回确认
# 大部分情况 QMT 返回的是数量,建议直接使用返回的 maxPurchaseNum
volume = info.get('maxPurchaseNum', 10000)
print(f"正在申购新债: {code} ({name}), 价格: {price}, 数量: {volume}")
# 下单
passorder(23, 1101, ContextInfo.acc_id, code, 11, price, volume, ContextInfo)
except Exception as e:
print(f"申购新债时发生错误: {e}")
# -*- coding: gbk -*-:
get_ipo_data(type):
type="STOCK" 返回新股数据。type="BOND" 返回新债(可转债)数据。price)、最大申购数量 (maxPurchaseNum) 等信息。get_new_purchase_limit(accid):
maxPurchaseNum(新股本身的申购上限)进行委托。passorder 函数:
opType=23:代表股票买入(申购新股/债在 QMT 中通常视为买入操作)。orderType=1101:代表单账号、按股数/张数下单。prType=11:代表指定价格(即发行价)。防重复机制:
ContextInfo.has_ordered 变量。脚本在 handlebar 中每根 K 线(或 Tick)都会被触发,因此必须加锁,确保每天只执行一次申购操作。ContextInfo.acc_id = 'YOUR_ACCOUNT_ID' 修改为您实际的资金账号。Q: 这个脚本需要一直开着吗?
A: 是的,需要在交易时间段内保持 QMT 软件和策略运行。策略会在检测到是交易时间且尚未申购时自动下单。
Q: 为什么申购数量直接用了 maxPurchaseNum?
A: 新股申购通常建议“顶格申购”。如果您的市值额度不足以支撑顶格申购,交易柜台会根据您的实际额度自动调整或废单。如果希望代码严格计算额度,需要解析 get_new_purchase_limit 返回的中文 Key(如"上海主板")并映射到具体的股票代码后缀(如 .SH),逻辑会相对复杂,上述脚本采用的是最通用的“尝试顶格”策略。
Q: 怎么确认申购成功了?
A: 脚本运行后,请查看 QMT 下方的【交易】->【委托】面板。如果看到新股/新债的委托记录,且状态为“已报”或“已成”(申购通常显示已报,晚上清算后才确认配号),即表示成功。
Q: 报错 name 'passorder' is not defined 怎么办?
A: 请确保您是在 QMT 的实盘或模拟交易模式下运行,并且账号已正确登录。回测模式下部分交易函数可能表现不同或无效。