avellaneda_market_making¶
📁 策略信息¶
- 文件夹: /hummingbot/strategy/avellaneda_market_making
- 配置文件: avellaneda_market_making_config_map_pydantic.py
- 维护者:无
📝 概述¶
该策略实现了由 Marco Avellaneda 和 Sasha Stoikov 在经典论文《High-frequency Trading in a Limit Order Book》中描述的做市策略。它允许用户直接调整论文中所述的 risk_factor(gamma)参数。此外,该策略还内置了一个订单簿流动性估算器,可自动计算交易强度参数(alpha 和 kappa)。同时,该策略还实现了订单规模调整算法及其 order_amount_shape_factor(eta)参数,如《Optimal High-Frequency Market Making》中所述。该策略可配置为在固定时间框架内运行,或无限期持续运行。
🏦 支持的交易所¶
- SPOT CLOB CEX
🛠️ 策略配置¶
| 参数 | 类型 | 默认值 | 提示 | 
|---|---|---|---|
| exchange | 字符串 | 请输入你的做市现货连接器 | |
| market | 字符串 | 请输入您希望在 exchange上交易的代币交易对 | |
| execution_timeframe | 字符串 | 选择执行时间框架( infinite/from_date_to_date/daily_between_times) | |
| start_time | 字符串 | 请输入开始日期和时间(YYYY-MM-DD HH:MM:SS),或仅输入开始时间(HH:MM:SS) | |
| end_time | 字符串 | 请输入结束日期和时间(YYYY-MM-DD HH:MM:SS),或仅输入结束时间(HH:MM:SS) | |
| order_amount | 小数 | 每笔订单的 base_asset数量是多少? | |
| order_optimization_enabled | 布尔值 | 是 | 是否启用最佳买卖盘跳跃? | 
| risk_factor | 小数 | 自动计算 | 请输入风险因子 (𝛾) | 
| order_amount_shape_factor | 小数 | 自动计算 | 请输入订单规模形状因子 (η) | 
| min_spread | 0 | 请输入最小价差限制(以中间价的百分比表示) | |
| order_refresh_time | 小数 | 你希望多久取消并替换一次买盘和卖盘订单(单位:秒)? | |
| max_order_age | 小数 | 1800 | 您希望以相同价格取消并替换买卖订单的间隔时间是多久(秒)? | 
| order_refresh_tolerance_pct | 小数 | 0 | 请输入每个周期中,价格变动多少百分比时才刷新订单? | 
| filled_order_delay | 小数 | 60 | 若您的订单被成交,您希望等待多久再放置下一个订单?(单位:秒) | 
| inventory_target_base_pct | 小数 | 50 | 基础资产的库存目标是多少? | 
| add_transaction_costs | 小数 | False | 是否希望自动将交易费用添加到订单价格中?(是/否) | 
| volatility_buffer_size | 小数 | 200 | 请输入用于计算波动率所存储的行情数据点数量 | 
| trading_intensity_buffer_size | 小数 | 200 | 请输入用于估算订单簿流动性的行情数据点存储数量? | 
| order_level_mode | 整数 | 1 | 您希望在买卖双方各放置多少个订单? | 
| level_distances | 小数 | 0 | 单侧订单应相对于最优价差间隔多少百分比? | 
| order_override | json | ||
| hanging_orders_mode | 布尔值 | False | 您希望如何处理挂单?(track_hanging_orders / ignore_hanging_orders) | 
| should_wait_order_cancel_confirmation | 布尔值 | 是 | 策略是否应在创建新订单前等待订单取消确认?(不等待需要足够的可用余额)(是/否) | 
📓 描述¶
仅为近似值
以下描述是对该策略的一般性近似说明。请查阅上方交易逻辑中的策略代码,以准确理解其工作原理。
概述¶
该策略会持续根据以下信息计算做市商买卖限价单的最优挂单位置:
- 当前订单簿流动性
- 资产价格波动率
- 期望的投资组合配置(目标库存)
- 交易时段时间框架
- 风险因子(用户选择)
模型基于上述因素计算出两个主要数值:
- 保留价格:一个不同于市场中间价的价格,用作挂单的参考基准。
- 最优价差:从保留价格出发,订单应创建的最佳价差范围。
与前一版本相比,以下参数已被移除:
- parameters_based_on_spread
- max_spread
- vol_to_spread_multiplier
- volatility_sensibility
- inventory_risk_aversion
- order_book_depth_factor
- closing_time
参数 min_spread 的含义已改变,参数 risk_factor 在计算中的使用方式也不同,因此其取值范围也随之变化。
保留价格¶
当前库存与目标资产配置(由 inventory_target_base_pct 参数定义)的偏差越大,保留价格与市场中间价之间的差距就越大。该策略会根据当前库存与 inventory_target_base_pct 的差异,调整买入或卖出订单成交的概率。
例如,若策略需要卖出资产以达到 inventory_target_base_pct 值,则卖出订单将比买入订单更靠近中间价。
最优价差¶
最优价差值(决定每个订单的挂单价格)是 订单簿流动性、资产价格波动率 和 交易时段时间范围 的函数。每个因素都会影响计算出的值:
- 订单簿流动性低 = 更小的最优价差值
- 价格波动率低 = 更小的最优价差值
- 交易时段接近结束 = 更小的最优价差值
风险因子¶
影响 保留价格 和 最优价差 值的最后一个重要参数是 risk_factor(即 gamma)。
该值由用户设定,代表其愿意承担的库存风险程度。
当 risk_factor 越接近 零,订单的分布将越对称,保留价格 也将非常接近市场中间价。
此时,用户承担了更多的库存风险,因为订单位置不会偏向于向 inventory_target_base_pct 靠拢。
该值越高,策略为达成 inventory_target_base_pct 而采取的激进程度就越高,保留价格 与市场中间价之间的差距也会越大。
这是一个无量纲参数,可根据用户愿意承担的库存风险,设置为任意非零值。
注意:
risk_factor是相对于资产以绝对价格表示的瞬时波动率定义的。对于所有资产,risk_factor的合理取值范围大致相同,但可能存在少数例外情况,即该参数需显著不同才能对 保留价格 和 最优价差 产生影响。例如,对于资产 A,risk_factor = 1可能已产生明显效果;而对于资产 B,则需至少达到约 10 才能产生明显影响。确定risk_factor的唯一方法是通过实验不同数值,观察其对 保留价格 和 最优价差 的影响。根据我们的经验,该参数的常用值介于 1 到 20 之间,但其上限无限制,必要时其值甚至可设为 100 或 1000,尽管这种情况并不常见。
在合适的市场条件和恰当的 risk_factor 下,最优价差可能大于资产的绝对价格,或保留价格可能远偏离中间价,这两种情况均可能导致最优买价低于或等于零。若发生这种情况,将不会挂出任何买入或卖出订单。为防止此类情况,用户可将 risk_factor 设置为较低的值。
在设置 risk_factor 时,重要的是观察其相对于中间价的保留价格。如果用户希望这两个价格之间的价差更大,则应将风险因子设置为更高的值。保留价格离中间价越远,策略在追求目标投资组合配置时就越激进,因为一侧的订单被成交的可能性将远高于另一侧。
ETA(订单规模调整)¶
如果用户选择设置 eta 参数,订单规模将被调整,以进一步优化策略在当前和目标投资组合配置方面的表现。
当 eta = 1 时,买入和卖出订单的规模将相同。使用其他值将产生不对称的订单规模,目的是更快达到 inventory_target_pct。
订单层级¶
用户可以选择在买卖双方都设置多层订单。若选择的 order_levels 值大于 1,则将在买卖双方创建多个限价订单,各层级价格间距预先设定,且最接近保留价格的层级将被设为最优买卖价。层级间的价差以策略计算出的最优价差的百分比表示,该百分比由 level_distances 参数定义。由于最优价差通常较窄,level_distances 的值一般应为几十或几百个百分点。
交易逻辑流程¶
| 步骤 | 含义 | 
|---|---|
| 缓冲区是否已填满? | 即时波动率指标和交易强度指标的缓冲区是否已填满? | 
| 特征是否已估算? | 订单簿流动性/交易强度参数的估算是否可用? | 
| 是否为无限时间范围? | 交易时段是否设置为 infinite,或受限于from_date_to_date或daily_between_times? | 
| 是否定义了多个层级? | order_levels的值是否大于 1? | 
| 是否定义了最小价差? | min_spread的值是否大于 0? | 
时间范围¶
原始的 Avellaneda-Stoikov 模型专为股票市场的做市设计,股票市场有明确的交易时段。其假设是做市商希望在交易日结束时持有与开始时相同的库存。
由于加密货币市场全天候开放,不存在“收盘时间”,因此该策略也应能基于无限时间范围持续运行。
注意:Avellaneda-Stoikov 也考虑了在无限时间范围下运行模型的可能性。
该策略支持三种可能的时间范围:
- infinite—— 不考虑交易时段的结束时间
- from_date_to_date—— 策略将在- start_time(YYYY-MM-DD HH:MM:SS)开始交易,并在- end_time(YYYY-MM-DD HH:MM:SS)结束,作为一个单一交易时段。
- daily_between_times—— 策略将以多个交易时段运行,每天在- start_time(HH:MM:SS)开始交易,并在- end_time(HH:MM:SS)停止。
对于 infinite 时间范围,用于计算保留价格和最优价差的公式略有不同,因为策略无需考虑距离交易时段结束的剩余时间。
start_time 和 end_time 参数均定义为客户端运行计算机的本地时间。对于 infinite 时间范围,这两个参数无效。
资产特征估算¶
该策略根据当前资产波动率和订单簿流动性测量值计算保留价格和最优价差。资产波动率估算器实现为 instant_volatility 指标,订单簿流动性估算器实现为 trading_intensity 指标。
在进行任何估算之前,两个估算器都需要填充其缓冲区。默认情况下,这些缓冲区的长度设置为 200 个 Tick。对于 trading_intensity 估算器,仅当订单簿快照与前一个快照不同时,才被视为有效 Tick。因此,该策略可能需要超过 200 秒(在缓冲区默认长度的情况下)才能开始下单。
trading_intensity 估算器的设计符合 Avellaneda-Stoikov 论文中提出的思想。instant_volatility 估算器将波动率定义为价格在相邻 Tick 之间的偏离程度,相对于零变化价格行为。
最小价差¶
minimum_spread 参数为可选参数,不影响计算出的保留价格和最优价差。它作为硬性下限,用于防止订单被放置在过近的位置,从而避免对做市商的手续费收入造成不利影响。最小价差以中间价的百分比形式由 minimum_spread 参数指定,默认值为 0,因此策略将在最优买卖价格上放置订单。
参考文献¶
- High-frequency Trading in a Limit Order Book - Avellaneda, Stoikov
- Optimal High-Frequency Market Making - Fushimi, Rojas, Herman
ℹ️ 更多资源¶
Avellaneda & Stoikov 做市策略全面指南:对基于著名学术论文的经典 Avellaneda 做市策略的完整解析。
Avellaneda 策略:技术深度剖析:我们解释了如何针对加密货币行业对原始的 Avellaneda-Stoikov 模型进行修改,以及如何简化关键参数(希腊字母)的计算。
