【转】谈高频交易中的冰山算法

作者:董可人
链接:https://www.zhihu.com/question/23667442/answer/28965906
来源:知乎

首先我相信不少人概念里的高频交易还是这个样子的:
这里写图片描述
但对高频交易来说,这种信息是非常粗糙的。所以这里先要对不熟悉背景的同学介绍一下什么叫做Order Book。现在主流的交易所一般都使用Order Book进行交易,交易所在内部的Order Book上记录所有买家和卖家的报价,比如像这样:
这里写图片描述
Bid表示买家,Offer表示卖家,这张报价单表示买卖双方发出的所有报价单(Limit Order)。这张表才是高频交易最关心的信息。任意时刻,买家的出价总是低于卖家(比如这里的98对101)。所以报价虽然一直在变化,但是只有报价是不会有任何成交的。什么时候会产生交易呢?有两种情况,第一是任一方发出市价单(Market Order),比如一个买家发出一张单量为10的市价单,就可以买到卖方在101价格上挂的10份,这个交易成功之后,Order Book会变成这样:<img src=”https://pic1.zhimg.com/874601e9fb4147559f198cbb09cf0668_b.jpg” data-rawwidth=”387” data-rawheight=”204” class=”content_image” width=”387”>第二是发出一个价格等于对方最优报价的限价单,也会产生和上述情况相同的结果。需要强调的是,虽然真正的Order Book只存在于交易所内部,所有交易都在交易所内完成,但是交易所会把每笔报价和市价单都转发给所有人,所以所有的买家和卖家都可以自己维护一个同样的数据结构,相当于交易所Order Book的镜像。通过跟踪分析自己手里这份的镜像变化,来制定交易策略,是高频交易算法的核心思想。~~~~~~~~~~~~~~~~~~基础知识介绍完毕,下面为了方便大家理解,我采用一种更形象的方式来表示Order Book:
这里写图片描述
这张图对应文章开始时的那个Order Book,应该可以明白地看出,横轴表示价格,纵轴表示订单量,绿色表示买家,红四表示卖家。这样做的目的是为了引出本篇讨论的主题:冰山订单。通过上述基本分析大家可以看出,交易所内的交易数据是完全公开的,市场上任意时刻,有谁想要买/卖多少,所有人一目了然,没有任何秘密。这样做本身是有经济学意义的,因为只有展示出买卖的需求,才会吸引潜在的商家来交易,所以在市场上一定程度的公开自己的需求是必要的。但这样同时带来一个严重的后果,一旦有某个人想要大量买/卖,他所发出的巨额限价单会直接展示给所有人。比如一个买家挂出巨额买单后,Order Book会像这样:
这里写图片描述
这对他非常不利,因为所有人都会利用这个信息来跟他做对。大家会判断,现在市场上存在大量的买压,于是会出现一大批为了赚钱而冲进来的人抢购,价格会快速上升,这样原来这个人可以在98这个价位买到的东西,很快就变得要在更高的价位上才能买到。这种情况,那些后来的人做的就是Front running,而原来的那个人则面对逆向选择风险。为了解决这个问题,交易所提供了一种针对性的工具,就是所谓的冰山订单(Iceberg Order)。这种订单可以很大,但只有一小部分是公开出来的,大部分则隐藏起来,除了交易所和发单者本人谁也看不到,真的像一座“冰山”一样。比如像这样:
这里写图片描述
灰色的部分就是冰山订单隐藏的部分。这样,只有当有对应隐藏量的交易发生时,交易所才会通知其他人,就避免了别人利用显示订单的信息来做Front running。凡事有一利必有一弊。冰山订单虽然保护了发单者的利益,但是对于其他市场参与者来说却又变成了一种不公平的规则。那些有真实的交易需求的参与者,会因为对局势的误判而损失惨重。所以接下来的问题就变成,如何发现市场上的冰山订单?首先有一种最简单的方法。有的时候,冰山订单是挂在最优买价和卖价之间(spread),像这样:
这里写图片描述
对于这种情况,有一个非常简单的探测方法,即发一个最小额度的限价单在spread里,紧跟着取消这个订单。比如这个例子中,发出一个卖价为99的限价单然后取消。因为这个价格本身对不上显式的买价(98),如果没有冰山单的存在,一定不会成交。但有冰山单的情况下,一旦交易所收到这个卖单,会立刻成交冰山单中对应的量,而之后的取消指令就无效了。这样,以一种微小的成本,就可以发现市场中隐藏着的订单。事实上,的确有人会做这种事情,频繁的发单然后取消,在最优价差之间形成一种高频扰动,用来探测隐藏单。为了应对这种扰动探测,大家一般都不会直接挂单在spread里。而是会像之前那样和普通的限价单挂在一起,这样发生交易之后,你就很难推测消耗掉的究竟是正常的限价单,还是冰山订单。那么应该怎么做呢?首先有一个直接的思路。冰山订单的存在,一定程度上反映了挂单人对市场情况的解读,认为有必要使用冰山订单而做出的判断。需要强调的是,使用冰山订单并不是没有代价的,因为你隐藏了真实的需求,在屏蔽掉潜在的攻击者的同时,也屏蔽掉了真正的交易者!而且会使得成交时间显著增加--因为没人知道你想买/卖这么多,你只能慢慢等待对手盘的出现。所以当有人下决定发出冰山订单的时候,也会有对市场情况的考虑,只有合适的时机才会做这种选择。什么是合适的时机?有一些数据应该是相关的,比如买卖价差spread,买单量对卖单量的比值等。对这些数据,你可以在历史数据上做回归分析,建立起他们和冰山订单之间的线性/非线性模型。通过历史数据训练出来的这个模型,就可以作为你在实时交易时使用的冰山订单探测器。这是 On the Dark Side of the Market: Identifying and Analyzing Hidden Order Placements 这篇论文使用的方法。基本模型可以定义为:F(spread,bidSize/offerSize,……) = Probability(Iceberg)如果你想玩高深的,还可以在此基础上做HMM,SVM,神经网络之类的高级模型,但基本思路是一致的:通过盘口分析计算存在冰山订单的概率。
~~~~~~~~~~~~~~~~~~
上面说的这个方法,看起来很高级,实际效果如何呢?我想大家也看出来了,这种建模不是很精确。作为事后分析手段用来说明什么情况下可能会出现冰山订单还不错,但是作为实时交易的探测器就不是很放心。因为使用的信息太模糊了,而且说到底建模的对象只是一种相关性,没有什么保证冰山订单的发送者一定是按照这个逻辑出牌的。所以接下来介绍的,才是真正具有高频玩家神采的方法,来自 Prediction of Hidden Liquidity in the Limit Order Book of GLOBEX Futures 这篇论文。
~~~~~~~~~~~~~~~~~~
高频世界里,有一条永恒的建模准则值得铭记:先看数据再建模。如果你看了上面的介绍就开始天马行空的思考数学模型,那基本上是死路一条。我见过很多年轻人,特别有热情,一上来就开始做数学定义,然后推导偏微分方程,数学公式写满一摞纸,最后一接触数据才发现模型根本行不通,这是非常遗憾的。而看了数据的人会怎么样呢?他很可能会发现,对于冰山订单的处理,交易所的规则是非常值得寻味的。有的交易所是这样做的:一个冰山订单包含两个参数,V表示订单总量,p表示公开显示的量。比如V=100,p=10的冰山单,实际上隐藏的量是90。如果有针对这个订单的交易发生,比如交易量10,交易所会顺序发出三条信息:成交10Order Book的Top bid size -10新Bid +10这三条信息一定会连续出现,并且第三条和第一条的时差dt很小。这样做的原因是尽管冰山订单存在隐藏量,但是每次的交易只能对显示出的量(p)发生,p被消耗掉以后,才会从剩余的隐藏量中翻新出一分新的p量。这样,每个人从交易所收到的信息仍然可以在逻辑上正确的更新Order Book,就好像冰山订单并不存在一样。因此,一旦在数据中观察到这个规律,我们就可以非常有把握的判定市场中存在冰山订单,并且连p的值都可以确定!接下来的关键问题是,如何确定V的值,即判断这个冰山订单的剩余存量有多少?这个问题从本质上说没法精确求解,因为V和p都是由下单人自己决定的,可以是任意值。但可以从两点考虑:第一,两个值都是整数;第二,人类不是完美的随机数生成器,下决定会遵循一定规律。从这两点出发,可以对V和p建立概率模型,即计算一个给定的(V,p)值组合出现的概率是多少?这里不去深入探讨数学分析,感兴趣的朋友可以自己去看原文。简单说,可以在历史数据上通过kernel estimation技术来估算他们的概率密度函数的形状。顺带一提,如果你亲手编写过这种估算程序,就会理解我为什么在“要想成为一名优秀的 Quant 需要什么样的编程水平?”这个答案中如此强调编程的重要性。在数据上估算出来的概率密度函数可能会是这样的:
这里写图片描述
这样,当你在实时数据中观测到一个p的值时,就可以得出对应的V值的条件概率密度函数,即上图的一个切面,比如(p = 8):
这里写图片描述
接下来显然就很容易计算V最可能是什么值了。这条函数曲线还有一个重要的作用是帮助你动态评估剩余存量,比如当你观察到已经有5份p被消耗掉,即可推出V>=40,由上图即可推出新的V值和剩余存量(V-5p)。综上,算法的核心在于,通过在实时数据中监测短时间内连续出现的三条相关记录判断冰山订单的存在,而对冰山订单的量化则通过由历史数据训练出的概率模型来完成。相信你也会看出,这种算法并不是什么作弊神器。它只是利用市场上的公开数据所做的一种推测。而且这个推测也仅仅是基于概率的,更多的应该是作为一种参考。它对做市商这种流动性提供者很有意义,可以使他们避免因为对局势的误判而遭受损失。但如果你想用它来作为一种攻击手段,觉得自己能发现隐藏大单而去Front run,那实在是很不明智的选择。最后,这种算法也只是针对特定的交易所。其他的交易所也许不会采用同样的冰山订单处理方式。所以真正有价值的是这种从实际数据出发的建模思路,具体的算法并不值钱。

