prediction-market-agent-tooling 0.48.18__py3-none-any.whl → 0.49.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/deploy/agent.py +25 -7
- prediction_market_agent_tooling/deploy/betting_strategy.py +5 -35
- prediction_market_agent_tooling/jobs/omen/omen_jobs.py +2 -1
- prediction_market_agent_tooling/markets/agent_market.py +11 -3
- prediction_market_agent_tooling/markets/data_models.py +14 -0
- prediction_market_agent_tooling/markets/manifold/api.py +3 -1
- prediction_market_agent_tooling/markets/manifold/manifold.py +7 -2
- prediction_market_agent_tooling/markets/metaculus/metaculus.py +5 -0
- prediction_market_agent_tooling/markets/omen/data_models.py +7 -1
- prediction_market_agent_tooling/markets/omen/omen.py +34 -18
- prediction_market_agent_tooling/markets/polymarket/polymarket.py +1 -1
- prediction_market_agent_tooling/monitor/markets/polymarket.py +4 -0
- prediction_market_agent_tooling/tools/langfuse_client_utils.py +5 -5
- {prediction_market_agent_tooling-0.48.18.dist-info → prediction_market_agent_tooling-0.49.0.dist-info}/METADATA +1 -1
- {prediction_market_agent_tooling-0.48.18.dist-info → prediction_market_agent_tooling-0.49.0.dist-info}/RECORD +18 -18
- {prediction_market_agent_tooling-0.48.18.dist-info → prediction_market_agent_tooling-0.49.0.dist-info}/LICENSE +0 -0
- {prediction_market_agent_tooling-0.48.18.dist-info → prediction_market_agent_tooling-0.49.0.dist-info}/WHEEL +0 -0
- {prediction_market_agent_tooling-0.48.18.dist-info → prediction_market_agent_tooling-0.49.0.dist-info}/entry_points.txt +0 -0
@@ -38,6 +38,7 @@ from prediction_market_agent_tooling.markets.agent_market import (
|
|
38
38
|
SortBy,
|
39
39
|
)
|
40
40
|
from prediction_market_agent_tooling.markets.data_models import (
|
41
|
+
PlacedTrade,
|
41
42
|
Position,
|
42
43
|
ProbabilisticAnswer,
|
43
44
|
Trade,
|
@@ -110,7 +111,7 @@ class OutOfFundsError(ValueError):
|
|
110
111
|
|
111
112
|
class ProcessedMarket(BaseModel):
|
112
113
|
answer: ProbabilisticAnswer
|
113
|
-
trades: list[
|
114
|
+
trades: list[PlacedTrade]
|
114
115
|
|
115
116
|
|
116
117
|
class AnsweredEnum(str, Enum):
|
@@ -282,7 +283,6 @@ class DeployableTraderAgent(DeployableAgent):
|
|
282
283
|
bet_on_n_markets_per_run: int = 1
|
283
284
|
min_required_balance_to_operate: xDai | None = xdai_type(1)
|
284
285
|
min_balance_to_keep_in_native_currency: xDai | None = xdai_type(0.1)
|
285
|
-
strategy: BettingStrategy = MaxAccuracyBettingStrategy()
|
286
286
|
|
287
287
|
def __init__(
|
288
288
|
self,
|
@@ -292,6 +292,15 @@ class DeployableTraderAgent(DeployableAgent):
|
|
292
292
|
super().__init__(enable_langfuse=enable_langfuse)
|
293
293
|
self.place_bet = place_bet
|
294
294
|
|
295
|
+
def get_betting_strategy(self, market: AgentMarket) -> BettingStrategy:
|
296
|
+
user_id = market.get_user_id(api_keys=APIKeys())
|
297
|
+
|
298
|
+
total_amount = market.get_user_balance(user_id=user_id) * 0.1
|
299
|
+
if existing_position := market.get_position(user_id=user_id):
|
300
|
+
total_amount += existing_position.total_amount.amount
|
301
|
+
|
302
|
+
return MaxAccuracyBettingStrategy(bet_amount=total_amount)
|
303
|
+
|
295
304
|
def initialize_langfuse(self) -> None:
|
296
305
|
super().initialize_langfuse()
|
297
306
|
# Auto-observe all the methods where it makes sense, so that subclassses don't need to do it manually.
|
@@ -410,7 +419,8 @@ class DeployableTraderAgent(DeployableAgent):
|
|
410
419
|
answer: ProbabilisticAnswer,
|
411
420
|
existing_position: Position | None,
|
412
421
|
) -> list[Trade]:
|
413
|
-
|
422
|
+
strategy = self.get_betting_strategy(market=market)
|
423
|
+
trades = strategy.calculate_trades(existing_position, answer, market)
|
414
424
|
BettingStrategy.assert_trades_currency_match_markets(market, trades)
|
415
425
|
return trades
|
416
426
|
|
@@ -443,24 +453,32 @@ class DeployableTraderAgent(DeployableAgent):
|
|
443
453
|
|
444
454
|
existing_position = market.get_position(user_id=APIKeys().bet_from_address)
|
445
455
|
trades = self.build_trades(
|
446
|
-
market=market,
|
456
|
+
market=market,
|
457
|
+
answer=answer,
|
458
|
+
existing_position=existing_position,
|
447
459
|
)
|
448
460
|
|
461
|
+
placed_trades = []
|
449
462
|
if self.place_bet:
|
450
463
|
for trade in trades:
|
451
464
|
logger.info(f"Executing trade {trade}")
|
452
465
|
|
453
466
|
match trade.trade_type:
|
454
467
|
case TradeType.BUY:
|
455
|
-
market.buy_tokens(
|
468
|
+
id = market.buy_tokens(
|
469
|
+
outcome=trade.outcome, amount=trade.amount
|
470
|
+
)
|
456
471
|
case TradeType.SELL:
|
457
|
-
market.sell_tokens(
|
472
|
+
id = market.sell_tokens(
|
473
|
+
outcome=trade.outcome, amount=trade.amount
|
474
|
+
)
|
458
475
|
case _:
|
459
476
|
raise ValueError(f"Unexpected trade type {trade.trade_type}.")
|
477
|
+
placed_trades.append(PlacedTrade.from_trade(trade, id))
|
460
478
|
|
461
479
|
self.after_process_market(market_type, market)
|
462
480
|
|
463
|
-
processed_market = ProcessedMarket(answer=answer, trades=
|
481
|
+
processed_market = ProcessedMarket(answer=answer, trades=placed_trades)
|
464
482
|
self.update_langfuse_trace_by_processed_market(market_type, processed_market)
|
465
483
|
|
466
484
|
logger.info(f"Processed market {market.question=} from {market.url=}.")
|
@@ -30,12 +30,6 @@ class BettingStrategy(ABC):
|
|
30
30
|
def build_zero_token_amount(self, currency: Currency) -> TokenAmount:
|
31
31
|
return TokenAmount(amount=0, currency=currency)
|
32
32
|
|
33
|
-
@abstractmethod
|
34
|
-
def adjust_bet_amount(
|
35
|
-
self, existing_position: Position | None, market: AgentMarket
|
36
|
-
) -> float:
|
37
|
-
pass
|
38
|
-
|
39
33
|
@staticmethod
|
40
34
|
def assert_trades_currency_match_markets(
|
41
35
|
market: AgentMarket, trades: list[Trade]
|
@@ -99,20 +93,7 @@ class BettingStrategy(ABC):
|
|
99
93
|
|
100
94
|
|
101
95
|
class MaxAccuracyBettingStrategy(BettingStrategy):
|
102
|
-
def
|
103
|
-
self, existing_position: Position | None, market: AgentMarket
|
104
|
-
) -> float:
|
105
|
-
existing_position_total_amount = (
|
106
|
-
existing_position.total_amount.amount if existing_position else 0
|
107
|
-
)
|
108
|
-
bet_amount = (
|
109
|
-
market.get_tiny_bet_amount().amount
|
110
|
-
if self.bet_amount is None
|
111
|
-
else self.bet_amount
|
112
|
-
)
|
113
|
-
return bet_amount + existing_position_total_amount
|
114
|
-
|
115
|
-
def __init__(self, bet_amount: float | None = None):
|
96
|
+
def __init__(self, bet_amount: float):
|
116
97
|
self.bet_amount = bet_amount
|
117
98
|
|
118
99
|
def calculate_trades(
|
@@ -121,13 +102,11 @@ class MaxAccuracyBettingStrategy(BettingStrategy):
|
|
121
102
|
answer: ProbabilisticAnswer,
|
122
103
|
market: AgentMarket,
|
123
104
|
) -> list[Trade]:
|
124
|
-
adjusted_bet_amount = self.adjust_bet_amount(existing_position, market)
|
125
|
-
|
126
105
|
direction = self.calculate_direction(market.current_p_yes, answer.p_yes)
|
127
106
|
|
128
107
|
amounts = {
|
129
108
|
market.get_outcome_str_from_bool(direction): TokenAmount(
|
130
|
-
amount=
|
109
|
+
amount=self.bet_amount,
|
131
110
|
currency=market.currency,
|
132
111
|
),
|
133
112
|
}
|
@@ -155,24 +134,15 @@ class MaxExpectedValueBettingStrategy(MaxAccuracyBettingStrategy):
|
|
155
134
|
|
156
135
|
|
157
136
|
class KellyBettingStrategy(BettingStrategy):
|
158
|
-
def __init__(self, max_bet_amount: float
|
137
|
+
def __init__(self, max_bet_amount: float):
|
159
138
|
self.max_bet_amount = max_bet_amount
|
160
139
|
|
161
|
-
def adjust_bet_amount(
|
162
|
-
self, existing_position: Position | None, market: AgentMarket
|
163
|
-
) -> float:
|
164
|
-
existing_position_total_amount = (
|
165
|
-
existing_position.total_amount.amount if existing_position else 0
|
166
|
-
)
|
167
|
-
return self.max_bet_amount + existing_position_total_amount
|
168
|
-
|
169
140
|
def calculate_trades(
|
170
141
|
self,
|
171
142
|
existing_position: Position | None,
|
172
143
|
answer: ProbabilisticAnswer,
|
173
144
|
market: AgentMarket,
|
174
145
|
) -> list[Trade]:
|
175
|
-
adjusted_bet_amount = self.adjust_bet_amount(existing_position, market)
|
176
146
|
outcome_token_pool = check_not_none(market.outcome_token_pool)
|
177
147
|
kelly_bet = (
|
178
148
|
get_kelly_bet_full(
|
@@ -183,12 +153,12 @@ class KellyBettingStrategy(BettingStrategy):
|
|
183
153
|
market.get_outcome_str_from_bool(False)
|
184
154
|
],
|
185
155
|
estimated_p_yes=answer.p_yes,
|
186
|
-
max_bet=
|
156
|
+
max_bet=self.max_bet_amount,
|
187
157
|
confidence=answer.confidence,
|
188
158
|
)
|
189
159
|
if market.has_token_pool()
|
190
160
|
else get_kelly_bet_simplified(
|
191
|
-
|
161
|
+
self.max_bet_amount,
|
192
162
|
market.current_p_yes,
|
193
163
|
answer.p_yes,
|
194
164
|
answer.confidence,
|
@@ -83,7 +83,8 @@ def compute_job_reward(
|
|
83
83
|
market: OmenAgentMarket, max_bond: float, web3: Web3 | None = None
|
84
84
|
) -> float:
|
85
85
|
# Because jobs are powered by prediction markets, potentional reward depends on job's liquidity and our will to bond (bet) our xDai into our job completion.
|
86
|
-
|
86
|
+
strategy = KellyBettingStrategy(max_bet_amount=max_bond)
|
87
|
+
required_trades = strategy.calculate_trades(
|
87
88
|
existing_position=None,
|
88
89
|
# We assume that we finish the job and so the probability of the market happening will be 100%.
|
89
90
|
answer=ProbabilisticAnswer(p_yes=Probability(1.0), confidence=1.0),
|
@@ -166,13 +166,13 @@ class AgentMarket(BaseModel):
|
|
166
166
|
def liquidate_existing_positions(self, outcome: bool) -> None:
|
167
167
|
raise NotImplementedError("Subclasses must implement this method")
|
168
168
|
|
169
|
-
def place_bet(self, outcome: bool, amount: BetAmount) ->
|
169
|
+
def place_bet(self, outcome: bool, amount: BetAmount) -> str:
|
170
170
|
raise NotImplementedError("Subclasses must implement this method")
|
171
171
|
|
172
|
-
def buy_tokens(self, outcome: bool, amount: TokenAmount) ->
|
172
|
+
def buy_tokens(self, outcome: bool, amount: TokenAmount) -> str:
|
173
173
|
return self.place_bet(outcome=outcome, amount=amount)
|
174
174
|
|
175
|
-
def sell_tokens(self, outcome: bool, amount: TokenAmount) ->
|
175
|
+
def sell_tokens(self, outcome: bool, amount: TokenAmount) -> str:
|
176
176
|
raise NotImplementedError("Subclasses must implement this method")
|
177
177
|
|
178
178
|
@staticmethod
|
@@ -281,3 +281,11 @@ class AgentMarket(BaseModel):
|
|
281
281
|
raise ValueError("Outcome token pool is not available.")
|
282
282
|
|
283
283
|
return self.outcome_token_pool[outcome]
|
284
|
+
|
285
|
+
@staticmethod
|
286
|
+
def get_user_balance(user_id: str) -> float:
|
287
|
+
raise NotImplementedError("Subclasses must implement this method")
|
288
|
+
|
289
|
+
@staticmethod
|
290
|
+
def get_user_id(api_keys: APIKeys) -> str:
|
291
|
+
raise NotImplementedError("Subclasses must implement this method")
|
@@ -37,6 +37,7 @@ ProfitAmount: TypeAlias = TokenAmount
|
|
37
37
|
|
38
38
|
|
39
39
|
class Bet(BaseModel):
|
40
|
+
id: str
|
40
41
|
amount: BetAmount
|
41
42
|
outcome: bool
|
42
43
|
created_time: datetime
|
@@ -126,3 +127,16 @@ class Trade(BaseModel):
|
|
126
127
|
trade_type: TradeType
|
127
128
|
outcome: bool
|
128
129
|
amount: TokenAmount
|
130
|
+
|
131
|
+
|
132
|
+
class PlacedTrade(Trade):
|
133
|
+
id: str
|
134
|
+
|
135
|
+
@staticmethod
|
136
|
+
def from_trade(trade: Trade, id: str) -> "PlacedTrade":
|
137
|
+
return PlacedTrade(
|
138
|
+
trade_type=trade.trade_type,
|
139
|
+
outcome=trade.outcome,
|
140
|
+
amount=trade.amount,
|
141
|
+
id=id,
|
142
|
+
)
|
@@ -110,7 +110,7 @@ def get_one_manifold_binary_market() -> ManifoldMarket:
|
|
110
110
|
)
|
111
111
|
def place_bet(
|
112
112
|
amount: Mana, market_id: str, outcome: bool, manifold_api_key: SecretStr
|
113
|
-
) ->
|
113
|
+
) -> ManifoldBet:
|
114
114
|
outcome_str = "YES" if outcome else "NO"
|
115
115
|
url = f"{MANIFOLD_API_BASE_URL}/v0/bet"
|
116
116
|
params = {
|
@@ -131,6 +131,7 @@ def place_bet(
|
|
131
131
|
raise RuntimeError(
|
132
132
|
f"Placing bet failed: {response.status_code} {response.reason} {response.text}"
|
133
133
|
)
|
134
|
+
return ManifoldBet.model_validate(data)
|
134
135
|
else:
|
135
136
|
raise Exception(
|
136
137
|
f"Placing bet failed: {response.status_code} {response.reason} {response.text}"
|
@@ -209,6 +210,7 @@ def manifold_to_generic_resolved_bet(
|
|
209
210
|
|
210
211
|
market_outcome = market.get_resolved_boolean_outcome()
|
211
212
|
return ResolvedBet(
|
213
|
+
id=bet.id,
|
212
214
|
amount=BetAmount(amount=bet.amount, currency=Currency.Mana),
|
213
215
|
outcome=bet.get_resolved_boolean_outcome(),
|
214
216
|
created_time=bet.createdTime,
|
@@ -49,15 +49,16 @@ class ManifoldAgentMarket(AgentMarket):
|
|
49
49
|
# Manifold lowest bet is 1 Mana, so we need to ceil the result.
|
50
50
|
return mana_type(ceil(minimum_bet_to_win(answer, amount_to_win, self)))
|
51
51
|
|
52
|
-
def place_bet(self, outcome: bool, amount: BetAmount) ->
|
52
|
+
def place_bet(self, outcome: bool, amount: BetAmount) -> str:
|
53
53
|
if amount.currency != self.currency:
|
54
54
|
raise ValueError(f"Manifold bets are made in Mana. Got {amount.currency}.")
|
55
|
-
place_bet(
|
55
|
+
bet = place_bet(
|
56
56
|
amount=Mana(amount.amount),
|
57
57
|
market_id=self.id,
|
58
58
|
outcome=outcome,
|
59
59
|
manifold_api_key=APIKeys().manifold_api_key,
|
60
60
|
)
|
61
|
+
return bet.id
|
61
62
|
|
62
63
|
@staticmethod
|
63
64
|
def from_data_model(model: FullManifoldMarket) -> "ManifoldAgentMarket":
|
@@ -119,3 +120,7 @@ class ManifoldAgentMarket(AgentMarket):
|
|
119
120
|
@classmethod
|
120
121
|
def get_user_url(cls, keys: APIKeys) -> str:
|
121
122
|
return get_authenticated_user(keys.manifold_api_key.get_secret_value()).url
|
123
|
+
|
124
|
+
@staticmethod
|
125
|
+
def get_user_id(api_keys: APIKeys) -> str:
|
126
|
+
return api_keys.manifold_user_id
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import typing as t
|
2
2
|
from datetime import datetime
|
3
3
|
|
4
|
+
from prediction_market_agent_tooling.config import APIKeys
|
4
5
|
from prediction_market_agent_tooling.gtypes import Probability
|
5
6
|
from prediction_market_agent_tooling.markets.agent_market import (
|
6
7
|
AgentMarket,
|
@@ -104,3 +105,7 @@ class MetaculusAgentMarket(AgentMarket):
|
|
104
105
|
def submit_prediction(self, p_yes: Probability, reasoning: str) -> None:
|
105
106
|
make_prediction(self.id, p_yes)
|
106
107
|
post_question_comment(self.id, reasoning)
|
108
|
+
|
109
|
+
@staticmethod
|
110
|
+
def get_user_id(api_keys: APIKeys) -> str:
|
111
|
+
return str(api_keys.metaculus_user_id)
|
@@ -382,7 +382,7 @@ class OmenBetCreator(BaseModel):
|
|
382
382
|
|
383
383
|
|
384
384
|
class OmenBet(BaseModel):
|
385
|
-
id: HexAddress
|
385
|
+
id: HexAddress # A concatenation of: FPMM contract ID, trader ID and nonce. See https://github.com/protofire/omen-subgraph/blob/f92bbfb6fa31ed9cd5985c416a26a2f640837d8b/src/FixedProductMarketMakerMapping.ts#L109
|
386
386
|
title: str
|
387
387
|
collateralToken: HexAddress
|
388
388
|
outcomeTokenMarginalPrice: xDai
|
@@ -431,6 +431,9 @@ class OmenBet(BaseModel):
|
|
431
431
|
|
432
432
|
def to_bet(self) -> Bet:
|
433
433
|
return Bet(
|
434
|
+
id=str(
|
435
|
+
self.transactionHash
|
436
|
+
), # Use the transaction hash instead of the bet id - both are valid, but we return the transaction hash from the trade functions, so be consistent here.
|
434
437
|
amount=BetAmount(amount=self.collateralAmountUSD, currency=Currency.xDai),
|
435
438
|
outcome=self.boolean_outcome,
|
436
439
|
created_time=self.creation_datetime,
|
@@ -445,6 +448,9 @@ class OmenBet(BaseModel):
|
|
445
448
|
)
|
446
449
|
|
447
450
|
return ResolvedBet(
|
451
|
+
id=str(
|
452
|
+
self.transactionHash
|
453
|
+
), # Use the transaction hash instead of the bet id - both are valid, but we return the transaction hash from the trade functions, so be consistent here.
|
448
454
|
amount=BetAmount(amount=self.collateralAmountUSD, currency=Currency.xDai),
|
449
455
|
outcome=self.boolean_outcome,
|
450
456
|
created_time=self.creation_datetime,
|
@@ -189,7 +189,7 @@ class OmenAgentMarket(AgentMarket):
|
|
189
189
|
omen_auto_deposit: bool = True,
|
190
190
|
web3: Web3 | None = None,
|
191
191
|
api_keys: APIKeys | None = None,
|
192
|
-
) ->
|
192
|
+
) -> str:
|
193
193
|
if not self.can_be_traded():
|
194
194
|
raise ValueError(
|
195
195
|
f"Market {self.id} is not open for trading. Cannot place bet."
|
@@ -197,7 +197,7 @@ class OmenAgentMarket(AgentMarket):
|
|
197
197
|
if amount.currency != self.currency:
|
198
198
|
raise ValueError(f"Omen bets are made in xDai. Got {amount.currency}.")
|
199
199
|
amount_xdai = xDai(amount.amount)
|
200
|
-
binary_omen_buy_outcome_tx(
|
200
|
+
return binary_omen_buy_outcome_tx(
|
201
201
|
api_keys=api_keys if api_keys is not None else APIKeys(),
|
202
202
|
amount=amount_xdai,
|
203
203
|
market=self,
|
@@ -212,7 +212,7 @@ class OmenAgentMarket(AgentMarket):
|
|
212
212
|
amount: TokenAmount,
|
213
213
|
web3: Web3 | None = None,
|
214
214
|
api_keys: APIKeys | None = None,
|
215
|
-
) ->
|
215
|
+
) -> str:
|
216
216
|
return self.place_bet(
|
217
217
|
outcome=outcome,
|
218
218
|
amount=amount,
|
@@ -245,7 +245,7 @@ class OmenAgentMarket(AgentMarket):
|
|
245
245
|
auto_withdraw: bool = False,
|
246
246
|
api_keys: APIKeys | None = None,
|
247
247
|
web3: Web3 | None = None,
|
248
|
-
) ->
|
248
|
+
) -> str:
|
249
249
|
if not self.can_be_traded():
|
250
250
|
raise ValueError(
|
251
251
|
f"Market {self.id} is not open for trading. Cannot sell tokens."
|
@@ -258,7 +258,7 @@ class OmenAgentMarket(AgentMarket):
|
|
258
258
|
outcome=outcome,
|
259
259
|
web3=web3,
|
260
260
|
)
|
261
|
-
binary_omen_sell_outcome_tx(
|
261
|
+
return binary_omen_sell_outcome_tx(
|
262
262
|
amount=collateral,
|
263
263
|
api_keys=api_keys if api_keys is not None else APIKeys(),
|
264
264
|
market=self,
|
@@ -633,6 +633,14 @@ class OmenAgentMarket(AgentMarket):
|
|
633
633
|
)
|
634
634
|
return Probability(new_p_yes)
|
635
635
|
|
636
|
+
@staticmethod
|
637
|
+
def get_user_balance(user_id: str) -> float:
|
638
|
+
return float(get_balances(Web3.to_checksum_address(user_id)).total)
|
639
|
+
|
640
|
+
@staticmethod
|
641
|
+
def get_user_id(api_keys: APIKeys) -> str:
|
642
|
+
return api_keys.bet_from_address
|
643
|
+
|
636
644
|
|
637
645
|
def get_omen_user_url(address: ChecksumAddress) -> str:
|
638
646
|
return f"https://gnosisscan.io/address/{address}"
|
@@ -659,7 +667,7 @@ def omen_buy_outcome_tx(
|
|
659
667
|
outcome: str,
|
660
668
|
auto_deposit: bool,
|
661
669
|
web3: Web3 | None = None,
|
662
|
-
) ->
|
670
|
+
) -> str:
|
663
671
|
"""
|
664
672
|
Bets the given amount of xDai for the given outcome in the given market.
|
665
673
|
"""
|
@@ -695,7 +703,7 @@ def omen_buy_outcome_tx(
|
|
695
703
|
)
|
696
704
|
|
697
705
|
# Buy shares using the deposited xDai in the collateral token.
|
698
|
-
market_contract.buy(
|
706
|
+
tx_receipt = market_contract.buy(
|
699
707
|
api_keys=api_keys,
|
700
708
|
amount_wei=amount_wei_to_buy,
|
701
709
|
outcome_index=outcome_index,
|
@@ -703,6 +711,8 @@ def omen_buy_outcome_tx(
|
|
703
711
|
web3=web3,
|
704
712
|
)
|
705
713
|
|
714
|
+
return tx_receipt["transactionHash"].hex()
|
715
|
+
|
706
716
|
|
707
717
|
def binary_omen_buy_outcome_tx(
|
708
718
|
api_keys: APIKeys,
|
@@ -711,8 +721,8 @@ def binary_omen_buy_outcome_tx(
|
|
711
721
|
binary_outcome: bool,
|
712
722
|
auto_deposit: bool,
|
713
723
|
web3: Web3 | None = None,
|
714
|
-
) ->
|
715
|
-
omen_buy_outcome_tx(
|
724
|
+
) -> str:
|
725
|
+
return omen_buy_outcome_tx(
|
716
726
|
api_keys=api_keys,
|
717
727
|
amount=amount,
|
718
728
|
market=market,
|
@@ -729,7 +739,7 @@ def omen_sell_outcome_tx(
|
|
729
739
|
outcome: str,
|
730
740
|
auto_withdraw: bool,
|
731
741
|
web3: Web3 | None = None,
|
732
|
-
) ->
|
742
|
+
) -> str:
|
733
743
|
"""
|
734
744
|
Sells the given xDai value of shares corresponding to the given outcome in
|
735
745
|
the given market.
|
@@ -770,7 +780,7 @@ def omen_sell_outcome_tx(
|
|
770
780
|
web3=web3,
|
771
781
|
)
|
772
782
|
# Sell the shares.
|
773
|
-
market_contract.sell(
|
783
|
+
tx_receipt = market_contract.sell(
|
774
784
|
api_keys,
|
775
785
|
amount_wei,
|
776
786
|
outcome_index,
|
@@ -792,6 +802,8 @@ def omen_sell_outcome_tx(
|
|
792
802
|
web3,
|
793
803
|
)
|
794
804
|
|
805
|
+
return tx_receipt["transactionHash"].hex()
|
806
|
+
|
795
807
|
|
796
808
|
def binary_omen_sell_outcome_tx(
|
797
809
|
api_keys: APIKeys,
|
@@ -800,8 +812,8 @@ def binary_omen_sell_outcome_tx(
|
|
800
812
|
binary_outcome: bool,
|
801
813
|
auto_withdraw: bool,
|
802
814
|
web3: Web3 | None = None,
|
803
|
-
) ->
|
804
|
-
omen_sell_outcome_tx(
|
815
|
+
) -> str:
|
816
|
+
return omen_sell_outcome_tx(
|
805
817
|
api_keys=api_keys,
|
806
818
|
amount=amount,
|
807
819
|
market=market,
|
@@ -930,7 +942,7 @@ def omen_fund_market_tx(
|
|
930
942
|
web3: Web3 | None = None,
|
931
943
|
) -> None:
|
932
944
|
market_contract = market.get_contract()
|
933
|
-
collateral_token_contract = market_contract.get_collateral_token_contract()
|
945
|
+
collateral_token_contract = market_contract.get_collateral_token_contract(web3=web3)
|
934
946
|
|
935
947
|
amount_to_fund = collateral_token_contract.get_in_shares(funds, web3)
|
936
948
|
|
@@ -1048,8 +1060,12 @@ def omen_remove_fund_market_tx(
|
|
1048
1060
|
"""
|
1049
1061
|
from_address = api_keys.bet_from_address
|
1050
1062
|
market_contract = market.get_contract()
|
1051
|
-
market_collateral_token_contract = market_contract.get_collateral_token_contract(
|
1052
|
-
|
1063
|
+
market_collateral_token_contract = market_contract.get_collateral_token_contract(
|
1064
|
+
web3=web3
|
1065
|
+
)
|
1066
|
+
original_balance = market_collateral_token_contract.balanceOf(
|
1067
|
+
from_address, web3=web3
|
1068
|
+
)
|
1053
1069
|
|
1054
1070
|
total_shares = market_contract.balanceOf(from_address, web3=web3)
|
1055
1071
|
if total_shares == 0:
|
@@ -1084,11 +1100,11 @@ def omen_remove_fund_market_tx(
|
|
1084
1100
|
web3=web3,
|
1085
1101
|
)
|
1086
1102
|
|
1087
|
-
new_balance = market_collateral_token_contract.balanceOf(from_address)
|
1103
|
+
new_balance = market_collateral_token_contract.balanceOf(from_address, web3=web3)
|
1088
1104
|
|
1089
1105
|
logger.debug(f"Result from merge positions {result}")
|
1090
1106
|
logger.info(
|
1091
|
-
f"Withdrawn {new_balance - original_balance} {market_collateral_token_contract.symbol_cached()} from liquidity at {market.url=}."
|
1107
|
+
f"Withdrawn {new_balance - original_balance} {market_collateral_token_contract.symbol_cached(web3=web3)} from liquidity at {market.url=}."
|
1092
1108
|
)
|
1093
1109
|
|
1094
1110
|
|
@@ -46,7 +46,7 @@ class PolymarketAgentMarket(AgentMarket):
|
|
46
46
|
def get_tiny_bet_amount(cls) -> BetAmount:
|
47
47
|
raise NotImplementedError("TODO: Implement to allow betting on Polymarket.")
|
48
48
|
|
49
|
-
def place_bet(self, outcome: bool, amount: BetAmount) ->
|
49
|
+
def place_bet(self, outcome: bool, amount: BetAmount) -> str:
|
50
50
|
raise NotImplementedError("TODO: Implement to allow betting on Polymarket.")
|
51
51
|
|
52
52
|
@staticmethod
|
@@ -43,3 +43,7 @@ class DeployedPolymarketAgent(DeployedAgent):
|
|
43
43
|
== MarketType.POLYMARKET.value,
|
44
44
|
) -> t.Sequence["DeployedPolymarketAgent"]:
|
45
45
|
return super().from_all_gcp_functions(filter_=filter_)
|
46
|
+
|
47
|
+
@staticmethod
|
48
|
+
def get_user_id(api_keys: APIKeys) -> str:
|
49
|
+
return api_keys.bet_from_address
|
@@ -7,9 +7,9 @@ from langfuse.client import TraceWithDetails
|
|
7
7
|
from pydantic import BaseModel
|
8
8
|
|
9
9
|
from prediction_market_agent_tooling.markets.data_models import (
|
10
|
+
PlacedTrade,
|
10
11
|
ProbabilisticAnswer,
|
11
12
|
ResolvedBet,
|
12
|
-
Trade,
|
13
13
|
TradeType,
|
14
14
|
)
|
15
15
|
from prediction_market_agent_tooling.markets.omen.omen import OmenAgentMarket
|
@@ -20,10 +20,10 @@ class ProcessMarketTrace(BaseModel):
|
|
20
20
|
timestamp: datetime
|
21
21
|
market: OmenAgentMarket
|
22
22
|
answer: ProbabilisticAnswer
|
23
|
-
trades: list[
|
23
|
+
trades: list[PlacedTrade]
|
24
24
|
|
25
25
|
@property
|
26
|
-
def buy_trade(self) ->
|
26
|
+
def buy_trade(self) -> PlacedTrade:
|
27
27
|
buy_trades = [t for t in self.trades if t.trade_type == TradeType.BUY]
|
28
28
|
if len(buy_trades) == 1:
|
29
29
|
return buy_trades[0]
|
@@ -107,10 +107,10 @@ def trace_to_answer(trace: TraceWithDetails) -> ProbabilisticAnswer:
|
|
107
107
|
return ProbabilisticAnswer.model_validate(trace.output["answer"])
|
108
108
|
|
109
109
|
|
110
|
-
def trace_to_trades(trace: TraceWithDetails) -> list[
|
110
|
+
def trace_to_trades(trace: TraceWithDetails) -> list[PlacedTrade]:
|
111
111
|
assert trace.output is not None, "Trace output is None"
|
112
112
|
assert trace.output["trades"] is not None, "Trace output trades is None"
|
113
|
-
return [
|
113
|
+
return [PlacedTrade.model_validate(t) for t in trace.output["trades"]]
|
114
114
|
|
115
115
|
|
116
116
|
def get_closest_datetime_from_list(
|
@@ -15,9 +15,9 @@ prediction_market_agent_tooling/benchmark/agents.py,sha256=BwE3U11tQq0rfOJBn-Xn5
|
|
15
15
|
prediction_market_agent_tooling/benchmark/benchmark.py,sha256=xiHKzZx5GHSsDerFHMZ9j_LXAXnSaITSvv67iPe3MEU,21095
|
16
16
|
prediction_market_agent_tooling/benchmark/utils.py,sha256=D0MfUkVZllmvcU0VOurk9tcKT7JTtwwOp-63zuCBVuc,2880
|
17
17
|
prediction_market_agent_tooling/config.py,sha256=9h68Nb9O1YZabZqtOBrH1S-4U5aIdLKfVYLSKspfUeA,6008
|
18
|
-
prediction_market_agent_tooling/deploy/agent.py,sha256=
|
18
|
+
prediction_market_agent_tooling/deploy/agent.py,sha256=QiGREI3YDafVP6kA7H6ejSTxMGBUEG-iYibda43k7vY,19749
|
19
19
|
prediction_market_agent_tooling/deploy/agent_example.py,sha256=dIIdZashExWk9tOdyDjw87AuUcGyM7jYxNChYrVK2dM,1001
|
20
|
-
prediction_market_agent_tooling/deploy/betting_strategy.py,sha256=
|
20
|
+
prediction_market_agent_tooling/deploy/betting_strategy.py,sha256=eCmKpi3EJxFNbPiT7zDYRxJrP76mj0idvSlzin1wtWg,8990
|
21
21
|
prediction_market_agent_tooling/deploy/constants.py,sha256=M5ty8URipYMGe_G-RzxRydK3AFL6CyvmqCraJUrLBnE,82
|
22
22
|
prediction_market_agent_tooling/deploy/gcp/deploy.py,sha256=CYUgnfy-9XVk04kkxA_5yp0GE9Mw5caYqlFUZQ2j3ks,3739
|
23
23
|
prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py,sha256=qYIHRxQLac3yxtZ8ChikiPG9O1aUQucHW0muTSm1nto,2627
|
@@ -26,35 +26,35 @@ prediction_market_agent_tooling/gtypes.py,sha256=O77co9-GWmHJo_NyBzRVkli5L1xqweI
|
|
26
26
|
prediction_market_agent_tooling/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
27
27
|
prediction_market_agent_tooling/jobs/jobs.py,sha256=I07yh0GJ-xhlvQaOUQB8xlSnihhcbU2c7DZ4ZND14c0,1246
|
28
28
|
prediction_market_agent_tooling/jobs/jobs_models.py,sha256=8JS9n_EVgmNzqRg1YUjopPVZRjqFneVYCKnX4UEFy3I,1326
|
29
|
-
prediction_market_agent_tooling/jobs/omen/omen_jobs.py,sha256=
|
29
|
+
prediction_market_agent_tooling/jobs/omen/omen_jobs.py,sha256=Mr6fZqfOs4tzGYsp7g0ygolYjQaFCLG7ljP1mKs71ng,3946
|
30
30
|
prediction_market_agent_tooling/loggers.py,sha256=Am6HHXRNO545BO3l7Ue9Wb2TkYE1OK8KKhGbI3XypVU,3751
|
31
|
-
prediction_market_agent_tooling/markets/agent_market.py,sha256=
|
31
|
+
prediction_market_agent_tooling/markets/agent_market.py,sha256=OmnoGgcH_jnYb-y7vG5XH9bEwb0VdCrBqfHAxLd7eIw,10457
|
32
32
|
prediction_market_agent_tooling/markets/categorize.py,sha256=jsoHWvZk9pU6n17oWSCcCxNNYVwlb_NXsZxKRI7vmsk,1301
|
33
|
-
prediction_market_agent_tooling/markets/data_models.py,sha256=
|
33
|
+
prediction_market_agent_tooling/markets/data_models.py,sha256=DoSWVrHgzrEbEELSZ19hK38ckBShJLobmp6IetZaL8E,3563
|
34
34
|
prediction_market_agent_tooling/markets/manifold/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
35
|
-
prediction_market_agent_tooling/markets/manifold/api.py,sha256=
|
35
|
+
prediction_market_agent_tooling/markets/manifold/api.py,sha256=pliGOyehEcApj1l6OaoVDeuGrws8AN2bymiTuP1y4t0,7295
|
36
36
|
prediction_market_agent_tooling/markets/manifold/data_models.py,sha256=2Rh3j9SM2om-q61Mbxm_UjOzXfxnoej-f_Vyx0LMMfE,6467
|
37
|
-
prediction_market_agent_tooling/markets/manifold/manifold.py,sha256=
|
37
|
+
prediction_market_agent_tooling/markets/manifold/manifold.py,sha256=e4T6IAxV2OfIHsPMOTqSpfTRfLZ7CxegAYbCLc35Os8,4450
|
38
38
|
prediction_market_agent_tooling/markets/manifold/utils.py,sha256=cPPFWXm3vCYH1jy7_ctJZuQH9ZDaPL4_AgAYzGWkoow,513
|
39
39
|
prediction_market_agent_tooling/markets/markets.py,sha256=EN0MgOBBk2ASSVTfqlk0MrsHxg3CVRyQl23jtzfeEi8,3222
|
40
40
|
prediction_market_agent_tooling/markets/metaculus/api.py,sha256=gvPQVAM5NlCyWzEMt4WML9saRBsK9eiHAZP6jwirVqc,2750
|
41
41
|
prediction_market_agent_tooling/markets/metaculus/data_models.py,sha256=6TBy17xntdLBR61QCE5wddwTa_k2D0D8ZgK6p7sGUuc,2448
|
42
|
-
prediction_market_agent_tooling/markets/metaculus/metaculus.py,sha256=
|
42
|
+
prediction_market_agent_tooling/markets/metaculus/metaculus.py,sha256=vvdN2DbOeSPyvCIzZyZmrAqAnmWqwCJgQ5bb5zRBlL4,3625
|
43
43
|
prediction_market_agent_tooling/markets/omen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
44
|
-
prediction_market_agent_tooling/markets/omen/data_models.py,sha256=
|
45
|
-
prediction_market_agent_tooling/markets/omen/omen.py,sha256=
|
44
|
+
prediction_market_agent_tooling/markets/omen/data_models.py,sha256=B5EfIkq_ezfGiGFbWXPbtVTUDAsrcQ0DM9lmcLXzoHw,17675
|
45
|
+
prediction_market_agent_tooling/markets/omen/omen.py,sha256=euiia_WHnHeAEPEh0WeHLleKVl6Yp289oKyQZDGMTZo,47147
|
46
46
|
prediction_market_agent_tooling/markets/omen/omen_contracts.py,sha256=MfaWfDDfEzHYVAbeT3Dgtl8KG7XsqEpdY3m3-rsOPwo,23588
|
47
47
|
prediction_market_agent_tooling/markets/omen/omen_resolving.py,sha256=udzte2jD33tONHPfMGhQbkAlHePRuw5iF8YXy71P8qo,9555
|
48
48
|
prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py,sha256=2K-B5rnT05oC0K1YbrB0cKXOz3wjagoDLXQ9fxBTlBs,30902
|
49
49
|
prediction_market_agent_tooling/markets/polymarket/api.py,sha256=HXmA1akA0qDj0m3e-GEvWG8x75pm6BX4H7YJPQcST7I,4767
|
50
50
|
prediction_market_agent_tooling/markets/polymarket/data_models.py,sha256=9CJzakyEcsn6DQBK2nOXjOMzTZBLAmK_KqevXvW17DI,4292
|
51
51
|
prediction_market_agent_tooling/markets/polymarket/data_models_web.py,sha256=IPsFT3FX9Ge5l5zR1nBd2w-sd5ue7oR8PJSW710vFWY,12479
|
52
|
-
prediction_market_agent_tooling/markets/polymarket/polymarket.py,sha256=
|
52
|
+
prediction_market_agent_tooling/markets/polymarket/polymarket.py,sha256=SONMs6gFAR_j8xgVK8MmQDTrFx64_JCi5IfVr52EeKE,2773
|
53
53
|
prediction_market_agent_tooling/markets/polymarket/utils.py,sha256=m4JG6WULh5epCJt4XBMHg0ae5NoVhqlOvAl0A7DR9iM,2023
|
54
54
|
prediction_market_agent_tooling/monitor/markets/manifold.py,sha256=GdYpgRX1GahDi-75Mr53jgtEg6nWcs_rHDUkg4o_7dQ,3352
|
55
55
|
prediction_market_agent_tooling/monitor/markets/metaculus.py,sha256=S8zeDVN2aA6yvQykQNPb8GUGohczfJuCYt9Ds9ESCzs,1473
|
56
56
|
prediction_market_agent_tooling/monitor/markets/omen.py,sha256=jOLPnIbDU9syjnYtHfOb2xa6-Ize3vbplgh-8WWkuT4,3323
|
57
|
-
prediction_market_agent_tooling/monitor/markets/polymarket.py,sha256=
|
57
|
+
prediction_market_agent_tooling/monitor/markets/polymarket.py,sha256=y7HVAEzeybfphB_VZPZpmAsQqjxPUM1uM7ZttQ56mm8,1888
|
58
58
|
prediction_market_agent_tooling/monitor/monitor.py,sha256=tvYzHJg8Nau4vGWVTngjUAcM26LcH3Emss76351xl2o,14636
|
59
59
|
prediction_market_agent_tooling/monitor/monitor_app.py,sha256=1e4LuzhAVjb7cPS6rGPZuZHMwMiNOeRhSxG8AVG-e0o,4839
|
60
60
|
prediction_market_agent_tooling/monitor/monitor_settings.py,sha256=Xiozs3AsufuJ04JOe1vjUri-IAMWHjjmc2ugGGiHNH4,947
|
@@ -75,7 +75,7 @@ prediction_market_agent_tooling/tools/image_gen/image_gen.py,sha256=HzRwBx62hOXB
|
|
75
75
|
prediction_market_agent_tooling/tools/image_gen/market_thumbnail_gen.py,sha256=8A3U2uxsCsOfLjru-6R_PPIAuiKY4qFkWp_GSBPV6-s,1280
|
76
76
|
prediction_market_agent_tooling/tools/is_predictable.py,sha256=QapzvJVgUZdhucgmxhzWAQ885BwSwvYUi0SG8mkLQMQ,6738
|
77
77
|
prediction_market_agent_tooling/tools/langfuse_.py,sha256=jI_4ROxqo41CCnWGS1vN_AeDVhRzLMaQLxH3kxDu3L8,1153
|
78
|
-
prediction_market_agent_tooling/tools/langfuse_client_utils.py,sha256=
|
78
|
+
prediction_market_agent_tooling/tools/langfuse_client_utils.py,sha256=PcBi9CSEkyjdSKU8AoGvC2guBsCrUzFNw9BhMkm-vvI,4771
|
79
79
|
prediction_market_agent_tooling/tools/omen/reality_accuracy.py,sha256=M1SF7iSW1gVlQSTskdVFTn09uPLST23YeipVIWj54io,2236
|
80
80
|
prediction_market_agent_tooling/tools/parallelism.py,sha256=6Gou0hbjtMZrYvxjTDFUDZuxmE2nqZVbb6hkg1hF82A,1022
|
81
81
|
prediction_market_agent_tooling/tools/safe.py,sha256=h0xOO0eNtitClf0fPkn-0oTc6A_bflDTee98V_aiV-A,5195
|
@@ -85,8 +85,8 @@ prediction_market_agent_tooling/tools/tavily_storage/tavily_models.py,sha256=Uq2
|
|
85
85
|
prediction_market_agent_tooling/tools/tavily_storage/tavily_storage.py,sha256=xrtQH9v5pXycBRyc5j45pWqkSffkoc9efNIU1_G633Q,3706
|
86
86
|
prediction_market_agent_tooling/tools/utils.py,sha256=uItjuwR5ZB6Qy7mmc5Dzx7fa2lkLO7oHhk2nzJMrIVo,7341
|
87
87
|
prediction_market_agent_tooling/tools/web3_utils.py,sha256=IZDxHhUJH5RsaRkK9DW6z1RYdk2cz5RqLMZG3T6Gv1U,11602
|
88
|
-
prediction_market_agent_tooling-0.
|
89
|
-
prediction_market_agent_tooling-0.
|
90
|
-
prediction_market_agent_tooling-0.
|
91
|
-
prediction_market_agent_tooling-0.
|
92
|
-
prediction_market_agent_tooling-0.
|
88
|
+
prediction_market_agent_tooling-0.49.0.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
|
89
|
+
prediction_market_agent_tooling-0.49.0.dist-info/METADATA,sha256=DjQQylYgmiw5_M2v-5BHozKAUGyX8Ykmpr1WlWyyiKE,7847
|
90
|
+
prediction_market_agent_tooling-0.49.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
91
|
+
prediction_market_agent_tooling-0.49.0.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
|
92
|
+
prediction_market_agent_tooling-0.49.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|