📁 Strategy Info¶
- Folder: /hummingbot/strategy/avellaneda_market_making
- Configs: avellaneda_market_making_config_map_pydantic.py
- Maintainer: None
🏆 Strategy Tier¶
Community strategies have passed the Minimum Voting Power Threshold in the latest Poll and are included in each monthly release. They are not maintained by Hummingbot Foundation but may be maintained by a community member.
This strategy implements a market making strategy described in the classic paper High-frequency Trading in a Limit Order Book written by Marco Avellaneda and Sasha Stoikov. It allows users to directly adjust the
gamma) parameter described in the paper. It also features an order book liquidity estimator calculating the trading intensity parameters (
kappa) automatically. Additionally, the strategy implements an order size adjustment algorithm and its
eta) parameter as described in Optimal High-Frequency Market Making. The strategy is implemented to be used either in fixed timeframes or to be ran indefinitely.
🏦 Exchanges supported¶
- SPOT CLOB CEX
🛠️ Strategy configs¶
||string||Enter your maker spot connector|
||string||Enter the token trading pair you would like to trade on
||string||Choose execution timeframe (
||string||Please enter the start date and time (YYYY-MM-DD HH:MM:SS) OR Please enter the start time (HH:MM:SS)|
||string||Please enter the end date and time (YYYY-MM-DD HH:MM:SS) OR Please enter the end time (HH:MM:SS)|
||decimal||What is the amount of
||bool||True||Do you want to enable best bid ask jumping?|
||decimal||Computed||Enter risk factor (𝛾)|
||decimal||Computed||Enter order amount shape factor (η)|
||0||Enter minimum spread limit (as % of mid price)|
||decimal||How often do you want to cancel and replace bids and asks (in seconds)?|
||decimal||1800||How long do you want to cancel and replace bids and asks with the same price (in seconds)?|
||decimal||0||Enter the percent change in price needed to refresh orders at each cycle|
||decimal||60||How long do you want to wait before placing the next order if your order gets filled (in seconds)?|
||decimal||50||What is the inventory target for the base asset?|
||decimal||False||Do you want to add transaction costs automatically to order prices? (Yes/No)|
||decimal||200||Enter amount of ticks that will be stored to calculate volatility|
||decimal||200||Enter amount of ticks that will be stored to estimate order book liquidity?|
||int||1||How many orders do you want to place on both sides?|
||decimal||0||How far apart in % of optimal spread should orders on one side be?|
||bool||False||How do you want to handle hanging orders? (track_hanging_orders/ignore_hanging_orders)|
||bool||True||Should the strategy wait to receive a confirmation for orders cancellation before creating a new set of orders? (Not waiting requires enough available balance) (Yes/No)|
The description below is a general approximation of this strategy. Please inspect the strategy code in Trading Logic above to understand exactly how it works.
The strategy continuously calculates optimal positioning of a market maker's buy and sell limit orders within an order book, based on the following information:
- Current order book liquidity
- Asset price volatility
- Desired portfolio allocation (target inventory)
- Trading session timeframe
- Risk factor (user choice)
There is two main values that are calculated by the model, based on the factors mentioned above:
- Reservation price: A price different from the market mid price, that will be used as reference to create orders.
- Optimal spread: The best possible spread from the reservation price where the orders will be created.
Compared to the previous version these parameters were removed:
min_spread has a different meaning, parameter
risk_factor is being used differently in the calculations and therefore attains a different range of values.
The farther the current inventory is from the desired asset allocation (as defined by the
inventory_target_base_pct parameter), the greater the distance between reservation price and the market mid price. The strategy skews the probability of either buy or sell orders being filled, depending on the difference between the current inventory and the
For example, If the strategy needs an asset to be sold to reach the
inventory_target_base_pct value, sell orders will be placed closer to the mid price than buy orders.
The Optimal spread values (which defines at what price each order will be created) is a function of the order book liquidity, asset price volatility and trading session timeframe. Each factor have an influence on the value calculated:
- Low order book liquidity = Smaller optimal spread value
- Low price volatility = Smaller optimal spread value
- Time closer to the end of the trading session = Smaller optimal spread value
The final piece of information that influence both Reservation price and Optimal Spread values is the
This value is defined by the user, and it represents how much inventory risk he is willing to take.
The closer the
risk_factor is to zero, the more symmetrical will be orders will be created, and the Reservation price will be pretty much equal to the market mid price.
In that case, the user is taking more inventory risk, because there will be no skew on the orders positions aiming to reach the
The higher the value, the more aggressive the strategy will be to reach the
inventory_target_base_pct, increasing the distance between the Reservation price and the market mid price.
It's a unit-less parameter, that can be set to any non-zero value as necessary, depending on the inventory risk the user is willing to take.
risk_factoris defined relative to the instant volatility of the asset given in absolute price values. For all assets the values
risk_factorcan attain should be roughly within the same range, however there can be a few exceptions where the parameter would require a significantly different value to start having an effect on the Reservation price and on the Optimal Spread As an example, for asset A, a
risk_factor = 1can already have a noticeable effect, while for asset B, the
risk_factormust be at least around 10 to have any noticeable effect. The only way to find a value for the
risk_factoris to experiment with different values and see it's effects on the Reservation price and the Optimal spread. Based on our experience common values of this parameter are between 1 and 20, however it is unrestricted on the upper side, therefore if necessary its value can be even 100 or 1000, although it's not very common.
Given the right market conditions and the right
risk_factor, it's possible that the optimal spread will be wider than the absolute price of the asset, or that the reservation price will by far away from the mid price, in both cases resulting in the optimal bid price to be lower than or equal to 0. If this happens neiher buy or sell will be placed. To prevent it from happening, users can set the
risk_factor to a lower value.
In setting the
risk_factor it's important to observe the reservation price in regards to the mid price. If the user wishes the spread between these two prices to be wider, the risk factor should be set to a higher value. The further away the reservation price is from the mid price, the more aggressive the strategy is in pursuing its target portfolio allocation, because orders on one side will be far more likely to be filled than on the other.
ETA (Order size adjustment)¶
If users choose to set the
eta parameter, order sizes will be adjusted to further optimize the strategy behavior in regards to the current and desired portfolio allocation.
With a value of
eta = 1, buy and sell orders will have the same size. A different value will create assymetrical order sizes, with the goal to reach the
Users have an option to layer orders on both sides. If more than 1
order_levels are chosen, multiple buy and sell limit orders will be created on both sides, with predefined price distances from each other, with the levels closest to the reservation price being set to the optimal bid and ask prices. This price distance between levels is defined as a percentage of the optimal spread calculated by the strategy. The percentage is given as the
level_distances parameter. Given that optimal spreads tend to be tight, the
level_distances values should be in general in tens or hundreds of percents.
Trading logic flow¶
|Are buffers filled?||Are instant volatility indicator and trading intensity indicator buffers full?|
|Are characteristics estimated?||Are order book liquidity / trading intensity parameter estimations available?|
|Is infinite timeframe?||Is the trading session set to be
|Are multiple levels defined?||Is value of
|Is minimum spread defined?||Is value of
The original Avellaneda-Stoikov model was designed to be used for market making on stock markets, which have defined trading hours. The assumption was that the market maker wants to end the trading day with the same inventory he started.
Since cryptocurrency markets are open 24/7, there is no "closing time", and the strategy should also be able run indefinitely, based on an infinite timeframe.
NOTE: Avellaneda-Stoikov also considered the possibility of running the model on an infinite timeframe
The strategy allows three possible timeframes to be used:
infinite- No closing time for the trading session is considered
from_date_to_date- The strategy will begin trading on the
start_time(YYYY-MM-DD HH:MM:SS) and stop at the
end_time(YYYY-MM-DD HH:MM:SS), as one single trading session.
daily_between_times- The strategy will run as multiple trading sessions, and every day will begin to trade at
start_time(HH:MM:SS) and stop at
infinite timeframe the equations used to calculate the reservation price and the optimal spread are slightly different, because the strategy doesn't have to take into account the time left until the end of a trading session.
start_time and the
end_time parameters are defined to be in the local time of the computer on which the client is running. For the
infinite timeframe these two parameters have no effect.
Asset Characteristics Estimation¶
The strategy calculates the reservation price and the optimal spread based on measurements of the current asset volatility and the order book liquidity. The asset volatility estimator is implemented as the
instant_volatility indicator, the order book liquidity estimator is implemented as the
Before any estimates can be given, both estimators need to have their buffers filled. By default the lengths of these buffers are set to be 200 ticks. In case of the
trading_intensity estimator only order book snapshots different from preceding snapshots count as valid ticks. Therefore the strategy may take longer than 200 seconds (in case of the default length of the buffer) to start placing orders.
trading_intensity estimator is designed to be consistent with ideas outlined in the Avellaneda-Stoikov paper. The
instant_volatility estimator defines volatility as a deviation of prices from one tick to another in regards to a zero-change price action.
minimum_spread parameter is optional, it has no effect on the calculated reservation price and the optimal spread. It serves as a hard limit below which orders won't be placed, if users choose to ensure that buy and sell orders won't be placed too close to each other, which may be detrimental to the market maker's earned fees. The minimum spread is given by the
minimum_spread parameter as a percentage of the mid price. By default its value is 0, therefore the strategy places orders at optimal bid and ask prices.
- High-frequency Trading in a Limit Order Book - Avellaneda, Stoikov
- Optimal High-Frequency Market Making - Fushimi, Rojas, Herman
ℹ️ More Resources¶
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).