Skip to content

rafalum/unistrat

Repository files navigation

UniStrat: A UniSwap LP strategy framework

What is UniStrat?

UniStrat is a tool for liquidity providers in UniSwap v3. It has been shown that most LPs in Uniswap are loosing money as they are effectively selling short puts on the market (see Guillaumes blog series). Without active management and careful choosing of the liquidity positions, most LPs are destined to loose money. UniStrat tries to give LPs a way to codify and backtest their strategies.

GUI

Get Started

First, clone the repositiory and create a new Python environment. I recommend using Anaconda.

conda create --name unistrat -c conda-forge python=3.11
pip install -r requirements.txt
conda activate unistrat

Next, you need to create a .env file with the following two entries:

ACCOUNT_PRIVATE_KEY=<PRIVATE_KEY>
PROVIDER_URL=<BLOCKCHAIN_PROVIDER_URL>

Replace the BLOCKCHAIN_PROVIDER_URL with the one given by your provider. I recommend using Infura as setting up is super fast and you get 100'000 API calls per day which should be plenty.

Finally, you can run the code. There are two mandatory arguments to pass in:

  1. pool_address: this is the address of the UniSwap pool you want to provide liquidity to. For example, the USDC-ETH pool on mainnet has the address 0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640
  2. network: possible values are mainnet, goerli, optimism, base

Additionally, there are several options available:

Flags Description
--gui runs the code with the GUI (as shown above)
--simulate runs the code on live data but without making transactions
--backest runs the code in backtesting mode
--from_block specifies which block to start the backtesting
--to_block specifies which block to finish the backtesting
--save_performance saves the perforamance of the closed positions in a file

So for example, if you want to backtest your strategy during from block 17000001 to block 17005000 and save the performance, run the following command:

python3 run.py 0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640 mainnet --backtest --from_block 17000001 --to_block 17005000 --save_performance performance_17000001_17005000

Structure

All the code lives in src/ and contains the following components:

- `provider.py`: is the interface to an Ethereum node and fetches all the relevant data
- `protocol_state.py`: represents the current state of the UniSwap pool
- `strategy.py`: codifies the strategy to provide liquidity
- `position.py`: represents a UniSwap LP position
- `position_manager.py`: manages the open and closed positions
- `gui.py`: simple visual interface to display all relevant informations

Structure

Limitations

  • no extensive unit tests