Source code for curvesim.metrics.state_log.log

"""
Module to house the `StateLog`, a generic class to record changing pool states
during simulations.
"""
from pandas import DataFrame, concat

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


[docs]class StateLog(Log): """ Logger that records simulation/pool state throughout each simulation run and computes metrics at the end of each run. """ __slots__ = [ "metrics", "pool", "state_per_run", "state_per_trade", ] def __init__(self, pool, metrics): self.pool = pool self.metrics = prepare_metrics(metrics, pool) 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.""" self.state_per_trade.append({"pool_state": get_pool_state(self.pool), **kwargs}) def get_logs(self): """Returns the accumulated log data.""" df = DataFrame(self.state_per_trade) times = [state["price_sample"].timestamp for state in self.state_per_trade] state_per_trade = {col: DataFrame(df[col].to_list(), index=times) for col in df} return { "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