Skip to content

Commit

Permalink
Sim Pipeline Redesign
Browse files Browse the repository at this point in the history
  • Loading branch information
allt0ld committed Oct 14, 2024
1 parent 9c45f17 commit 2c8949b
Show file tree
Hide file tree
Showing 39 changed files with 1,306 additions and 225 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ format:
black:
@echo "$(REVERSE)Running$(RESET) $(BOLD)black$(RESET)..."
@black --version
@black .
@black --extend-exclude "/(lib|bin)" .
@echo "$(REVERSE)Running$(RESET) $(BOLD)isort$(RESET)..."
@isort --version-number
@isort curvesim
Expand Down
10 changes: 5 additions & 5 deletions curvesim/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""Package to simulate Curve pool."""
__all__ = ["autosim", "bonding_curve", "order_book", "__version__", "__version_info__"]
# __all__ = ["autosim", "bonding_curve", "order_book", "__version__", "__version_info__"]

from ._order_book import order_book
from .sim import autosim
from .tools import bonding_curve
from .version import __version__, __version_info__
# from ._order_book import order_book
# from .sim import autosim
# from .tools import bonding_curve
# from .version import __version__, __version_info__
18 changes: 18 additions & 0 deletions curvesim/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,28 @@ class Chain(StrEnum):
AVALANCHE = "avalanche"
MATIC = "matic"
XDAI = "xdai"
BASE = "base"
FRAXTAL = "fraxtal"


class Env(StrEnum):
"""Names for different API environments."""

PROD = "prod"
STAGING = "staging"


class CurvePreset(StrEnum):
"""Names for presets within Curve.fi's pool creation UI."""
# Stableswap
FIAT_REDEEMDABLE_STABLECOINS = "fiat redeemable stablecoins"
CRYPTO_COLLATERALIZED_STABLECOINS = "crypto collateralized stablecoins"
STABLESWAP_LIQUID_RESTAKING_TOKENS = "stableswap liquid restaking tokens"
# Cryptoswap
CRYPTO = "crypto"
FOREX = "forex"
LIQUID_STAKING_DERIVATIVES = "liquid staking derivatives"
CRYPTOSWAP_LIQUID_RESTAKING_TOKENS = "cryptoswap liquid restaking tokens"
# Tricrypto
TRICRYPTO = "tricrypto" # USD-wrapped BTC-ETH
THREE_COIN_VOLATILE = "three coin volatile" # USD-ETH-any volatile token
2 changes: 1 addition & 1 deletion curvesim/metrics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
2. :class:`.StateLog`:
Logger that records simulation/pool state throughout a simulation and computes
metrics at the end of each simulation run.
metrics at the end of each simulation run. TODO: update
3. :class:`.SimResults`:
Container for simulation results with methods to plot or return recorded
Expand Down
54 changes: 20 additions & 34 deletions curvesim/metrics/state_log/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,41 +2,52 @@
Module to house the `StateLog`, a generic class to record changing pool states
during simulations.
"""
from pandas import DataFrame, concat
import gin

from pandas import DataFrame

from curvesim.metrics.base import PoolMetric
from curvesim.templates import Log
from curvesim.utils import override

from .pool_parameters import get_pool_parameters
from .pool_state import get_pool_state


@gin.register
class StateLog(Log):
"""
Logger that records simulation/pool state throughout each simulation run and
computes metrics at the end of each run.
computes metrics at the end of each run. TODO: CHANGE LATER
"""

__slots__ = [
"metrics",
"pool",
"state_per_run",
"state_per_trade",
]

def __init__(self, pool, metrics):
self.pool = pool
self.metrics = prepare_metrics(metrics, pool)
def __init__(self, pool):
"""
TODO
pool : SimPool
"""
# TODO: config the func with gin?
self.state_per_run = get_pool_parameters(pool)
self.state_per_trade = []

@override
def update(self, **kwargs):
"""Records pool state and any keyword arguments provided."""
state: dict = {}

if "pool" in kwargs:
pool = kwargs.pop("pool") # Simpool type
state["pool_state"] = get_pool_state(pool)

state.update(kwargs)

self.state_per_trade.append({"pool_state": get_pool_state(self.pool), **kwargs})
self.state_per_trade.append(state)

@override
def get_logs(self):
"""Returns the accumulated log data."""

Expand All @@ -49,28 +60,3 @@ def get_logs(self):
"pool_parameters": DataFrame(self.state_per_run, index=[0]),
**state_per_trade,
}

@override
def compute_metrics(self):
"""Computes metrics from the accumulated log data."""

state_logs = self.get_logs()
metric_data = [metric.compute(state_logs) for metric in self.metrics]
data_per_trade, summary_data = tuple(zip(*metric_data)) # transpose tuple list

return (
state_logs["pool_parameters"],
concat(data_per_trade, axis=1),
concat(summary_data, axis=1),
)


def prepare_metrics(metrics, pool):
"""
Applies any neccessary preparations to the input metrics.
Currently, only updates the pool object for PoolMetrics.
"""
for metric in metrics:
if isinstance(metric, PoolMetric):
metric.set_pool(pool)
return metrics
20 changes: 19 additions & 1 deletion curvesim/network/coingecko.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
"""
Network connector for Coingecko.
"""
import os

# pylint: disable=redefined-outer-name
import pandas as pd

from curvesim.utils import get_env_var

from .http import HTTP
from .utils import sync

URL = "https://api.coingecko.com/api/v3/"

# Creating a free API key on Coingecko enables increased response speed and rate limits
# https://www.coingecko.com/en/api/pricing
API_KEY = get_env_var("COINGECKO_API_KEY", default=None)

PLATFORMS = {
"mainnet": "ethereum",
"arbitrum": "arbitrum-one",
Expand All @@ -24,6 +32,7 @@
async def _get_prices(coin_id, vs_currency, start, end):
url = URL + f"coins/{coin_id}/market_chart/range"
p = {"vs_currency": vs_currency, "from": start, "to": end}
p = _add_api_key_param(p)

r = await HTTP.get(url, params=p)

Expand All @@ -46,14 +55,23 @@ async def coin_id_from_address(address, chain):
address = address.lower()
chain = PLATFORMS[chain.lower()]
url = URL + f"coins/{chain}/contract/{address}"
p = _add_api_key_param({})

r = await HTTP.get(url)
r = await HTTP.get(url, params=p)

coin_id = r["id"]

return coin_id


def _add_api_key_param(query_params: dict) -> dict:
api_key_param = "x_cg_demo_api_key"
if (API_KEY != None) and (api_key_param not in query_params):
query_params.update({api_key_param: API_KEY})

return query_params


# Sync
get_prices_sync = sync(get_prices)
coin_id_from_address_sync = sync(coin_id_from_address)
Expand Down
Loading

0 comments on commit 2c8949b

Please sign in to comment.