-
Notifications
You must be signed in to change notification settings - Fork 32
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #285 from curveresearch/cryptoswap-liquidity-density
Add cryptoswap liquidity density metric
- Loading branch information
Showing
19 changed files
with
237 additions
and
51 deletions.
There are no files selected for viewing
12 changes: 12 additions & 0 deletions
12
changelog.d/20230823_141423_nagakingg_cryptoswap_liquidity_density.rst
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
|
||
Added | ||
----- | ||
|
||
- Added PriceDepth (liquidity density) metric for Cryptoswap pools | ||
- Added virtual price and block timestamp to get_cryptoswap_pool_state() | ||
- Added detailed testing of liquidity density calculations | ||
|
||
Changed | ||
------- | ||
|
||
- Improved liquidity density calculation for robustness across pool types |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file modified
BIN
+0 Bytes
(100%)
test/data/0x4ebdf703948ddcea3b11f675b4d1fba9d2414a14-results_per_run.pickle
Binary file not shown.
Binary file modified
BIN
+7.82 KB
(110%)
test/data/0x4ebdf703948ddcea3b11f675b4d1fba9d2414a14-results_per_trade.pickle
Binary file not shown.
Binary file modified
BIN
+335 Bytes
(110%)
test/data/0x4ebdf703948ddcea3b11f675b4d1fba9d2414a14-results_summary.pickle
Binary file not shown.
Binary file modified
BIN
+0 Bytes
(100%)
test/data/0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7-results_per_run.pickle
Binary file not shown.
Binary file modified
BIN
+2.01 KB
(110%)
test/data/0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7-results_per_trade.pickle
Binary file not shown.
Binary file modified
BIN
+140 Bytes
(110%)
test/data/0xbebc44782c7db0a1a60cb6fe97d0b483032ff1c7-results_summary.pickle
Binary file not shown.
Binary file modified
BIN
+0 Bytes
(100%)
test/data/0xd632f22692fac7611d2aa1c0d552930d43caed3b-results_per_run.pickle
Binary file not shown.
Binary file modified
BIN
+2.01 KB
(110%)
test/data/0xd632f22692fac7611d2aa1c0d552930d43caed3b-results_per_trade.pickle
Binary file not shown.
Binary file modified
BIN
+140 Bytes
(110%)
test/data/0xd632f22692fac7611d2aa1c0d552930d43caed3b-results_summary.pickle
Binary file not shown.
Binary file modified
BIN
+0 Bytes
(100%)
test/data/0xdebf20617708857ebe4f679508e7b7863a8a8eee-results_per_run.pickle
Binary file not shown.
Binary file modified
BIN
+2.01 KB
(110%)
test/data/0xdebf20617708857ebe4f679508e7b7863a8a8eee-results_per_trade.pickle
Binary file not shown.
Binary file modified
BIN
+140 Bytes
(110%)
test/data/0xdebf20617708857ebe4f679508e7b7863a8a8eee-results_summary.pickle
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
from numpy import inf, mean | ||
|
||
from curvesim.metrics.metrics import _compute_liquidity_density | ||
from curvesim.utils import get_pairs | ||
|
||
|
||
def test_liquidity_density_sim_curve_pool(sim_curve_pool): | ||
_test_liquidity_density_stableswap(sim_curve_pool) | ||
|
||
|
||
def test_liquidity_density_sim_curve_tripool(sim_curve_tripool): | ||
_test_liquidity_density_stableswap(sim_curve_tripool) | ||
|
||
|
||
def test_liquidity_density_sim_curve_meta_pool(sim_curve_meta_pool): | ||
basepool = sim_curve_meta_pool.basepool | ||
coin_names = ["BP_SYM" + str(i) for i in range(basepool.n)] | ||
basepool.metadata = {"coins": {"names": coin_names}} | ||
_test_liquidity_density_stableswap(sim_curve_meta_pool) | ||
|
||
|
||
def test_liquidity_density_sim_curve_crypto_pool(sim_curve_crypto_pool): | ||
_test_liquidity_density_cryptoswap(sim_curve_crypto_pool) | ||
|
||
|
||
def test_liquidity_density_sim_curve_tricrypto_pool(sim_curve_tricrypto_pool): | ||
_test_liquidity_density_cryptoswap(sim_curve_tricrypto_pool) | ||
|
||
|
||
def _test_liquidity_density_stableswap(pool): | ||
""" | ||
Tests liquidity density for stableswap pools: | ||
- Ensure LD is max at center | ||
- Ensure LDs ~equal at equivalent curve positions for every trading pair/direction | ||
- Ensure LD at center is ~correct | ||
""" | ||
|
||
def trade_size_function(pool, coin_in): | ||
x_per_dx = 10**8 | ||
return pool.asset_balances[coin_in] // x_per_dx | ||
|
||
A_list = [10, 50, 100, 500, 1000, 5000] | ||
for A in A_list: | ||
pool.A = A | ||
LD_range = _test_compute_liquidity_density(pool, trade_size_function) | ||
|
||
# Ensure LD at center is ~correct | ||
LD_max_expected = (A + 1) / 2 | ||
assert abs(LD_range[0] - LD_max_expected) / LD_max_expected < 0.001 | ||
|
||
|
||
def _test_liquidity_density_cryptoswap(pool): | ||
""" | ||
Tests liquidity density for cryptoswap pools: | ||
- Ensure LD is max at center | ||
- Ensure LDs ~equal at equivalent curve positions for every trading pair/direction | ||
- Ensure LD at center is ~correct | ||
- Ensure LD near tail is ~.5 (constant product LD) | ||
""" | ||
|
||
def trade_size_function(pool, coin_in): | ||
return pool.get_min_trade_size(coin_in) | ||
|
||
pool.allowed_extra_profit = inf # disable _tweak_price | ||
pool.balances = pool._convert_D_to_balances(pool.D) # balance pool | ||
n = pool.n | ||
|
||
A_list = [10, 50, 100, 500] | ||
gamma_list = [10**x for x in range(13, 16)] | ||
for A in A_list: | ||
for gamma in gamma_list: | ||
pool.A = A * n**n * 10000 | ||
pool.gamma = gamma | ||
LD_range = _test_compute_liquidity_density(pool, trade_size_function) | ||
|
||
# Ensure LD at center is ~correct | ||
A_v1 = A * n ** (n - 1) | ||
LD_max_expected = (A_v1 + 1) / 2 | ||
assert abs(LD_range[0] - LD_max_expected) / LD_max_expected < 0.0015 | ||
|
||
# Ensure LD near tail is ~.5 (constant product LD) | ||
assert 0.47 < LD_range[-1] < 0.501 | ||
|
||
|
||
def _test_compute_liquidity_density(pool, trade_size_fn): | ||
""" | ||
Computes liquidity density ranges for each trading pair/direction and tests that: | ||
- LD is max at center | ||
- LDs ~equal at equivalent curve positions | ||
""" | ||
coin_names = ["SYM" + str(i) for i in range(pool.n)] | ||
pool.metadata = {"coins": {"names": coin_names}} | ||
|
||
# Compute LD range for each trading pair/direction | ||
coin_pairs = get_pairs(pool.coin_names) | ||
LD_ranges = [] | ||
for pair in coin_pairs: | ||
coin_in, coin_out = pair | ||
LD0 = _compute_liquidity_density_range(pool, coin_in, coin_out, trade_size_fn) | ||
LD1 = _compute_liquidity_density_range(pool, coin_out, coin_in, trade_size_fn) | ||
LD_ranges += [LD0, LD1] | ||
|
||
# Ensure LD is max at center | ||
for LD_range in LD_ranges: | ||
assert LD_range[0] == max(LD_range) | ||
|
||
# Ensure LDs ~equal at equivalent curve positions for every trading pair/direction | ||
LD_ranges_aligned = list(zip(*LD_ranges)) | ||
LD_ranges_means = [mean(LDs) for LDs in LD_ranges_aligned] | ||
for LDs, LD_mean in zip(LD_ranges_aligned, LD_ranges_means): | ||
percent_deviations = [abs(LD - LD_mean) / LD_mean for LD in LDs] | ||
assert max(percent_deviations) < 1e-4 | ||
|
||
return LD_ranges_means | ||
|
||
|
||
def _compute_liquidity_density_range(pool, coin_in, coin_out, trade_size_function): | ||
"""Computes liquidity density at a range of locations along the bonding curve.""" | ||
|
||
pre_trade_size = 0 | ||
pre_trade_step_size = pool.asset_balances[coin_in] // 250 | ||
|
||
coin_out_balances = pool.asset_balances[coin_out] | ||
coin_out_balances_limit = coin_out_balances * 0.05 | ||
|
||
LD_range = [] | ||
while coin_out_balances > coin_out_balances_limit: | ||
with pool.use_snapshot_context(): | ||
if pre_trade_size > 0: | ||
pool.trade(coin_in, coin_out, pre_trade_size) | ||
LD_trade_size = trade_size_function(pool, coin_in) | ||
LD = _compute_liquidity_density(pool, coin_in, coin_out, LD_trade_size) | ||
coin_out_balances = pool.asset_balances[coin_out] | ||
|
||
LD_range.append(LD) | ||
pre_trade_size += pre_trade_step_size | ||
|
||
return LD_range |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters