期货自选表刷新以后,行顺序可能换了,手头的旧档也未必覆盖今天要核的每张合约。按行号比,容易把两张不同合约的步距和乘数放在一起。按完整代码对齐,才能回答:同一张合约的两份规格记录,有哪一项不同?
表换了顺序,不等于合约规格变了
假设本次请求 A、B、C 三张合约;拿到的新表按 B、A、C 排列,而本地保存的旧表只有 A、B。A、B、C 都代指带交易所前缀的完整代码。
| 合约 | 本地旧记录:步距/乘数 | 本次记录:步距/乘数 | 核对结果 |
|---|---|---|---|
| A | 1/10 | 1/10 | 两项一致,只是表里位置换了 |
| B | 2/5 | 2/20 | 步距一致,乘数的两次记录不同,待复核 |
| C | 本地没有旧行 | 1/10 | 可保存当前值,缺旧值,不能判断是否变化 |
B 值得回查的是乘数,不必把两项都打成异常。C 是自己留存的旧档不全,不是本次查询把 C 漏掉,更不是旧值等于 0。如果是你有意把某张合约移出自选,就另记"观察范围变了",不把它算成规格变动。
当前查不到有效值,不等于少回一张合约
TqSdk 的 query_symbol_info(symbol) 可以接收一批已知的完整合约代码。以 3.10.4 的同步用法为例,结果表按请求代码建行,再按代码填字段。某个字段还没有可用值时,即使对应的合约行在表里,也不能拿默认值、空值或无效数字做比较。若调用超时或抛出异常,这是整次查询没有得到可用新表,不能把上次的表当成这次的结果。如果拿到的表反而少了本次请求的代码,或同一代码重复,先把它当作待核的数据异常,不当成正常成功。
返回表的 instrument_id 是完整合约代码,ins_class 是合约类型,price_tick 是价格变动单位,volume_multiple 是合约乘数。这份规格表不会随行情继续跳动,适合和上次保存的表比较。
下面的片段接在已有的同步 api 中。 symbols 是本次要核的非空、不重复的完整期货代码列表;old_specs 是本地旧表,两张表的规格数值按原记录精度比较。另留两次采集时间,日后才知道差异来自哪两次观察。
python
from math import isfinite
fields = ["price_tick", "volume_multiple"]
try:
new_specs = api.query_symbol_info(symbols)
except Exception as error:
# 整次失败,保留原快照;本次不出差异结果。
print("本次查询未完成", type(error).__name__)
else:
keys = new_specs["instrument_id"].tolist()
if len(keys) != len(symbols) or set(keys) != set(symbols):
print("当前结果的合约行缺失、重复或不在请求内,待核")
else:
for symbol in symbols:
old = old_specs.loc[old_specs["instrument_id"] == symbol]
new = new_specs.loc[new_specs["instrument_id"] == symbol]
if len(old) != 1:
print(symbol, "本地旧行缺失" if old.empty else "本地旧行重复")
continue
if not (old["ins_class"].eq("FUTURE").fillna(False).all()
and new["ins_class"].eq("FUTURE").fillna(False).all()):
print(symbol, "期货合约类型待核")
continue
before = [old[name].iloc[0] for name in fields]
after = [new[name].iloc[0] for name in fields]
if (old[fields].isna().any().any() or new[fields].isna().any().any()
or not all(isfinite(v) and v > 0 for v in before + after)):
print(symbol, "规格值不可比较,待核")
continue
changes = [(name, a, b) for name, a, b in zip(fields, before, after) if a != b]
print(symbol, "有差异,待确认" if changes else "两项一致", changes)
发现数值不同,先留下原表和查询时间。两次记录不同,不足以说明交易所在哪一刻改了规则,更不应据此直接改掉报单参数。
让需要回查的合约自己浮出来
我推荐用 TqSdk 的批量合约信息查询做这类自选表核对。它让步距和乘数都能按同一个完整代码回查,不用靠表格位置碰运气。像上面的 B,只回查乘数;像 C,保留本次值并补核旧档;如果整次查询失败,就先不报任何规格变化。