prediction-market-agent-tooling 0.33.0__py3-none-any.whl → 0.35.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- prediction_market_agent_tooling/markets/manifold/data_models.py +1 -1
- prediction_market_agent_tooling/markets/omen/omen.py +43 -4
- prediction_market_agent_tooling/monitor/monitor.py +36 -5
- prediction_market_agent_tooling/tools/utils.py +33 -0
- {prediction_market_agent_tooling-0.33.0.dist-info → prediction_market_agent_tooling-0.35.0.dist-info}/METADATA +2 -2
- {prediction_market_agent_tooling-0.33.0.dist-info → prediction_market_agent_tooling-0.35.0.dist-info}/RECORD +9 -9
- {prediction_market_agent_tooling-0.33.0.dist-info → prediction_market_agent_tooling-0.35.0.dist-info}/LICENSE +0 -0
- {prediction_market_agent_tooling-0.33.0.dist-info → prediction_market_agent_tooling-0.35.0.dist-info}/WHEEL +0 -0
- {prediction_market_agent_tooling-0.33.0.dist-info → prediction_market_agent_tooling-0.35.0.dist-info}/entry_points.txt +0 -0
@@ -79,7 +79,7 @@ class ManifoldMarket(BaseModel):
|
|
79
79
|
"""
|
80
80
|
Clip the timestamp to the maximum valid timestamp.
|
81
81
|
"""
|
82
|
-
max_timestamp = (datetime.max - timedelta(
|
82
|
+
max_timestamp = (datetime.max - timedelta(days=1)).timestamp()
|
83
83
|
value = int(min(value / 1000, max_timestamp))
|
84
84
|
return datetime.fromtimestamp(value)
|
85
85
|
|
@@ -10,6 +10,7 @@ from prediction_market_agent_tooling.gtypes import (
|
|
10
10
|
ChecksumAddress,
|
11
11
|
HexAddress,
|
12
12
|
HexStr,
|
13
|
+
OmenOutcomeToken,
|
13
14
|
OutcomeStr,
|
14
15
|
Probability,
|
15
16
|
Wei,
|
@@ -54,7 +55,10 @@ from prediction_market_agent_tooling.markets.omen.omen_subgraph_handler import (
|
|
54
55
|
)
|
55
56
|
from prediction_market_agent_tooling.tools.balances import get_balances
|
56
57
|
from prediction_market_agent_tooling.tools.hexbytes_custom import HexBytes
|
57
|
-
from prediction_market_agent_tooling.tools.utils import
|
58
|
+
from prediction_market_agent_tooling.tools.utils import (
|
59
|
+
calculate_sell_amount_in_collateral,
|
60
|
+
check_not_none,
|
61
|
+
)
|
58
62
|
from prediction_market_agent_tooling.tools.web3_utils import (
|
59
63
|
add_fraction,
|
60
64
|
remove_fraction,
|
@@ -80,6 +84,8 @@ class OmenAgentMarket(AgentMarket):
|
|
80
84
|
finalized_time: datetime | None
|
81
85
|
created_time: datetime
|
82
86
|
close_time: datetime
|
87
|
+
outcome_token_amounts: list[OmenOutcomeToken]
|
88
|
+
fee: float # proportion, from 0 to 1
|
83
89
|
|
84
90
|
INVALID_MARKET_ANSWER: HexStr = HexStr(
|
85
91
|
"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
@@ -155,19 +161,50 @@ class OmenAgentMarket(AgentMarket):
|
|
155
161
|
web3=web3,
|
156
162
|
)
|
157
163
|
|
164
|
+
def calculate_sell_amount_in_collateral(
|
165
|
+
self, amount: TokenAmount, outcome: bool
|
166
|
+
) -> xDai:
|
167
|
+
if len(self.outcome_token_amounts) != 2:
|
168
|
+
raise ValueError(
|
169
|
+
f"Market {self.id} has {len(self.outcome_token_amounts)} "
|
170
|
+
f"outcomes. This method only supports binary markets."
|
171
|
+
)
|
172
|
+
sell_index = self.yes_index if outcome else self.no_index
|
173
|
+
other_index = self.no_index if outcome else self.yes_index
|
174
|
+
collateral = calculate_sell_amount_in_collateral(
|
175
|
+
shares_to_sell=amount.amount,
|
176
|
+
holdings=wei_to_xdai(Wei(self.outcome_token_amounts[sell_index])),
|
177
|
+
other_holdings=wei_to_xdai(Wei(self.outcome_token_amounts[other_index])),
|
178
|
+
fee=self.fee,
|
179
|
+
)
|
180
|
+
return xDai(collateral)
|
181
|
+
|
158
182
|
def sell_tokens(
|
159
|
-
self,
|
183
|
+
self,
|
184
|
+
outcome: bool,
|
185
|
+
amount: TokenAmount,
|
186
|
+
auto_withdraw: bool = False,
|
187
|
+
api_keys: APIKeys | None = None,
|
188
|
+
web3: Web3 | None = None,
|
160
189
|
) -> None:
|
161
190
|
if not self.can_be_traded():
|
162
191
|
raise ValueError(
|
163
192
|
f"Market {self.id} is not open for trading. Cannot sell tokens."
|
164
193
|
)
|
194
|
+
|
195
|
+
# Convert from token (i.e. share) number to xDai value of tokens, as
|
196
|
+
# this is the expected unit of the argument in the smart contract.
|
197
|
+
collateral = self.calculate_sell_amount_in_collateral(
|
198
|
+
amount=amount,
|
199
|
+
outcome=outcome,
|
200
|
+
)
|
165
201
|
binary_omen_sell_outcome_tx(
|
166
|
-
|
167
|
-
|
202
|
+
amount=collateral,
|
203
|
+
api_keys=api_keys if api_keys is not None else APIKeys(),
|
168
204
|
market=self,
|
169
205
|
binary_outcome=outcome,
|
170
206
|
auto_withdraw=auto_withdraw,
|
207
|
+
web3=web3,
|
171
208
|
)
|
172
209
|
|
173
210
|
def was_any_bet_outcome_correct(
|
@@ -245,6 +282,8 @@ class OmenAgentMarket(AgentMarket):
|
|
245
282
|
url=model.url,
|
246
283
|
volume=wei_to_xdai(model.collateralVolume),
|
247
284
|
close_time=model.close_time,
|
285
|
+
outcome_token_amounts=model.outcomeTokenAmounts,
|
286
|
+
fee=float(wei_to_xdai(model.fee)) if model.fee is not None else 0.0,
|
248
287
|
)
|
249
288
|
|
250
289
|
@staticmethod
|
@@ -185,7 +185,7 @@ def monitor_agent(agent: DeployedAgent) -> None:
|
|
185
185
|
col3.markdown(f"Public ID: `{agent.public_id}`")
|
186
186
|
|
187
187
|
show_agent_bets = st.checkbox(
|
188
|
-
"Show resolved bets", value=False, key=f"{agent.name}_show_bets"
|
188
|
+
"Show resolved bets statistics", value=False, key=f"{agent.name}_show_bets"
|
189
189
|
)
|
190
190
|
if not show_agent_bets:
|
191
191
|
return
|
@@ -203,16 +203,43 @@ def monitor_agent(agent: DeployedAgent) -> None:
|
|
203
203
|
"Is Correct": [bet.is_correct for bet in agent_bets],
|
204
204
|
"Profit": [round(bet.profit.amount, 2) for bet in agent_bets],
|
205
205
|
}
|
206
|
-
|
206
|
+
|
207
|
+
# Time column to use for x-axes and sorting
|
208
|
+
x_axis_column = st.selectbox(
|
209
|
+
"X-axis column",
|
210
|
+
["Created Time", "Resolved Time"],
|
211
|
+
key=f"{agent.name}_x_axis_column",
|
212
|
+
)
|
213
|
+
|
214
|
+
bets_df = pd.DataFrame(bets_info).sort_values(by=x_axis_column, ascending=False)
|
215
|
+
bets_df["x-axis-day"] = bets_df[x_axis_column].dt.date
|
207
216
|
|
208
217
|
# Metrics
|
209
218
|
col1, col2 = st.columns(2)
|
210
219
|
col1.metric(label="Number of bets", value=f"{len(agent_bets)}")
|
211
220
|
col2.metric(label="% Correct", value=f"{100 * bets_df['Is Correct'].mean():.2f}%")
|
212
221
|
|
222
|
+
# Chart of grouped accuracy per day
|
223
|
+
per_day_accuracy = bets_df.groupby("x-axis-day")["Is Correct"].mean()
|
224
|
+
per_day_accuracy_chart = (
|
225
|
+
alt.Chart(per_day_accuracy.reset_index())
|
226
|
+
.encode(
|
227
|
+
x=alt.X("x-axis-day", axis=alt.Axis(format="%Y-%m-%d"), title=None),
|
228
|
+
y=alt.Y("Is Correct", axis=alt.Axis(format=".2f")),
|
229
|
+
)
|
230
|
+
.interactive()
|
231
|
+
)
|
232
|
+
st.altair_chart(
|
233
|
+
per_day_accuracy_chart.mark_line()
|
234
|
+
+ per_day_accuracy_chart.transform_loess("x-axis-day", "Is Correct").mark_line(
|
235
|
+
color="red", strokeDash=[5, 5]
|
236
|
+
),
|
237
|
+
use_container_width=True,
|
238
|
+
)
|
239
|
+
|
213
240
|
# Chart of cumulative profit per day
|
214
241
|
profit_info = {
|
215
|
-
"Time": bets_df[
|
242
|
+
"Time": bets_df[x_axis_column],
|
216
243
|
"Cumulative Profit": bets_df["Profit"].astype(float),
|
217
244
|
}
|
218
245
|
profit_df = pd.DataFrame(profit_info)
|
@@ -233,8 +260,12 @@ def monitor_agent(agent: DeployedAgent) -> None:
|
|
233
260
|
)
|
234
261
|
|
235
262
|
# Table of resolved bets
|
236
|
-
st.
|
237
|
-
|
263
|
+
show_bet_history = st.checkbox(
|
264
|
+
"Show resolved bet history", value=False, key=f"{agent.name}_show_bet_history"
|
265
|
+
)
|
266
|
+
if show_bet_history:
|
267
|
+
st.subheader("Resolved Bet History")
|
268
|
+
st.table(bets_df.drop(columns=["x-axis-day"]))
|
238
269
|
|
239
270
|
|
240
271
|
def monitor_market(
|
@@ -7,6 +7,7 @@ from typing import Any, NoReturn, Optional, Type, TypeVar, cast
|
|
7
7
|
import pytz
|
8
8
|
import requests
|
9
9
|
from pydantic import BaseModel, ValidationError
|
10
|
+
from scipy.optimize import newton
|
10
11
|
from scipy.stats import entropy
|
11
12
|
|
12
13
|
from prediction_market_agent_tooling.gtypes import (
|
@@ -173,3 +174,35 @@ def prob_uncertainty(prob: Probability) -> float:
|
|
173
174
|
- Market's probability is 0.95, so the market is quite certain about YES: prob_uncertainty(0.95) == 0.286
|
174
175
|
"""
|
175
176
|
return float(entropy([prob, 1 - prob], base=2))
|
177
|
+
|
178
|
+
|
179
|
+
def calculate_sell_amount_in_collateral(
|
180
|
+
shares_to_sell: float,
|
181
|
+
holdings: float,
|
182
|
+
other_holdings: float,
|
183
|
+
fee: float,
|
184
|
+
) -> float:
|
185
|
+
"""
|
186
|
+
Computes the amount of collateral that needs to be sold to get `shares`
|
187
|
+
amount of shares. Returns None if the amount can't be computed.
|
188
|
+
|
189
|
+
Taken from https://github.com/protofire/omen-exchange/blob/29d0ab16bdafa5cc0d37933c1c7608a055400c73/app/src/util/tools/fpmm/trading/index.ts#L99
|
190
|
+
Simplified for binary markets.
|
191
|
+
"""
|
192
|
+
|
193
|
+
if not (0 <= fee < 1.0):
|
194
|
+
raise ValueError("Fee must be between 0 and 1")
|
195
|
+
|
196
|
+
for v in [shares_to_sell, holdings, other_holdings]:
|
197
|
+
if v <= 0:
|
198
|
+
raise ValueError("All share args must be greater than 0")
|
199
|
+
|
200
|
+
def f(r: float) -> float:
|
201
|
+
R = r / (1 - fee)
|
202
|
+
first_term = other_holdings - R
|
203
|
+
second_term = holdings + shares_to_sell - R
|
204
|
+
third_term = holdings * other_holdings
|
205
|
+
return (first_term * second_term) - third_term
|
206
|
+
|
207
|
+
amount_to_sell = newton(f, 0)
|
208
|
+
return float(amount_to_sell) * 0.999999 # Avoid rounding errors
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: prediction-market-agent-tooling
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.35.0
|
4
4
|
Summary: Tools to benchmark, deploy and monitor prediction market agents.
|
5
5
|
Author: Gnosis
|
6
6
|
Requires-Python: >=3.10,<3.12
|
@@ -35,7 +35,7 @@ Requires-Dist: streamlit (>=1.31.0,<2.0.0)
|
|
35
35
|
Requires-Dist: subgrounds (>=1.8.1,<2.0.0)
|
36
36
|
Requires-Dist: tabulate (>=0.9.0,<0.10.0)
|
37
37
|
Requires-Dist: tqdm (>=4.66.2,<5.0.0)
|
38
|
-
Requires-Dist: typer (>=0.
|
38
|
+
Requires-Dist: typer (>=0.12.3,<0.13.0)
|
39
39
|
Requires-Dist: types-pytz (>=2024.1.0.20240203,<2025.0.0.0)
|
40
40
|
Requires-Dist: types-requests (>=2.31.0.0,<3.0.0.0)
|
41
41
|
Requires-Dist: web3 (>=6.15.1,<7.0.0)
|
@@ -25,13 +25,13 @@ prediction_market_agent_tooling/markets/categorize.py,sha256=yTd-lDMPW4ESDSzmxeL
|
|
25
25
|
prediction_market_agent_tooling/markets/data_models.py,sha256=uODY3aoFp8YYeLAUcrzMk1yU8pIKsTLobB9xIEGTmKs,1170
|
26
26
|
prediction_market_agent_tooling/markets/manifold/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
27
27
|
prediction_market_agent_tooling/markets/manifold/api.py,sha256=m6qOzDiyQfxj62Eo_SzzQLkX4ijpi8KtQKGd4CpKAsk,7307
|
28
|
-
prediction_market_agent_tooling/markets/manifold/data_models.py,sha256=
|
28
|
+
prediction_market_agent_tooling/markets/manifold/data_models.py,sha256=Iw-ajDPYhtfcTfN45nJN_kZShfWcWe9mgzexSWnQCCQ,5295
|
29
29
|
prediction_market_agent_tooling/markets/manifold/manifold.py,sha256=EwRL06E2Y_ZAzr8efwS5yD6p6rnykrcBhqmNDUGZ8Aw,4075
|
30
30
|
prediction_market_agent_tooling/markets/manifold/utils.py,sha256=cPPFWXm3vCYH1jy7_ctJZuQH9ZDaPL4_AgAYzGWkoow,513
|
31
31
|
prediction_market_agent_tooling/markets/markets.py,sha256=w05Oo7yCA2axpCw69Q9y4i9Gcdpht0u5bZGbWqld3rU,2964
|
32
32
|
prediction_market_agent_tooling/markets/omen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
33
33
|
prediction_market_agent_tooling/markets/omen/data_models.py,sha256=EXtjmcujx68Xu50BVkYXvLuf_Asx5o65RvFS3ZS6HGs,14405
|
34
|
-
prediction_market_agent_tooling/markets/omen/omen.py,sha256=
|
34
|
+
prediction_market_agent_tooling/markets/omen/omen.py,sha256=aJ5CCste61B7q0OD3EjLP8H7AjD_RaBBNyUfnZGh5KM,33597
|
35
35
|
prediction_market_agent_tooling/markets/omen/omen_contracts.py,sha256=eDS8vN4Klv_-Y1wwfIeLDt3twhl9U_AJjPQov0JScb0,19888
|
36
36
|
prediction_market_agent_tooling/markets/omen/omen_resolving.py,sha256=g77QsQ5WnSI2rzBlX87L_EhWMwobkyXyfRhHQmpAdzo,9012
|
37
37
|
prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py,sha256=RlaQMDF75lo2fos8LUb_OAdrw_ILLOXQLdejzE7tOmA,23053
|
@@ -44,7 +44,7 @@ prediction_market_agent_tooling/monitor/langfuse/langfuse_wrapper.py,sha256=b6T6
|
|
44
44
|
prediction_market_agent_tooling/monitor/markets/manifold.py,sha256=GdYpgRX1GahDi-75Mr53jgtEg6nWcs_rHDUkg4o_7dQ,3352
|
45
45
|
prediction_market_agent_tooling/monitor/markets/omen.py,sha256=jOLPnIbDU9syjnYtHfOb2xa6-Ize3vbplgh-8WWkuT4,3323
|
46
46
|
prediction_market_agent_tooling/monitor/markets/polymarket.py,sha256=I9z9aO1wncyGI3a09ihrw17JkeBKjAuMmC0I9pl_9o4,1781
|
47
|
-
prediction_market_agent_tooling/monitor/monitor.py,sha256=
|
47
|
+
prediction_market_agent_tooling/monitor/monitor.py,sha256=uJdaEpGWp4VcejoQLF0uOxhV75AhrXNyWPVG38gBeOo,14505
|
48
48
|
prediction_market_agent_tooling/monitor/monitor_app.py,sha256=rDxgdDJqSK0ARx0TJFMkS76npkHZJz0__Rp0xTpiRok,4611
|
49
49
|
prediction_market_agent_tooling/monitor/monitor_settings.py,sha256=Xiozs3AsufuJ04JOe1vjUri-IAMWHjjmc2ugGGiHNH4,947
|
50
50
|
prediction_market_agent_tooling/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -64,10 +64,10 @@ prediction_market_agent_tooling/tools/parallelism.py,sha256=8mgkF5sBwFGS5GMvlpza
|
|
64
64
|
prediction_market_agent_tooling/tools/safe.py,sha256=h0xOO0eNtitClf0fPkn-0oTc6A_bflDTee98V_aiV-A,5195
|
65
65
|
prediction_market_agent_tooling/tools/singleton.py,sha256=CiIELUiI-OeS7U7eeHEt0rnVhtQGzwoUdAgn_7u_GBM,729
|
66
66
|
prediction_market_agent_tooling/tools/streamlit_user_login.py,sha256=NXEqfjT9Lc9QtliwSGRASIz1opjQ7Btme43H4qJbzgE,3010
|
67
|
-
prediction_market_agent_tooling/tools/utils.py,sha256
|
67
|
+
prediction_market_agent_tooling/tools/utils.py,sha256=-G22UEbCRm59bm1RWFdeF55hRsaxgwZVAHvK32-Ye1g,6190
|
68
68
|
prediction_market_agent_tooling/tools/web3_utils.py,sha256=cboATXNmEdn5RmPbVblHOwOdUMKBYrUK3GiI6i6Vzxo,9855
|
69
|
-
prediction_market_agent_tooling-0.
|
70
|
-
prediction_market_agent_tooling-0.
|
71
|
-
prediction_market_agent_tooling-0.
|
72
|
-
prediction_market_agent_tooling-0.
|
73
|
-
prediction_market_agent_tooling-0.
|
69
|
+
prediction_market_agent_tooling-0.35.0.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
|
70
|
+
prediction_market_agent_tooling-0.35.0.dist-info/METADATA,sha256=PGIW673s30z0PdKLKcyhroDIjsBJWwzuZ7S-2bqIzyU,7515
|
71
|
+
prediction_market_agent_tooling-0.35.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
72
|
+
prediction_market_agent_tooling-0.35.0.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
|
73
|
+
prediction_market_agent_tooling-0.35.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|