From 995aa7b0033ff41f5623e6d90c808dddf8693eac Mon Sep 17 00:00:00 2001 From: nagakingg <82352736+nagakingg@users.noreply.github.com> Date: Fri, 28 Jul 2023 14:28:48 -0500 Subject: [PATCH] Update volume limits Updates volume limiting to support multiple asset denominations. Previously, all volume limits were in dollars. This approximation worked for v1 pools where all assets were worth ~1 dollar, but will not work for v2. Coingecko volumes are now returned in the base currency for each pair, and volume limits for trades in the opposite direction are computed using the current price at each tick in the volume limited arb pipeline. --- ...30728_150932_nagakingg_vol_mult_update.rst | 5 +++++ curvesim/network/coingecko.py | 21 ++++++++++++------- .../pipelines/vol_limited_arb/strategy.py | 9 +++++--- 3 files changed, 24 insertions(+), 11 deletions(-) create mode 100644 changelog.d/20230728_150932_nagakingg_vol_mult_update.rst diff --git a/changelog.d/20230728_150932_nagakingg_vol_mult_update.rst b/changelog.d/20230728_150932_nagakingg_vol_mult_update.rst new file mode 100644 index 000000000..856a3d34b --- /dev/null +++ b/changelog.d/20230728_150932_nagakingg_vol_mult_update.rst @@ -0,0 +1,5 @@ +Added +----- +- Add volume limiting in multiple denominations. Previously, volume + limiting was only in USD. This update allows for volume limiting + across multiple asset types (e.g., in v2 pools). diff --git a/curvesim/network/coingecko.py b/curvesim/network/coingecko.py index c1874bd00..554ac9530 100644 --- a/curvesim/network/coingecko.py +++ b/curvesim/network/coingecko.py @@ -4,11 +4,12 @@ # pylint: disable=redefined-outer-name import asyncio from datetime import datetime, timedelta, timezone -from itertools import combinations import numpy as np import pandas as pd +from curvesim.utils import get_pairs + from .http import HTTP from .utils import sync @@ -113,17 +114,21 @@ def pool_prices(coins, vs_currency, days, chain="mainnet", end=None): qprices, qvolumes = _pool_prices_sync(coins, vs_currency, days, end) # Compute prices by coin pairs - combos = list(combinations(range(len(coins)), 2)) + combos = get_pairs(len(coins)) prices = [] volumes = [] for pair in combos: - prices.append( - qprices.iloc[:, pair[0]] / qprices.iloc[:, pair[1]] - ) # divide prices - volumes.append( - qvolumes.iloc[:, pair[0]] + qvolumes.iloc[:, pair[1]] - ) # sum volumes + base_price = qprices.iloc[:, pair[0]] + base_volume = qvolumes.iloc[:, pair[0]] + + quote_price = qprices.iloc[:, pair[1]] + quote_volume = qvolumes.iloc[:, pair[1]] + + # divide prices: (usd/base) / (usd/quote) = quote/base + prices.append(base_price / quote_price) + # sum volumes and convert to base: usd / (usd/base) = base + volumes.append((base_volume + quote_volume) / base_price) prices = pd.concat(prices, axis=1) volumes = pd.concat(volumes, axis=1) diff --git a/curvesim/pipelines/vol_limited_arb/strategy.py b/curvesim/pipelines/vol_limited_arb/strategy.py index 802a53ce4..e8c127615 100644 --- a/curvesim/pipelines/vol_limited_arb/strategy.py +++ b/curvesim/pipelines/vol_limited_arb/strategy.py @@ -29,11 +29,14 @@ def __init__(self, metrics, vol_mult): self.vol_mult = vol_mult def _get_trader_inputs(self, sample): # pylint: disable=too-few-public-methods - volume_limits = _compute_volume_limits(sample.volumes, self.vol_mult) + volume_limits = _compute_volume_limits(sample, self.vol_mult) return sample.prices, volume_limits -def _compute_volume_limits(volumes, vol_mult): +def _compute_volume_limits(sample, vol_mult): + prices = sample.prices + volumes = sample.volumes + limits = {key: volumes[key] * vol_mult[key] for key in volumes} - reversed_limits = {(j, i): lim for (i, j), lim in limits.items()} + reversed_limits = {(j, i): lim * prices[(i, j)] for (i, j), lim in limits.items()} return {**limits, **reversed_limits}