From 8e65c9af96c5f6bd5a6e2a5b24b44a1fefc14e22 Mon Sep 17 00:00:00 2001 From: Sheng Lundquist Date: Tue, 25 Jul 2023 16:24:10 -0700 Subject: [PATCH 1/2] Fixing fixed rate calculation with fixing spot price calculation --- examples/hackweek_demo/extract_data_logs.py | 46 +----------------- examples/hackweek_demo/plot_fixed_rate.py | 26 +++++------ examples/hackweek_demo/plot_ohlcv.py | 9 ++-- examples/hackweek_demo/plot_pnl.py | 52 ++++++++++++++++++++- examples/hackweek_demo/run_demo.py | 2 +- 5 files changed, 71 insertions(+), 64 deletions(-) diff --git a/examples/hackweek_demo/extract_data_logs.py b/examples/hackweek_demo/extract_data_logs.py index b4e7f7cc5f..c3210a6f5a 100644 --- a/examples/hackweek_demo/extract_data_logs.py +++ b/examples/hackweek_demo/extract_data_logs.py @@ -3,7 +3,6 @@ from __future__ import annotations import json -import logging import time import numpy as np @@ -26,49 +25,8 @@ def read_json_to_pd(json_file): return pd.DataFrame(json_data) -def calculate_spot_price_from_state(state, maturity_timestamp, block_timestamp, config_data): - """Calculate spot price from reserves stored in a state variable.""" - return calculate_spot_price( - state.shareReserves, - state.bondReserves, - state.lpTotalSupply, - config_data["invTimeStretch"], - config_data["initialSharePrice"], - config_data["positionDuration"], - maturity_timestamp, - block_timestamp, - ) - - -def calculate_spot_price( - share_reserves, - bond_reserves, - lp_total_supply, - stretch_time, - initial_share_price, - position_duration=None, - maturity_timestamp=None, - block_timestamp=None, -): - """Calculate the spot price given the pool info data.""" - # pylint: disable=too-many-arguments - - full_term_spot_price = ((initial_share_price * share_reserves) / (bond_reserves + lp_total_supply)) ** stretch_time - - if maturity_timestamp is None or block_timestamp is None or position_duration is None: - return full_term_spot_price - time_left_seconds = maturity_timestamp - block_timestamp - if isinstance(time_left_seconds, pd.Timedelta): - time_left_seconds = time_left_seconds.total_seconds() - time_left_in_years = time_left_seconds / position_duration - logging.info( - " spot price is weighted average of %s(%s) and 1 (%s)", - full_term_spot_price, - time_left_in_years, - 1 - time_left_in_years, - ) - - return full_term_spot_price * time_left_in_years + 1 * (1 - time_left_in_years) +def calculate_spot_price(share_reserves, bond_reserves, initial_share_price, time_stretch): + return ((initial_share_price * share_reserves) / bond_reserves) ** time_stretch def get_combined_data(txn_data, pool_info_data): diff --git a/examples/hackweek_demo/plot_fixed_rate.py b/examples/hackweek_demo/plot_fixed_rate.py index 54378b6b22..5f71a299ed 100644 --- a/examples/hackweek_demo/plot_fixed_rate.py +++ b/examples/hackweek_demo/plot_fixed_rate.py @@ -14,19 +14,19 @@ def calc_fixed_rate(trade_data, config_data): Calculates the fixed rate given trade data """ trade_data["rate"] = np.nan - for idx, row in trade_data.iterrows(): - spot_price = calculate_spot_price( - row.share_reserves, - row.bond_reserves, - row.lp_total_supply, - stretch_time=config_data["invTimeStretch"], - initial_share_price=config_data["initialSharePrice"], - ) - trade_data.loc[idx, "rate"] = (1 - spot_price) / spot_price - - x_data = trade_data.loc[:, "timestamp"] - col_names = ["rate"] - y_data = trade_data.loc[:, col_names] + annualized_time = config_data["positionDuration"] / (60 * 60 * 24 * 365) + + spot_price = calculate_spot_price( + trade_data["share_reserves"], + trade_data["bond_reserves"], + config_data["initialSharePrice"], + config_data["invTimeStretch"], + ) + + fixed_rate = (1 - spot_price) / (spot_price * annualized_time) + + x_data = trade_data["timestamp"] + y_data = fixed_rate return (x_data, y_data) diff --git a/examples/hackweek_demo/plot_ohlcv.py b/examples/hackweek_demo/plot_ohlcv.py index 81972e2bc8..30a9d6897c 100644 --- a/examples/hackweek_demo/plot_ohlcv.py +++ b/examples/hackweek_demo/plot_ohlcv.py @@ -30,11 +30,10 @@ def calc_ohlcv(trade_data, config_data, freq="D"): """ spot_prices = ( calculate_spot_price( - share_reserves=trade_data["share_reserves"], - bond_reserves=trade_data["bond_reserves"], - lp_total_supply=trade_data["lp_total_supply"], - stretch_time=config_data["invTimeStretch"], - initial_share_price=config_data["initialSharePrice"], + trade_data["share_reserves"], + trade_data["bond_reserves"], + config_data["initialSharePrice"], + config_data["invTimeStretch"], ) .to_frame() .astype(float) diff --git a/examples/hackweek_demo/plot_pnl.py b/examples/hackweek_demo/plot_pnl.py index 6f78d6a73c..d2a5dd9346 100644 --- a/examples/hackweek_demo/plot_pnl.py +++ b/examples/hackweek_demo/plot_pnl.py @@ -1,12 +1,62 @@ """Plots the pnl.""" from __future__ import annotations +import logging + import pandas as pd -from extract_data_logs import calculate_spot_price_from_state from elfpy.data import postgres as pg +# TODO fix calculating spot price with position duration +def calculate_spot_price_from_state(state, maturity_timestamp, block_timestamp, config_data): + """Calculate spot price from reserves stored in a state variable.""" + return calculate_spot_price_for_position( + state.shareReserves, + state.bondReserves, + state.lpTotalSupply, + config_data["invTimeStretch"], + config_data["initialSharePrice"], + config_data["positionDuration"], + maturity_timestamp, + block_timestamp, + ) + + +# Old calculate spot price +def calculate_spot_price_for_position( + share_reserves, + bond_reserves, + lp_total_supply, + stretch_time, + initial_share_price, + position_duration=None, + maturity_timestamp=None, + block_timestamp=None, +): + """Calculate the spot price given the pool info data.""" + # pylint: disable=too-many-arguments + + # TODO this calculation is broken + + full_term_spot_price = ((initial_share_price * share_reserves) / (bond_reserves + lp_total_supply)) ** stretch_time + + if maturity_timestamp is None or block_timestamp is None or position_duration is None: + return full_term_spot_price + time_left_seconds = maturity_timestamp - block_timestamp + if isinstance(time_left_seconds, pd.Timedelta): + time_left_seconds = time_left_seconds.total_seconds() + time_left_in_years = time_left_seconds / position_duration + logging.info( + " spot price is weighted average of %s(%s) and 1 (%s)", + full_term_spot_price, + time_left_in_years, + 1 - time_left_in_years, + ) + + return full_term_spot_price * time_left_in_years + 1 * (1 - time_left_in_years) + + def calculate_pnl( pool_config: pd.DataFrame, pool_info: pd.DataFrame, diff --git a/examples/hackweek_demo/run_demo.py b/examples/hackweek_demo/run_demo.py index 1c95c153ac..b0ecff07d5 100644 --- a/examples/hackweek_demo/run_demo.py +++ b/examples/hackweek_demo/run_demo.py @@ -170,8 +170,8 @@ def username_to_address(lookup: pd.DataFrame, selected_list: pd.DataFrame) -> pd combined_data = get_combined_data(txn_data, pool_info_data) ticker = get_ticker(combined_data, user_lookup) - ohlcv = calc_ohlcv(combined_data, config_data, freq="5T") (fixed_rate_x, fixed_rate_y) = calc_fixed_rate(combined_data, config_data) + ohlcv = calc_ohlcv(combined_data, config_data, freq="5T") with ticker_placeholder.container(): st.dataframe(ticker, height=200, use_container_width=True) From f399311c5e54041df7537b57568c296db1e4c344 Mon Sep 17 00:00:00 2001 From: Sheng Lundquist Date: Tue, 25 Jul 2023 16:29:49 -0700 Subject: [PATCH 2/2] Adding docstring --- examples/hackweek_demo/extract_data_logs.py | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/hackweek_demo/extract_data_logs.py b/examples/hackweek_demo/extract_data_logs.py index c3210a6f5a..311d52820c 100644 --- a/examples/hackweek_demo/extract_data_logs.py +++ b/examples/hackweek_demo/extract_data_logs.py @@ -26,6 +26,7 @@ def read_json_to_pd(json_file): def calculate_spot_price(share_reserves, bond_reserves, initial_share_price, time_stretch): + """Calculate the spot price.""" return ((initial_share_price * share_reserves) / bond_reserves) ** time_stretch