prediction-market-agent-tooling 0.14.1__py3-none-any.whl → 0.15.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/abis/erc20.abi.json +315 -0
- prediction_market_agent_tooling/benchmark/agents.py +7 -1
- prediction_market_agent_tooling/benchmark/benchmark.py +22 -24
- prediction_market_agent_tooling/config.py +27 -4
- prediction_market_agent_tooling/deploy/agent.py +3 -3
- prediction_market_agent_tooling/markets/agent_market.py +20 -9
- prediction_market_agent_tooling/markets/manifold/manifold.py +9 -1
- prediction_market_agent_tooling/markets/omen/data_models.py +42 -11
- prediction_market_agent_tooling/markets/omen/omen.py +135 -52
- prediction_market_agent_tooling/markets/omen/omen_contracts.py +36 -34
- prediction_market_agent_tooling/markets/omen/omen_replicate.py +11 -16
- prediction_market_agent_tooling/markets/omen/omen_resolve_replicated.py +32 -25
- prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +46 -13
- prediction_market_agent_tooling/markets/polymarket/polymarket.py +1 -1
- prediction_market_agent_tooling/monitor/markets/omen.py +5 -3
- prediction_market_agent_tooling/monitor/markets/polymarket.py +3 -2
- prediction_market_agent_tooling/monitor/monitor.py +26 -20
- prediction_market_agent_tooling/tools/betting_strategies/minimum_bet_to_win.py +1 -1
- prediction_market_agent_tooling/tools/contract.py +32 -17
- prediction_market_agent_tooling/tools/costs.py +31 -0
- prediction_market_agent_tooling/tools/parallelism.py +16 -1
- prediction_market_agent_tooling/tools/safe.py +130 -0
- prediction_market_agent_tooling/tools/web3_utils.py +100 -15
- {prediction_market_agent_tooling-0.14.1.dist-info → prediction_market_agent_tooling-0.15.0.dist-info}/METADATA +13 -1
- {prediction_market_agent_tooling-0.14.1.dist-info → prediction_market_agent_tooling-0.15.0.dist-info}/RECORD +28 -25
- {prediction_market_agent_tooling-0.14.1.dist-info → prediction_market_agent_tooling-0.15.0.dist-info}/LICENSE +0 -0
- {prediction_market_agent_tooling-0.14.1.dist-info → prediction_market_agent_tooling-0.15.0.dist-info}/WHEEL +0 -0
- {prediction_market_agent_tooling-0.14.1.dist-info → prediction_market_agent_tooling-0.15.0.dist-info}/entry_points.txt +0 -0
@@ -21,7 +21,10 @@ from prediction_market_agent_tooling.markets.data_models import (
|
|
21
21
|
Resolution,
|
22
22
|
ResolvedBet,
|
23
23
|
)
|
24
|
-
from prediction_market_agent_tooling.tools.utils import
|
24
|
+
from prediction_market_agent_tooling.tools.utils import (
|
25
|
+
check_not_none,
|
26
|
+
should_not_happen,
|
27
|
+
)
|
25
28
|
from prediction_market_agent_tooling.tools.web3_utils import wei_to_xdai
|
26
29
|
|
27
30
|
OMEN_TRUE_OUTCOME = "Yes"
|
@@ -154,6 +157,8 @@ class OmenMarket(BaseModel):
|
|
154
157
|
creationTimestamp: int
|
155
158
|
condition: Condition
|
156
159
|
question: Question
|
160
|
+
lastActiveDay: int
|
161
|
+
lastActiveHour: int
|
157
162
|
|
158
163
|
@property
|
159
164
|
def openingTimestamp(self) -> int:
|
@@ -241,11 +246,19 @@ class OmenMarket(BaseModel):
|
|
241
246
|
)
|
242
247
|
|
243
248
|
@property
|
244
|
-
def
|
245
|
-
return
|
249
|
+
def yes_index(self) -> int:
|
250
|
+
return self.outcomes.index(OMEN_TRUE_OUTCOME)
|
251
|
+
|
252
|
+
@property
|
253
|
+
def no_index(self) -> int:
|
254
|
+
return self.outcomes.index(OMEN_FALSE_OUTCOME)
|
246
255
|
|
247
256
|
@property
|
248
|
-
def
|
257
|
+
def current_p_no(self) -> Probability:
|
258
|
+
return Probability(1 - self.current_p_yes)
|
259
|
+
|
260
|
+
@property
|
261
|
+
def current_p_yes(self) -> Probability:
|
249
262
|
"""
|
250
263
|
Calculate the probability of the outcomes from the relative token amounts.
|
251
264
|
|
@@ -257,21 +270,29 @@ class OmenMarket(BaseModel):
|
|
257
270
|
the the lower the price of that token, and therefore the lower the
|
258
271
|
probability of that outcome.
|
259
272
|
"""
|
260
|
-
if self.outcomeTokenAmounts is None:
|
261
|
-
raise ValueError(
|
262
|
-
f"Market with title {self.title} has no outcomeTokenAmounts."
|
263
|
-
)
|
264
273
|
if len(self.outcomeTokenAmounts) != 2:
|
265
274
|
raise ValueError(
|
266
275
|
f"Market with title {self.title} has {len(self.outcomeTokenAmounts)} outcomes."
|
267
276
|
)
|
268
|
-
true_index = self.outcomes.index(OMEN_TRUE_OUTCOME)
|
269
277
|
|
270
278
|
if sum(self.outcomeTokenAmounts) == 0:
|
271
|
-
|
279
|
+
# If there are no outcome tokens, it should mean that market is closed and without liquidity, so we need to infer the probabilities based on the answer.
|
280
|
+
return (
|
281
|
+
Probability(1.0)
|
282
|
+
if self.yes_index == self.answer_index
|
283
|
+
else (
|
284
|
+
Probability(0.0)
|
285
|
+
if self.no_index == self.answer_index
|
286
|
+
else (
|
287
|
+
Probability(0.5)
|
288
|
+
if not self.has_valid_answer # Invalid market or closed market without resolution.
|
289
|
+
else should_not_happen("Unknown condition.")
|
290
|
+
)
|
291
|
+
)
|
292
|
+
)
|
272
293
|
|
273
294
|
return Probability(
|
274
|
-
1 - self.outcomeTokenAmounts[
|
295
|
+
1 - self.outcomeTokenAmounts[self.yes_index] / sum(self.outcomeTokenAmounts)
|
275
296
|
)
|
276
297
|
|
277
298
|
def __repr__(self) -> str:
|
@@ -335,6 +356,16 @@ class OmenBet(BaseModel):
|
|
335
356
|
def boolean_outcome(self) -> bool:
|
336
357
|
return get_boolean_outcome(self.fpmm.outcomes[self.outcomeIndex])
|
337
358
|
|
359
|
+
@property
|
360
|
+
def old_probability(self) -> Probability:
|
361
|
+
# Old marginal price is the probability of the outcome before placing this bet.
|
362
|
+
return Probability(float(self.oldOutcomeTokenMarginalPrice))
|
363
|
+
|
364
|
+
@property
|
365
|
+
def probability(self) -> Probability:
|
366
|
+
# Marginal price is the probability of the outcome after placing this bet.
|
367
|
+
return Probability(float(self.outcomeTokenMarginalPrice))
|
368
|
+
|
338
369
|
def get_profit(self) -> ProfitAmount:
|
339
370
|
bet_amount_xdai = wei_to_xdai(self.collateralAmount)
|
340
371
|
profit = (
|
@@ -6,13 +6,13 @@ from loguru import logger
|
|
6
6
|
from web3 import Web3
|
7
7
|
from web3.constants import HASH_ZERO
|
8
8
|
|
9
|
-
from prediction_market_agent_tooling.config import APIKeys
|
9
|
+
from prediction_market_agent_tooling.config import APIKeys, PrivateCredentials
|
10
10
|
from prediction_market_agent_tooling.gtypes import (
|
11
11
|
ChecksumAddress,
|
12
12
|
HexAddress,
|
13
13
|
HexStr,
|
14
14
|
OutcomeStr,
|
15
|
-
|
15
|
+
Probability,
|
16
16
|
Wei,
|
17
17
|
wei_type,
|
18
18
|
xDai,
|
@@ -56,7 +56,6 @@ from prediction_market_agent_tooling.tools.hexbytes_custom import HexBytes
|
|
56
56
|
from prediction_market_agent_tooling.tools.utils import check_not_none
|
57
57
|
from prediction_market_agent_tooling.tools.web3_utils import (
|
58
58
|
add_fraction,
|
59
|
-
private_key_to_public_key,
|
60
59
|
remove_fraction,
|
61
60
|
wei_to_xdai,
|
62
61
|
xdai_to_wei,
|
@@ -85,6 +84,38 @@ class OmenAgentMarket(AgentMarket):
|
|
85
84
|
"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
86
85
|
)
|
87
86
|
|
87
|
+
_binary_market_p_yes_history: list[Probability] | None = None
|
88
|
+
|
89
|
+
@property
|
90
|
+
def yes_index(self) -> int:
|
91
|
+
return self.outcomes.index(OMEN_TRUE_OUTCOME)
|
92
|
+
|
93
|
+
@property
|
94
|
+
def no_index(self) -> int:
|
95
|
+
return self.outcomes.index(OMEN_FALSE_OUTCOME)
|
96
|
+
|
97
|
+
def get_p_yes_history_cached(self) -> list[Probability]:
|
98
|
+
if self._binary_market_p_yes_history is None:
|
99
|
+
self._binary_market_p_yes_history = get_binary_market_p_yes_history(self)
|
100
|
+
return self._binary_market_p_yes_history
|
101
|
+
|
102
|
+
def get_last_trade_p_yes(self) -> Probability | None:
|
103
|
+
"""On Omen, probablities converge after the resolution, so we need to get market's predicted probability from the trade history."""
|
104
|
+
return (
|
105
|
+
self.get_p_yes_history_cached()[-1]
|
106
|
+
if self.get_p_yes_history_cached()
|
107
|
+
else None
|
108
|
+
)
|
109
|
+
|
110
|
+
def get_last_trade_p_no(self) -> Probability | None:
|
111
|
+
"""On Omen, probablities converge after the resolution, so we need to get market's predicted probability from the trade history."""
|
112
|
+
last_trade_p_yes = self.get_last_trade_p_yes()
|
113
|
+
return (
|
114
|
+
Probability(1.0 - last_trade_p_yes)
|
115
|
+
if last_trade_p_yes is not None
|
116
|
+
else None
|
117
|
+
)
|
118
|
+
|
88
119
|
def get_liquidity(self) -> Wei:
|
89
120
|
return self.get_contract().totalSupply()
|
90
121
|
|
@@ -95,27 +126,34 @@ class OmenAgentMarket(AgentMarket):
|
|
95
126
|
return BetAmount(amount=0.00001, currency=self.currency)
|
96
127
|
|
97
128
|
def place_bet(
|
98
|
-
self,
|
129
|
+
self,
|
130
|
+
outcome: bool,
|
131
|
+
amount: BetAmount,
|
132
|
+
omen_auto_deposit: bool = True,
|
133
|
+
web3: Web3 | None = None,
|
99
134
|
) -> None:
|
100
135
|
if amount.currency != self.currency:
|
101
136
|
raise ValueError(f"Omen bets are made in xDai. Got {amount.currency}.")
|
102
137
|
amount_xdai = xDai(amount.amount)
|
103
138
|
keys = APIKeys()
|
139
|
+
private_credentials = PrivateCredentials.from_api_keys(keys)
|
104
140
|
binary_omen_buy_outcome_tx(
|
141
|
+
private_credentials=private_credentials,
|
105
142
|
amount=amount_xdai,
|
106
|
-
from_private_key=keys.bet_from_private_key,
|
107
143
|
market=self,
|
108
144
|
binary_outcome=outcome,
|
109
145
|
auto_deposit=omen_auto_deposit,
|
146
|
+
web3=web3,
|
110
147
|
)
|
111
148
|
|
112
149
|
def sell_tokens(
|
113
150
|
self, outcome: bool, amount: TokenAmount, auto_withdraw: bool = True
|
114
151
|
) -> None:
|
115
152
|
keys = APIKeys()
|
153
|
+
private_credentials = PrivateCredentials.from_api_keys(keys)
|
116
154
|
binary_omen_sell_outcome_tx(
|
155
|
+
private_credentials=private_credentials,
|
117
156
|
amount=xDai(amount.amount),
|
118
|
-
from_private_key=keys.bet_from_private_key,
|
119
157
|
market=self,
|
120
158
|
binary_outcome=outcome,
|
121
159
|
auto_withdraw=auto_withdraw,
|
@@ -165,8 +203,11 @@ class OmenAgentMarket(AgentMarket):
|
|
165
203
|
)
|
166
204
|
return len(user_positions) > 0
|
167
205
|
|
168
|
-
def redeem_positions(
|
169
|
-
|
206
|
+
def redeem_positions(
|
207
|
+
self,
|
208
|
+
private_credentials: PrivateCredentials,
|
209
|
+
) -> None:
|
210
|
+
for_public_key = private_credentials.public_key
|
170
211
|
market_is_redeemable = self.market_redeemable_by(user=for_public_key)
|
171
212
|
if not market_is_redeemable:
|
172
213
|
logger.debug(
|
@@ -174,7 +215,9 @@ class OmenAgentMarket(AgentMarket):
|
|
174
215
|
)
|
175
216
|
return None
|
176
217
|
|
177
|
-
omen_redeem_full_position_tx(
|
218
|
+
omen_redeem_full_position_tx(
|
219
|
+
private_credentials=private_credentials, market=self
|
220
|
+
)
|
178
221
|
|
179
222
|
@staticmethod
|
180
223
|
def from_data_model(model: OmenMarket) -> "OmenAgentMarket":
|
@@ -188,7 +231,7 @@ class OmenAgentMarket(AgentMarket):
|
|
188
231
|
resolution=model.get_resolution_enum(),
|
189
232
|
created_time=model.creation_datetime,
|
190
233
|
finalized_time=model.finalized_datetime,
|
191
|
-
|
234
|
+
current_p_yes=model.current_p_yes,
|
192
235
|
condition=model.condition,
|
193
236
|
url=model.url,
|
194
237
|
volume=wei_to_xdai(model.collateralVolume),
|
@@ -222,9 +265,11 @@ class OmenAgentMarket(AgentMarket):
|
|
222
265
|
)
|
223
266
|
)
|
224
267
|
|
225
|
-
def get_contract(
|
268
|
+
def get_contract(
|
269
|
+
self,
|
270
|
+
) -> OmenFixedProductMarketMakerContract:
|
226
271
|
return OmenFixedProductMarketMakerContract(
|
227
|
-
address=self.market_maker_contract_address_checksummed
|
272
|
+
address=self.market_maker_contract_address_checksummed,
|
228
273
|
)
|
229
274
|
|
230
275
|
def get_index_set(self, outcome: str) -> int:
|
@@ -238,10 +283,12 @@ class OmenAgentMarket(AgentMarket):
|
|
238
283
|
cls.get_outcome_str(cls.index_set_to_outcome_index(index_set))
|
239
284
|
)
|
240
285
|
|
241
|
-
def get_token_balance(
|
286
|
+
def get_token_balance(
|
287
|
+
self, user_id: str, outcome: str, web3: Web3 | None = None
|
288
|
+
) -> TokenAmount:
|
242
289
|
index_set = self.get_index_set(outcome)
|
243
290
|
balances = get_conditional_tokens_balance_for_market(
|
244
|
-
self, Web3.to_checksum_address(user_id)
|
291
|
+
self, Web3.to_checksum_address(user_id), web3=web3
|
245
292
|
)
|
246
293
|
return TokenAmount(
|
247
294
|
amount=wei_to_xdai(balances[index_set]),
|
@@ -309,72 +356,79 @@ def pick_binary_market(
|
|
309
356
|
|
310
357
|
|
311
358
|
def omen_buy_outcome_tx(
|
359
|
+
private_credentials: PrivateCredentials,
|
312
360
|
amount: xDai,
|
313
|
-
from_private_key: PrivateKey,
|
314
361
|
market: OmenAgentMarket,
|
315
362
|
outcome: str,
|
316
363
|
auto_deposit: bool,
|
364
|
+
web3: Web3 | None = None,
|
317
365
|
) -> None:
|
318
366
|
"""
|
319
367
|
Bets the given amount of xDai for the given outcome in the given market.
|
320
368
|
"""
|
321
369
|
amount_wei = xdai_to_wei(amount)
|
322
|
-
from_address_checksummed =
|
370
|
+
from_address_checksummed = private_credentials.public_key
|
323
371
|
|
324
372
|
market_contract: OmenFixedProductMarketMakerContract = market.get_contract()
|
373
|
+
|
325
374
|
collateral_token_contract = OmenCollateralTokenContract()
|
326
375
|
|
327
376
|
# Get the index of the outcome we want to buy.
|
328
377
|
outcome_index: int = market.get_outcome_index(outcome)
|
329
378
|
|
330
379
|
# Calculate the amount of shares we will get for the given investment amount.
|
331
|
-
expected_shares = market_contract.calcBuyAmount(
|
380
|
+
expected_shares = market_contract.calcBuyAmount(
|
381
|
+
amount_wei, outcome_index, web3=web3
|
382
|
+
)
|
332
383
|
# Allow 1% slippage.
|
333
384
|
expected_shares = remove_fraction(expected_shares, 0.01)
|
334
385
|
# Approve the market maker to withdraw our collateral token.
|
335
386
|
collateral_token_contract.approve(
|
387
|
+
private_credentials=private_credentials,
|
336
388
|
for_address=market_contract.address,
|
337
389
|
amount_wei=amount_wei,
|
338
|
-
|
390
|
+
web3=web3,
|
339
391
|
)
|
340
392
|
# Deposit xDai to the collateral token,
|
341
393
|
# this can be skipped, if we know we already have enough collateral tokens.
|
342
394
|
collateral_token_balance = collateral_token_contract.balanceOf(
|
343
|
-
for_address=from_address_checksummed,
|
395
|
+
for_address=from_address_checksummed, web3=web3
|
344
396
|
)
|
345
397
|
if auto_deposit and collateral_token_balance < amount_wei:
|
346
398
|
collateral_token_contract.deposit(
|
347
|
-
amount_wei=amount_wei,
|
348
|
-
from_private_key=from_private_key,
|
399
|
+
private_credentials=private_credentials, amount_wei=amount_wei, web3=web3
|
349
400
|
)
|
350
401
|
# Buy shares using the deposited xDai in the collateral token.
|
351
402
|
market_contract.buy(
|
403
|
+
private_credentials=private_credentials,
|
352
404
|
amount_wei=amount_wei,
|
353
405
|
outcome_index=outcome_index,
|
354
406
|
min_outcome_tokens_to_buy=expected_shares,
|
355
|
-
|
407
|
+
web3=web3,
|
356
408
|
)
|
357
409
|
|
358
410
|
|
359
411
|
def binary_omen_buy_outcome_tx(
|
412
|
+
private_credentials: PrivateCredentials,
|
360
413
|
amount: xDai,
|
361
|
-
from_private_key: PrivateKey,
|
362
414
|
market: OmenAgentMarket,
|
363
415
|
binary_outcome: bool,
|
364
416
|
auto_deposit: bool,
|
417
|
+
web3: Web3 | None = None,
|
365
418
|
) -> None:
|
366
419
|
omen_buy_outcome_tx(
|
420
|
+
private_credentials=private_credentials,
|
367
421
|
amount=amount,
|
368
|
-
from_private_key=from_private_key,
|
369
422
|
market=market,
|
370
423
|
outcome=OMEN_TRUE_OUTCOME if binary_outcome else OMEN_FALSE_OUTCOME,
|
371
424
|
auto_deposit=auto_deposit,
|
425
|
+
web3=web3,
|
372
426
|
)
|
373
427
|
|
374
428
|
|
375
429
|
def omen_sell_outcome_tx(
|
430
|
+
private_credentials: PrivateCredentials,
|
376
431
|
amount: xDai, # The xDai value of shares to sell.
|
377
|
-
from_private_key: PrivateKey,
|
378
432
|
market: OmenAgentMarket,
|
379
433
|
outcome: str,
|
380
434
|
auto_withdraw: bool,
|
@@ -410,35 +464,35 @@ def omen_sell_outcome_tx(
|
|
410
464
|
|
411
465
|
# Approve the market maker to move our (all) conditional tokens.
|
412
466
|
conditional_token_contract.setApprovalForAll(
|
467
|
+
private_credentials=private_credentials,
|
413
468
|
for_address=market_contract.address,
|
414
469
|
approve=True,
|
415
|
-
from_private_key=from_private_key,
|
416
470
|
)
|
417
471
|
# Sell the shares.
|
418
472
|
market_contract.sell(
|
473
|
+
private_credentials,
|
419
474
|
amount_wei,
|
420
475
|
outcome_index,
|
421
476
|
max_outcome_tokens_to_sell,
|
422
|
-
from_private_key,
|
423
477
|
)
|
424
478
|
if auto_withdraw:
|
425
479
|
# Optionally, withdraw from the collateral token back to the `from_address` wallet.
|
426
480
|
collateral_token.withdraw(
|
481
|
+
private_credentials=private_credentials,
|
427
482
|
amount_wei=amount_wei,
|
428
|
-
from_private_key=from_private_key,
|
429
483
|
)
|
430
484
|
|
431
485
|
|
432
486
|
def binary_omen_sell_outcome_tx(
|
487
|
+
private_credentials: PrivateCredentials,
|
433
488
|
amount: xDai,
|
434
|
-
from_private_key: PrivateKey,
|
435
489
|
market: OmenAgentMarket,
|
436
490
|
binary_outcome: bool,
|
437
491
|
auto_withdraw: bool,
|
438
492
|
) -> None:
|
439
493
|
omen_sell_outcome_tx(
|
494
|
+
private_credentials=private_credentials,
|
440
495
|
amount=amount,
|
441
|
-
from_private_key=from_private_key,
|
442
496
|
market=market,
|
443
497
|
outcome=OMEN_TRUE_OUTCOME if binary_outcome else OMEN_FALSE_OUTCOME,
|
444
498
|
auto_withdraw=auto_withdraw,
|
@@ -446,12 +500,12 @@ def binary_omen_sell_outcome_tx(
|
|
446
500
|
|
447
501
|
|
448
502
|
def omen_create_market_tx(
|
503
|
+
private_credentials: PrivateCredentials,
|
449
504
|
initial_funds: xDai,
|
450
505
|
question: str,
|
451
506
|
closing_time: datetime,
|
452
507
|
category: str,
|
453
508
|
language: str,
|
454
|
-
from_private_key: PrivateKey,
|
455
509
|
outcomes: list[str],
|
456
510
|
auto_deposit: bool,
|
457
511
|
fee: float = OMEN_DEFAULT_MARKET_FEE,
|
@@ -459,7 +513,7 @@ def omen_create_market_tx(
|
|
459
513
|
"""
|
460
514
|
Based on omen-exchange TypeScript code: https://github.com/protofire/omen-exchange/blob/b0b9a3e71b415d6becf21fe428e1c4fc0dad2e80/app/src/services/cpk/cpk.ts#L308
|
461
515
|
"""
|
462
|
-
from_address =
|
516
|
+
from_address = private_credentials.public_key
|
463
517
|
initial_funds_wei = xdai_to_wei(initial_funds)
|
464
518
|
|
465
519
|
realitio_contract = OmenRealitioContract()
|
@@ -482,9 +536,9 @@ def omen_create_market_tx(
|
|
482
536
|
|
483
537
|
# Approve the market maker to withdraw our collateral token.
|
484
538
|
collateral_token_contract.approve(
|
539
|
+
private_credentials=private_credentials,
|
485
540
|
for_address=factory_contract.address,
|
486
541
|
amount_wei=initial_funds_wei,
|
487
|
-
from_private_key=from_private_key,
|
488
542
|
)
|
489
543
|
|
490
544
|
# Deposit xDai to the collateral token,
|
@@ -497,17 +551,17 @@ def omen_create_market_tx(
|
|
497
551
|
and initial_funds_wei > 0
|
498
552
|
and collateral_token_balance < initial_funds_wei
|
499
553
|
):
|
500
|
-
collateral_token_contract.deposit(
|
554
|
+
collateral_token_contract.deposit(private_credentials, initial_funds_wei)
|
501
555
|
|
502
556
|
# Create the question on Realitio.
|
503
557
|
question_id = realitio_contract.askQuestion(
|
558
|
+
private_credentials=private_credentials,
|
504
559
|
question=question,
|
505
560
|
category=category,
|
506
561
|
outcomes=outcomes,
|
507
562
|
language=language,
|
508
563
|
arbitrator=Arbitrator.KLEROS,
|
509
564
|
opening=closing_time, # The question is opened at the closing time of the market.
|
510
|
-
from_private_key=from_private_key,
|
511
565
|
)
|
512
566
|
|
513
567
|
# Construct the condition id.
|
@@ -518,15 +572,15 @@ def omen_create_market_tx(
|
|
518
572
|
)
|
519
573
|
if not conditional_token_contract.does_condition_exists(condition_id):
|
520
574
|
conditional_token_contract.prepareCondition(
|
575
|
+
private_credentials=private_credentials,
|
521
576
|
question_id=question_id,
|
522
577
|
oracle_address=oracle_contract.address,
|
523
578
|
outcomes_slot_count=len(outcomes),
|
524
|
-
from_private_key=from_private_key,
|
525
579
|
)
|
526
580
|
|
527
581
|
# Create the market.
|
528
582
|
create_market_receipt_tx = factory_contract.create2FixedProductMarketMaker(
|
529
|
-
|
583
|
+
private_credentials=private_credentials,
|
530
584
|
condition_id=condition_id,
|
531
585
|
fee=fee,
|
532
586
|
initial_funds_wei=initial_funds_wei,
|
@@ -544,12 +598,12 @@ def omen_create_market_tx(
|
|
544
598
|
|
545
599
|
|
546
600
|
def omen_fund_market_tx(
|
601
|
+
private_credentials: PrivateCredentials,
|
547
602
|
market: OmenAgentMarket,
|
548
603
|
funds: Wei,
|
549
|
-
from_private_key: PrivateKey,
|
550
604
|
auto_deposit: bool,
|
551
605
|
) -> None:
|
552
|
-
from_address =
|
606
|
+
from_address = private_credentials.public_key
|
553
607
|
market_contract = market.get_contract()
|
554
608
|
collateral_token_contract = OmenCollateralTokenContract()
|
555
609
|
|
@@ -562,15 +616,15 @@ def omen_fund_market_tx(
|
|
562
616
|
)
|
563
617
|
< funds
|
564
618
|
):
|
565
|
-
collateral_token_contract.deposit(
|
619
|
+
collateral_token_contract.deposit(private_credentials, funds)
|
566
620
|
|
567
621
|
collateral_token_contract.approve(
|
622
|
+
private_credentials=private_credentials,
|
568
623
|
for_address=market_contract.address,
|
569
624
|
amount_wei=funds,
|
570
|
-
from_private_key=from_private_key,
|
571
625
|
)
|
572
626
|
|
573
|
-
market_contract.addFunding(
|
627
|
+
market_contract.addFunding(private_credentials, funds)
|
574
628
|
|
575
629
|
|
576
630
|
def build_parent_collection_id() -> HexStr:
|
@@ -578,8 +632,8 @@ def build_parent_collection_id() -> HexStr:
|
|
578
632
|
|
579
633
|
|
580
634
|
def omen_redeem_full_position_tx(
|
635
|
+
private_credentials: PrivateCredentials,
|
581
636
|
market: OmenAgentMarket,
|
582
|
-
from_private_key: PrivateKey,
|
583
637
|
web3: Web3 | None = None,
|
584
638
|
) -> None:
|
585
639
|
"""
|
@@ -587,7 +641,7 @@ def omen_redeem_full_position_tx(
|
|
587
641
|
to be redeemed before sending the transaction.
|
588
642
|
"""
|
589
643
|
|
590
|
-
from_address =
|
644
|
+
from_address = private_credentials.public_key
|
591
645
|
|
592
646
|
market_contract: OmenFixedProductMarketMakerContract = market.get_contract()
|
593
647
|
conditional_token_contract = OmenConditionalTokenContract()
|
@@ -617,7 +671,7 @@ def omen_redeem_full_position_tx(
|
|
617
671
|
return
|
618
672
|
|
619
673
|
conditional_token_contract.redeemPositions(
|
620
|
-
|
674
|
+
private_credentials=private_credentials,
|
621
675
|
collateral_token_address=market.collateral_token_contract_address_checksummed,
|
622
676
|
condition_id=market.condition.id,
|
623
677
|
parent_collection_id=parent_collection_id,
|
@@ -658,9 +712,9 @@ def get_conditional_tokens_balance_for_market(
|
|
658
712
|
|
659
713
|
|
660
714
|
def omen_remove_fund_market_tx(
|
715
|
+
private_credentials: PrivateCredentials,
|
661
716
|
market: OmenAgentMarket,
|
662
717
|
shares: Wei | None,
|
663
|
-
from_private_key: PrivateKey,
|
664
718
|
web3: Web3 | None = None,
|
665
719
|
) -> None:
|
666
720
|
"""
|
@@ -671,7 +725,7 @@ def omen_remove_fund_market_tx(
|
|
671
725
|
After we remove funding, using the `mergePositions` we get `min(shares per index)` of wxDai back, but the remaining shares can be converted back only after the market is resolved.
|
672
726
|
That can be done using the `redeem_from_all_user_positions` function below.
|
673
727
|
"""
|
674
|
-
from_address =
|
728
|
+
from_address = private_credentials.public_key
|
675
729
|
market_contract = market.get_contract()
|
676
730
|
original_balances = get_balances(from_address)
|
677
731
|
|
@@ -687,7 +741,7 @@ def omen_remove_fund_market_tx(
|
|
687
741
|
shares = total_shares
|
688
742
|
|
689
743
|
market_contract.removeFunding(
|
690
|
-
|
744
|
+
private_credentials=private_credentials, remove_funding=shares, web3=web3
|
691
745
|
)
|
692
746
|
|
693
747
|
conditional_tokens = OmenConditionalTokenContract()
|
@@ -701,7 +755,7 @@ def omen_remove_fund_market_tx(
|
|
701
755
|
amount_to_merge = min(amount_per_index_set.values())
|
702
756
|
|
703
757
|
result = conditional_tokens.mergePositions(
|
704
|
-
|
758
|
+
private_credentials=private_credentials,
|
705
759
|
collateral_token_address=market.collateral_token_contract_address_checksummed,
|
706
760
|
parent_collection_id=parent_collection_id,
|
707
761
|
conditionId=market.condition.id,
|
@@ -718,13 +772,13 @@ def omen_remove_fund_market_tx(
|
|
718
772
|
|
719
773
|
|
720
774
|
def redeem_from_all_user_positions(
|
721
|
-
|
775
|
+
private_credentials: PrivateCredentials,
|
722
776
|
web3: Web3 | None = None,
|
723
777
|
) -> None:
|
724
778
|
"""
|
725
779
|
Redeems from all user positions where the user didn't redeem yet.
|
726
780
|
"""
|
727
|
-
public_key =
|
781
|
+
public_key = private_credentials.public_key
|
728
782
|
|
729
783
|
conditional_token_contract = OmenConditionalTokenContract()
|
730
784
|
user_positions = OmenSubgraphHandler().get_user_positions(
|
@@ -748,7 +802,7 @@ def redeem_from_all_user_positions(
|
|
748
802
|
|
749
803
|
original_balances = get_balances(public_key)
|
750
804
|
conditional_token_contract.redeemPositions(
|
751
|
-
|
805
|
+
private_credentials=private_credentials,
|
752
806
|
collateral_token_address=user_position.position.collateral_token_contract_address_checksummed,
|
753
807
|
condition_id=condition_id,
|
754
808
|
parent_collection_id=build_parent_collection_id(),
|
@@ -760,3 +814,32 @@ def redeem_from_all_user_positions(
|
|
760
814
|
logger.info(
|
761
815
|
f"Redeemed {new_balances.wxdai - original_balances.wxdai} wxDai from position {user_position.id=}."
|
762
816
|
)
|
817
|
+
|
818
|
+
|
819
|
+
def get_binary_market_p_yes_history(market: OmenAgentMarket) -> list[Probability]:
|
820
|
+
history: list[Probability] = []
|
821
|
+
trades = sorted(
|
822
|
+
OmenSubgraphHandler().get_trades( # We need to look at price both after buying or selling, so get trades, not bets.
|
823
|
+
market_id=market.market_maker_contract_address_checksummed,
|
824
|
+
end_time=market.close_time, # Even after market is closed, there can be many `Sell` trades which will converge the probability to the true one.
|
825
|
+
),
|
826
|
+
key=lambda x: x.creation_datetime,
|
827
|
+
)
|
828
|
+
|
829
|
+
for index, trade in enumerate(trades):
|
830
|
+
# We need to append the old probability to have also the initial state of the market (before any bet placement).
|
831
|
+
history.append(
|
832
|
+
trade.old_probability
|
833
|
+
if trade.outcomeIndex == market.yes_index
|
834
|
+
else Probability(1 - trade.old_probability)
|
835
|
+
)
|
836
|
+
|
837
|
+
# At the last trade, we also need to append the new probability, to have the market latest state.
|
838
|
+
if index == len(trades) - 1:
|
839
|
+
history.append(
|
840
|
+
trade.probability
|
841
|
+
if trade.outcomeIndex == market.yes_index
|
842
|
+
else Probability(1 - trade.probability)
|
843
|
+
)
|
844
|
+
|
845
|
+
return history
|