prediction-market-agent-tooling 0.63.2__py3-none-any.whl → 0.63.4__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.
@@ -30,7 +30,7 @@ from prediction_market_agent_tooling.deploy.trade_interval import (
30
30
  FixedInterval,
31
31
  TradeInterval,
32
32
  )
33
- from prediction_market_agent_tooling.gtypes import xDai
33
+ from prediction_market_agent_tooling.gtypes import USD, OutcomeToken, xDai
34
34
  from prediction_market_agent_tooling.loggers import logger
35
35
  from prediction_market_agent_tooling.markets.agent_market import (
36
36
  AgentMarket,
@@ -499,7 +499,7 @@ class DeployablePredictionAgent(DeployableAgent):
499
499
 
500
500
  for market_idx, market in enumerate(available_markets):
501
501
  logger.info(
502
- f"Going to process market {market_idx+1} / {len(available_markets)}."
502
+ f"Going to process market {market.url}: {market_idx+1} / {len(available_markets)}."
503
503
  )
504
504
  self.before_process_market(market_type, market)
505
505
  processed_market = self.process_market(market_type, market)
@@ -648,19 +648,27 @@ class DeployableTraderAgent(DeployablePredictionAgent):
648
648
  )
649
649
  case TradeType.SELL:
650
650
  # 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.
