import pandas as pd import gradio as gr import gc import plotly.express as px from plotly.subplots import make_subplots import plotly.graph_objects as go from datetime import datetime, timedelta from tqdm import tqdm trader_daily_metric_choices = ["mech calls", "collateral amount", "nr_trades"] default_daily_metric = "collateral amount" color_mapping = [ "darkviolet", "purple", "goldenrod", "darkgoldenrod", "green", "darkgreen", ] def get_current_week_data(trades_df: pd.DataFrame) -> pd.DataFrame: # Get current date now = datetime.now() # Get start of the current week (Monday) start_of_week = now - timedelta(days=now.weekday()) start_of_week = start_of_week.replace(hour=0, minute=0, second=0, microsecond=0) # print(f"start of the week = {start_of_week}") # Get end of the current week (Sunday) end_of_week = start_of_week + timedelta(days=6) end_of_week = end_of_week.replace(hour=23, minute=59, second=59, microsecond=999999) # print(f"end of the week = {end_of_week}") trades_df["creation_date"] = pd.to_datetime(trades_df["creation_date"]) # Filter the dataframe return trades_df[ (trades_df["creation_date"] >= start_of_week) & (trades_df["creation_date"] <= end_of_week) ] def get_boxplot_daily_metrics( column_name: str, trades_df: pd.DataFrame ) -> pd.DataFrame: trades_filtered = trades_df[ [ "creation_timestamp", "creation_date", "market_creator", "trader_address", "staking", column_name, ] ] # adding the total trades_filtered_all = trades_filtered.copy(deep=True) trades_filtered_all["market_creator"] = "all" # merging both dataframes all_filtered_trades = pd.concat( [trades_filtered, trades_filtered_all], ignore_index=True ) all_filtered_trades = all_filtered_trades.sort_values( by="creation_timestamp", ascending=True ) gc.collect() return all_filtered_trades def plot_daily_metrics( metric_name: str, trades_df: pd.DataFrame, trader_filter: str = None ) -> gr.Plot: """Plots the trade metrics.""" if metric_name == "mech calls": metric_name = "nr_mech_calls" column_name = "nr_mech_calls" yaxis_title = "Total nr of mech calls per trader" elif metric_name == "nr_trades": column_name = metric_name yaxis_title = "Total nr of trades per trader" elif metric_name == "ROI": column_name = "roi" yaxis_title = "Total ROI (net profit/cost)" elif metric_name == "collateral amount": metric_name = "bet_amount" column_name = metric_name yaxis_title = "Total bet amount per trader (xDAI)" elif metric_name == "net earnings": metric_name = "net_earnings" column_name = metric_name yaxis_title = "Total net profit per trader (xDAI)" else: # earnings column_name = metric_name yaxis_title = "Total gross profit per trader (xDAI)" color_discrete_sequence = ["purple", "goldenrod", "darkgreen"] if trader_filter == "agent": color_discrete_sequence = ["darkviolet", "goldenrod", "green"] trades_filtered = trades_df.loc[trades_df["staking"] != "non_agent"] elif trader_filter == "non_agent": trades_filtered = trades_df.loc[trades_df["staking"] == "non_agent"] else: trades_filtered = trades_df # Create binary staking category trades_filtered["trader_type"] = trades_filtered["staking"].apply( lambda x: "non_agent" if x == "non_agent" else "agent" ) trades_filtered["trader_market"] = trades_filtered.apply( lambda x: (x["trader_type"], x["market_creator"]), axis=1 ) all_dates = sorted(trades_filtered["creation_date"].unique()) fig = px.box( trades_filtered, x="creation_date", y=column_name, color="market_creator", color_discrete_sequence=color_discrete_sequence, category_orders={ "market_creator": ["pearl", "quickstart", "all"], "trader_market": [ ("agent", "pearl"), ("non_agent", "pearl"), ("agent", "quickstart"), ("non_agent", "quickstart"), ("agent", "all"), ("non_agent", "all"), ], }, # facet_col="market_creator", ) fig.update_traces(boxmean=True) fig.update_layout( xaxis_title="Day", yaxis_title=yaxis_title, legend=dict(yanchor="top", y=0.5), ) # for axis in fig.layout: # if axis.startswith("xaxis"): # fig.layout[axis].update(title="Day") fig.update_xaxes(tickformat="%b %d") # Update layout to force x-axis category order (hotfix for a sorting issue) fig.update_layout(xaxis={"categoryorder": "array", "categoryarray": all_dates}) return gr.Plot( value=fig, ) def plot_daily_metrics_v2( metric_name: str, trades_df: pd.DataFrame, trader_filter: str = None ) -> gr.Plot: """Plots the trade metrics.""" if metric_name == "mech calls": metric_name = "mech_calls" column_name = "num_mech_calls" yaxis_title = "Nr of mech calls per trade" elif metric_name == "ROI": column_name = "roi" yaxis_title = "ROI (net profit/cost)" elif metric_name == "collateral amount": metric_name = "collateral_amount" column_name = metric_name yaxis_title = "Collateral amount per trade (xDAI)" elif metric_name == "net earnings": metric_name = "net_earnings" column_name = metric_name yaxis_title = "Net profit per trade (xDAI)" else: # earnings column_name = metric_name yaxis_title = "Gross profit per trade (xDAI)" color_discrete = ["purple", "darkgoldenrod", "darkgreen"] trades_filtered = get_boxplot_daily_metrics(column_name, trades_df) fig = make_subplots(rows=1, cols=2, subplot_titles=("Agent", "Non-Agents")) # Create first boxplot for staking=True fig.add_trace( go.Box( x=trades_filtered[trades_filtered["staking"] != "non_agent"][ "creation_date" ], y=trades_filtered[trades_filtered["staking"] != "non_agent"][column_name], name="Trades from agents", marker_color=color_discrete[0], legendgroup="staking_true", showlegend=True, ), row=1, col=1, ) # Create second boxplot for staking=False fig.add_trace( go.Box( x=trades_filtered[trades_filtered["staking"] == False]["creation_date"], y=trades_filtered[trades_filtered["staking"] == False][column_name], name="Staking False", marker_color=color_discrete[1], legendgroup="staking_false", showlegend=True, ), row=1, col=2, ) # Update layout fig.update_layout( height=600, width=1200, title_text=f"Box Plot of {column_name} by Staking Status", showlegend=True, ) # Update y-axes to have the same range fig.update_yaxes(matches="y")