<think>好的,我现在需要帮助用户了解如何实现股指期货的高频交易策略,并提供代码示例和算法。首先,我得回顾用户提供的引用内容,看看有没有相关的信息可以整合进去。 用户提到了引用[2]和[3],其中引用[2]讨论了股指期货的规则类量价策略,包括趋势、回归、突破、形态等策略类型,以及技术指标和风险管理。而引用[3]则涉及高频数据处理和预测模型,比如CEEMDAN-SSA-LSTM。这些信息可能对构建策略有帮助。 用户的需求是高频交易策略的实现方式、代码示例和算法高频交易通常涉及快速执行、低延迟,所以可能需要考虑算法效率。常见的策略有做市、套利、动量等。但用户可能更关注具体的策略模型,比如基于量价关系的规则或者机器学习模型。 首先,我需要确定一个适合示例的策略。由于高频交易策略的实现可能比较复杂,选择一个相对简单的动量策略作为示例可能比较合适。动量策略可以利用短期价格变动来预测趋势,适合高频环境。 接下来,代码部分需要用Python,可能使用pandas处理数据,numpy进行计算,以及一些回测库如backtrader。不过用户可能需要一个简化的示例,不需要完整的回测框架,而是核心逻辑。 然后,算法部分需要解释动量策略的原理,比如计算短期和长期移动平均线的交叉,或者计算收益率的变化率。同时,结合引用[2]中的量价指标,比如成交量加权价格(VWAP)或订单簿数据,但考虑到高频数据可能难以获取,示例中可能使用分时数据。 数据处理方面,引用[3]提到高频数据噪声大,可能需要降噪处理。例如,使用滑动平均或卡尔曼滤波,但代码示例中可以简单展示数据预处理步骤,比如去噪和特征计算。 风险管理和订单执行也是高频交易的关键,但示例代码可能简化这部分,主要展示信号生成。 现在,整理步骤: 1. 数据预处理:加载数据,计算收益率、移动平均线。 2. 生成交易信号:比如当短期均线上穿长期均线时买入,下穿时卖出。 3. 策略执行:模拟交易,计算持仓。 4. 可视化结果。 需要确保代码示例简洁,并注释清楚。同时,算法部分要解释清楚,并提到可能的优化和扩展,如引用中的CEEMDAN降噪和LSTM预测。 最后,生成相关问题,覆盖策略优化、风险管理、数据处理和模型应用等方面。</think>### 股指期货高频交易策略实现方法 高频交易策略通常基于量价关系、订单流分析或统计套利。以下是基于**动量效应**的简化实现示例,结合分时数据特征提取和信号生成。 #### 核心算法逻辑 1. **数据预处理** - 使用滑动窗口法降噪(参考引用[3]的CEEMDAN降噪思想) - 计算短期(1分钟)和长期(5分钟)收益率 $$r_t = \frac{p_t - p_{t-1}}{p_{t-1}}$$ 2. **信号生成规则**(参考引用[2]的趋势策略) - 当短期均线突破长期均线时做多 - 当短期均线下穿长期均线时平仓 #### Python代码示例 ```python import pandas as pd import numpy as np import matplotlib.pyplot as plt # 模拟数据生成(假设已获取1分钟K线数据) dates = pd.date_range('2024-01-01', periods=1440, freq='T') prices = np.cumprod(1 + np.random.normal(0, 0.0005, 1440)) # 几何布朗运动 df = pd.DataFrame({'close': prices}, index=dates) # 特征计算 df['ma5'] = df.close.rolling(5).mean() # 5分钟均线 df['ma15'] = df.close.rolling(15).mean() # 15分钟均线 df['returns'] = df.close.pct_change() # 信号生成 df['signal'] = 0 df.loc[df['ma5'] > df['ma15'], 'signal'] = 1 # 做多信号 df.loc[df['ma5'] < df['ma15'], 'signal'] = -1 # 平仓信号 # 持仓模拟 df['position'] = df.signal.shift(1) # 延迟一周期交易 # 收益计算 df['strategy_returns'] = df['position'] * df['returns'] cum_returns = (1 + df.strategy_returns).cumprod() # 可视化 plt.figure(figsize=(12,6)) cum_returns.plot(label='策略收益') df.close.plot(secondary_y=True, label='价格') plt.legend() plt.show() ``` #### 优化方向 1. **特征工程** - 加入成交量加权指标(参考引用[2]的量价关系) - 引入订单簿不平衡度特征 2. **执行优化** ```python # 示例:冰山订单拆分执行 def iceberg_order(total_qty, display_qty): return [display_qty]*(total_qty//display_qty) + [total_qty%display_qty] ``` 3. **风险管理** - 设置每日最大回撤阈值(如2%) - 实现动态止盈止损: $$stop_loss = \mu - 3\sigma,\quad take_profit = \mu + 2\sigma$$ #### 高频策略关键要素 1. 延迟优化:使用UDP协议传输订单 2. 内存计算:使用polars替代pandas提升速度 3. 并行处理:采用Dask框架进行分布式计算
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值