前言
做期货程序化时,策略已经算出要开 3 手,报单却被拒或成交后才发现资金不够用,这类问题往往不是信号错了,而是下单前没把账户资金读对。我在帮同事排查时,常见情况是只看权益、没看可用,或者策略里自己算的盈亏和 get_account 返回的不一致,越跑越不敢下单。
天勤 TqSdk 里账户信息通过 api.get_account() 拿到,和 position 一样,会在 wait_update() 之后随柜台回报更新。下面用趋势策略开仓前的资金检查场景,说明该看哪些字段、怎么和持仓手数联动,并给一段可放进主循环的核对写法。代码能跑通之前,先把"钱够不够"这件事在模拟盘里养成习惯。
一、下单前为什么要单独读 account
很多教程在讲 insert_order 或 TargetPosTask 时,默认账户资金充足。实盘里保证金会随价格变动,已有持仓也会占用资金。若策略只在启动时读一次 account,盘中加仓时可能仍按旧数据判断,容易在夜盘或波动加大时踩线。
更稳妥的做法是:每次准备放大仓位前,在当根 K 线判定完成后读最新 account,并结合 get_position 看已有占用。模拟盘 TqSim、快期模拟 TqKq、实盘 TqAccount 的字段名大体一致,但具体以当前文档和模拟测试为准。
二、常见字段各自表示什么
不同期货公司回报细节会有差异,策略里应以对象实际字段为准。一般可关注:
| 关注点 | 常见字段含义(以文档为准) | 策略里典型用法 |
|---|---|---|
| 还能下多少单 | 可用资金类字段 | 开仓前判断是否够保证金 |
| 账户总体 | 权益、浮动盈亏 | 风控上限、当日回撤 |
| 占用 | 保证金占用 | 和可用对照,避免满仓 |
不要用手工公式重算一遍权益去替代 account 对象,除非你很清楚口径与柜台一致。对不上时,优先以 account 和 position 为准做风控,再查手续费和合约乘数是否读对。
三、和持仓、合约规格一起估算一手保证金
开仓前除了看 account,还要读 quote 上的合约乘数、价格,以及已有 position 占用。下面是一段示意:在发多单前粗算是否还有余量(乘数、费率以实际为准,仅演示读取顺序)。
python
from tqsdk import TqApi, TqAuth, TqSim
api = TqApi(TqSim(), auth=TqAuth("账户", "密码"))
symbol = "SHFE.rb2510"
quote = api.get_quote(symbol)
acc = api.get_account()
pos = api.get_position(symbol)
def can_open_long(volume, price):
acc = api.get_account()
mult = quote.volume_multiple
# 粗算:实际保证金以期货公司规则为准,应用保守系数
need = price * mult * volume * 0.12
available = acc.available
return available >= need
while True:
api.wait_update()
if api.is_changing(quote, "last_price"):
if can_open_long(1, quote.last_price):
# 通过资金检查后再考虑信号与下单
pass
模拟盘里可把 need 的系数调大一点做压力测试,看接近满仓时策略是否还会发单。
四、和 TargetPosTask 配合时的注意点
用 TargetPosTask 时,策略层往往只 set_target_volume,不逐笔算保证金。仍建议在大幅加仓前读 account:例如从 0 手调到 5 手、或夜盘跳空后调仓,先确认可用资金是否撑得住目标仓。
若 account 不足,柜台可能拒单或只成交一部分,此时应结合 order、position 和 account 三者一起看,不要只盯着目标仓数字。
五、模拟与实盘切换时重新核对
从 TqSim 换到 TqKq 或 TqAccount 时,资金数值量纲不同,风控阈值不能照搬。建议在切换环境的第一周,用只读方式多打印几次 account 与 position,确认字段含义没理解反。
总结
下单前资金核对,核心是每次关键调仓前读最新的 get_account,并与 position、合约乘数对照,而不是启动时读一次就不管。天勤把账户对象和行情、委托放在同一套 wait_update 更新里,养成"先资金、后信号、再下单"的顺序,能少很多莫名其妙的拒单。
建议在模拟盘故意把资金用到接近上限,看策略是否还能按预期拦截开仓;再对照快期客户端或柜台软件里的可用资金,确认字段读对。资金层稳了,信号层和 execution 层才值得继续优化。
FAQ
1)available 和 balance 搞混怎么办?
以 TqSdk 当前文档对 Account 对象的说明为准,模拟盘打印几个字段对照客户端。
2)回测里要读 account 吗?
回测也有模拟账户对象,若要模拟资金约束,应在回测里同样读取并限制开仓。
3)多账户怎么读?
每个账户对应各自的 get_account(),不要混用一个全局变量存旧值。
4)资金够但还拒单?
可能是品种权限、交易时段、开平规则等问题,要分开排查。
风险提示
本文用于期货量化技术实践讨论,不构成任何投资建议。保证金与风控规则以期货公司为准,请充分模拟测试。