651
- current_position_value = check_not_none(
651
+ current_position = check_not_none(
652
652
  market.get_position(user_id),
653
653
  "Should exists if we are going to sell outcomes.",
654
- ).amounts_current[
654
+ )
655
+ current_position_value_usd = current_position.amounts_current[
655
656
  market.get_outcome_str_from_bool(trade.outcome)
656
657
  ]
657
- if current_position_value < trade.amount:
658
+ amount_to_sell: USD | OutcomeToken
659
+ if current_position_value_usd <= trade.amount:
658
660
  logger.warning(
659
- f"Current value of position {trade.outcome=}, {current_position_value=} is less than the desired selling amount {trade.amount=}. Selling all."
661
+ f"Current value of position {trade.outcome=}, {current_position_value_usd=} is less than the desired selling amount {trade.amount=}. Selling all."
660
662
  )
663
+ # In case the agent asked to sell too much, provide the amount to sell as all outcome tokens, instead of in USD, to minimze fx fluctuations when selling.
664
+ amount_to_sell = current_position.amounts_ot[
665
+ market.get_outcome_str_from_bool(trade.outcome)
666
+ ]
667
+ else:
668
+ amount_to_sell = trade.amount
661
669
  id = market.sell_tokens(
662
670
  outcome=trade.outcome,
663
- amount=min(trade.amount, current_position_value),
671
+ amount=amount_to_sell,
664
672
  )
665
673
  case _:
666
674
  raise ValueError(f"Unexpected trade type {trade.trade_type}.")
@@ -34,7 +34,7 @@ class CollateralToken(_GenericValue[int | float | str | Decimal, float], parser=
34
34
 
35
35
  @property
36
36
  def as_wei(self) -> "Wei":
37
- return Wei(Web3.to_wei(self.value, "ether"))
37
+ return Wei(to_wei_inc_negative(self.value))
38
38
 
39
39
 
40
40
  class OutcomeToken(_GenericValue[int | float | str | Decimal, float], parser=float):
@@ -51,7 +51,7 @@ class OutcomeToken(_GenericValue[int | float | str | Decimal, float], parser=flo
51
51
 
52
52
  @property
53
53
  def as_outcome_wei(self) -> "OutcomeWei":
54
- return OutcomeWei(Web3.to_wei(self.value, "ether"))
54
+ return OutcomeWei(to_wei_inc_negative(self.value))
55
55
 
56
56
  @property
57
57
  def as_token(self) -> CollateralToken:
@@ -77,7 +77,7 @@ class xDai(_GenericValue[int | float | str | Decimal, float], parser=float):
77
77
 
78
78
  @property
79
79
  def as_xdai_wei(self) -> "xDaiWei":
80
- return xDaiWei(Web3.to_wei(self.value, "ether"))
80
+ return xDaiWei(to_wei_inc_negative(self.value))
81
81
 
82
82
 
83
83
  class Mana(_GenericValue[int | float | str | Decimal, float], parser=float):
@@ -93,7 +93,7 @@ class Wei(_GenericValue[Web3Wei | int | str, Web3Wei], parser=int):
93
93
 
94
94
  @property
95
95
  def as_token(self) -> CollateralToken:
96
- return CollateralToken(Web3.from_wei(self.value, "ether"))
96
+ return CollateralToken(from_wei_inc_negative(self.value))
97
97
 
98
98
 
99
99
  class OutcomeWei(_GenericValue[Web3Wei | int | str, Web3Wei], parser=int):
@@ -107,7 +107,7 @@ class OutcomeWei(_GenericValue[Web3Wei | int | str, Web3Wei], parser=int):
107
107
 
108
108
  @property
109
109
  def as_outcome_token(self) -> OutcomeToken:
110
- return OutcomeToken(Web3.from_wei(self.value, "ether"))
110
+ return OutcomeToken(from_wei_inc_negative(self.value))
111
111
 
112
112
  @property
113
113
  def as_wei(self) -> Wei:
@@ -122,7 +122,7 @@ class xDaiWei(_GenericValue[Web3Wei | int | str, Web3Wei], parser=int):
122
122
 
123
123
  @property
124
124
  def as_xdai(self) -> xDai:
125
- return xDai(Web3.from_wei(self.value, "ether"))
125
+ return xDai(from_wei_inc_negative(self.value))
126
126
 
127
127
  @property
128
128
  def as_wei(self) -> Wei:
@@ -162,3 +162,19 @@ def secretstr_to_v1_secretstr(s: SecretStr | None) -> SecretStrV1 | None:
162
162
  def int_to_hexbytes(v: int) -> HexBytes:
163
163
  # Example: 1 -> HexBytes("0x0000000000000000000000000000000000000000000000000000000000000001"). # web3-private-key-ok
164
164
  return HexBytes.fromhex(format(v, "064x"))
165
+
166
+
167
+ def to_wei_inc_negative(value: int | float | str | Decimal) -> Web3Wei:
168
+ """
169
+ Handles conversion of a value to Wei, taking into account negative values.
170
+ """
171
+ return Web3Wei(
172
+ Web3.to_wei(abs(Decimal(value)), "ether") * (-1 if Decimal(value) < 0 else 1)
173
+ )
174
+
175
+
176
+ def from_wei_inc_negative(value: int) -> int | Decimal:
177
+ """
178
+ Handles conversion from Wei to a float value, taking into account negative values.
179
+ """
180
+ return Web3.from_wei(abs(value), "ether") * (-1 if value < 0 else 1)
@@ -86,7 +86,10 @@ from prediction_market_agent_tooling.tools.utils import (
86
86
  calculate_sell_amount_in_collateral,
87
87
  check_not_none,
88
88
  )
89
- from prediction_market_agent_tooling.tools.web3_utils import get_receipt_block_timestamp
89
+ from prediction_market_agent_tooling.tools.web3_utils import (
90
+ get_receipt_block_timestamp,
91
+ is_valid_wei,
92
+ )
90
93
 
91
94
  OMEN_DEFAULT_REALITIO_BOND_VALUE = xDai(0.01)
92
95
  OMEN_TINY_BET_AMOUNT = USD(0.00001)
@@ -336,6 +339,11 @@ class OmenAgentMarket(AgentMarket):
336
339
 
337
340
  @staticmethod
338
341
  def from_data_model(model: OmenMarket) -> "OmenAgentMarket":
342
+ if not all(is_valid_wei(number.value) for number in model.outcomeTokenAmounts):
343
+ raise ValueError(
344
+ f"Market {model.url} has invalid {model.outcomeTokenAmounts=}."
345
+ )
346
+
339
347
  return OmenAgentMarket(
340
348
  id=model.id,
341
349
  question=model.title,
@@ -1,3 +1,5 @@
1
+ import typing as t
2
+
1
3
  from cachetools import TTLCache, cached
2
4
  from web3 import Web3
3
5
 
@@ -21,6 +23,27 @@ from prediction_market_agent_tooling.tools.cow.cow_order import (
21
23
  from prediction_market_agent_tooling.tools.hexbytes_custom import HexBytes
22
24
 
23
25
 
26
+ def _make_cache_key(
27
+ *args: t.Any,
28
+ token: ChecksumAddress,
29
+ collateral_exchange_amount: CollateralToken | None = None,
30
+ ) -> str:
31
+ """
32
+ Generate a unique cache key based on a token address and optional collateral token.
33
+ """
34
+
35
+ if collateral_exchange_amount is None:
36
+ return f"{token}-no_collateral"
37
+
38
+ return "-".join(
39
+ [
40
+ token,
41
+ collateral_exchange_amount.symbol,
42
+ str(collateral_exchange_amount.value),
43
+ ]
44
+ )
45
+
46
+
24
47
  class PriceManager:
25
48
  def __init__(self, seer_market: SeerMarket, seer_subgraph: SeerSubgraphHandler):
26
49
  self.seer_market = seer_market
@@ -66,7 +89,7 @@ class PriceManager:
66
89
  else:
67
90
  return None
68
91
 
69
- @cached(TTLCache(maxsize=100, ttl=5 * 60))
92
+ @cached(TTLCache(maxsize=100, ttl=5 * 60), key=_make_cache_key)
70
93
  def get_price_for_token(
71
94
  self,
72
95
  token: ChecksumAddress,
@@ -231,6 +231,9 @@ class _GenericValue(
231
231
  def __bool__(self) -> bool:
232
232
  return bool(self.value)
233
233
 
234
+ def __hash__(self) -> int: # type: ignore[override]
235
+ return hash(tuple(sorted(self.items())))
236
+
234
237
  @classmethod
235
238
  def __get_pydantic_core_schema__(
236
239
  cls, source_type: t.Any, handler: GetCoreSchemaHandler
@@ -6,6 +6,7 @@ import base58
6
6
  import tenacity
7
7
  from eth_account import Account
8
8
  from eth_typing import URI
9
+ from eth_utils.currency import MAX_WEI, MIN_WEI
9
10
  from pydantic.types import SecretStr
10
11
  from safe_eth.eth import EthereumClient
11
12
  from safe_eth.safe.safe import SafeV141
@@ -21,6 +22,7 @@ from prediction_market_agent_tooling.gtypes import (
21
22
  HexStr,
22
23
  IPFSCIDVersion0,
23
24
  PrivateKey,
25
+ Web3Wei,
24
26
  private_key_type,
25
27
  xDai,
26
28
  xDaiWei,
@@ -354,3 +356,7 @@ def get_receipt_block_timestamp(receipt_tx: TxReceipt, web3: Web3) -> int:
354
356
  block = web3.eth.get_block(block_number)
355
357
  block_timestamp: int = block["timestamp"]
356
358
  return block_timestamp
359
+
360
+
361
+ def is_valid_wei(value: Web3Wei) -> bool:
362
+ return MIN_WEI <= value <= MAX_WEI
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: prediction-market-agent-tooling
3
- Version: 0.63.2
3
+ Version: 0.63.4
4
4
  Summary: Tools to benchmark, deploy and monitor prediction market agents.
5
5
  Author: Gnosis
6
6
  Requires-Python: >=3.10,<3.13
@@ -21,7 +21,7 @@ prediction_market_agent_tooling/benchmark/agents.py,sha256=B1-uWdyeN4GGKMWGK_-Cc
21
21
  prediction_market_agent_tooling/benchmark/benchmark.py,sha256=MqTiaaJ3cYiOLUVR7OyImLWxcEya3Rl5JyFYW-K0lwM,17097
22
22
  prediction_market_agent_tooling/benchmark/utils.py,sha256=D0MfUkVZllmvcU0VOurk9tcKT7JTtwwOp-63zuCBVuc,2880
23
23
  prediction_market_agent_tooling/config.py,sha256=So5l8KbgmzcCpxzzf13TNrEJPu_4iQnUDhzus6XRvSc,10151
24
- prediction_market_agent_tooling/deploy/agent.py,sha256=OyrhPOjByQOAi1_VWhef7ieKqREjVhvjGHgnUIQc3gI,25877
24
+ prediction_market_agent_tooling/deploy/agent.py,sha256=uh1_sf7W6Ti9HHdRw5uf540EYUEU13tLi-XQsXPzN6Q,26469
25
25
  prediction_market_agent_tooling/deploy/agent_example.py,sha256=dIIdZashExWk9tOdyDjw87AuUcGyM7jYxNChYrVK2dM,1001
26
26
  prediction_market_agent_tooling/deploy/betting_strategy.py,sha256=p25t7VU7I4hSkSl6SpzI_W55kLbYEySQdBqeschmARY,12918
27
27
  prediction_market_agent_tooling/deploy/constants.py,sha256=M5ty8URipYMGe_G-RzxRydK3AFL6CyvmqCraJUrLBnE,82
@@ -29,7 +29,7 @@ prediction_market_agent_tooling/deploy/gcp/deploy.py,sha256=CYUgnfy-9XVk04kkxA_5
29
29
  prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py,sha256=OsPboCFGiZKsvGyntGZHwdqPlLTthITkNF5rJFvGgU8,2582
30
30
  prediction_market_agent_tooling/deploy/gcp/utils.py,sha256=WI2ycX1X-IlTRoNoG4ggFlRwPL28kwM9VGDFD2fePLo,5699
31
31
  prediction_market_agent_tooling/deploy/trade_interval.py,sha256=Xk9j45alQ_vrasGvsNyuW70XHIQ7wfvjoxNR3F6HYCw,1155
32
- prediction_market_agent_tooling/gtypes.py,sha256=DaerVkKVqhIhTwCB9A8piwCR97ZMnd8nSTSOlI9XcLM,5549
32
+ prediction_market_agent_tooling/gtypes.py,sha256=bUIZfZIGvIi3aiZNu5rVE9kRevw8sfMa4bcze6QeBg8,6058
33
33
  prediction_market_agent_tooling/jobs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
34
  prediction_market_agent_tooling/jobs/jobs_models.py,sha256=8vYafsK1cqMWQtjBoq9rruroF84xAVD00vBTMWH6QMg,2166
35
35
  prediction_market_agent_tooling/jobs/omen/omen_jobs.py,sha256=Pf6QxPXGyie-2l_wZUjaGPTjZTlpv50_JhP40mULBaU,5048
@@ -51,7 +51,7 @@ prediction_market_agent_tooling/markets/metaculus/data_models.py,sha256=FaBCTPPe
51
51
  prediction_market_agent_tooling/markets/metaculus/metaculus.py,sha256=86TIx6cavEWc8Cv4KpZxSvwiSw9oFybXE3YB49pg-CA,4377
52
52
  prediction_market_agent_tooling/markets/omen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
53
  prediction_market_agent_tooling/markets/omen/data_models.py,sha256=URvplDcTLeL6vfpkSgi8ln2iEKxt8w5qf6mTZkSyrCo,29189
54
- prediction_market_agent_tooling/markets/omen/omen.py,sha256=Jf2qSJJn0UUISpi24xYRwoVycGuYE42kZ2z1HRGl43w,51927
54
+ prediction_market_agent_tooling/markets/omen/omen.py,sha256=L2JcFdbjLGu2hF-mYnO-EUqo2vDKFUXstsoncSEVxdg,52167
55
55
  prediction_market_agent_tooling/markets/omen/omen_constants.py,sha256=D9oflYKafLQiHYtB5sScMHqmXyzM8JP8J0yATmc4SQQ,233
56
56
  prediction_market_agent_tooling/markets/omen/omen_contracts.py,sha256=bCC9A7ZTJxMDJcPbl3jof6HcAGGHv1BrFq3RRWbkQ_c,28739
57
57
  prediction_market_agent_tooling/markets/omen/omen_resolving.py,sha256=Cyi9Ci-Z-K8WCZWVLs9oSuJC6qRobi_CpqDCno_5F-0,10238
@@ -62,7 +62,7 @@ prediction_market_agent_tooling/markets/polymarket/data_models_web.py,sha256=LVE
62
62
  prediction_market_agent_tooling/markets/polymarket/polymarket.py,sha256=6rc9qulPl90MxXKB55XiiWKLhjfAyG_eUzAlqpq1UIE,3339
63
63
  prediction_market_agent_tooling/markets/polymarket/utils.py,sha256=8kTeVjXPcXC6DkDvWYsZQLY7x8DS6CEp_yznSEazsNU,2037
64
64
  prediction_market_agent_tooling/markets/seer/data_models.py,sha256=FwTOq9X2iJ7r3ijtE0evl8pMSbFPm4lUwuc9m7YsMVA,6373
65
- prediction_market_agent_tooling/markets/seer/price_manager.py,sha256=PtGD9cm8JlxVTkSD-QgZuh_gWfG7WATakh8-t0szomk,4924
65
+ prediction_market_agent_tooling/markets/seer/price_manager.py,sha256=EuOe6zCmEEWXz1loXaQQOYC7ZNQ0cDJn0rZadK1dBlc,5460
66
66
  prediction_market_agent_tooling/markets/seer/seer.py,sha256=_FzFGTkaOHQ2WTkUa_ba-Tc9zqw4KTmbCTrH4EmvOsU,16035
67
67
  prediction_market_agent_tooling/markets/seer/seer_contracts.py,sha256=yufEojZxLa_SQv9xhsG23wLGsyHOWD8Azm7-7E5Zn_8,2714
68
68
  prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py,sha256=KKRI493VNNAY9tR1AjzNraeH76MvDsBV6GsiLZas0_Y,9859
@@ -76,7 +76,7 @@ prediction_market_agent_tooling/monitor/monitor.py,sha256=yvSXwV-3DSAm3vsFZnFC9j
76
76
  prediction_market_agent_tooling/monitor/monitor_app.py,sha256=-_6w_ZvQ-Ad5qaeuo7NKTXUOOZ_6OrR8jMe25BGOY4k,4615
77
77
  prediction_market_agent_tooling/monitor/monitor_settings.py,sha256=Xiozs3AsufuJ04JOe1vjUri-IAMWHjjmc2ugGGiHNH4,947
78
78
  prediction_market_agent_tooling/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
- prediction_market_agent_tooling/tools/_generic_value.py,sha256=0_EDybTsr3iXqPPqy2U1WMw4st_SlYaCrf2p1MZhED4,10511
79
+ prediction_market_agent_tooling/tools/_generic_value.py,sha256=pD_PI13lpPp1gFoljHwa_Lzlp-u2pu0m-Z7LcxwDM2U,10618
80
80
  prediction_market_agent_tooling/tools/balances.py,sha256=Osab21btfJDw2Y-jT_TV-KHGrseCRxcsYeW6WcOMB8E,1050
81
81
  prediction_market_agent_tooling/tools/betting_strategies/kelly_criterion.py,sha256=L9yp3m_81i-y85dGZH1rYRv9YXYYt1w3RGroFAAYSbw,4873
82
82
  prediction_market_agent_tooling/tools/betting_strategies/market_moving.py,sha256=36ucOuF38bdB4rnSPNjC1qpidBo30Ff4P5Kb-7emKEQ,5469
@@ -120,9 +120,9 @@ prediction_market_agent_tooling/tools/tokens/token_utils.py,sha256=fhs-FH9m9IbzG
120
120
  prediction_market_agent_tooling/tools/tokens/usd.py,sha256=yuW8iPPtcpP4eLH2nORMDAfztcq0Nv2ascSrCquF1f8,3115
121
121
  prediction_market_agent_tooling/tools/transaction_cache.py,sha256=K5YKNL2_tR10Iw2TD9fuP-CTGpBbZtNdgbd0B_R7pjg,1814
122
122
  prediction_market_agent_tooling/tools/utils.py,sha256=1xsyBBJfiEdSoMlceB2F8o2sCb6Z8-qNz11pEJFrdyE,6566
123
- prediction_market_agent_tooling/tools/web3_utils.py,sha256=eYCc1iWAVtqDKUPTwnMUHuYolPdwh_OTiM3-AdRgDp4,12198
124
- prediction_market_agent_tooling-0.63.2.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
125
- prediction_market_agent_tooling-0.63.2.dist-info/METADATA,sha256=8842h65SdEztkGfvqLpAOdd1DdOrrJ7eFtSQtBcQYcA,8689
126
- prediction_market_agent_tooling-0.63.2.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
127
- prediction_market_agent_tooling-0.63.2.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
128
- prediction_market_agent_tooling-0.63.2.dist-info/RECORD,,
123
+ prediction_market_agent_tooling/tools/web3_utils.py,sha256=zRq-eeBGWt8uUGN9G_WfjmJ0eVvO8aWE9S0Pz_Y6AOA,12342
124
+ prediction_market_agent_tooling-0.63.4.dist-info/LICENSE,sha256=6or154nLLU6bELzjh0mCreFjt0m2v72zLi3yHE0QbeE,7650
125
+ prediction_market_agent_tooling-0.63.4.dist-info/METADATA,sha256=_zWTgyTGpx-YPI1eYzV8YpbFyuLlM0Jc1wG9-2UuSI0,8689
126
+ prediction_market_agent_tooling-0.63.4.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
127
+ prediction_market_agent_tooling-0.63.4.dist-info/entry_points.txt,sha256=m8PukHbeH5g0IAAmOf_1Ahm-sGAMdhSSRQmwtpmi2s8,81
128
+ prediction_market_agent_tooling-0.63.4.dist-info/RECORD,,