|
import gradio as gr |
|
import pandas as pd |
|
import plotly.express as px |
|
from tabs.market_plots import color_mapping |
|
from datetime import datetime |
|
|
|
trader_metric_choices = [ |
|
"mech calls", |
|
"bet amount", |
|
"earnings", |
|
"net earnings", |
|
"ROI", |
|
"nr_trades", |
|
] |
|
default_trader_metric = "ROI" |
|
|
|
|
|
def get_metrics_text(trader_type: str = None, daily: bool = False) -> gr.Markdown: |
|
if daily: |
|
metric_text = """ |
|
## Metrics at the graph |
|
These metrics are computed daily. 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 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: |
|
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) |
|
|
|
|
|
def get_interpretation_text() -> gr.Markdown: |
|
interpretation_text = """ |
|
## Meaning of KL-divergence values |
|
* Y = 0.05129 |
|
* Market accuracy off by 5% |
|
* Y = 0.1053 |
|
* Market accuracy off by 10% |
|
* Y = 0.2876 |
|
* Market accuracy off by 25% |
|
* Y = 0.5108 |
|
* Market accuracy off by 40% |
|
* Y = 1.2040 |
|
* Market accuracy off by 70% |
|
* Y = 2.3026 |
|
* Market accuracy off by 90% |
|
""" |
|
return gr.Markdown(interpretation_text) |
|
|
|
|
|
def plot_trader_metrics_by_market_creator( |
|
metric_name: str, traders_df: pd.DataFrame |
|
) -> gr.Plot: |
|
"""Plots the weekly trader metrics.""" |
|
|
|
if metric_name == "mech calls": |
|
metric_name = "mech_calls" |
|
column_name = "nr_mech_calls" |
|
yaxis_title = "Total nr of mech calls per trader" |
|
elif metric_name == "ROI": |
|
column_name = "roi" |
|
yaxis_title = "Total ROI (net profit/cost)" |
|
elif metric_name == "bet 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)" |
|
elif metric_name == "nr_trades": |
|
column_name = metric_name |
|
yaxis_title = "Total nr of trades per trader" |
|
else: |
|
column_name = metric_name |
|
yaxis_title = "Total gross profit per trader (xDAI)" |
|
|
|
traders_filtered = traders_df[["month_year_week", "market_creator", column_name]] |
|
|
|
all_dates_dt = sorted( |
|
[ |
|
datetime.strptime(date, "%b-%d-%Y") |
|
for date in traders_filtered["month_year_week"].unique() |
|
] |
|
) |
|
|
|
all_dates = [date.strftime("%b-%d-%Y") for date in all_dates_dt] |
|
fig = px.box( |
|
traders_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") |
|
|
|
fig.update_layout(xaxis={"categoryorder": "array", "categoryarray": all_dates}) |
|
|
|
return gr.Plot( |
|
value=fig, |
|
) |
|
|
|
|
|
def plot_trader_daily_metrics_by_market_creator( |
|
metric_name: str, traders_df: pd.DataFrame |
|
) -> gr.Plot: |
|
"""Plots the daily trader metrics.""" |
|
|
|
if metric_name == "mech calls": |
|
metric_name = "mech_calls" |
|
column_name = "nr_mech_calls" |
|
yaxis_title = "Total nr of mech calls per trader" |
|
elif metric_name == "ROI": |
|
column_name = "roi" |
|
yaxis_title = "Total ROI (net profit/cost)" |
|
elif metric_name == "bet 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)" |
|
elif metric_name == "nr_trades": |
|
column_name = metric_name |
|
yaxis_title = "Total nr of trades per trader" |
|
else: |
|
column_name = metric_name |
|
yaxis_title = "Total gross profit per trader (xDAI)" |
|
|
|
traders_filtered = traders_df[["creation_date", "market_creator", column_name]] |
|
|
|
fig = px.box( |
|
traders_filtered, |
|
x="creation_date", |
|
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="Day", |
|
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_winning_metric_per_trader(traders_winning_df: pd.DataFrame) -> gr.Plot: |
|
fig = px.box( |
|
traders_winning_df, |
|
x="month_year_week", |
|
y="winning_perc", |
|
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="Weekly winning percentage %", |
|
legend=dict(yanchor="top", y=0.5), |
|
width=1000, |
|
height=600, |
|
) |
|
fig.update_xaxes(tickformat="%b %d\n%Y") |
|
|
|
return gr.Plot( |
|
value=fig, |
|
) |
|
|
|
|
|
def plot_total_bet_amount( |
|
trades_df: pd.DataFrame, market_filter: str = "all" |
|
) -> gr.Plot: |
|
"""Plots the trade metrics.""" |
|
traders_all = trades_df.copy(deep=True) |
|
traders_all["market_creator"] = "all" |
|
|
|
|
|
final_traders = pd.concat([traders_all, trades_df], ignore_index=True) |
|
final_traders = final_traders.sort_values(by="creation_date", ascending=True) |
|
|
|
final_traders["trader_type"] = final_traders["staking"].apply( |
|
lambda x: "non_Olas" if x == "non_Olas" else "Olas" |
|
) |
|
|
|
total_bet_amount = ( |
|
final_traders.groupby( |
|
["month_year_week", "market_creator", "trader_type"], sort=False |
|
)["collateral_amount"] |
|
.sum() |
|
.reset_index(name="total_bet_amount") |
|
) |
|
|
|
all_dates_dt = sorted( |
|
[ |
|
datetime.strptime(date, "%b-%d-%Y") |
|
for date in total_bet_amount["month_year_week"].unique() |
|
] |
|
) |
|
|
|
all_dates = [date.strftime("%b-%d-%Y") for date in all_dates_dt] |
|
total_bet_amount["trader_market"] = total_bet_amount.apply( |
|
lambda x: (x["trader_type"], x["market_creator"]), axis=1 |
|
) |
|
color_discrete_sequence = ["purple", "goldenrod", "darkgreen"] |
|
if market_filter == "pearl": |
|
color_discrete_sequence = ["darkviolet", "goldenrod", "green"] |
|
total_bet_amount = total_bet_amount.loc[ |
|
total_bet_amount["market_creator"] == "pearl" |
|
] |
|
elif market_filter == "quickstart": |
|
total_bet_amount = total_bet_amount.loc[ |
|
total_bet_amount["market_creator"] == "quickstart" |
|
] |
|
else: |
|
total_bet_amount = total_bet_amount.loc[ |
|
total_bet_amount["market_creator"] == "all" |
|
] |
|
|
|
fig = px.bar( |
|
total_bet_amount, |
|
x="month_year_week", |
|
y="total_bet_amount", |
|
color="trader_market", |
|
color_discrete_sequence=color_mapping, |
|
category_orders={ |
|
"market_creator": ["pearl", "quickstart", "all"], |
|
"trader_market": [ |
|
("Olas", "pearl"), |
|
("non_Olas", "pearl"), |
|
("Olas", "quickstart"), |
|
("non_Olas", "quickstart"), |
|
("Olas", "all"), |
|
("non_Olas", "all"), |
|
], |
|
}, |
|
barmode="group", |
|
) |
|
|
|
fig.update_layout( |
|
xaxis_title="Week", |
|
yaxis_title="Weekly total bet amount per trader type", |
|
legend=dict(yanchor="top", y=0.5), |
|
) |
|
|
|
fig.update_xaxes(tickformat="%b %d") |
|
|
|
fig.update_layout(xaxis={"categoryorder": "array", "categoryarray": all_dates}) |
|
return gr.Plot( |
|
value=fig, |
|
) |
|
|
|
|
|
def plot_active_traders( |
|
active_traders_data: pd.DataFrame, |
|
market_creator: str = None, |
|
): |
|
"""Function to plot the volume of active traders for the different categories and markets""" |
|
|
|
filtered_traders_data = active_traders_data.copy() |
|
if market_creator is not None: |
|
filtered_traders_data = filtered_traders_data.loc[ |
|
filtered_traders_data["market_creator"] == market_creator |
|
] |
|
active_traders = ( |
|
filtered_traders_data.groupby(by=["month_year_week", "trader_type"])[ |
|
"trader_address" |
|
] |
|
.nunique() |
|
.reset_index(name="nr_traders") |
|
) |
|
|
|
all_dates_dt = sorted( |
|
[ |
|
datetime.strptime(date, "%b-%d-%Y") |
|
for date in active_traders["month_year_week"].unique() |
|
] |
|
) |
|
|
|
all_dates = [date.strftime("%b-%d-%Y") for date in all_dates_dt] |
|
color_mapping = [ |
|
"royalblue", |
|
"goldenrod", |
|
"gray", |
|
] |
|
fig = px.bar( |
|
active_traders, |
|
x="month_year_week", |
|
y="nr_traders", |
|
color="trader_type", |
|
color_discrete_sequence=color_mapping, |
|
category_orders={ |
|
"trader_type": ["Olas", "non_Olas", "unknown"], |
|
}, |
|
barmode="group", |
|
) |
|
fig.update_layout( |
|
xaxis_title="Week", |
|
yaxis_title="Weekly active traders per trader type", |
|
legend=dict(yanchor="top", y=0.5), |
|
) |
|
|
|
fig.update_xaxes(tickformat="%b %d") |
|
|
|
fig.update_layout(xaxis={"categoryorder": "array", "categoryarray": all_dates}) |
|
return gr.Plot( |
|
value=fig, |
|
) |
|
|