import pandas as pd import gradio as gr import plotly.express as px 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 plot_trade_details(metric_name: str, trades_df: pd.DataFrame) -> gr.LinePlot: """Plots the trade details for the given trade detail.""" column_name = metric_name if metric_name == "mech calls": metric_name = "mech_calls" column_name = "num_mech_calls" elif metric_name == "ROI": column_name = "roi" # this is to filter out the data before 2023-09-01 trades_filtered = trades_df[trades_df["creation_timestamp"] > "2023-09-01"] trades_filtered = ( trades_filtered.groupby("month_year_week")[column_name] .quantile([0.25, 0.5, 0.75]) .unstack() ) trades_filtered.columns = trades_filtered.columns.astype(str) trades_filtered.reset_index(inplace=True) trades_filtered.columns = [ "month_year_week", "25th_percentile", "50th_percentile", "75th_percentile", ] # reformat the data as percentile, date, value trades_filtered = trades_filtered.melt( id_vars=["month_year_week"], var_name="percentile", value_name=metric_name ) return gr.LinePlot( value=trades_filtered, x="month_year_week", y=metric_name, color="percentile", show_label=True, interactive=True, show_actions_button=True, tooltip=["month_year_week", "percentile", metric_name], height=HEIGHT, width=WIDTH, ) def get_metrics( metric_name: str, column_name: str, market_creator: str, trades_df: pd.DataFrame ) -> pd.DataFrame: # this is to filter out the data before 2023-09-01 trades_filtered = trades_df[trades_df["creation_timestamp"] > "2023-09-01"] if market_creator != "all": trades_filtered = trades_filtered.loc[ trades_filtered["market_creator"] == market_creator ] trades_filtered = ( trades_filtered.groupby("month_year_week", sort=False)[column_name] .quantile([0.25, 0.5, 0.75]) .unstack() ) # reformat the data as percentile, date, value trades_filtered = trades_filtered.melt( id_vars=["month_year_week"], var_name="percentile", value_name=metric_name ) trades_filtered.columns = trades_filtered.columns.astype(str) trades_filtered.reset_index(inplace=True) trades_filtered.columns = [ "month_year_week", "25th_percentile", "50th_percentile", "75th_percentile", ] # reformat the data as percentile, date, value trades_filtered = trades_filtered.melt( id_vars=["month_year_week"], var_name="percentile", value_name=metric_name ) return trades_filtered def get_boxplot_metrics(column_name: str, trades_df: pd.DataFrame) -> pd.DataFrame: # this is to filter out the data before 2023-09-01 trades_filtered = trades_df[trades_df["creation_timestamp"] > "2023-09-01"] trades_filtered = trades_filtered[ ["creation_timestamp", "month_year_week", "market_creator", 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 ) return all_filtered_trades def plot2_trade_details( metric_name: str, market_creator: str, trades_df: pd.DataFrame ) -> gr.Plot: """Plots the trade details for the given trade detail.""" 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)" trades_filtered = get_metrics(metric_name, column_name, market_creator, trades_df) fig = px.line( trades_filtered, x="month_year_week", y=metric_name, color="percentile" ) 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") return gr.Plot( value=fig, ) def plot_trade_metrics( metric_name: str, trades_df: pd.DataFrame, height: int = None, width: int = 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)" trades_filtered = get_boxplot_metrics(column_name, trades_df) fig = px.box( trades_filtered, x="month_year_week", y=column_name, color="market_creator", color_discrete_sequence=["purple", "goldenrod", "darkgreen"], 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") if height is not None: fig.update_layout(width=WIDTH, height=HEIGHT) return gr.Plot( value=fig, ) def plot_average_roi_per_market_by_week(trades_df: pd.DataFrame) -> gr.LinePlot: mean_roi_per_market_by_week = ( trades_df.groupby(["market_creator", "month_year_week"])["roi"] .mean() .reset_index() ) mean_roi_per_market_by_week.rename(columns={"roi": "mean_roi"}, inplace=True) return gr.LinePlot( value=mean_roi_per_market_by_week, x="month_year_week", y="ROI", color="market_creator", show_label=True, interactive=True, show_actions_button=True, tooltip=["month_year_week", "market_creator", "mean_roi"], height=HEIGHT, width=WIDTH, ) def get_trade_metrics_text() -> gr.Markdown: 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 """ return gr.Markdown(metric_text)