cyberosa
commited on
Commit
·
c005138
1
Parent(s):
9097549
updating some graphs
Browse files- app.py +6 -2
- requirements.txt +3 -2
- scripts/live_traders_data.py +44 -33
- tabs/dist_gap.py +28 -22
app.py
CHANGED
@@ -3,6 +3,7 @@ import gradio as gr
|
|
3 |
import pandas as pd
|
4 |
import duckdb
|
5 |
import logging
|
|
|
6 |
|
7 |
from tabs.tokens_dist import (
|
8 |
get_extreme_cases,
|
@@ -14,6 +15,7 @@ from tabs.dist_gap import (
|
|
14 |
get_kde_with_trades,
|
15 |
get_kde_with_total_bet_amount,
|
16 |
get_dist_gap_time_evolution,
|
|
|
17 |
)
|
18 |
|
19 |
|
@@ -59,6 +61,8 @@ def prepare_data():
|
|
59 |
|
60 |
demo = gr.Blocks()
|
61 |
markets_data = prepare_data()
|
|
|
|
|
62 |
live_markets_data = markets_data.loc[markets_data["open"] == True]
|
63 |
# filter only those with trades
|
64 |
markets_data = markets_data.loc[markets_data["total_trades"] > 0]
|
@@ -77,7 +81,7 @@ with demo:
|
|
77 |
f"Market id = {best_market_id} Dist gap = {round(best_gap,2)}"
|
78 |
)
|
79 |
with gr.Row():
|
80 |
-
best_case =
|
81 |
best_market_id, live_markets_data
|
82 |
)
|
83 |
|
@@ -89,7 +93,7 @@ with demo:
|
|
89 |
)
|
90 |
|
91 |
with gr.Row():
|
92 |
-
worst_case =
|
93 |
worst_market_id, live_markets_data
|
94 |
)
|
95 |
with gr.Row():
|
|
|
3 |
import pandas as pd
|
4 |
import duckdb
|
5 |
import logging
|
6 |
+
import plotly.express as px
|
7 |
|
8 |
from tabs.tokens_dist import (
|
9 |
get_extreme_cases,
|
|
|
15 |
get_kde_with_trades,
|
16 |
get_kde_with_total_bet_amount,
|
17 |
get_dist_gap_time_evolution,
|
18 |
+
get_dist_gap_timeline_plotly,
|
19 |
)
|
20 |
|
21 |
|
|
|
61 |
|
62 |
demo = gr.Blocks()
|
63 |
markets_data = prepare_data()
|
64 |
+
print(f"markets data")
|
65 |
+
markets_data["sample_date"] = pd.to_datetime(markets_data["sample_datetime"]).dt.date
|
66 |
live_markets_data = markets_data.loc[markets_data["open"] == True]
|
67 |
# filter only those with trades
|
68 |
markets_data = markets_data.loc[markets_data["total_trades"] > 0]
|
|
|
81 |
f"Market id = {best_market_id} Dist gap = {round(best_gap,2)}"
|
82 |
)
|
83 |
with gr.Row():
|
84 |
+
best_case = get_dist_gap_timeline_plotly(
|
85 |
best_market_id, live_markets_data
|
86 |
)
|
87 |
|
|
|
93 |
)
|
94 |
|
95 |
with gr.Row():
|
96 |
+
worst_case = get_dist_gap_timeline_plotly(
|
97 |
worst_market_id, live_markets_data
|
98 |
)
|
99 |
with gr.Row():
|
requirements.txt
CHANGED
@@ -1,11 +1,12 @@
|
|
1 |
-
pandas
|
2 |
seaborn
|
3 |
matplotlib
|
4 |
huggingface-hub
|
5 |
pyarrow
|
6 |
requests
|
7 |
gradio
|
8 |
-
plotly
|
|
|
9 |
nbformat
|
10 |
pytz
|
11 |
duckdb
|
|
|
1 |
+
pandas==2.2.2
|
2 |
seaborn
|
3 |
matplotlib
|
4 |
huggingface-hub
|
5 |
pyarrow
|
6 |
requests
|
7 |
gradio
|
8 |
+
plotly==5.24.0
|
9 |
+
pydantic==2.8.2
|
10 |
nbformat
|
11 |
pytz
|
12 |
duckdb
|
scripts/live_traders_data.py
CHANGED
@@ -14,16 +14,13 @@ from utils import SUBGRAPH_API_KEY, _to_content
|
|
14 |
from queries import omen_market_trades_query
|
15 |
|
16 |
|
17 |
-
|
18 |
headers = {
|
19 |
"Accept": "application/json, multipart/mixed",
|
20 |
"Content-Type": "application/json",
|
21 |
}
|
22 |
|
23 |
|
24 |
-
def _query_omen_xdai_subgraph(
|
25 |
-
fpmm_id: str, logger
|
26 |
-
) -> dict[str, Any]:
|
27 |
"""Query the subgraph."""
|
28 |
omen_subgraph = OMEN_SUBGRAPH_URL.substitute(subgraph_api_key=SUBGRAPH_API_KEY)
|
29 |
logger.info(f"omen_subgraph = {omen_subgraph}")
|
@@ -37,7 +34,7 @@ def _query_omen_xdai_subgraph(
|
|
37 |
id_gt=id_gt,
|
38 |
fpmm_id=fpmm_id,
|
39 |
)
|
40 |
-
#logger.debug(f"query for the omen to collect trades {query}")
|
41 |
content_json = _to_content(query)
|
42 |
|
43 |
res = requests.post(omen_subgraph, headers=headers, json=content_json)
|
@@ -90,7 +87,6 @@ def transform_trades(trades_json: dict, logger) -> pd.DataFrame:
|
|
90 |
return df
|
91 |
|
92 |
|
93 |
-
|
94 |
def compute_votes_distribution(market_trades: pd.DataFrame, logger):
|
95 |
"""Function to compute the distribution of votes for the trades of a market"""
|
96 |
logger.info("Computing the votes distribution")
|
@@ -102,15 +98,23 @@ def compute_votes_distribution(market_trades: pd.DataFrame, logger):
|
|
102 |
percentage_index_1 = round((sum_outcome_index_1 / total_trades) * 100, 2)
|
103 |
return (100 - percentage_index_1), percentage_index_1
|
104 |
|
105 |
-
|
106 |
-
|
|
|
|
|
|
|
107 |
total_tokens_outcome_0 = sum(trades_outcome_0.outcomeTokensTraded)
|
108 |
total_tokens_outcome_1 = sum(trades_outcome_1.outcomeTokensTraded)
|
109 |
total_bought_tokens = total_tokens_outcome_0 + total_tokens_outcome_1
|
110 |
-
percentage_bought_outcome_0 = round(
|
111 |
-
|
|
|
|
|
|
|
112 |
|
113 |
-
def compute_price_weighted_perc(
|
|
|
|
|
114 |
"""It computes the price weighted distribution with the percentages of each outcome"""
|
115 |
logger.info("Computing the price weighted distribution")
|
116 |
total_usd_outcome_0 = sum(trades_outcome_0.collateralAmountUSD)
|
@@ -119,47 +123,54 @@ def compute_price_weighted_perc(trades_outcome_0: pd.DataFrame, trades_outcome_1
|
|
119 |
if total_usd == 0.0:
|
120 |
raise ValueError("The total amount of dollars is 0")
|
121 |
|
122 |
-
percentage_pwc_outcome_0 = round((total_usd_outcome_0/total_usd)*100, 2)
|
123 |
logger.debug(f"total amount for outcome 0 = {total_usd_outcome_0}")
|
124 |
logger.debug(f"total usd = {total_usd}")
|
125 |
-
return percentage_pwc_outcome_0, 100 - percentage_pwc_outcome_0
|
|
|
126 |
|
127 |
def add_trading_info(fpmms: pd.DataFrame, current_timestamp: int, logger) -> None:
|
128 |
"""Function to update only the information related with the current timestamp"""
|
129 |
-
|
130 |
logger.info("Adding price weighted distribution per market")
|
131 |
fpmms["liquidityMeasure"] = fpmms["liquidityMeasure"].apply(lambda x: int(x))
|
132 |
# Iterate over the markets
|
133 |
for i, fpmm in tqdm(fpmms.iterrows(), total=len(fpmms), desc="Analysing trades"):
|
134 |
# update the trades for this market and at this specific current_timestamp
|
135 |
-
logger.debug(f"current timestamp = {current_timestamp} and market timestamp={fpmm["sample_timestamp"]}")
|
136 |
to_update = fpmm["open"] and fpmm["sample_timestamp"] == current_timestamp
|
137 |
if not to_update: # jump closed markets or old data
|
138 |
logger.debug("Jumping this row")
|
139 |
continue
|
140 |
market_id = fpmm["id"]
|
141 |
-
|
142 |
logger.info(f"Adding trades information for the market {market_id}")
|
143 |
-
market_trades_json = _query_omen_xdai_subgraph(
|
144 |
-
fpmm_id=market_id, logger=logger
|
145 |
-
)
|
146 |
market_trades = transform_trades(market_trades_json, logger)
|
147 |
-
fpmms.at[i,"total_trades"] = len(market_trades)
|
148 |
|
149 |
if len(market_trades) > 0:
|
150 |
# adding average trade size
|
151 |
-
market_trades["collateralAmountUSD"] =
|
152 |
-
|
|
|
|
|
|
|
|
|
153 |
mean_trade_size = market_trades.collateralAmountUSD.mean()
|
154 |
total_bet_amount = sum(market_trades.collateralAmountUSD)
|
155 |
# trades for outcome 0
|
156 |
-
trades_outcome_0 = market_trades.loc[market_trades["outcomeIndex"]==0]
|
157 |
logger.debug(f"Total trades for outcome 0 = {len(trades_outcome_0)}")
|
158 |
# trades for outcome 1
|
159 |
-
trades_outcome_1 = market_trades.loc[market_trades["outcomeIndex"]==1]
|
160 |
logger.debug(f"Total trades for outcome 1 = {len(trades_outcome_1)}")
|
161 |
-
first_outcome, second_outcome = compute_price_weighted_perc(
|
162 |
-
|
|
|
|
|
|
|
|
|
163 |
metric = abs(fpmm["first_token_perc"] - first_outcome)
|
164 |
logger.info(f"metric for this market {metric}")
|
165 |
else:
|
@@ -168,16 +179,16 @@ def add_trading_info(fpmms: pd.DataFrame, current_timestamp: int, logger) -> Non
|
|
168 |
bought_tokens_first = bought_tokens_second = 0.0
|
169 |
first_outcome = second_outcome = 0.0
|
170 |
metric = 0.0
|
171 |
-
fpmms.at[i,"mean_trade_size"] = mean_trade_size
|
172 |
-
fpmms.at[i,"total_bet_amount"] = total_bet_amount
|
173 |
logger.info(
|
174 |
f"first outcome pwc ={first_outcome}, second outcome pwc = {second_outcome}"
|
175 |
)
|
176 |
-
fpmms.at[i,"price_weighted_first_outcome_perc"] = first_outcome
|
177 |
-
fpmms.at[i,"price_weighted_second_outcome_perc"] = second_outcome
|
178 |
-
fpmms.at[i,"bought_tokens_first_perc"] = bought_tokens_first
|
179 |
-
fpmms.at[i,"bought_tokens_second_perc"] = bought_tokens_second
|
180 |
-
fpmms.at[i,"dist_gap_perc"] = metric
|
181 |
logger.debug("Dataset after adding trading info")
|
182 |
logger.debug(fpmms.head())
|
183 |
return
|
|
|
14 |
from queries import omen_market_trades_query
|
15 |
|
16 |
|
|
|
17 |
headers = {
|
18 |
"Accept": "application/json, multipart/mixed",
|
19 |
"Content-Type": "application/json",
|
20 |
}
|
21 |
|
22 |
|
23 |
+
def _query_omen_xdai_subgraph(fpmm_id: str, logger) -> dict[str, Any]:
|
|
|
|
|
24 |
"""Query the subgraph."""
|
25 |
omen_subgraph = OMEN_SUBGRAPH_URL.substitute(subgraph_api_key=SUBGRAPH_API_KEY)
|
26 |
logger.info(f"omen_subgraph = {omen_subgraph}")
|
|
|
34 |
id_gt=id_gt,
|
35 |
fpmm_id=fpmm_id,
|
36 |
)
|
37 |
+
# logger.debug(f"query for the omen to collect trades {query}")
|
38 |
content_json = _to_content(query)
|
39 |
|
40 |
res = requests.post(omen_subgraph, headers=headers, json=content_json)
|
|
|
87 |
return df
|
88 |
|
89 |
|
|
|
90 |
def compute_votes_distribution(market_trades: pd.DataFrame, logger):
|
91 |
"""Function to compute the distribution of votes for the trades of a market"""
|
92 |
logger.info("Computing the votes distribution")
|
|
|
98 |
percentage_index_1 = round((sum_outcome_index_1 / total_trades) * 100, 2)
|
99 |
return (100 - percentage_index_1), percentage_index_1
|
100 |
|
101 |
+
|
102 |
+
def compute_bought_tokens_distribution(
|
103 |
+
trades_outcome_0: pd.DataFrame, trades_outcome_1: pd.DataFrame
|
104 |
+
) -> Tuple:
|
105 |
+
"""Function to compute the distribution of bought tokens from the trades on each outcome"""
|
106 |
total_tokens_outcome_0 = sum(trades_outcome_0.outcomeTokensTraded)
|
107 |
total_tokens_outcome_1 = sum(trades_outcome_1.outcomeTokensTraded)
|
108 |
total_bought_tokens = total_tokens_outcome_0 + total_tokens_outcome_1
|
109 |
+
percentage_bought_outcome_0 = round(
|
110 |
+
(total_tokens_outcome_0 / total_bought_tokens) * 100, 2
|
111 |
+
)
|
112 |
+
return percentage_bought_outcome_0, 100 - percentage_bought_outcome_0
|
113 |
+
|
114 |
|
115 |
+
def compute_price_weighted_perc(
|
116 |
+
trades_outcome_0: pd.DataFrame, trades_outcome_1: pd.DataFrame, logger
|
117 |
+
) -> Tuple:
|
118 |
"""It computes the price weighted distribution with the percentages of each outcome"""
|
119 |
logger.info("Computing the price weighted distribution")
|
120 |
total_usd_outcome_0 = sum(trades_outcome_0.collateralAmountUSD)
|
|
|
123 |
if total_usd == 0.0:
|
124 |
raise ValueError("The total amount of dollars is 0")
|
125 |
|
126 |
+
percentage_pwc_outcome_0 = round((total_usd_outcome_0 / total_usd) * 100, 2)
|
127 |
logger.debug(f"total amount for outcome 0 = {total_usd_outcome_0}")
|
128 |
logger.debug(f"total usd = {total_usd}")
|
129 |
+
return percentage_pwc_outcome_0, 100 - percentage_pwc_outcome_0
|
130 |
+
|
131 |
|
132 |
def add_trading_info(fpmms: pd.DataFrame, current_timestamp: int, logger) -> None:
|
133 |
"""Function to update only the information related with the current timestamp"""
|
134 |
+
|
135 |
logger.info("Adding price weighted distribution per market")
|
136 |
fpmms["liquidityMeasure"] = fpmms["liquidityMeasure"].apply(lambda x: int(x))
|
137 |
# Iterate over the markets
|
138 |
for i, fpmm in tqdm(fpmms.iterrows(), total=len(fpmms), desc="Analysing trades"):
|
139 |
# update the trades for this market and at this specific current_timestamp
|
140 |
+
# logger.debug(f"current timestamp = {current_timestamp} and market timestamp={fpmm["sample_timestamp"]}")
|
141 |
to_update = fpmm["open"] and fpmm["sample_timestamp"] == current_timestamp
|
142 |
if not to_update: # jump closed markets or old data
|
143 |
logger.debug("Jumping this row")
|
144 |
continue
|
145 |
market_id = fpmm["id"]
|
146 |
+
|
147 |
logger.info(f"Adding trades information for the market {market_id}")
|
148 |
+
market_trades_json = _query_omen_xdai_subgraph(fpmm_id=market_id, logger=logger)
|
|
|
|
|
149 |
market_trades = transform_trades(market_trades_json, logger)
|
150 |
+
fpmms.at[i, "total_trades"] = len(market_trades)
|
151 |
|
152 |
if len(market_trades) > 0:
|
153 |
# adding average trade size
|
154 |
+
market_trades["collateralAmountUSD"] = (
|
155 |
+
market_trades.collateralAmountUSD.apply(lambda x: round(float(x), 3))
|
156 |
+
)
|
157 |
+
market_trades["outcomeTokensTraded"] = (
|
158 |
+
market_trades.outcomeTokensTraded.apply(lambda x: int(x))
|
159 |
+
)
|
160 |
mean_trade_size = market_trades.collateralAmountUSD.mean()
|
161 |
total_bet_amount = sum(market_trades.collateralAmountUSD)
|
162 |
# trades for outcome 0
|
163 |
+
trades_outcome_0 = market_trades.loc[market_trades["outcomeIndex"] == 0]
|
164 |
logger.debug(f"Total trades for outcome 0 = {len(trades_outcome_0)}")
|
165 |
# trades for outcome 1
|
166 |
+
trades_outcome_1 = market_trades.loc[market_trades["outcomeIndex"] == 1]
|
167 |
logger.debug(f"Total trades for outcome 1 = {len(trades_outcome_1)}")
|
168 |
+
first_outcome, second_outcome = compute_price_weighted_perc(
|
169 |
+
trades_outcome_0, trades_outcome_1, logger
|
170 |
+
)
|
171 |
+
bought_tokens_first, bought_tokens_second = (
|
172 |
+
compute_bought_tokens_distribution(trades_outcome_0, trades_outcome_1)
|
173 |
+
)
|
174 |
metric = abs(fpmm["first_token_perc"] - first_outcome)
|
175 |
logger.info(f"metric for this market {metric}")
|
176 |
else:
|
|
|
179 |
bought_tokens_first = bought_tokens_second = 0.0
|
180 |
first_outcome = second_outcome = 0.0
|
181 |
metric = 0.0
|
182 |
+
fpmms.at[i, "mean_trade_size"] = mean_trade_size
|
183 |
+
fpmms.at[i, "total_bet_amount"] = total_bet_amount
|
184 |
logger.info(
|
185 |
f"first outcome pwc ={first_outcome}, second outcome pwc = {second_outcome}"
|
186 |
)
|
187 |
+
fpmms.at[i, "price_weighted_first_outcome_perc"] = first_outcome
|
188 |
+
fpmms.at[i, "price_weighted_second_outcome_perc"] = second_outcome
|
189 |
+
fpmms.at[i, "bought_tokens_first_perc"] = bought_tokens_first
|
190 |
+
fpmms.at[i, "bought_tokens_second_perc"] = bought_tokens_second
|
191 |
+
fpmms.at[i, "dist_gap_perc"] = metric
|
192 |
logger.debug("Dataset after adding trading info")
|
193 |
logger.debug(fpmms.head())
|
194 |
return
|
tabs/dist_gap.py
CHANGED
@@ -9,16 +9,18 @@ HEIGHT = 300
|
|
9 |
WIDTH = 600
|
10 |
|
11 |
|
12 |
-
def get_dist_gap_time_evolution(
|
|
|
|
|
13 |
"""Function to paint the evolution in time of the distance gap between the tokens and the price weighted distributions"""
|
14 |
sns.set_style("darkgrid")
|
15 |
selected_market = all_markets.loc[all_markets["id"] == market_id]
|
16 |
-
selected_market["
|
17 |
selected_market.columns = selected_market.columns.astype(str)
|
18 |
|
19 |
return gr.LinePlot(
|
20 |
value=selected_market,
|
21 |
-
x="
|
22 |
y="dist_gap_perc",
|
23 |
y_title="Distribution gap in %",
|
24 |
interactive=True,
|
@@ -34,31 +36,35 @@ def get_dist_gap_time_evolution(market_id: str, all_markets: pd.DataFrame):
|
|
34 |
)
|
35 |
|
36 |
|
37 |
-
def
|
38 |
-
|
39 |
-
|
|
|
|
|
|
|
40 |
)
|
41 |
-
|
42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
)
|
|
|
44 |
avg_dist_gap_perc.rename(
|
45 |
columns={"dist_gap_perc": "mean_dist_gap_perc"}, inplace=True
|
46 |
)
|
47 |
-
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
y="mean_dist_gap_perc",
|
52 |
-
y_title="Mean dist gap percentage (%)",
|
53 |
-
interactive=True,
|
54 |
-
show_actions_button=True,
|
55 |
-
tooltip=[
|
56 |
-
"sample_datetime",
|
57 |
-
"mean_dist_gap_perc",
|
58 |
-
],
|
59 |
-
height=HEIGHT,
|
60 |
-
width=WIDTH,
|
61 |
)
|
|
|
|
|
|
|
|
|
62 |
|
63 |
|
64 |
def get_top_best_behaviour_markets(markets_data: pd.DataFrame):
|
|
|
9 |
WIDTH = 600
|
10 |
|
11 |
|
12 |
+
def get_dist_gap_time_evolution(
|
13 |
+
market_id: str, all_markets: pd.DataFrame
|
14 |
+
) -> gr.LinePlot:
|
15 |
"""Function to paint the evolution in time of the distance gap between the tokens and the price weighted distributions"""
|
16 |
sns.set_style("darkgrid")
|
17 |
selected_market = all_markets.loc[all_markets["id"] == market_id]
|
18 |
+
selected_market["sample_date"] = selected_market["sample_date"].astype(str)
|
19 |
selected_market.columns = selected_market.columns.astype(str)
|
20 |
|
21 |
return gr.LinePlot(
|
22 |
value=selected_market,
|
23 |
+
x="sample_date",
|
24 |
y="dist_gap_perc",
|
25 |
y_title="Distribution gap in %",
|
26 |
interactive=True,
|
|
|
36 |
)
|
37 |
|
38 |
|
39 |
+
def get_dist_gap_timeline_plotly(market_id: str, all_markets: pd.DataFrame) -> gr.Plot:
|
40 |
+
selected_market = all_markets.loc[all_markets["id"] == market_id]
|
41 |
+
fig = px.line(selected_market, x="sample_date", y="dist_gap_perc")
|
42 |
+
fig.update_layout(
|
43 |
+
xaxis_title="Day of the sample",
|
44 |
+
yaxis_title="Distribution gap in %",
|
45 |
)
|
46 |
+
fig.update_layout(width=WIDTH, height=HEIGHT)
|
47 |
+
fig.update_xaxes(tickformat="%b-%d-%Y")
|
48 |
+
return gr.Plot(value=fig)
|
49 |
+
|
50 |
+
|
51 |
+
def get_avg_gap_time_evolution(all_markets: pd.DataFrame) -> gr.Plot:
|
52 |
+
avg_dist_gap_perc = (
|
53 |
+
all_markets.groupby("sample_date")["dist_gap_perc"].mean().reset_index()
|
54 |
)
|
55 |
+
avg_dist_gap_perc["sample_date"] = avg_dist_gap_perc["sample_date"].astype(str)
|
56 |
avg_dist_gap_perc.rename(
|
57 |
columns={"dist_gap_perc": "mean_dist_gap_perc"}, inplace=True
|
58 |
)
|
59 |
+
fig = px.line(avg_dist_gap_perc, x="sample_date", y="mean_dist_gap_perc")
|
60 |
+
fig.update_layout(
|
61 |
+
xaxis_title="Day of the sample",
|
62 |
+
yaxis_title="Mean dist gap percentage (%)",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
)
|
64 |
+
# fig.update_layout(width=WIDTH, height=HEIGHT)
|
65 |
+
# fig.update_xaxes(tickangle=45)
|
66 |
+
fig.update_xaxes(tickformat="%b-%d-%Y")
|
67 |
+
return gr.Plot(value=fig)
|
68 |
|
69 |
|
70 |
def get_top_best_behaviour_markets(markets_data: pd.DataFrame):
|