撤单:先查单号再撤
这是工程记录。只演示怎么拿到委托号、怎么发撤。不写追价、不写买卖条件。不构成投资建议,不代操盘。
对照
| QMT | PTrade | |
|---|---|---|
| 查单 | get_trade_detail_data(..., 'ORDER') / get_last_order_id | get_orders() / get_order(id) |
| 撤 | cancel(orderId, accountId, accountType, C) | cancel_order(order_id 或 Order) |
| 返回 | bool,只表示「发出了撤」 | None |
| 已成 | 撤不掉,先看状态 | 同上 |
cancel 返回 True 不等于柜台已经撤完。再查一次委托状态。
QMT:未成的单才撤
python
#coding:gbk
def init(C):
C.acc = '你的资金账号'
C.acct_type = 'STOCK'
def handlebar(C):
if not C.is_last_bar():
return
orders = get_trade_detail_data(C.acc, C.acct_type, 'ORDER') or []
for o in orders:
oid = getattr(o, 'm_strOrderSysID', '') or getattr(o, 'm_strOrderID', '')
status = str(getattr(o, 'm_nOrderStatus', ''))
traded = int(getattr(o, 'm_nVolumeTraded', 0) or 0)
total = int(getattr(o, 'm_nVolumeTotalOriginal', 0) or 0)
print('order', oid, 'status', status, 'traded', traded, '/', total)
if not oid:
continue
if traded >= total and total > 0:
continue
print('cancel', oid, cancel(oid, C.acc, C.acct_type, C))账号类型要和开户一致:STOCK / CREDIT / FUTURE。填错就是 False。
PTrade:用 get_orders 取 id
python
def handle_data(context, data):
bag = get_orders() or {}
for oid, o in bag.items():
log.info('id=%s sid=%s status=%s filled=%s', oid, getattr(o, 'sid', ''),
getattr(o, 'status', ''), getattr(o, 'filled', None))
st = str(getattr(o, 'status', '')).lower()
if 'fill' in st or 'cancel' in st or 'reject' in st:
continue
cancel_order(oid)
log.info('after cancel %s', get_order(oid))只演示「查到未完成 → 撤」。要不要撤、撤哪一笔,自己对账,不要写成追价循环。
坑
- 编辑器里点运行,常常没有真实委托号,
cancel无意义。 - QMT 委托号用
m_strOrderSysID,和成交里是同一个字段。版本不同先dir(obj)。 - PTrade 回测日终会自动取消未完成单,和实盘不一样。
- 已经部成、已成、已拒的单再撤,柜台会拒,先过滤状态。
完整讨论和附件在 知识星球 Kimi量化研究所。
