Active Liquidity Provisioning
Background
Active liquidity provisioning (LP) is a strategy that involves providing liquidity to a decentralized exchange (DEX) like Uniswap and actively managing the liquidity to maximize returns. Unlike passive LPing, where liquidity is distributed across the entire price range of an asset pair, active LPing concentrates liquidity in a specific price range, where trades are most likely to occur. This allows liquidity providers (LPs) to earn higher fees with the same amount of capital by focusing liquidity in a narrower band.
The downside of concentrated liquidity is that the price of the asset can move outside the range where liquidity is concentrated, causing LPs to no longer earn fees and potentially lose money due to impermanent loss. To mitigate this, liquidity providers can actively manage their liquidity by adjusting the tick range of their liquidity position once the price moves outside the range.
On Uniswap, ticks correspond to price of the asset. So by tick range, we mean the price range where liquidity is concentrated.
The chart shows the price movement of ETH/USD over time. The black rectangles overlaying the chart represent specific price ranges chosen by our strategy to concentrate the liquidity. The height of the rectangles represent the tick range of the liquidity position and the width is the duration of the position.
It's important to balance the benefits of a narrow tick range with the need to minimize rebalancing. A narrow range maximizes earnings but requires frequent adjustments. A wider range reduces rebalancing frequency and gas costs, keeping liquidity active during volatility, but doesn't earn as much as fees.
Active LP Strategy
The agent can be in one of five states: idle, rebalanced, invested, withdrawn and collected. The agent first rebalances the tokens it holds to the 50/50 ratio, then provides liquidity to the pool in the active tick range. If the price moves outside the tick range, the agent withdraws the liquidity and collects the fees. It then repeats the process of rebalancing the tokens and providing liquidity.
How To Run
Installation
Follow our Getting Started guide to install the dojo library and other required tools.
Then clone the dojo_examples
repository and go into the relevant directory.
Running
Download the dashboard to view the simulation results.
To view example simulation data, download active_lp.db
from here and click 'Add A Simulation' on the dashboard.
To run the simulation yourself, use the following command.
This command will setup your local blockchain, contracts, accounts and agents. You can then access your results on your Dojo dashboard by connecting to a running simulation.
Step-By-Step Explanation
Initialization
We create a new class called ActiveConcentratedLP
which inherits from the UniswapV3Policy
class.
We initialize some variables which are used later in the policy such as:
state
to keep track of the state of the agent,position_info
to keep track of the tick range of our LP position,lp_width
to adjust the tick range,swap_volume
to track the trading volume of our agent,swap_count
to track the frequency of rebalancing our tokens and adjusting the tick range,
Rebalancing Assets
The _get_provide_lp_range
method retrieves the current tick range of the pool and returns the tick range where we want to provide liquidity.
This tick range is used in the _rebalance
method to return a UniswapV3TradeToTickRange
object containing the order to rebalance our tokens to the 50/50 ratio.
We then set the state of the agent to REBALANCED
so in the next block, the agent can provide liquidity.
Providing Concentrated Liquidity
In the _invest
method, we provide liquidity to the pool in the tick range we want to concentrate our liquidity by returning a UniswapV3ProvideQuantities
object.
We then set the state of the agent to INVESTED
and set position_info
to the current active tick range. This will be used later in the policy to
check if the price has moved outside the tick range in which case the LP position will be withdrawn, fees will be collected and the strategy will repeat.
Checking If Price Has Moved Outside Tick Range
We retrieve the active tick range of the pool using the active_tick_range
method of the UniswapV3Observation
class.
We compare the lower_active_tick
and upper_active_tick
with the lower and upper bounds of the tick range we provided liquidity in which is
stored in self.position_info
.
If the active tick range is outside the tick range we provided liquidity in, we withdraw our liquidity and set the state of the agent
to WITHDRAWN
so that the agent can collect the fees and burn the LP position in the next few blocks and repeat this process.
In the run.py
file, we create a pool, a Uniswap environment and an agent to implement the active LPing strategy.
Results
You can download the results to this example below.
We offer a dashboard desktop application for visualizing your simulation results. You can download the file for the desktop application here, or just open the results in our hosted dashboard.