avellaneda_market_making
¶
📁 策略信息¶
- 文件夹: /hummingbot/strategy/avellaneda_market_making
- 配置: avellaneda_market_making_config_map_pydantic.py
- 维护者: None
📝 摘要¶
该策略实现了 Marco Avellaneda 和 Sasha Stoikov 撰写的经典论文 High-frequency Trading in a Limit Order Book 中描述的市场制造策略。它允许用户直接调整论文中描述的 risk_factor
(gamma
) 参数。它还具有一个订单簿流动性估算器,可以自动计算交易强度参数(alpha
和 kappa
)。另外,该策略根据 Optimal High-Frequency Market Making 中的描述实现了订单规模调整算法及其 order_amount_shape_factor
(eta
) 参数。该策略的实现可以用于固定时间范围或无限期运行。
🏦 支持的交易所¶
- SPOT CLOB CEX
🛠️ 策略配置¶
参数 | 类型 | 默认 | 提示 |
---|---|---|---|
exchange |
string | 输入您的做市现货连接器 | |
market |
string | 输入您希望在 exchange 上交易的代币交易对 |
|
execution_timeframe |
string | 选择执行时间范围(infinite / from_date_to_date / daily_between_times ) |
|
start_time |
string | 请输入开始日期和时间(YYYY-MM-DD HH:MM:SS)或者请输入开始时间(HH:MM:SS) | |
end_time |
string | 请输入结束日期和时间(YYYY-MM-DD HH:MM:SS)或者请输入结束时间(HH:MM:SS) | |
order_amount |
decimal | 每个订单的 base_asset 数量是多少? |
|
order_optimization_enabled |
bool | True | 您是否要启用最佳买卖跳跃? |
risk_factor |
decimal | 已计算 | 输入风险因子 (𝛾) |
order_amount_shape_factor |
decimal | 已计算 | 输入订单数量形状因子 (η) |
min_spread |
0 | 输入最小价差限制(以中间价的百分比表示) | |
order_refresh_time |
decimal | 您希望多久取消和替换一次买入和卖出订单(以秒为单位)? | |
max_order_age |
decimal | 1800 | 您希望以相同价格取消和替换买卖报价多长时间(以秒为单位)? |
order_refresh_tolerance_pct |
decimal | 0 | 输入在每个周期刷新订单所需的百分比价格变动 |
filled_order_delay |
decimal | 60 | 如果您的订单成交,您希望等待多长时间再放置下一个订单(以秒为单位)? |
inventory_target_base_pct |
decimal | 50 | 基础资产的库存目标是什么? |
add_transaction_costs |
decimal | False | 您是否希望自动将交易成本添加到订单价格中?(是/否) |
volatility_buffer_size |
decimal | 200 | 输入将要存储以计算波动率的刻度数量 |
trading_intensity_buffer_size |
decimal | 200 | 输入将要存储以估算订单簿流动性的刻度数量? |
order_level_mode |
int | 1 | 您希望在两侧放置多少张订单? |
level_distances |
decimal | 0 | 单边订单之间的间隔应为最优价差的百分比是多少? |
order_override |
json | ||
hanging_orders_mode |
bool | False | 您希望如何处理挂单?(track_hanging_orders/ignore_hanging_orders) |
should_wait_order_cancel_confirmation |
bool | True | 策略在创建新订单组合之前是否应等待订单取消确认?(不等待需要足够的可用余额)(是/否) |
📓 描述¶
仅近似
以下是对该策略的总体近似描述。请检查上面的交易逻辑中的策略代码以确切了解其工作原理。
概述¶
该策略根据以下信息持续计算市场制造者在订单簿中的买入和卖出限价订单的最优定位:
- 当前订单簿流动性
- 资产价格波动率
- 期望的投资组合分配(目标库存)
- 交易时段时间范围
- 风险因子(用户选择)
有两个主要值是根据上述因素由模型计算的:
- 预留价格:与市场中间价不同的价格,将用作创建订单的参考。
- 最优价差:从 预留价格 到创建订单的最佳可能价差。
与以前版本相比,这些参数已被移除:
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,risk_factor
必须至少达到 10 左右才有任何明显效果。找到risk_factor
值的唯一方法是尝试不同的值,并观察其对 预约价格 和 最优价差 的影响。根据我们的经验,此参数的常见值介于 1 到 20 之间,但上侧没有限制,因此必要时其值甚至可以是 100 或 1000,尽管这不太常见。
在合适的市场条件和合适的 risk_factor
下,最优价差可能比资产的绝对价格更宽,或者预约价格可能远偏离中间价,这两种情况都会导致最优买价低于或等于 0。如果发生这种情况,既不会下买单也不会下卖单。为防止这种情况发生,用户可以将 risk_factor
设置为较低的值。
在设置risk_factor
时,重要的是观察预留价格与中间价格的关系。如果用户希望这两个价格之间的价差更宽,则应将风险因子设置为更高的值。预留价格距离中间价格越远,策略在追求其目标投资组合分配时就越激进,因为一侧的订单比另一侧更有可能成交。
ETA(订单规模调整)¶
如果用户选择设置eta
参数,订单规模将被调整,以进一步优化策略在当前和期望的投资组合分配方面的行为。
当eta = 1
时,买入和卖出订单的规模将相同。不同的值将产生不对称的订单规模,目标是更快地达到inventory_target_pct
。
订单层级¶
用户可以选择在两侧分层下单。如果选择了超过 1 个order_levels
,将在两侧创建多个买入和卖出限价订单,彼此之间有预定的价格距离,最接近预留价格的层级将被设置为最优的买卖价格。层级之间的价格距离被定义为策略计算出的最优价差的百分比。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 到另一个 tick 的偏差。
最小价差¶
minimum_spread
参数是可选的,它对计算的预留价格和最优价差没有影响。它作为硬性限制,低于此限制的订单将不会下达,如果用户选择确保买卖订单不会相互过于接近,这可能对做市商赚取的费用有害。最小价差由 minimum_spread
参数以中间价的百分比形式给出。默认值为 0,因此该策略在最优买入和卖出价格下订单。
参考文献¶
- High-frequency Trading in a Limit Order Book - Avellaneda, Stoikov
- Optimal High-Frequency Market Making - Fushimi, Rojas, Herman
ℹ️ 更多资源¶
A comprehensive guide to Avellaneda & Stoikov's market-making strategy: A comprehensive walkthrough of the classic avellaneda market making strategy that is based on a famous classic academic paper.
Avellaneda strategy: A technical deep dive: We explain how we modified the original Avellaneda-Stoikov model for the cryptocurrency industry, as well as how we simplified the calculation of key parameters (Greeks).