Skip to content

Commit 4e440f0

Browse files
authored
Merge pull request #41 from drift-labs:goldhaxx/DATA-73/add-filter-for-each-isolated-pool-on-price-shock-page
Goldhaxx/DATA-73/add-filter-for-each-isolated-pool-on-price-shock-page
2 parents 07f6b25 + 35cbf6b commit 4e440f0

File tree

2 files changed

+77
-45
lines changed

2 files changed

+77
-45
lines changed

backend/utils/user_metrics.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,8 @@ def get_user_leverages_for_price_shock(
308308
new_oracles_dat_down.append({})
309309

310310
distorted_oracles = []
311-
cache_up = copy.deepcopy(drift_client.account_subscriber.cache)
312-
cache_down = copy.deepcopy(drift_client.account_subscriber.cache)
311+
cache_up = copy.copy(drift_client.account_subscriber.cache)
312+
cache_down = copy.copy(drift_client.account_subscriber.cache)
313313

314314
for key, val in drift_client.account_subscriber.cache["oracle_price_data"].items():
315315
for i in range(scenarios):

src/page/price_shock.py

Lines changed: 75 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -35,77 +35,108 @@ def price_shock_plot(df_plot):
3535

3636
return fig
3737

38+
# Helper to initialize session state for a specific widget
39+
def initialize_widget_state(param_name, session_state_key, options, default_value, type_converter=None):
40+
query_val_str = st.query_params.get(param_name)
41+
if query_val_str is not None:
42+
try:
43+
converted_val = type_converter(query_val_str) if type_converter else query_val_str
44+
if converted_val in options:
45+
st.session_state[session_state_key] = converted_val
46+
return
47+
else: # Invalid value in query param
48+
st.session_state[session_state_key] = default_value
49+
except (ValueError, TypeError): # Conversion failed
50+
st.session_state[session_state_key] = default_value
51+
elif session_state_key not in st.session_state:
52+
st.session_state[session_state_key] = default_value
53+
# If query_val_str is None but session_state_key IS in st.session_state,
54+
# it means the user interacted, then maybe removed query param. Let existing session_state value persist.
55+
56+
# Define callbacks (these need to be defined before use in widgets)
57+
def on_asset_group_change():
58+
st.query_params["asset_group"] = st.session_state.selected_asset_group
59+
60+
def on_n_scenarios_change():
61+
st.query_params["n_scenarios"] = str(st.session_state.n_scenarios) # query params are strings
62+
63+
def on_pool_id_change():
64+
st.query_params["pool_id"] = st.session_state.selected_pool_id
3865

3966
def price_shock_cached_page():
40-
params = st.query_params
41-
asset_group = params.get("asset_group", PriceShockAssetGroup.IGNORE_STABLES.value)
42-
n_scenarios_param = params.get("n_scenarios", 5)
43-
pool_id_param = params.get("pool_id", "all")
44-
45-
asset_groups = [
67+
# Define options lists
68+
asset_group_options = [
4669
PriceShockAssetGroup.IGNORE_STABLES.value,
4770
PriceShockAssetGroup.JLP_ONLY.value,
4871
]
72+
scenario_options = [5, 10]
73+
pool_value_options = ["all", "0", "1", "3"]
74+
pool_display_names_map = {
75+
"all": "All Pools",
76+
"0": "Main Pool (0)",
77+
"1": "Isolated Pool 1",
78+
"3": "Isolated Pool 3"
79+
}
4980

81+
# Initialize widget states from query_params or defaults
82+
initialize_widget_state("asset_group", "selected_asset_group", asset_group_options, PriceShockAssetGroup.IGNORE_STABLES.value)
83+
initialize_widget_state("n_scenarios", "n_scenarios", scenario_options, 5, type_converter=int)
84+
initialize_widget_state("pool_id", "selected_pool_id", pool_value_options, "all")
85+
86+
# Asset Group Selection
5087
asset_group = st.selectbox(
51-
"Asset Group", asset_groups, index=asset_groups.index(asset_group)
88+
"Asset Group",
89+
options=asset_group_options,
90+
index=asset_group_options.index(st.session_state.selected_asset_group),
91+
key="selected_asset_group",
92+
on_change=on_asset_group_change
5293
)
53-
st.query_params.update({"asset_group": asset_group})
5494

55-
scenario_options = [5, 10]
56-
radio = st.radio(
95+
# Scenarios Selection
96+
n_scenarios = st.radio(
5797
"Scenarios",
58-
scenario_options,
59-
index=scenario_options.index(int(n_scenarios_param)),
98+
options=scenario_options,
99+
index=scenario_options.index(st.session_state.n_scenarios),
60100
key="n_scenarios",
101+
on_change=on_n_scenarios_change
61102
)
62-
n_scenarios = radio
63-
64-
st.query_params.update({"n_scenarios": n_scenarios})
65103

66104
# Pool ID selection
67-
pool_options = ["all", "0", "1", "3"]
68-
pool_display_names = ["All Pools", "Main Pool (0)", "Isolated Pool 1", "Isolated Pool 3"]
69-
70-
try:
71-
pool_index = pool_options.index(str(pool_id_param))
72-
except ValueError:
73-
pool_index = 0 # Default to "all"
74-
75-
pool_selection = st.selectbox(
105+
def format_pool_id(pool_id_value):
106+
return pool_display_names_map.get(pool_id_value, str(pool_id_value))
107+
108+
selected_pool_id = st.selectbox(
76109
"Pool Filter",
77-
pool_display_names,
78-
index=pool_index,
110+
options=pool_value_options,
111+
index=pool_value_options.index(st.session_state.selected_pool_id),
112+
format_func=format_pool_id,
113+
key="selected_pool_id",
114+
on_change=on_pool_id_change,
79115
help="Filter positions by pool ID. Main Pool (0) has more lenient parameters, Isolated Pools (>0) have stricter risk parameters."
80116
)
81117

82-
# Map display name back to value
83-
selected_pool_id = pool_options[pool_display_names.index(pool_selection)]
84-
st.query_params.update({"pool_id": selected_pool_id})
85-
86-
if n_scenarios == 5:
118+
# Determine oracle_distort based on n_scenarios from session_state
119+
if st.session_state.n_scenarios == 5:
87120
oracle_distort = 0.05
88121
else:
89122
oracle_distort = 0.1
90123

91-
# Prepare API parameters
124+
# Prepare API parameters using values from st.session_state
92125
api_params = {
93-
"asset_group": asset_group,
126+
"asset_group": st.session_state.selected_asset_group,
94127
"oracle_distortion": oracle_distort,
95-
"n_scenarios": n_scenarios,
128+
"n_scenarios": st.session_state.n_scenarios,
96129
}
97130

98-
# Add pool_id to params if not "all"
99-
if selected_pool_id != "all":
100-
api_params["pool_id"] = int(selected_pool_id)
131+
if st.session_state.selected_pool_id != "all":
132+
api_params["pool_id"] = int(st.session_state.selected_pool_id)
101133

102-
# Create cache key that includes pool_id
103134
cache_key_parts = [
104135
"price-shock/usermap",
105-
asset_group,
136+
st.session_state.selected_asset_group,
106137
str(oracle_distort),
107-
str(n_scenarios),
108-
selected_pool_id
138+
str(st.session_state.n_scenarios),
139+
st.session_state.selected_pool_id
109140
]
110141
cache_key = "_".join(cache_key_parts)
111142

@@ -129,9 +160,10 @@ def price_shock_cached_page():
129160
st.stop()
130161

131162
current_slot = get_current_slot()
132-
pool_display = f" (Pool {selected_pool_id})" if selected_pool_id != "all" else " (All Pools)"
163+
# Use selected_pool_id from session_state for display
164+
pool_display_text = f" (Pool {st.session_state.selected_pool_id})" if st.session_state.selected_pool_id != "all" else " (All Pools)"
133165
st.info(
134-
f"This data is for slot {result['slot']}{pool_display}, which is now {int(current_slot) - int(result['slot'])} slots old"
166+
f"This data is for slot {result['slot']}{pool_display_text}, which is now {int(current_slot) - int(result['slot'])} slots old"
135167
)
136168
df_plot = pd.DataFrame(json.loads(result["result"]))
137169

0 commit comments

Comments
 (0)