Spaces:
Runtime error
Runtime error
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() | |
# this is a fix til we have | |
# 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"]) | |
# check that we have data in the current week, if not, take previous week | |
current_week_data = trades_df[ | |
(trades_df["creation_date"] >= start_of_week) | |
& (trades_df["creation_date"] <= end_of_week) | |
] | |
if len(current_week_data) > 0: | |
return current_week_data | |
prev_monday = start_of_week - timedelta(days=7) | |
prev_monday = prev_monday.replace(hour=0, minute=0, second=0, microsecond=0) | |
prev_sunday = prev_monday + timedelta(days=6) | |
prev_sunday = prev_sunday.replace(hour=23, minute=59, second=59, microsecond=999999) | |
prev_week_data = trades_df[ | |
(trades_df["creation_date"] >= prev_monday) | |
& (trades_df["creation_date"] <= prev_sunday) | |
] | |
return prev_week_data | |
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 == "Olas": | |
color_discrete_sequence = ["darkviolet", "goldenrod", "green"] | |
trades_filtered = trades_df.loc[trades_df["staking"] != "non_agent"] | |
elif trader_filter == "non_Olas": | |
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") | |