4. OFI的标准计算公式

订单流失衡(Order Flow Imbalance,OFI)的核心思想并不复杂:它试图用一个标量,刻画在某一时间步内,限价订单簿最顶层——也就是买一价、买一量、卖一价、卖一量——所发生的净变化,究竟在多大程度上偏向买方或卖方。真正让 OFI 具备可计算性、可复现性的,是它的分段定义:因为买一和卖一的价格可能上升、下降或保持不变,不同情形下“数量变化”对失衡的贡献方向并不相同,必须分情况讨论,而不能简单地把买一量变化减去卖一量变化。

本节先明确参照约定,再逐段推导单步 OFI 的数学表达式,最后用一个可手算的示例把公式跑通。

一、参照约定:先定方向,再谈正负

在整门课程中,我们统一采用如下约定,后续所有公式、图示与代码都与此保持一致:

  • 买方为正、卖方为负。OFI 为正,表示该时间步内买方力量占优;OFI 为负,表示卖方力量占优。
  • 记第 n 步的买一价为 Pbn、买一量为 Qbn;卖一价为 Pan、卖一量为 Qan。上标 b 表示 bid(买),a 表示 ask(卖)。
  • 单步变化量用差分表示:ΔPb = Pbn − Pbn−1,其余同理。
  • 数量以“手”或“股”为单位,价格以最小报价单位(tick)为参照;OFI 的量纲是“数量”,不是价格。

二、分段定义:为什么必须分情况

考虑买方一侧。如果买一价上升了,说明有新的、更激进的买单进入了最优价位,原来的买一量即使减少,也代表买方在向上推进,此时买一量的变化应整体计入买方贡献。如果买一价下降了,说明原买一档被吃掉或撤单,新的买一价更低,此时原买一量整体退出,应作为负贡献计入。如果买一价不变,则只有买一量的增减才是真实的边际变化,直接取 ΔQb。

卖方一侧完全对称,但符号相反:卖一价上升意味着卖方后退,是买方占优的信号,应计为正贡献;卖一价下降意味着卖方压价进攻,应计为负贡献;卖一价不变时,卖一量增加代表卖压增强,应计为负,即取 −ΔQa。

把两侧合并,就得到单步 OFI 的标准分段表达式:

定义买方贡献 e_b:
  若 P^b_n > P^b_{n-1}:  e_b = +Q^b_n
  若 P^b_n < P^b_{n-1}:  e_b = −Q^b_{n-1}
  若 P^b_n = P^b_{n-1}:  e_b = +(Q^b_n − Q^b_{n-1})

定义卖方贡献 e_a:
  若 P^a_n > P^a_{n-1}:  e_a = −Q^a_{n-1}
  若 P^a_n < P^a_{n-1}:  e_a = +Q^a_n
  若 P^a_n = P^a_{n-1}:  e_a = −(Q^a_n − Q^a_{n-1})

单步 OFI:
  OFI_n = e_b + e_a

注意几个容易出错的细节。第一,价格上升时买方用的是新量 Qbn,价格下降时用的是旧量 Qbn−1,这是因为“进入”的是新挂单,“退出”的是原有挂单,二者对应的数量主体不同。第二,卖方在价格上升时用旧量、下降时用新量,与买方恰好镜像。第三,价格不变的分支本质上是“同价位数量净变化”,它才是很多人直觉中的“买量减卖量”,但它只是三种情形之一,不能推广到全部。

记忆口诀:价格动,看“谁进场、谁离场”;价格不动,看“量增还是量减”。买方价格上移计新量、下移计旧量;卖方价格上移计旧量、下移计新量,且卖方整体取反号。

三、图示:四类价格变动下的贡献方向

下面的信号链式示意图把“价格变动类型 → 数量取值 → 贡献符号”这条判断路径画在一起,便于对照公式快速定位。

单步 OFI 分段判断路径 价格变动类型决定数量取值,买方为正、卖方取反 买方贡献 e_b P^b 上升(买一价上移) 取新量 Q^b_n → 贡献 +Q^b_n P^b 下降(买一价下移) 取旧量 Q^b_{n-1} → 贡献 −Q^b_{n-1} P^b 不变(同价位) 取差分 → 贡献 +(Q^b_n − Q^b_{n-1}) 合并 OFI_n = e_b + e_a 正值:买方占优 负值:卖方占优 卖方贡献 e_a(整体取反) P^a 上升(卖一价上移) 取旧量 Q^a_{n-1} → 贡献 −Q^a_{n-1} P^a 下降(卖一价下移) 取新量 Q^a_n → 贡献 +Q^a_n P^a 不变(同价位) 取差分 → 贡献 −(Q^a_n − Q^a_{n-1}) 符号直觉 卖价上移 = 卖方后退 = 买方占优 卖价下移 = 卖方进攻 = 卖方占优 卖量增加 = 卖压增强 = 负贡献 相加

四、手算示例:把公式跑一遍

假设某标的的最小报价单位为 0.01 元,我们观察连续两步的买一卖一快照(以下数据为教学示例,非实测行情):

时点买一价买一量卖一价卖一量
n−110.0050010.02400
n10.0130010.02650

先看买方:买一价由 10.00 升至 10.01,属于“价格上升”分支,取新量 Qbn = 300,贡献 e_b = +300。再看卖方:卖一价保持 10.02 不变,属于“同价位”分支,取差分 Qan − Qan−1 = 650 − 400 = 250,贡献 e_a = −250。于是:

OFI_n = e_b + e_a = 300 + (−250) = +50

结果为正,说明这一步买方力量略占上风:买一价上移带来了 300 手的正向贡献,而卖一量增加 250 手形成了 250 手的负向抵消,净失衡为 +50 手。若我们错误地采用“买一量变化减卖一量变化”的简化算法,会得到 (300−500) − (650−400) = −450,符号完全相反——这正是分段定义不可省略的原因。

五、实现要点与边界处理

把公式落到代码时,有几个工程细节值得提前约定。其一,缺失档位:若某一侧在 n−1 或 n 时刻不存在买一或卖一(例如单边行情、集合竞价前后),应将该步 OFI 记为缺失或按约定置零,而不是用 0 价格参与计算。其二,时间对齐:OFI 依赖相邻快照,必须保证快照按时间戳严格排序,同一时间戳的多条更新应先聚合再计算。其三,单位一致:买卖两侧数量单位必须相同,若一侧以手、一侧以股,需先换算。其四,累计与单步:单步 OFI 可累加为区间 OFI,但累加前要确认没有跨过缺失步,否则会引入偏差。

常见错误:把“价格不变”分支写成 Qbn − Qbn−1 却忘了卖方要取负号;或在价格变动分支里混用新旧数量。建议在实现时把 e_b、e_a 分别写成独立函数,并用本节示例做单元测试,断言结果为 +50。

至此,单步 OFI 的数学表达式已经完整:它由买方贡献与卖方贡献相加而成,每一侧又按价格上升、下降、不变三种情形分段取值,数量取“新量”还是“旧量”由价格变动方向决定,卖方整体取反号。掌握这套分段逻辑,后续无论是做多步累计、构建 OFI 时间序列,还是把它作为特征输入模型,都能保证符号与量纲的一致性。