import pandas as pd import gradio as gr import plotly.express as px import gc from datetime import datetime trade_metric_choices = [ "mech calls", "collateral amount", "earnings", "net earnings", "ROI", ] tool_metric_choices = { "Weekly Mean Mech Tool Accuracy as (Accurate Responses/All) %": "win_perc", "Total Weekly Inaccurate Nr of Mech Tool Responses": "losses", "Total Weekly Accurate Nr of Mech Tool Responses": "wins", "Total Weekly Nr of Mech Tool Requests": "total_request", } default_trade_metric = "ROI" default_tool_metric = "Weekly Mean Mech Tool Accuracy as (Accurate Responses/All) %" HEIGHT = 600 WIDTH = 1000 def get_boxplot_metrics(column_name: str, trades_df: pd.DataFrame) -> pd.DataFrame: trades_filtered = trades_df[ ["creation_timestamp", "month_year_week", "market_creator", column_name] ] # adding the total trades_filtered_all = trades_df.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_trade_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 = "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"] if trader_filter == "Olas": trades_filtered = get_boxplot_metrics( column_name, trades_df.loc[trades_df["staking"] != "non_Olas"] ) color_discrete = ["darkviolet", "goldenrod", "green"] elif trader_filter == "non_Olas": trades_filtered = get_boxplot_metrics( column_name, trades_df.loc[trades_df["staking"] == "non_Olas"] ) else: trades_filtered = get_boxplot_metrics(column_name, trades_df) # Convert string dates to datetime and sort them all_dates_dt = sorted( [ datetime.strptime(date, "%b-%d-%Y") for date in trades_filtered["month_year_week"].unique() ] ) # Convert back to string format all_dates = [date.strftime("%b-%d-%Y") for date in all_dates_dt] fig = px.box( trades_filtered, x="month_year_week", y=column_name, color="market_creator", color_discrete_sequence=color_discrete, category_orders={"market_creator": ["pearl", "quickstart", "all"]}, ) fig.update_traces(boxmean=True) fig.update_layout( xaxis_title="Week", yaxis_title=yaxis_title, legend=dict(yanchor="top", y=0.5), ) fig.update_xaxes(tickformat="%b %d\n%Y") # 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 get_trade_metrics_text(trader_type: str = None) -> gr.Markdown: if trader_type is None: metric_text = """ ## Description of the graph These metrics are computed weekly. The statistical measures are: * min, max, 25th(q1), 50th(median) and 75th(q2) percentiles * the upper and lower fences to delimit possible outliers * the average values as the dotted lines """ elif trader_type == "Olas": metric_text = """ ## Definition of Olas trader Agents using Mech, with a service ID and the corresponding safe in the registry ## Description of the graph These metrics are computed weekly. The statistical measures are: * min, max, 25th(q1), 50th(median) and 75th(q2) percentiles * the upper and lower fences to delimit possible outliers * the average values as the dotted lines """ elif trader_type == "non_Olas": metric_text = """ ## Definition of non-Olas trader Agents using Mech, with no service ID ## Description of the graph These metrics are computed weekly. The statistical measures are: * min, max, 25th(q1), 50th(median) and 75th(q2) percentiles * the upper and lower fences to delimit possible outliers * the average values as the dotted lines """ else: # Unclassified metric_text = """ ## Definition of unclassified trader Agents (safe/EOAs) not using Mechs ## Description of the graph These metrics are computed weekly. The statistical measures are: * min, max, 25th(q1), 50th(median) and 75th(q2) percentiles * the upper and lower fences to delimit possible outliers * the average values as the dotted lines """ return gr.Markdown(metric_text)