prediction-market-agent-tooling 0.67.2__py3-none-any.whl → 0.67.3__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/erc1155.abi.json +352 -0
- prediction_market_agent_tooling/deploy/agent.py +57 -51
- prediction_market_agent_tooling/deploy/betting_strategy.py +1 -1
- prediction_market_agent_tooling/markets/agent_market.py +7 -1
- prediction_market_agent_tooling/markets/manifold/manifold.py +2 -1
- prediction_market_agent_tooling/markets/metaculus/metaculus.py +2 -1
- prediction_market_agent_tooling/markets/omen/omen.py +2 -1
- prediction_market_agent_tooling/markets/polymarket/polymarket.py +2 -1
- prediction_market_agent_tooling/markets/seer/data_models.py +25 -1
- prediction_market_agent_tooling/markets/seer/seer.py +74 -24
- prediction_market_agent_tooling/markets/seer/seer_contracts.py +18 -0
- prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py +122 -18
- prediction_market_agent_tooling/tools/contract.py +59 -0
- prediction_market_agent_tooling/tools/cow/cow_order.py +4 -1
- prediction_market_agent_tooling/tools/rephrase.py +1 -1
- prediction_market_agent_tooling/tools/tokens/auto_deposit.py +57 -0
- {prediction_market_agent_tooling-0.67.2.dist-info → prediction_market_agent_tooling-0.67.3.dist-info}/METADATA +1 -1
- {prediction_market_agent_tooling-0.67.2.dist-info → prediction_market_agent_tooling-0.67.3.dist-info}/RECORD +21 -20
- {prediction_market_agent_tooling-0.67.2.dist-info → prediction_market_agent_tooling-0.67.3.dist-info}/LICENSE +0 -0
- {prediction_market_agent_tooling-0.67.2.dist-info → prediction_market_agent_tooling-0.67.3.dist-info}/WHEEL +0 -0
- {prediction_market_agent_tooling-0.67.2.dist-info → prediction_market_agent_tooling-0.67.3.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,352 @@
|
|
1
|
+
[
|
2
|
+
{
|
3
|
+
"inputs": [],
|
4
|
+
"stateMutability": "nonpayable",
|
5
|
+
"type": "constructor"
|
6
|
+
},
|
7
|
+
{
|
8
|
+
"anonymous": false,
|
9
|
+
"inputs": [
|
10
|
+
{
|
11
|
+
"indexed": true,
|
12
|
+
"internalType": "address",
|
13
|
+
"name": "owner",
|
14
|
+
"type": "address"
|
15
|
+
},
|
16
|
+
{
|
17
|
+
"indexed": true,
|
18
|
+
"internalType": "address",
|
19
|
+
"name": "spender",
|
20
|
+
"type": "address"
|
21
|
+
},
|
22
|
+
{
|
23
|
+
"indexed": false,
|
24
|
+
"internalType": "uint256",
|
25
|
+
"name": "value",
|
26
|
+
"type": "uint256"
|
27
|
+
}
|
28
|
+
],
|
29
|
+
"name": "Approval",
|
30
|
+
"type": "event"
|
31
|
+
},
|
32
|
+
{
|
33
|
+
"anonymous": false,
|
34
|
+
"inputs": [
|
35
|
+
{
|
36
|
+
"indexed": true,
|
37
|
+
"internalType": "address",
|
38
|
+
"name": "from",
|
39
|
+
"type": "address"
|
40
|
+
},
|
41
|
+
{
|
42
|
+
"indexed": true,
|
43
|
+
"internalType": "address",
|
44
|
+
"name": "to",
|
45
|
+
"type": "address"
|
46
|
+
},
|
47
|
+
{
|
48
|
+
"indexed": false,
|
49
|
+
"internalType": "uint256",
|
50
|
+
"name": "value",
|
51
|
+
"type": "uint256"
|
52
|
+
}
|
53
|
+
],
|
54
|
+
"name": "Transfer",
|
55
|
+
"type": "event"
|
56
|
+
},
|
57
|
+
{
|
58
|
+
"inputs": [
|
59
|
+
{
|
60
|
+
"internalType": "address",
|
61
|
+
"name": "owner",
|
62
|
+
"type": "address"
|
63
|
+
},
|
64
|
+
{
|
65
|
+
"internalType": "address",
|
66
|
+
"name": "spender",
|
67
|
+
"type": "address"
|
68
|
+
}
|
69
|
+
],
|
70
|
+
"name": "allowance",
|
71
|
+
"outputs": [
|
72
|
+
{
|
73
|
+
"internalType": "uint256",
|
74
|
+
"name": "",
|
75
|
+
"type": "uint256"
|
76
|
+
}
|
77
|
+
],
|
78
|
+
"stateMutability": "view",
|
79
|
+
"type": "function"
|
80
|
+
},
|
81
|
+
{
|
82
|
+
"inputs": [
|
83
|
+
{
|
84
|
+
"internalType": "address",
|
85
|
+
"name": "spender",
|
86
|
+
"type": "address"
|
87
|
+
},
|
88
|
+
{
|
89
|
+
"internalType": "uint256",
|
90
|
+
"name": "amount",
|
91
|
+
"type": "uint256"
|
92
|
+
}
|
93
|
+
],
|
94
|
+
"name": "approve",
|
95
|
+
"outputs": [
|
96
|
+
{
|
97
|
+
"internalType": "bool",
|
98
|
+
"name": "",
|
99
|
+
"type": "bool"
|
100
|
+
}
|
101
|
+
],
|
102
|
+
"stateMutability": "nonpayable",
|
103
|
+
"type": "function"
|
104
|
+
},
|
105
|
+
{
|
106
|
+
"inputs": [
|
107
|
+
{
|
108
|
+
"internalType": "address",
|
109
|
+
"name": "account",
|
110
|
+
"type": "address"
|
111
|
+
}
|
112
|
+
],
|
113
|
+
"name": "balanceOf",
|
114
|
+
"outputs": [
|
115
|
+
{
|
116
|
+
"internalType": "uint256",
|
117
|
+
"name": "",
|
118
|
+
"type": "uint256"
|
119
|
+
}
|
120
|
+
],
|
121
|
+
"stateMutability": "view",
|
122
|
+
"type": "function"
|
123
|
+
},
|
124
|
+
{
|
125
|
+
"inputs": [
|
126
|
+
{
|
127
|
+
"internalType": "address",
|
128
|
+
"name": "account",
|
129
|
+
"type": "address"
|
130
|
+
},
|
131
|
+
{
|
132
|
+
"internalType": "uint256",
|
133
|
+
"name": "amount",
|
134
|
+
"type": "uint256"
|
135
|
+
}
|
136
|
+
],
|
137
|
+
"name": "burn",
|
138
|
+
"outputs": [],
|
139
|
+
"stateMutability": "nonpayable",
|
140
|
+
"type": "function"
|
141
|
+
},
|
142
|
+
{
|
143
|
+
"inputs": [],
|
144
|
+
"name": "decimals",
|
145
|
+
"outputs": [
|
146
|
+
{
|
147
|
+
"internalType": "uint8",
|
148
|
+
"name": "",
|
149
|
+
"type": "uint8"
|
150
|
+
}
|
151
|
+
],
|
152
|
+
"stateMutability": "view",
|
153
|
+
"type": "function"
|
154
|
+
},
|
155
|
+
{
|
156
|
+
"inputs": [
|
157
|
+
{
|
158
|
+
"internalType": "address",
|
159
|
+
"name": "spender",
|
160
|
+
"type": "address"
|
161
|
+
},
|
162
|
+
{
|
163
|
+
"internalType": "uint256",
|
164
|
+
"name": "subtractedValue",
|
165
|
+
"type": "uint256"
|
166
|
+
}
|
167
|
+
],
|
168
|
+
"name": "decreaseAllowance",
|
169
|
+
"outputs": [
|
170
|
+
{
|
171
|
+
"internalType": "bool",
|
172
|
+
"name": "",
|
173
|
+
"type": "bool"
|
174
|
+
}
|
175
|
+
],
|
176
|
+
"stateMutability": "nonpayable",
|
177
|
+
"type": "function"
|
178
|
+
},
|
179
|
+
{
|
180
|
+
"inputs": [],
|
181
|
+
"name": "factory",
|
182
|
+
"outputs": [
|
183
|
+
{
|
184
|
+
"internalType": "contract Wrapped1155Factory",
|
185
|
+
"name": "",
|
186
|
+
"type": "address"
|
187
|
+
}
|
188
|
+
],
|
189
|
+
"stateMutability": "view",
|
190
|
+
"type": "function"
|
191
|
+
},
|
192
|
+
{
|
193
|
+
"inputs": [
|
194
|
+
{
|
195
|
+
"internalType": "address",
|
196
|
+
"name": "spender",
|
197
|
+
"type": "address"
|
198
|
+
},
|
199
|
+
{
|
200
|
+
"internalType": "uint256",
|
201
|
+
"name": "addedValue",
|
202
|
+
"type": "uint256"
|
203
|
+
}
|
204
|
+
],
|
205
|
+
"name": "increaseAllowance",
|
206
|
+
"outputs": [
|
207
|
+
{
|
208
|
+
"internalType": "bool",
|
209
|
+
"name": "",
|
210
|
+
"type": "bool"
|
211
|
+
}
|
212
|
+
],
|
213
|
+
"stateMutability": "nonpayable",
|
214
|
+
"type": "function"
|
215
|
+
},
|
216
|
+
{
|
217
|
+
"inputs": [
|
218
|
+
{
|
219
|
+
"internalType": "address",
|
220
|
+
"name": "account",
|
221
|
+
"type": "address"
|
222
|
+
},
|
223
|
+
{
|
224
|
+
"internalType": "uint256",
|
225
|
+
"name": "amount",
|
226
|
+
"type": "uint256"
|
227
|
+
}
|
228
|
+
],
|
229
|
+
"name": "mint",
|
230
|
+
"outputs": [],
|
231
|
+
"stateMutability": "nonpayable",
|
232
|
+
"type": "function"
|
233
|
+
},
|
234
|
+
{
|
235
|
+
"inputs": [],
|
236
|
+
"name": "multiToken",
|
237
|
+
"outputs": [
|
238
|
+
{
|
239
|
+
"internalType": "contract IERC1155",
|
240
|
+
"name": "",
|
241
|
+
"type": "address"
|
242
|
+
}
|
243
|
+
],
|
244
|
+
"stateMutability": "view",
|
245
|
+
"type": "function"
|
246
|
+
},
|
247
|
+
{
|
248
|
+
"inputs": [],
|
249
|
+
"name": "name",
|
250
|
+
"outputs": [
|
251
|
+
{
|
252
|
+
"internalType": "string",
|
253
|
+
"name": "",
|
254
|
+
"type": "string"
|
255
|
+
}
|
256
|
+
],
|
257
|
+
"stateMutability": "view",
|
258
|
+
"type": "function"
|
259
|
+
},
|
260
|
+
{
|
261
|
+
"inputs": [],
|
262
|
+
"name": "symbol",
|
263
|
+
"outputs": [
|
264
|
+
{
|
265
|
+
"internalType": "string",
|
266
|
+
"name": "",
|
267
|
+
"type": "string"
|
268
|
+
}
|
269
|
+
],
|
270
|
+
"stateMutability": "view",
|
271
|
+
"type": "function"
|
272
|
+
},
|
273
|
+
{
|
274
|
+
"inputs": [],
|
275
|
+
"name": "tokenId",
|
276
|
+
"outputs": [
|
277
|
+
{
|
278
|
+
"internalType": "uint256",
|
279
|
+
"name": "",
|
280
|
+
"type": "uint256"
|
281
|
+
}
|
282
|
+
],
|
283
|
+
"stateMutability": "view",
|
284
|
+
"type": "function"
|
285
|
+
},
|
286
|
+
{
|
287
|
+
"inputs": [],
|
288
|
+
"name": "totalSupply",
|
289
|
+
"outputs": [
|
290
|
+
{
|
291
|
+
"internalType": "uint256",
|
292
|
+
"name": "",
|
293
|
+
"type": "uint256"
|
294
|
+
}
|
295
|
+
],
|
296
|
+
"stateMutability": "view",
|
297
|
+
"type": "function"
|
298
|
+
},
|
299
|
+
{
|
300
|
+
"inputs": [
|
301
|
+
{
|
302
|
+
"internalType": "address",
|
303
|
+
"name": "recipient",
|
304
|
+
"type": "address"
|
305
|
+
},
|
306
|
+
{
|
307
|
+
"internalType": "uint256",
|
308
|
+
"name": "amount",
|
309
|
+
"type": "uint256"
|
310
|
+
}
|
311
|
+
],
|
312
|
+
"name": "transfer",
|
313
|
+
"outputs": [
|
314
|
+
{
|
315
|
+
"internalType": "bool",
|
316
|
+
"name": "",
|
317
|
+
"type": "bool"
|
318
|
+
}
|
319
|
+
],
|
320
|
+
"stateMutability": "nonpayable",
|
321
|
+
"type": "function"
|
322
|
+
},
|
323
|
+
{
|
324
|
+
"inputs": [
|
325
|
+
{
|
326
|
+
"internalType": "address",
|
327
|
+
"name": "sender",
|
328
|
+
"type": "address"
|
329
|
+
},
|
330
|
+
{
|
331
|
+
"internalType": "address",
|
332
|
+
"name": "recipient",
|
333
|
+
"type": "address"
|
334
|
+
},
|
335
|
+
{
|
336
|
+
"internalType": "uint256",
|
337
|
+
"name": "amount",
|
338
|
+
"type": "uint256"
|
339
|
+
}
|
340
|
+
],
|
341
|
+
"name": "transferFrom",
|
342
|
+
"outputs": [
|
343
|
+
{
|
344
|
+
"internalType": "bool",
|
345
|
+
"name": "",
|
346
|
+
"type": "bool"
|
347
|
+
}
|
348
|
+
],
|
349
|
+
"stateMutability": "nonpayable",
|
350
|
+
"type": "function"
|
351
|
+
}
|
352
|
+
]
|
@@ -22,6 +22,7 @@ from prediction_market_agent_tooling.gtypes import USD, OutcomeToken, xDai
|
|
22
22
|
from prediction_market_agent_tooling.loggers import logger
|
23
23
|
from prediction_market_agent_tooling.markets.agent_market import (
|
24
24
|
AgentMarket,
|
25
|
+
ConditionalFilterType,
|
25
26
|
FilterBy,
|
26
27
|
ProcessedMarket,
|
27
28
|
ProcessedTradedMarket,
|
@@ -48,7 +49,7 @@ from prediction_market_agent_tooling.tools.is_invalid import is_invalid
|
|
48
49
|
from prediction_market_agent_tooling.tools.is_predictable import is_predictable_binary
|
49
50
|
from prediction_market_agent_tooling.tools.langfuse_ import langfuse_context, observe
|
50
51
|
from prediction_market_agent_tooling.tools.rephrase import (
|
51
|
-
|
52
|
+
rephrase_question_to_unconditional,
|
52
53
|
)
|
53
54
|
from prediction_market_agent_tooling.tools.tokens.main_token import (
|
54
55
|
MINIMUM_NATIVE_TOKEN_IN_EOA_FOR_FEES,
|
@@ -199,7 +200,7 @@ class DeployablePredictionAgent(DeployableAgent):
|
|
199
200
|
trade_on_markets_created_after: DatetimeUTC | None = None
|
200
201
|
get_markets_sort_by: SortBy = SortBy.CLOSING_SOONEST
|
201
202
|
get_markets_filter_by: FilterBy = FilterBy.OPEN
|
202
|
-
|
203
|
+
rephrase_conditional_markets: bool = True
|
203
204
|
|
204
205
|
# Agent behaviour when filtering fetched markets
|
205
206
|
allow_invalid_questions: bool = False
|
@@ -230,7 +231,7 @@ class DeployablePredictionAgent(DeployableAgent):
|
|
230
231
|
self.answer_categorical_market = observe()(self.answer_categorical_market) # type: ignore[method-assign]
|
231
232
|
self.answer_scalar_market = observe()(self.answer_scalar_market) # type: ignore[method-assign]
|
232
233
|
self.process_market = observe()(self.process_market) # type: ignore[method-assign]
|
233
|
-
self.
|
234
|
+
self.rephrase_market_to_unconditional = observe()(self.rephrase_market_to_unconditional) # type: ignore[method-assign]
|
234
235
|
|
235
236
|
def update_langfuse_trace_by_market(
|
236
237
|
self, market_type: MarketType, market: AgentMarket
|
@@ -305,21 +306,21 @@ class DeployablePredictionAgent(DeployableAgent):
|
|
305
306
|
|
306
307
|
return True
|
307
308
|
|
308
|
-
def
|
309
|
+
def rephrase_market_to_unconditional(
|
309
310
|
self,
|
310
311
|
market_: AgentMarket,
|
311
312
|
) -> AgentMarket:
|
312
313
|
"""
|
313
|
-
If `
|
314
|
+
If `rephrase_conditional_markets` is set to True,
|
314
315
|
this method will be used to rephrase the question to account for the parent's market probability in the agent's decision process.
|
315
316
|
"""
|
316
317
|
new = market_.model_copy(deep=True)
|
317
318
|
|
318
319
|
if new.parent is not None and new.parent.market.parent is not None:
|
319
|
-
new.parent.market = self.
|
320
|
+
new.parent.market = self.rephrase_market_to_unconditional(new.parent.market)
|
320
321
|
|
321
322
|
rephrased_question = (
|
322
|
-
|
323
|
+
rephrase_question_to_unconditional(
|
323
324
|
new.question,
|
324
325
|
new.parent.market.question,
|
325
326
|
new.parent.market.outcomes[new.parent.parent_outcome],
|
@@ -373,14 +374,10 @@ class DeployablePredictionAgent(DeployableAgent):
|
|
373
374
|
return False
|
374
375
|
|
375
376
|
@property
|
376
|
-
def
|
377
|
-
|
378
|
-
|
379
|
-
return
|
380
|
-
# `include_conditional_markets` if `rephrase_conditioned_markets` is enabled.
|
381
|
-
# We can expand this method in teh future, when we implement also more complex logic about conditional markets.
|
382
|
-
# Note that conditional market isn't a type of the market like Binary or Categorical, it means that it uses outcome tokens from parent market as a collateral token in this market.
|
383
|
-
return self.rephrase_conditioned_markets
|
377
|
+
def conditional_filter_type(self) -> ConditionalFilterType:
|
378
|
+
if self.rephrase_conditional_markets:
|
379
|
+
return ConditionalFilterType.ALL
|
380
|
+
return ConditionalFilterType.ONLY_NOT_CONDITIONAL
|
384
381
|
|
385
382
|
@property
|
386
383
|
def agent_question_type(self) -> QuestionType:
|
@@ -407,7 +404,7 @@ class DeployablePredictionAgent(DeployableAgent):
|
|
407
404
|
filter_by=self.get_markets_filter_by,
|
408
405
|
created_after=self.trade_on_markets_created_after,
|
409
406
|
question_type=self.agent_question_type,
|
410
|
-
|
407
|
+
conditional_filter_type=self.conditional_filter_type,
|
411
408
|
)
|
412
409
|
return available_markets
|
413
410
|
|
@@ -440,8 +437,8 @@ class DeployablePredictionAgent(DeployableAgent):
|
|
440
437
|
|
441
438
|
logger.info(f"Answering market '{market.question}'.")
|
442
439
|
|
443
|
-
if self.
|
444
|
-
market = self.
|
440
|
+
if self.rephrase_conditional_markets and market.parent is not None:
|
441
|
+
market = self.rephrase_market_to_unconditional(market)
|
445
442
|
|
446
443
|
if market.is_binary:
|
447
444
|
try:
|
@@ -633,6 +630,7 @@ class DeployableTraderAgent(DeployablePredictionAgent):
|
|
633
630
|
super().initialize_langfuse()
|
634
631
|
# Auto-observe all the methods where it makes sense, so that subclassses don't need to do it manually.
|
635
632
|
self.build_trades = observe()(self.build_trades) # type: ignore[method-assign]
|
633
|
+
self.execute_trades = observe()(self.execute_trades) # type: ignore[method-assign]
|
636
634
|
|
637
635
|
def check_min_required_balance_to_trade(self, market: AgentMarket) -> None:
|
638
636
|
api_keys = APIKeys()
|
@@ -678,37 +676,9 @@ class DeployableTraderAgent(DeployablePredictionAgent):
|
|
678
676
|
trades = strategy.calculate_trades(existing_position, answer, market)
|
679
677
|
return trades
|
680
678
|
|
681
|
-
def
|
682
|
-
self,
|
683
|
-
) ->
|
684
|
-
super().before_process_market(market_type, market)
|
685
|
-
self.check_min_required_balance_to_trade(market)
|
686
|
-
|
687
|
-
def process_market(
|
688
|
-
self,
|
689
|
-
market_type: MarketType,
|
690
|
-
market: AgentMarket,
|
691
|
-
verify_market: bool = True,
|
692
|
-
) -> ProcessedTradedMarket | None:
|
693
|
-
processed_market = super().process_market(market_type, market, verify_market)
|
694
|
-
if processed_market is None:
|
695
|
-
return None
|
696
|
-
|
697
|
-
api_keys = APIKeys()
|
698
|
-
user_id = market.get_user_id(api_keys=api_keys)
|
699
|
-
|
700
|
-
try:
|
701
|
-
existing_position = market.get_position(user_id=user_id)
|
702
|
-
except Exception as e:
|
703
|
-
logger.warning(f"Could not get position for user {user_id}, exception {e}")
|
704
|
-
return None
|
705
|
-
|
706
|
-
trades = self.build_trades(
|
707
|
-
market=market,
|
708
|
-
answer=processed_market.answer,
|
709
|
-
existing_position=existing_position,
|
710
|
-
)
|
711
|
-
|
679
|
+
def execute_trades(
|
680
|
+
self, market: AgentMarket, trades: list[Trade]
|
681
|
+
) -> list[PlacedTrade]:
|
712
682
|
# It can take quite some time before agent processes all the markets, recheck here if the market didn't get closed in the meantime, to not error out completely.
|
713
683
|
# Unfortunately, we can not just add some room into closing time of the market while fetching them, because liquidity can be removed at any time by the liquidity providers.
|
714
684
|
still_tradeable = market.can_be_traded()
|
@@ -717,7 +687,8 @@ class DeployableTraderAgent(DeployablePredictionAgent):
|
|
717
687
|
f"Market {market.question=} ({market.url}) was selected to processing, but is not tradeable anymore."
|
718
688
|
)
|
719
689
|
|
720
|
-
placed_trades = []
|
690
|
+
placed_trades: list[PlacedTrade] = []
|
691
|
+
|
721
692
|
for trade in trades:
|
722
693
|
logger.info(f"Executing trade {trade} on market {market.id} ({market.url})")
|
723
694
|
|
@@ -730,7 +701,9 @@ class DeployableTraderAgent(DeployablePredictionAgent):
|
|
730
701
|
case TradeType.SELL:
|
731
702
|
# Get actual value of the position we are going to sell, and if it's less than we wanted to sell, simply sell all of it.
|
732
703
|
current_position = check_not_none(
|
733
|
-
market.get_position(
|
704
|
+
market.get_position(
|
705
|
+
market.get_user_id(api_keys=self.api_keys)
|
706
|
+
),
|
734
707
|
"Should exists if we are going to sell outcomes.",
|
735
708
|
)
|
736
709
|
|
@@ -758,6 +731,39 @@ class DeployableTraderAgent(DeployablePredictionAgent):
|
|
758
731
|
f"Trade execution skipped because, {self.place_trades=} or {still_tradeable=}."
|
759
732
|
)
|
760
733
|
|
734
|
+
return placed_trades
|
735
|
+
|
736
|
+
def before_process_market(
|
737
|
+
self, market_type: MarketType, market: AgentMarket
|
738
|
+
) -> None:
|
739
|
+
super().before_process_market(market_type, market)
|
740
|
+
self.check_min_required_balance_to_trade(market)
|
741
|
+
|
742
|
+
def process_market(
|
743
|
+
self,
|
744
|
+
market_type: MarketType,
|
745
|
+
market: AgentMarket,
|
746
|
+
verify_market: bool = True,
|
747
|
+
) -> ProcessedTradedMarket | None:
|
748
|
+
processed_market = super().process_market(market_type, market, verify_market)
|
749
|
+
if processed_market is None:
|
750
|
+
return None
|
751
|
+
|
752
|
+
user_id = market.get_user_id(api_keys=self.api_keys)
|
753
|
+
|
754
|
+
try:
|
755
|
+
existing_position = market.get_position(user_id=user_id)
|
756
|
+
except Exception as e:
|
757
|
+
logger.warning(f"Could not get position for user {user_id}, exception {e}")
|
758
|
+
return None
|
759
|
+
|
760
|
+
trades = self.build_trades(
|
761
|
+
market=market,
|
762
|
+
answer=processed_market.answer,
|
763
|
+
existing_position=existing_position,
|
764
|
+
)
|
765
|
+
placed_trades = self.execute_trades(market, trades)
|
766
|
+
|
761
767
|
traded_market = ProcessedTradedMarket(
|
762
768
|
answer=processed_market.answer, trades=placed_trades
|
763
769
|
)
|
@@ -84,7 +84,7 @@ class BettingStrategy(ABC):
|
|
84
84
|
|
85
85
|
if outcome_tokens_to_get_in_usd <= trade.amount:
|
86
86
|
raise GuaranteedLossError(
|
87
|
-
f"Trade {trade=} would result in guaranteed loss by getting only {outcome_tokens_to_get=}. Halting execution."
|
87
|
+
f"Trade {trade=} on market {market.url=} would result in guaranteed loss by getting only {outcome_tokens_to_get=}. Halting execution."
|
88
88
|
)
|
89
89
|
|
90
90
|
clean_trades.append(trade)
|
@@ -76,6 +76,12 @@ class QuestionType(str, Enum):
|
|
76
76
|
BINARY = "binary"
|
77
77
|
|
78
78
|
|
79
|
+
class ConditionalFilterType(Enum):
|
80
|
+
ALL = 1
|
81
|
+
ONLY_CONDITIONAL = 2
|
82
|
+
ONLY_NOT_CONDITIONAL = 3
|
83
|
+
|
84
|
+
|
79
85
|
class AgentMarket(BaseModel):
|
80
86
|
"""
|
81
87
|
Common market class that can be created from vendor specific markets.
|
@@ -384,7 +390,7 @@ class AgentMarket(BaseModel):
|
|
384
390
|
created_after: t.Optional[DatetimeUTC] = None,
|
385
391
|
excluded_questions: set[str] | None = None,
|
386
392
|
question_type: QuestionType = QuestionType.ALL,
|
387
|
-
|
393
|
+
conditional_filter_type: ConditionalFilterType = ConditionalFilterType.ONLY_NOT_CONDITIONAL,
|
388
394
|
) -> t.Sequence["AgentMarket"]:
|
389
395
|
raise NotImplementedError("Subclasses must implement this method")
|
390
396
|
|
@@ -10,6 +10,7 @@ from prediction_market_agent_tooling.gtypes import (
|
|
10
10
|
)
|
11
11
|
from prediction_market_agent_tooling.markets.agent_market import (
|
12
12
|
AgentMarket,
|
13
|
+
ConditionalFilterType,
|
13
14
|
FilterBy,
|
14
15
|
MarketFees,
|
15
16
|
QuestionType,
|
@@ -112,7 +113,7 @@ class ManifoldAgentMarket(AgentMarket):
|
|
112
113
|
created_after: t.Optional[DatetimeUTC] = None,
|
113
114
|
excluded_questions: set[str] | None = None,
|
114
115
|
question_type: QuestionType = QuestionType.ALL,
|
115
|
-
|
116
|
+
conditional_filter_type: ConditionalFilterType = ConditionalFilterType.ONLY_NOT_CONDITIONAL,
|
116
117
|
) -> t.Sequence["ManifoldAgentMarket"]:
|
117
118
|
sort: t.Literal["newest", "close-date"] | None
|
118
119
|
if sort_by == SortBy.CLOSING_SOONEST:
|
@@ -7,6 +7,7 @@ from prediction_market_agent_tooling.config import APIKeys
|
|
7
7
|
from prediction_market_agent_tooling.gtypes import OutcomeStr, Probability
|
8
8
|
from prediction_market_agent_tooling.markets.agent_market import (
|
9
9
|
AgentMarket,
|
10
|
+
ConditionalFilterType,
|
10
11
|
FilterBy,
|
11
12
|
MarketFees,
|
12
13
|
ProcessedMarket,
|
@@ -74,7 +75,7 @@ class MetaculusAgentMarket(AgentMarket):
|
|
74
75
|
created_after: t.Optional[DatetimeUTC] = None,
|
75
76
|
excluded_questions: set[str] | None = None,
|
76
77
|
question_type: QuestionType = QuestionType.ALL,
|
77
|
-
|
78
|
+
conditional_filter_type: ConditionalFilterType = ConditionalFilterType.ONLY_NOT_CONDITIONAL,
|
78
79
|
tournament_id: int | None = None,
|
79
80
|
) -> t.Sequence["MetaculusAgentMarket"]:
|
80
81
|
order_by: str | None
|
@@ -23,6 +23,7 @@ from prediction_market_agent_tooling.gtypes import (
|
|
23
23
|
from prediction_market_agent_tooling.loggers import logger
|
24
24
|
from prediction_market_agent_tooling.markets.agent_market import (
|
25
25
|
AgentMarket,
|
26
|
+
ConditionalFilterType,
|
26
27
|
FilterBy,
|
27
28
|
MarketFees,
|
28
29
|
ProcessedMarket,
|
@@ -381,7 +382,7 @@ class OmenAgentMarket(AgentMarket):
|
|
381
382
|
created_after: t.Optional[DatetimeUTC] = None,
|
382
383
|
excluded_questions: set[str] | None = None,
|
383
384
|
question_type: QuestionType = QuestionType.ALL,
|
384
|
-
|
385
|
+
conditional_filter_type: ConditionalFilterType = ConditionalFilterType.ONLY_NOT_CONDITIONAL,
|
385
386
|
) -> t.Sequence["OmenAgentMarket"]:
|
386
387
|
fetch_categorical_markets = question_type == QuestionType.CATEGORICAL
|
387
388
|
|
@@ -9,6 +9,7 @@ from prediction_market_agent_tooling.gtypes import (
|
|
9
9
|
)
|
10
10
|
from prediction_market_agent_tooling.markets.agent_market import (
|
11
11
|
AgentMarket,
|
12
|
+
ConditionalFilterType,
|
12
13
|
FilterBy,
|
13
14
|
MarketFees,
|
14
15
|
QuestionType,
|
@@ -124,7 +125,7 @@ class PolymarketAgentMarket(AgentMarket):
|
|
124
125
|
created_after: t.Optional[DatetimeUTC] = None,
|
125
126
|
excluded_questions: set[str] | None = None,
|
126
127
|
question_type: QuestionType = QuestionType.ALL,
|
127
|
-
|
128
|
+
conditional_filter_type: ConditionalFilterType = ConditionalFilterType.ONLY_NOT_CONDITIONAL,
|
128
129
|
) -> t.Sequence["PolymarketAgentMarket"]:
|
129
130
|
closed: bool | None
|
130
131
|
|