prediction-market-agent-tooling 0.48.17__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 -8
- prediction_market_agent_tooling/deploy/betting_strategy.py +64 -27
- 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/omen/omen_resolving.py +3 -1
- prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +20 -2
- 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/tools/omen/reality_accuracy.py +74 -0
- prediction_market_agent_tooling/tools/utils.py +18 -0
- {prediction_market_agent_tooling-0.48.17.dist-info → prediction_market_agent_tooling-0.49.0.dist-info}/METADATA +1 -1
- {prediction_market_agent_tooling-0.48.17.dist-info → prediction_market_agent_tooling-0.49.0.dist-info}/RECORD +22 -21
- {prediction_market_agent_tooling-0.48.17.dist-info → prediction_market_agent_tooling-0.49.0.dist-info}/LICENSE +0 -0
- {prediction_market_agent_tooling-0.48.17.dist-info → prediction_market_agent_tooling-0.49.0.dist-info}/WHEEL +0 -0
- {prediction_market_agent_tooling-0.48.17.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,8 +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
|
-
allow_opposite_bets: bool = False
|
287
286
|
|
288
287
|
def __init__(
|
289
288
|
self,
|
@@ -293,6 +292,15 @@ class DeployableTraderAgent(DeployableAgent):
|
|
293
292
|
super().__init__(enable_langfuse=enable_langfuse)
|
294
293
|
self.place_bet = place_bet
|
295
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
|
+
|
296
304
|
def initialize_langfuse(self) -> None:
|
297
305
|
super().initialize_langfuse()
|
298
306
|
# Auto-observe all the methods where it makes sense, so that subclassses don't need to do it manually.
|
@@ -411,7 +419,8 @@ class DeployableTraderAgent(DeployableAgent):
|
|
411
419
|
answer: ProbabilisticAnswer,
|
412
420
|
existing_position: Position | None,
|
413
421
|
) -> list[Trade]:
|
414
|
-
|
422
|
+
strategy = self.get_betting_strategy(market=market)
|
423
|
+
trades = strategy.calculate_trades(existing_position, answer, market)
|
415
424
|
BettingStrategy.assert_trades_currency_match_markets(market, trades)
|
416
425
|
return trades
|
417
426
|
|
@@ -444,24 +453,32 @@ class DeployableTraderAgent(DeployableAgent):
|
|
444
453
|
|
445
454
|
existing_position = market.get_position(user_id=APIKeys().bet_from_address)
|
446
455
|
trades = self.build_trades(
|
447
|
-
market=market,
|
456
|
+
market=market,
|
457
|
+
answer=answer,
|
458
|
+
existing_position=existing_position,
|
448
459
|
)
|
449
460
|
|
461
|
+
placed_trades = []
|
450
462
|
if self.place_bet:
|
451
463
|
for trade in trades:
|
452
464
|
logger.info(f"Executing trade {trade}")
|
453
465
|
|
454
466
|
match trade.trade_type:
|
455
467
|
case TradeType.BUY:
|
456
|
-
market.buy_tokens(
|
468
|
+
id = market.buy_tokens(
|
469
|
+
outcome=trade.outcome, amount=trade.amount
|
470
|
+
)
|
457
471
|
case TradeType.SELL:
|
458
|
-
market.sell_tokens(
|
472
|
+
id = market.sell_tokens(
|
473
|
+
outcome=trade.outcome, amount=trade.amount
|
474
|
+
)
|
459
475
|
case _:
|
460
476
|
raise ValueError(f"Unexpected trade type {trade.trade_type}.")
|
477
|
+
placed_trades.append(PlacedTrade.from_trade(trade, id))
|
461
478
|
|
462
479
|
self.after_process_market(market_type, market)
|
463
480
|
|
464
|
-
processed_market = ProcessedMarket(answer=answer, trades=
|
481
|
+
processed_market = ProcessedMarket(answer=answer, trades=placed_trades)
|
465
482
|
self.update_langfuse_trace_by_processed_market(market_type, processed_market)
|
466
483
|
|
467
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
|
}
|
@@ -141,6 +120,9 @@ class MaxAccuracyBettingStrategy(BettingStrategy):
|
|
141
120
|
def calculate_direction(market_p_yes: float, estimate_p_yes: float) -> bool:
|
142
121
|
return estimate_p_yes >= 0.5
|
143
122
|
|
123
|
+
def __repr__(self) -> str:
|
124
|
+
return f"{self.__class__.__name__}(bet_amount={self.bet_amount})"
|
125
|
+
|
144
126
|
|
145
127
|
class MaxExpectedValueBettingStrategy(MaxAccuracyBettingStrategy):
|
146
128
|
@staticmethod
|
@@ -152,6 +134,53 @@ class MaxExpectedValueBettingStrategy(MaxAccuracyBettingStrategy):
|
|
152
134
|
|
153
135
|
|
154
136
|
class KellyBettingStrategy(BettingStrategy):
|
137
|
+
def __init__(self, max_bet_amount: float):
|
138
|
+
self.max_bet_amount = max_bet_amount
|
139
|
+
|
140
|
+
def calculate_trades(
|
141
|
+
self,
|
142
|
+
existing_position: Position | None,
|
143
|
+
answer: ProbabilisticAnswer,
|
144
|
+
market: AgentMarket,
|
145
|
+
) -> list[Trade]:
|
146
|
+
outcome_token_pool = check_not_none(market.outcome_token_pool)
|
147
|
+
kelly_bet = (
|
148
|
+
get_kelly_bet_full(
|
149
|
+
yes_outcome_pool_size=outcome_token_pool[
|
150
|
+
market.get_outcome_str_from_bool(True)
|
151
|
+
],
|
152
|
+
no_outcome_pool_size=outcome_token_pool[
|
153
|
+
market.get_outcome_str_from_bool(False)
|
154
|
+
],
|
155
|
+
estimated_p_yes=answer.p_yes,
|
156
|
+
max_bet=self.max_bet_amount,
|
157
|
+
confidence=answer.confidence,
|
158
|
+
)
|
159
|
+
if market.has_token_pool()
|
160
|
+
else get_kelly_bet_simplified(
|
161
|
+
self.max_bet_amount,
|
162
|
+
market.current_p_yes,
|
163
|
+
answer.p_yes,
|
164
|
+
answer.confidence,
|
165
|
+
)
|
166
|
+
)
|
167
|
+
|
168
|
+
amounts = {
|
169
|
+
market.get_outcome_str_from_bool(kelly_bet.direction): TokenAmount(
|
170
|
+
amount=kelly_bet.size, currency=market.currency
|
171
|
+
),
|
172
|
+
}
|
173
|
+
target_position = Position(market_id=market.id, amounts=amounts)
|
174
|
+
trades = self._build_rebalance_trades_from_positions(
|
175
|
+
existing_position, target_position, market=market
|
176
|
+
)
|
177
|
+
return trades
|
178
|
+
|
179
|
+
def __repr__(self) -> str:
|
180
|
+
return f"{self.__class__.__name__}(max_bet_amount={self.max_bet_amount})"
|
181
|
+
|
182
|
+
|
183
|
+
class MaxAccuracyWithKellyScaledBetsStrategy(BettingStrategy):
|
155
184
|
def __init__(self, max_bet_amount: float = 10):
|
156
185
|
self.max_bet_amount = max_bet_amount
|
157
186
|
|
@@ -171,6 +200,11 @@ class KellyBettingStrategy(BettingStrategy):
|
|
171
200
|
) -> list[Trade]:
|
172
201
|
adjusted_bet_amount = self.adjust_bet_amount(existing_position, market)
|
173
202
|
outcome_token_pool = check_not_none(market.outcome_token_pool)
|
203
|
+
|
204
|
+
# Fixed direction of bet, only use Kelly to adjust the bet size based on market's outcome pool size.
|
205
|
+
estimated_p_yes = float(answer.p_yes > 0.5)
|
206
|
+
confidence = 1.0
|
207
|
+
|
174
208
|
kelly_bet = (
|
175
209
|
get_kelly_bet_full(
|
176
210
|
yes_outcome_pool_size=outcome_token_pool[
|
@@ -179,16 +213,16 @@ class KellyBettingStrategy(BettingStrategy):
|
|
179
213
|
no_outcome_pool_size=outcome_token_pool[
|
180
214
|
market.get_outcome_str_from_bool(False)
|
181
215
|
],
|
182
|
-
estimated_p_yes=
|
216
|
+
estimated_p_yes=estimated_p_yes,
|
183
217
|
max_bet=adjusted_bet_amount,
|
184
|
-
confidence=
|
218
|
+
confidence=confidence,
|
185
219
|
)
|
186
220
|
if market.has_token_pool()
|
187
221
|
else get_kelly_bet_simplified(
|
188
222
|
adjusted_bet_amount,
|
189
223
|
market.current_p_yes,
|
190
|
-
|
191
|
-
|
224
|
+
estimated_p_yes,
|
225
|
+
confidence,
|
192
226
|
)
|
193
227
|
)
|
194
228
|
|
@@ -202,3 +236,6 @@ class KellyBettingStrategy(BettingStrategy):
|
|
202
236
|
existing_position, target_position, market=market
|
203
237
|
)
|
204
238
|
return trades
|
239
|
+
|
240
|
+
def __repr__(self) -> str:
|
241
|
+
return f"{self.__class__.__name__}(max_bet_amount={self.max_bet_amount})"
|
@@ -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
|
|
@@ -66,7 +66,9 @@ def claim_bonds_on_realitio_question(
|
|
66
66
|
realitio_contract = OmenRealitioContract()
|
67
67
|
|
68
68
|
# Get all answers for the question.
|
69
|
-
responses = OmenSubgraphHandler().get_responses(
|
69
|
+
responses = OmenSubgraphHandler().get_responses(
|
70
|
+
limit=None, question_id=question.questionId
|
71
|
+
)
|
70
72
|
|
71
73
|
# They need to be processed in order.
|
72
74
|
responses = sorted(responses, key=lambda x: x.timestamp)
|
@@ -677,6 +677,7 @@ class OmenSubgraphHandler(metaclass=SingletonMeta):
|
|
677
677
|
|
678
678
|
def get_questions(
|
679
679
|
self,
|
680
|
+
limit: int | None,
|
680
681
|
user: HexAddress | None = None,
|
681
682
|
claimed: bool | None = None,
|
682
683
|
current_answer_before: datetime | None = None,
|
@@ -694,7 +695,12 @@ class OmenSubgraphHandler(metaclass=SingletonMeta):
|
|
694
695
|
id_in=id_in,
|
695
696
|
question_id_in=question_id_in,
|
696
697
|
)
|
697
|
-
questions = self.realityeth_subgraph.Query.questions(
|
698
|
+
questions = self.realityeth_subgraph.Query.questions(
|
699
|
+
first=(
|
700
|
+
limit if limit else sys.maxsize
|
701
|
+
), # if not limit, we fetch all possible
|
702
|
+
where=where_stms,
|
703
|
+
)
|
698
704
|
fields = self._get_fields_for_reality_questions(questions)
|
699
705
|
result = self.sg.query_json(fields)
|
700
706
|
items = self._parse_items_from_json(result)
|
@@ -715,10 +721,14 @@ class OmenSubgraphHandler(metaclass=SingletonMeta):
|
|
715
721
|
|
716
722
|
def get_responses(
|
717
723
|
self,
|
724
|
+
limit: int | None,
|
718
725
|
user: HexAddress | None = None,
|
719
726
|
question_id: HexBytes | None = None,
|
720
727
|
question_claimed: bool | None = None,
|
721
728
|
question_finalized_before: datetime | None = None,
|
729
|
+
question_finalized_after: datetime | None = None,
|
730
|
+
question_current_answer_before: datetime | None = None,
|
731
|
+
question_id_in: list[HexBytes] | None = None,
|
722
732
|
) -> list[RealityResponse]:
|
723
733
|
where_stms: dict[str, t.Any] = {}
|
724
734
|
|
@@ -729,9 +739,17 @@ class OmenSubgraphHandler(metaclass=SingletonMeta):
|
|
729
739
|
question_id=question_id,
|
730
740
|
claimed=question_claimed,
|
731
741
|
finalized_before=question_finalized_before,
|
742
|
+
finalized_after=question_finalized_after,
|
743
|
+
current_answer_before=question_current_answer_before,
|
744
|
+
question_id_in=question_id_in,
|
732
745
|
)
|
733
746
|
|
734
|
-
responses = self.realityeth_subgraph.Query.responses(
|
747
|
+
responses = self.realityeth_subgraph.Query.responses(
|
748
|
+
first=(
|
749
|
+
limit if limit else sys.maxsize
|
750
|
+
), # if not limit, we fetch all possible
|
751
|
+
where=where_stms,
|
752
|
+
)
|
735
753
|
fields = self._get_fields_for_responses(responses)
|
736
754
|
result = self.sg.query_json(fields)
|
737
755
|
items = self._parse_items_from_json(result)
|
@@ -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(
|
@@ -0,0 +1,74 @@
|
|
1
|
+
from datetime import timedelta
|
2
|
+
|
3
|
+
from pydantic import BaseModel
|
4
|
+
|
5
|
+
from prediction_market_agent_tooling.markets.omen.omen_subgraph_handler import (
|
6
|
+
ChecksumAddress,
|
7
|
+
OmenSubgraphHandler,
|
8
|
+
RealityResponse,
|
9
|
+
)
|
10
|
+
from prediction_market_agent_tooling.tools.utils import utcnow
|
11
|
+
|
12
|
+
|
13
|
+
class RealityAccuracyReport(BaseModel):
|
14
|
+
total: int
|
15
|
+
correct: int
|
16
|
+
|
17
|
+
@property
|
18
|
+
def accuracy(self) -> float:
|
19
|
+
return self.correct / self.total
|
20
|
+
|
21
|
+
|
22
|
+
def reality_accuracy(user: ChecksumAddress, since: timedelta) -> RealityAccuracyReport:
|
23
|
+
now = utcnow()
|
24
|
+
start_from = now - since
|
25
|
+
|
26
|
+
# Get all question ids where we placed the higher bond.
|
27
|
+
user_responses = OmenSubgraphHandler().get_responses(
|
28
|
+
limit=None,
|
29
|
+
user=user,
|
30
|
+
question_finalized_before=now,
|
31
|
+
question_finalized_after=start_from,
|
32
|
+
)
|
33
|
+
unique_question_ids = set(r.question.questionId for r in user_responses)
|
34
|
+
|
35
|
+
# Get all responses for these questions (including not ours)
|
36
|
+
question_to_responses = {
|
37
|
+
question_id: OmenSubgraphHandler().get_responses(
|
38
|
+
limit=None, question_id=question_id
|
39
|
+
)
|
40
|
+
for question_id in unique_question_ids
|
41
|
+
}
|
42
|
+
|
43
|
+
total = 0
|
44
|
+
correct = 0
|
45
|
+
|
46
|
+
for question_id, responses in question_to_responses.items():
|
47
|
+
is_correct = user_was_correct(user, responses)
|
48
|
+
assert (
|
49
|
+
is_correct is not None
|
50
|
+
), f"All these questions should be challenged by provided user: {responses[0].question.url}"
|
51
|
+
|
52
|
+
total += 1
|
53
|
+
correct += int(is_correct)
|
54
|
+
|
55
|
+
return RealityAccuracyReport(total=total, correct=correct)
|
56
|
+
|
57
|
+
|
58
|
+
def user_was_correct(
|
59
|
+
user: ChecksumAddress, responses: list[RealityResponse]
|
60
|
+
) -> bool | None:
|
61
|
+
sorted_responses = sorted(responses, key=lambda r: r.timestamp)
|
62
|
+
users_sorted_responses = [r for r in sorted_responses if r.user_checksummed == user]
|
63
|
+
|
64
|
+
if not users_sorted_responses:
|
65
|
+
return None
|
66
|
+
|
67
|
+
# Find the user's last response
|
68
|
+
users_last_response = users_sorted_responses[-1]
|
69
|
+
|
70
|
+
# Last response is the final one (if market is finalized)
|
71
|
+
actual_resolution = sorted_responses[-1]
|
72
|
+
|
73
|
+
# Compare the user's last answer with the actual resolution
|
74
|
+
return users_last_response.answer == actual_resolution.answer
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import json
|
1
2
|
import os
|
2
3
|
import subprocess
|
3
4
|
import typing as t
|
@@ -6,12 +7,14 @@ from typing import Any, NoReturn, Optional, Type, TypeVar, cast
|
|
6
7
|
|
7
8
|
import pytz
|
8
9
|
import requests
|
10
|
+
from google.cloud import secretmanager
|
9
11
|
from pydantic import BaseModel, ValidationError
|
10
12
|
from scipy.optimize import newton
|
11
13
|
from scipy.stats import entropy
|
12
14
|
|
13
15
|
from prediction_market_agent_tooling.gtypes import (
|
14
16
|
DatetimeWithTimezone,
|
17
|
+
PrivateKey,
|
15
18
|
Probability,
|
16
19
|
SecretStr,
|
17
20
|
)
|
@@ -210,3 +213,18 @@ def calculate_sell_amount_in_collateral(
|
|
210
213
|
|
211
214
|
amount_to_sell = newton(f, 0)
|
212
215
|
return float(amount_to_sell) * 0.999999 # Avoid rounding errors
|
216
|
+
|
217
|
+
|
218
|
+
def get_private_key_from_gcp_secret(
|
219
|
+
secret_id: str,
|
220
|
+
project_id: str = "582587111398", # Gnosis AI default project_id
|
221
|
+
version_id: str = "latest",
|
222
|
+
) -> PrivateKey:
|
223
|
+
client = secretmanager.SecretManagerServiceClient()
|
224
|
+
name = f"projects/{project_id}/secrets/{secret_id}/versions/{version_id}"
|
225
|
+
response = client.access_secret_version(request={"name": name})
|
226
|
+
secret_payload = response.payload.data.decode("UTF-8")
|
227
|
+
secret_json = json.loads(secret_payload)
|
228
|
+
if "private_key" not in secret_json:
|
229
|
+
raise ValueError(f"Private key not found in gcp secret {secret_id}")
|
230
|
+
return PrivateKey(SecretStr(secret_json["private_key"]))
|
@@ -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
|
-
prediction_market_agent_tooling/markets/omen/omen_resolving.py,sha256=
|
48
|
-
prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py,sha256=
|
47
|
+
prediction_market_agent_tooling/markets/omen/omen_resolving.py,sha256=udzte2jD33tONHPfMGhQbkAlHePRuw5iF8YXy71P8qo,9555
|
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,17 +75,18 @@ 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
|
+
prediction_market_agent_tooling/tools/omen/reality_accuracy.py,sha256=M1SF7iSW1gVlQSTskdVFTn09uPLST23YeipVIWj54io,2236
|
79
80
|
prediction_market_agent_tooling/tools/parallelism.py,sha256=6Gou0hbjtMZrYvxjTDFUDZuxmE2nqZVbb6hkg1hF82A,1022
|
80
81
|
prediction_market_agent_tooling/tools/safe.py,sha256=h0xOO0eNtitClf0fPkn-0oTc6A_bflDTee98V_aiV-A,5195
|
81
82
|
prediction_market_agent_tooling/tools/singleton.py,sha256=CiIELUiI-OeS7U7eeHEt0rnVhtQGzwoUdAgn_7u_GBM,729
|
82
83
|
prediction_market_agent_tooling/tools/streamlit_user_login.py,sha256=NXEqfjT9Lc9QtliwSGRASIz1opjQ7Btme43H4qJbzgE,3010
|
83
84
|
prediction_market_agent_tooling/tools/tavily_storage/tavily_models.py,sha256=Uq2iyDygVRxp6qHAnz9t5c1uTLGV2RPQE15sVJFLds8,6341
|
84
85
|
prediction_market_agent_tooling/tools/tavily_storage/tavily_storage.py,sha256=xrtQH9v5pXycBRyc5j45pWqkSffkoc9efNIU1_G633Q,3706
|
85
|
-
prediction_market_agent_tooling/tools/utils.py,sha256=
|
86
|
+
prediction_market_agent_tooling/tools/utils.py,sha256=uItjuwR5ZB6Qy7mmc5Dzx7fa2lkLO7oHhk2nzJMrIVo,7341
|
86
87
|
prediction_market_agent_tooling/tools/web3_utils.py,sha256=IZDxHhUJH5RsaRkK9DW6z1RYdk2cz5RqLMZG3T6Gv1U,11602
|
87
|
-
prediction_market_agent_tooling-0.
|
88
|
-
prediction_market_agent_tooling-0.
|
89
|
-
prediction_market_agent_tooling-0.
|
90
|
-
prediction_market_agent_tooling-0.
|
91
|
-
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
|