Skip to content

Commit 20d4cce

Browse files
authored
Merge pull request #51 from drift-labs:goldhaxx/DPE-3459/fix-risk-dashboard-loading-issues
goldhaxx/DPE-3459/fix-risk-dashboard-loading-issues
2 parents 595d0e3 + 799bc10 commit 20d4cce

File tree

2 files changed

+51
-5
lines changed

2 files changed

+51
-5
lines changed

backend/api/user_retention_explorer_api.py

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import os
44
from datetime import datetime, timedelta, timezone
5-
from typing import Dict, List, Tuple, Set, Optional, Any
5+
from typing import Callable, Dict, List, Tuple, Set, Optional, Any
66

77
import pandas as pd
88
from dateutil import tz, parser
@@ -84,6 +84,10 @@ class RetentionExplorerItem(BaseModel):
8484
retention_ratio_14d: float
8585
retention_ratio_28d: float
8686
user_data: List[UserVolumeDetails]
87+
total_initial_selected_market_volume_7d: float
88+
total_initial_other_market_volume_7d: float
89+
total_volume_14d: float
90+
total_volume_28d: float
8791

8892
UTC = tz.tzutc()
8993

@@ -142,7 +146,7 @@ def sql_users_volume(
142146
users: List[str],
143147
start_dt: datetime,
144148
end_dt: datetime,
145-
partition_func: callable,
149+
partition_func: Callable[[Set[Tuple[str, str, str]]], str],
146150
market_index: Optional[int] = None,
147151
exclude_market_index: Optional[int] = None
148152
) -> str:
@@ -219,11 +223,15 @@ async def calculate_retention_for_market(market_name: str, start_date_str: str)
219223
return {
220224
"market": market_name, "category": market_config.get("category", []), "start_date": start_date_str,
221225
"new_traders_count": 0, "retained_14d_count": 0, "retained_28d_count": 0,
222-
"retention_ratio_14d": 0.0, "retention_ratio_28d": 0.0, "user_data": []
226+
"retention_ratio_14d": 0.0, "retention_ratio_28d": 0.0, "user_data": [],
227+
"total_initial_selected_market_volume_7d": 0.0,
228+
"total_initial_other_market_volume_7d": 0.0,
229+
"total_volume_14d": 0.0,
230+
"total_volume_28d": 0.0,
223231
}
224232

225233
# --- Volume Calculation ---
226-
traders_df = pd.DataFrame(mkt_traders, columns=['user'])
234+
traders_df = pd.DataFrame({"user": mkt_traders})
227235

228236
# Define time windows
229237
initial_window_end = start_date + timedelta(days=NEW_TRADER_WINDOW_DAYS)
@@ -240,6 +248,9 @@ def get_and_merge_volume(
240248

241249
vol_df = pd.read_sql(vol_sql, conn)
242250
merged_df = base_df.merge(vol_df, on='user', how='left')
251+
252+
# Explicitly convert to numeric to avoid FutureWarning on downcasting
253+
merged_df['total_volume'] = pd.to_numeric(merged_df['total_volume'], errors='coerce')
243254
merged_df['total_volume'] = merged_df['total_volume'].fillna(0)
244255
return merged_df.rename(columns={'total_volume': column_name})
245256

@@ -253,6 +264,12 @@ def get_and_merge_volume(
253264

254265
traders_df = traders_df.rename(columns={'user': 'user_address'})
255266

267+
# --- Summary Volume Metrics ---
268+
total_initial_selected_market_volume_7d = traders_df['initial_selected_market_volume'].sum()
269+
total_initial_other_market_volume_7d = traders_df['initial_other_market_volume'].sum()
270+
total_volume_14d = (traders_df['selected_market_volume_14d'] + traders_df['other_market_volume_14d']).sum()
271+
total_volume_28d = (traders_df['selected_market_volume_28d'] + traders_df['other_market_volume_28d']).sum()
272+
256273
# --- Summary Statistics ---
257274
retained_14d_count = int((traders_df['other_market_volume_14d'] > 0).sum())
258275
retained_28d_count = int((traders_df['other_market_volume_28d'] > 0).sum())
@@ -268,7 +285,11 @@ def get_and_merge_volume(
268285
"retained_28d_count": retained_28d_count,
269286
"retention_ratio_14d": round(retention_ratio_14d, 4),
270287
"retention_ratio_28d": round(retention_ratio_28d, 4),
271-
"user_data": traders_df.to_dict('records')
288+
"user_data": traders_df.to_dict('records'),
289+
"total_initial_selected_market_volume_7d": float(total_initial_selected_market_volume_7d),
290+
"total_initial_other_market_volume_7d": float(total_initial_other_market_volume_7d),
291+
"total_volume_14d": float(total_volume_14d),
292+
"total_volume_28d": float(total_volume_28d),
272293
}
273294

274295
logger.info(f"Successfully calculated consolidated retention for {market_name}.")

src/page/user_retention_explorer_page.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,31 @@ def user_retention_explorer_page():
121121
elif isinstance(result, dict) and "user_data" in result:
122122
st.header("Analysis Results")
123123

124+
# --- Display Summary Metrics ---
125+
st.subheader("High-Level Volume Metrics")
126+
metric_cols = st.columns(4)
127+
metric_cols[0].metric(
128+
"ISMV7d",
129+
f"${result.get('total_initial_selected_market_volume_7d', 0):,.0f}",
130+
help="Initial Selected Market Volume (7d): Total volume in the selected market from new traders during their first 7 days."
131+
)
132+
metric_cols[1].metric(
133+
"IOMV7d",
134+
f"${result.get('total_initial_other_market_volume_7d', 0):,.0f}",
135+
help="Initial Other Market Volume (7d): Total volume in all other markets from new traders during their first 7 days."
136+
)
137+
metric_cols[2].metric(
138+
"TV14d",
139+
f"${result.get('total_volume_14d', 0):,.0f}",
140+
help="Total Volume (14d): Total volume from the cohort during the 14-day retention period (Days 8-21)."
141+
)
142+
metric_cols[3].metric(
143+
"TV28d",
144+
f"${result.get('total_volume_28d', 0):,.0f}",
145+
help="Total Volume (28d): Total volume from the cohort during the 28-day retention period (Days 8-35)."
146+
)
147+
148+
st.subheader("Retention Summary")
124149
df_data = {
125150
'Metric': [
126151
"Market", "Category", "Analysis Start Date", "New Traders (Count)",

0 commit comments

Comments
 (0)