prediction-market-agent-tooling 0.66.2__tar.gz → 0.66.4__tar.gz

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.
Files changed (131) hide show
  1. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/PKG-INFO +1 -1
  2. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/benchmark/utils.py +13 -0
  3. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/deploy/agent.py +25 -1
  4. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/deploy/betting_strategy.py +30 -3
  5. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/deploy/constants.py +2 -0
  6. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/jobs/omen/omen_jobs.py +2 -0
  7. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/agent_market.py +35 -0
  8. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/data_models.py +64 -0
  9. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/manifold/manifold.py +1 -0
  10. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/markets.py +2 -0
  11. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/metaculus/metaculus.py +1 -0
  12. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/omen/omen.py +1 -0
  13. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +7 -7
  14. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/polymarket/polymarket.py +1 -0
  15. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/seer/data_models.py +15 -1
  16. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/seer/seer.py +71 -11
  17. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py +68 -30
  18. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/pyproject.toml +1 -1
  19. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/LICENSE +0 -0
  20. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/README.md +0 -0
  21. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/agentresultmapping.abi.json +0 -0
  22. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/debuggingcontract.abi.json +0 -0
  23. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/depositablewrapper_erc20.abi.json +0 -0
  24. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/erc20.abi.json +0 -0
  25. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/erc4626.abi.json +0 -0
  26. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/erc721.abi.json +0 -0
  27. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/gvp2_settlement.abi.json +0 -0
  28. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/omen_dxdao.abi.json +0 -0
  29. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/omen_fpmm.abi.json +0 -0
  30. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/omen_fpmm_conditionaltokens.abi.json +0 -0
  31. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/omen_fpmm_factory.abi.json +0 -0
  32. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/omen_kleros.abi.json +0 -0
  33. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/omen_oracle.abi.json +0 -0
  34. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/omen_realitio.abi.json +0 -0
  35. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/omen_thumbnailmapping.abi.json +0 -0
  36. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/ownable.abi.json +0 -0
  37. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/ownable_erc721.abi.json +0 -0
  38. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/proxy.abi.json +0 -0
  39. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/seer_gnosis_router.abi.json +0 -0
  40. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/seer_market_factory.abi.json +0 -0
  41. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/abis/swapr_router.abi.json +0 -0
  42. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/benchmark/__init__.py +0 -0
  43. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/benchmark/agents.py +0 -0
  44. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/benchmark/benchmark.py +0 -0
  45. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/chains.py +0 -0
  46. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/config.py +0 -0
  47. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/data_download/langfuse_data_downloader.py +0 -0
  48. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/deploy/agent_example.py +0 -0
  49. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/deploy/gcp/deploy.py +0 -0
  50. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py +0 -0
  51. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/deploy/gcp/utils.py +0 -0
  52. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/deploy/trade_interval.py +0 -0
  53. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/gtypes.py +0 -0
  54. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/jobs/__init__.py +0 -0
  55. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/jobs/jobs_models.py +0 -0
  56. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/loggers.py +0 -0
  57. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/logprobs_parser.py +0 -0
  58. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/base_subgraph_handler.py +0 -0
  59. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/blockchain_utils.py +0 -0
  60. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/categorize.py +0 -0
  61. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/manifold/__init__.py +0 -0
  62. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/manifold/api.py +0 -0
  63. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/manifold/data_models.py +0 -0
  64. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/manifold/utils.py +0 -0
  65. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/market_fees.py +0 -0
  66. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/metaculus/api.py +0 -0
  67. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/metaculus/data_models.py +0 -0
  68. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/omen/__init__.py +0 -0
  69. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/omen/cow_contracts.py +0 -0
  70. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/omen/data_models.py +0 -0
  71. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/omen/omen_constants.py +0 -0
  72. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/omen/omen_contracts.py +0 -0
  73. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/omen/omen_resolving.py +0 -0
  74. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/polymarket/api.py +0 -0
  75. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/polymarket/data_models.py +0 -0
  76. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/polymarket/data_models_web.py +0 -0
  77. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/polymarket/utils.py +0 -0
  78. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/seer/exceptions.py +0 -0
  79. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/seer/price_manager.py +0 -0
  80. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/seer/seer_contracts.py +0 -0
  81. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/seer/subgraph_data_models.py +0 -0
  82. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/markets/seer/swap_pool_handler.py +0 -0
  83. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/py.typed +0 -0
  84. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/_generic_value.py +0 -0
  85. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/balances.py +0 -0
  86. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/betting_strategies/kelly_criterion.py +0 -0
  87. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/betting_strategies/stretch_bet_between.py +0 -0
  88. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/betting_strategies/utils.py +0 -0
  89. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/caches/db_cache.py +0 -0
  90. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/caches/inmemory_cache.py +0 -0
  91. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/caches/serializers.py +0 -0
  92. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/contract.py +0 -0
  93. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/costs.py +0 -0
  94. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/cow/cow_order.py +0 -0
  95. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/cow/models.py +0 -0
  96. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/cow/semaphore.py +0 -0
  97. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/custom_exceptions.py +0 -0
  98. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/datetime_utc.py +0 -0
  99. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/db/db_manager.py +0 -0
  100. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/google_utils.py +0 -0
  101. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/hexbytes_custom.py +0 -0
  102. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/httpx_cached_client.py +0 -0
  103. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/image_gen/image_gen.py +0 -0
  104. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/image_gen/market_thumbnail_gen.py +0 -0
  105. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/ipfs/ipfs_handler.py +0 -0
  106. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/is_invalid.py +0 -0
  107. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/is_predictable.py +0 -0
  108. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/langfuse_.py +0 -0
  109. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/langfuse_client_utils.py +0 -0
  110. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/omen/reality_accuracy.py +0 -0
  111. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/omen/sell_positions.py +0 -0
  112. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/parallelism.py +0 -0
  113. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/perplexity/perplexity_client.py +0 -0
  114. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/perplexity/perplexity_models.py +0 -0
  115. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/perplexity/perplexity_search.py +0 -0
  116. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/relevant_news_analysis/data_models.py +0 -0
  117. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_analysis.py +0 -0
  118. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/relevant_news_analysis/relevant_news_cache.py +0 -0
  119. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/safe.py +0 -0
  120. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/singleton.py +0 -0
  121. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/streamlit_user_login.py +0 -0
  122. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/tavily/tavily_models.py +0 -0
  123. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/tavily/tavily_search.py +0 -0
  124. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/tokens/auto_deposit.py +0 -0
  125. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/tokens/auto_withdraw.py +0 -0
  126. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/tokens/main_token.py +0 -0
  127. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/tokens/token_utils.py +0 -0
  128. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/tokens/usd.py +0 -0
  129. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/transaction_cache.py +0 -0
  130. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/utils.py +0 -0
  131. {prediction_market_agent_tooling-0.66.2 → prediction_market_agent_tooling-0.66.4}/prediction_market_agent_tooling/tools/web3_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: prediction-market-agent-tooling
3
- Version: 0.66.2
3
+ Version: 0.66.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
@@ -6,6 +6,7 @@ from pydantic import BaseModel
6
6
  from prediction_market_agent_tooling.gtypes import OutcomeStr, Probability
7
7
  from prediction_market_agent_tooling.markets.data_models import (
8
8
  CategoricalProbabilisticAnswer,
9
+ ScalarProbabilisticAnswer,
9
10
  )
10
11
 
11
12
 
@@ -16,6 +17,18 @@ def get_most_probable_outcome(
16
17
  return max(probability_map, key=lambda k: float(probability_map[k]))
17
18
 
18
19
 
20
+ class ScalarPrediction(BaseModel):
21
+ is_predictable: bool = True
22
+ outcome_prediction: t.Optional[ScalarProbabilisticAnswer] = None
23
+
24
+ time: t.Optional[float] = None
25
+ cost: t.Optional[float] = None
26
+
27
+ @property
28
+ def is_answered(self) -> bool:
29
+ return self.outcome_prediction is not None
30
+
31
+
19
32
  class Prediction(BaseModel):
20
33
  is_predictable: bool = True
21
34
  outcome_prediction: t.Optional[CategoricalProbabilisticAnswer] = None
@@ -31,6 +31,7 @@ from prediction_market_agent_tooling.markets.data_models import (
31
31
  ExistingPosition,
32
32
  PlacedTrade,
33
33
  ProbabilisticAnswer,
34
+ ScalarProbabilisticAnswer,
34
35
  Trade,
35
36
  )
36
37
  from prediction_market_agent_tooling.markets.markets import MarketType
@@ -219,6 +220,7 @@ class DeployablePredictionAgent(DeployableAgent):
219
220
  self.verify_market = observe()(self.verify_market) # type: ignore[method-assign]
220
221
  self.answer_binary_market = observe()(self.answer_binary_market) # type: ignore[method-assign]
221
222
  self.answer_categorical_market = observe()(self.answer_categorical_market) # type: ignore[method-assign]
223
+ self.answer_scalar_market = observe()(self.answer_scalar_market) # type: ignore[method-assign]
222
224
  self.process_market = observe()(self.process_market) # type: ignore[method-assign]
223
225
 
224
226
  def update_langfuse_trace_by_market(
@@ -299,6 +301,11 @@ class DeployablePredictionAgent(DeployableAgent):
299
301
  ) -> CategoricalProbabilisticAnswer | None:
300
302
  raise NotImplementedError("This method must be implemented by the subclass")
301
303
 
304
+ def answer_scalar_market(
305
+ self, market: AgentMarket
306
+ ) -> ScalarProbabilisticAnswer | None:
307
+ raise NotImplementedError("This method must be implemented by the subclass")
308
+
302
309
  def answer_binary_market(self, market: AgentMarket) -> ProbabilisticAnswer | None:
303
310
  """
304
311
  Answer the binary market.
@@ -321,6 +328,13 @@ class DeployablePredictionAgent(DeployableAgent):
321
328
  return True
322
329
  return False
323
330
 
331
+ @property
332
+ def fetch_scalar_markets(self) -> bool:
333
+ # Check if the subclass has implemented the answer_scalar_market method, if yes, fetch scalar markets as well.
334
+ if self.answer_scalar_market.__wrapped__.__func__ is not DeployablePredictionAgent.answer_scalar_market: # type: ignore[attr-defined] # This works just fine, but mypy doesn't know about it for some reason.
335
+ return True
336
+ return False
337
+
324
338
  def get_markets(
325
339
  self,
326
340
  market_type: MarketType,
@@ -336,6 +350,7 @@ class DeployablePredictionAgent(DeployableAgent):
336
350
  filter_by=self.get_markets_filter_by,
337
351
  created_after=self.trade_on_markets_created_after,
338
352
  fetch_categorical_markets=self.fetch_categorical_markets,
353
+ fetch_scalar_markets=self.fetch_scalar_markets,
339
354
  )
340
355
  return available_markets
341
356
 
@@ -383,7 +398,16 @@ class DeployablePredictionAgent(DeployableAgent):
383
398
  logger.info(
384
399
  "answer_binary_market() not implemented, falling back to answer_categorical_market()"
385
400
  )
386
-
401
+ elif market.is_scalar:
402
+ scalar_answer = self.answer_scalar_market(market)
403
+ return (
404
+ CategoricalProbabilisticAnswer.from_scalar_answer(
405
+ scalar_answer,
406
+ market.outcomes,
407
+ )
408
+ if scalar_answer is not None
409
+ else None
410
+ )
387
411
  return self.answer_categorical_market(market)
388
412
 
389
413
  def verify_answer_outcomes(
@@ -40,6 +40,9 @@ class GuaranteedLossError(RuntimeError):
40
40
 
41
41
 
42
42
  class BettingStrategy(ABC):
43
+ def __init__(self, take_profit: bool = True) -> None:
44
+ self.take_profit = take_profit
45
+
43
46
  @abstractmethod
44
47
  def calculate_trades(
45
48
  self,
@@ -209,10 +212,22 @@ class BettingStrategy(ABC):
209
212
  )
210
213
 
211
214
  diff_amount = target_amount - existing_amount
215
+
212
216
  if diff_amount == 0:
213
217
  continue
214
218
 
215
219
  trade_type = TradeType.SELL if diff_amount < 0 else TradeType.BUY
220
+
221
+ # We work with positions, so imagine following scenario: Agent invested $10 when probs were 50:50,
222
+ # now the probs are 99:1 and his initial $10 is worth $100.
223
+ # If `take_profit` is set to False, agent won't sell the $90 to get back to the $10 position.
224
+ if (
225
+ not self.take_profit
226
+ and target_amount > 0
227
+ and trade_type == TradeType.SELL
228
+ ):
229
+ continue
230
+
216
231
  trade = Trade(
217
232
  amount=abs(diff_amount),
218
233
  outcome=outcome,
@@ -231,7 +246,8 @@ class BettingStrategy(ABC):
231
246
 
232
247
 
233
248
  class MultiCategoricalMaxAccuracyBettingStrategy(BettingStrategy):
234
- def __init__(self, max_position_amount: USD):
249
+ def __init__(self, max_position_amount: USD, take_profit: bool = True):
250
+ super().__init__(take_profit=take_profit)
235
251
  self.max_position_amount = max_position_amount
236
252
 
237
253
  @property
@@ -336,7 +352,13 @@ class MaxExpectedValueBettingStrategy(MultiCategoricalMaxAccuracyBettingStrategy
336
352
 
337
353
 
338
354
  class KellyBettingStrategy(BettingStrategy):
339
- def __init__(self, max_position_amount: USD, max_price_impact: float | None = None):
355
+ def __init__(
356
+ self,
357
+ max_position_amount: USD,
358
+ max_price_impact: float | None = None,
359
+ take_profit: bool = True,
360
+ ):
361
+ super().__init__(take_profit=take_profit)
340
362
  self.max_position_amount = max_position_amount
341
363
  self.max_price_impact = max_price_impact
342
364
 
@@ -492,7 +514,12 @@ class KellyBettingStrategy(BettingStrategy):
492
514
 
493
515
 
494
516
  class MaxAccuracyWithKellyScaledBetsStrategy(BettingStrategy):
495
- def __init__(self, max_position_amount: USD):
517
+ def __init__(
518
+ self,
519
+ max_position_amount: USD,
520
+ take_profit: bool = True,
521
+ ):
522
+ super().__init__(take_profit)
496
523
  self.max_position_amount = max_position_amount
497
524
 
498
525
  @property
@@ -5,3 +5,5 @@ INVALID_OUTCOME_LOWERCASE_IDENTIFIER = "invalid"
5
5
  # Market-agnostic outcome identifiers
6
6
  YES_OUTCOME_LOWERCASE_IDENTIFIER = "yes"
7
7
  NO_OUTCOME_LOWERCASE_IDENTIFIER = "no"
8
+ UP_OUTCOME_LOWERCASE_IDENTIFIER = "up"
9
+ DOWN_OUTCOME_LOWERCASE_IDENTIFIER = "down"
@@ -133,4 +133,6 @@ class OmenJobAgentMarket(OmenAgentMarket, JobAgentMarket):
133
133
  condition=market.condition,
134
134
  finalized_time=market.finalized_time,
135
135
  fees=market.fees,
136
+ upper_bound=market.upper_bound,
137
+ lower_bound=market.lower_bound,
136
138
  )
@@ -11,8 +11,10 @@ from web3 import Web3
11
11
  from prediction_market_agent_tooling.benchmark.utils import get_most_probable_outcome
12
12
  from prediction_market_agent_tooling.config import APIKeys
13
13
  from prediction_market_agent_tooling.deploy.constants import (
14
+ DOWN_OUTCOME_LOWERCASE_IDENTIFIER,
14
15
  INVALID_OUTCOME_LOWERCASE_IDENTIFIER,
15
16
  NO_OUTCOME_LOWERCASE_IDENTIFIER,
17
+ UP_OUTCOME_LOWERCASE_IDENTIFIER,
16
18
  YES_OUTCOME_LOWERCASE_IDENTIFIER,
17
19
  )
18
20
  from prediction_market_agent_tooling.gtypes import (
@@ -20,6 +22,7 @@ from prediction_market_agent_tooling.gtypes import (
20
22
  OutcomeToken,
21
23
  OutcomeWei,
22
24
  Probability,
25
+ Wei,
23
26
  )
24
27
  from prediction_market_agent_tooling.markets.data_models import (
25
28
  USD,
@@ -83,6 +86,9 @@ class AgentMarket(BaseModel):
83
86
  volume: CollateralToken | None
84
87
  fees: MarketFees
85
88
 
89
+ upper_bound: Wei | None = None
90
+ lower_bound: Wei | None = None
91
+
86
92
  @field_validator("probabilities")
87
93
  def validate_probabilities(
88
94
  cls,
@@ -165,6 +171,34 @@ class AgentMarket(BaseModel):
165
171
 
166
172
  return has_yes and has_no
167
173
 
174
+ @property
175
+ def is_scalar(self) -> bool:
176
+ # 3 outcomes can also be binary if 3rd outcome is invalid (Seer)
177
+ if len(self.outcomes) not in [2, 3]:
178
+ return False
179
+
180
+ lowercase_outcomes = [outcome.lower() for outcome in self.outcomes]
181
+
182
+ has_up = UP_OUTCOME_LOWERCASE_IDENTIFIER in lowercase_outcomes
183
+ has_down = DOWN_OUTCOME_LOWERCASE_IDENTIFIER in lowercase_outcomes
184
+
185
+ if len(lowercase_outcomes) == 3:
186
+ invalid_outcome = lowercase_outcomes[-1]
187
+ has_invalid = INVALID_OUTCOME_LOWERCASE_IDENTIFIER in invalid_outcome
188
+ return has_up and has_down and has_invalid
189
+
190
+ return has_up and has_down
191
+
192
+ @property
193
+ def p_up(self) -> Probability:
194
+ probs_lowercase = {o.lower(): p for o, p in self.probabilities.items()}
195
+ return check_not_none(probs_lowercase.get(UP_OUTCOME_LOWERCASE_IDENTIFIER))
196
+
197
+ @property
198
+ def p_down(self) -> Probability:
199
+ probs_lowercase = {o.lower(): p for o, p in self.probabilities.items()}
200
+ return check_not_none(probs_lowercase.get(DOWN_OUTCOME_LOWERCASE_IDENTIFIER))
201
+
168
202
  @property
169
203
  def p_yes(self) -> Probability:
170
204
  probs_lowercase = {o.lower(): p for o, p in self.probabilities.items()}
@@ -336,6 +370,7 @@ class AgentMarket(BaseModel):
336
370
  created_after: t.Optional[DatetimeUTC] = None,
337
371
  excluded_questions: set[str] | None = None,
338
372
  fetch_categorical_markets: bool = False,
373
+ fetch_scalar_markets: bool = False,
339
374
  ) -> t.Sequence["AgentMarket"]:
340
375
  raise NotImplementedError("Subclasses must implement this method")
341
376
 
@@ -4,7 +4,10 @@ from typing import Annotated, Sequence
4
4
  from pydantic import BaseModel, BeforeValidator, computed_field
5
5
 
6
6
  from prediction_market_agent_tooling.deploy.constants import (
7
+ DOWN_OUTCOME_LOWERCASE_IDENTIFIER,
8
+ INVALID_OUTCOME_LOWERCASE_IDENTIFIER,
7
9
  NO_OUTCOME_LOWERCASE_IDENTIFIER,
10
+ UP_OUTCOME_LOWERCASE_IDENTIFIER,
8
11
  YES_OUTCOME_LOWERCASE_IDENTIFIER,
9
12
  )
10
13
  from prediction_market_agent_tooling.gtypes import (
@@ -13,6 +16,7 @@ from prediction_market_agent_tooling.gtypes import (
13
16
  OutcomeStr,
14
17
  OutcomeToken,
15
18
  Probability,
19
+ Wei,
16
20
  )
17
21
  from prediction_market_agent_tooling.logprobs_parser import FieldLogprobs
18
22
  from prediction_market_agent_tooling.markets.omen.omen_constants import (
@@ -100,6 +104,31 @@ def to_boolean_outcome(value: str | bool) -> bool:
100
104
  Decision = Annotated[bool, BeforeValidator(to_boolean_outcome)]
101
105
 
102
106
 
107
+ class ScalarProbabilisticAnswer(BaseModel):
108
+ scalar_value: Wei
109
+ upperBound: Wei
110
+ lowerBound: Wei
111
+ confidence: float
112
+ reasoning: str | None = None
113
+ logprobs: list[FieldLogprobs] | None = None
114
+
115
+ @property
116
+ def p_up(self) -> Probability:
117
+ if self.scalar_value > self.upperBound:
118
+ return Probability(1)
119
+ elif self.scalar_value < self.lowerBound:
120
+ return Probability(0)
121
+ else:
122
+ return Probability(
123
+ (self.scalar_value - self.lowerBound)
124
+ / (self.upperBound - self.lowerBound)
125
+ )
126
+
127
+ @property
128
+ def p_down(self) -> Probability:
129
+ return Probability(1 - self.p_up)
130
+
131
+
103
132
  class ProbabilisticAnswer(BaseModel):
104
133
  p_yes: Probability
105
134
  confidence: float
@@ -165,6 +194,41 @@ class CategoricalProbabilisticAnswer(BaseModel):
165
194
  reasoning=answer.reasoning,
166
195
  )
167
196
 
197
+ @staticmethod
198
+ def from_scalar_answer(
199
+ answer: ScalarProbabilisticAnswer,
200
+ market_outcomes: Sequence[OutcomeStr],
201
+ ) -> "CategoricalProbabilisticAnswer":
202
+ probabilities = {}
203
+ lowercase_market_outcomes = [outcome.lower() for outcome in market_outcomes]
204
+
205
+ if not set(
206
+ [
207
+ DOWN_OUTCOME_LOWERCASE_IDENTIFIER,
208
+ UP_OUTCOME_LOWERCASE_IDENTIFIER,
209
+ ]
210
+ ).issubset(lowercase_market_outcomes):
211
+ raise ValueError("Market with no outcomes")
212
+
213
+ probabilities[OutcomeStr(UP_OUTCOME_LOWERCASE_IDENTIFIER.upper())] = answer.p_up
214
+ probabilities[
215
+ OutcomeStr(DOWN_OUTCOME_LOWERCASE_IDENTIFIER.upper())
216
+ ] = answer.p_down
217
+
218
+ if (
219
+ market_outcomes
220
+ and INVALID_OUTCOME_LOWERCASE_IDENTIFIER in lowercase_market_outcomes
221
+ ):
222
+ probabilities[
223
+ OutcomeStr(INVALID_OUTCOME_LOWERCASE_IDENTIFIER.capitalize())
224
+ ] = Probability(1 - answer.p_up - answer.p_down)
225
+
226
+ return CategoricalProbabilisticAnswer(
227
+ probabilities=probabilities,
228
+ confidence=answer.confidence,
229
+ reasoning=answer.reasoning,
230
+ )
231
+
168
232
  def probability_for_market_outcome(self, market_outcome: OutcomeStr) -> Probability:
169
233
  for k, v in self.probabilities.items():
170
234
  if k.lower() == market_outcome.lower():
@@ -111,6 +111,7 @@ class ManifoldAgentMarket(AgentMarket):
111
111
  created_after: t.Optional[DatetimeUTC] = None,
112
112
  excluded_questions: set[str] | None = None,
113
113
  fetch_categorical_markets: bool = False,
114
+ fetch_scalar_markets: bool = False,
114
115
  ) -> t.Sequence["ManifoldAgentMarket"]:
115
116
  sort: t.Literal["newest", "close-date"] | None
116
117
  if sort_by == SortBy.CLOSING_SOONEST:
@@ -68,6 +68,7 @@ def get_binary_markets(
68
68
  sort_by: SortBy = SortBy.NONE,
69
69
  excluded_questions: set[str] | None = None,
70
70
  created_after: DatetimeUTC | None = None,
71
+ fetch_scalar_markets: bool = False,
71
72
  ) -> t.Sequence[AgentMarket]:
72
73
  agent_market_class = MARKET_TYPE_TO_AGENT_MARKET[market_type]
73
74
  markets = agent_market_class.get_markets(
@@ -76,5 +77,6 @@ def get_binary_markets(
76
77
  filter_by=filter_by,
77
78
  created_after=created_after,
78
79
  excluded_questions=excluded_questions,
80
+ fetch_scalar_markets=fetch_scalar_markets,
79
81
  )
80
82
  return markets
@@ -73,6 +73,7 @@ class MetaculusAgentMarket(AgentMarket):
73
73
  created_after: t.Optional[DatetimeUTC] = None,
74
74
  excluded_questions: set[str] | None = None,
75
75
  tournament_id: int | None = None,
76
+ fetch_scalar_markets: bool = False,
76
77
  ) -> t.Sequence["MetaculusAgentMarket"]:
77
78
  order_by: str | None
78
79
  if sort_by == SortBy.NONE:
@@ -380,6 +380,7 @@ class OmenAgentMarket(AgentMarket):
380
380
  created_after: t.Optional[DatetimeUTC] = None,
381
381
  excluded_questions: set[str] | None = None,
382
382
  fetch_categorical_markets: bool = False,
383
+ fetch_scalar_markets: bool = False,
383
384
  ) -> t.Sequence["OmenAgentMarket"]:
384
385
  return [
385
386
  OmenAgentMarket.from_data_model(m)
@@ -53,7 +53,7 @@ from prediction_market_agent_tooling.tools.web3_utils import (
53
53
  unwrap_generic_value,
54
54
  )
55
55
 
56
- SAFE_COLLATERAL_TOKENS = (
56
+ SAFE_COLLATERAL_TOKENS = [
57
57
  WrappedxDaiContract(),
58
58
  sDaiContract(),
59
59
  GNOContract(),
@@ -62,10 +62,10 @@ SAFE_COLLATERAL_TOKENS = (
62
62
  SAFEContract(),
63
63
  COWContract(),
64
64
  MetriSuperGroup(),
65
- )
66
- SAFE_COLLATERAL_TOKENS_ADDRESSES = tuple(
65
+ ]
66
+ SAFE_COLLATERAL_TOKENS_ADDRESSES = [
67
67
  contract.address for contract in SAFE_COLLATERAL_TOKENS
68
- )
68
+ ]
69
69
 
70
70
 
71
71
  class OmenSubgraphHandler(BaseSubgraphHandler):
@@ -237,7 +237,7 @@ class OmenSubgraphHandler(BaseSubgraphHandler):
237
237
  liquidity_bigger_than: Wei | None,
238
238
  condition_id_in: list[HexBytes] | None,
239
239
  id_in: list[str] | None,
240
- collateral_token_address_in: tuple[ChecksumAddress, ...] | None,
240
+ collateral_token_address_in: t.Sequence[ChecksumAddress] | None,
241
241
  category: str | None,
242
242
  include_categorical_markets: bool = False,
243
243
  include_scalar_markets: bool = False,
@@ -348,7 +348,7 @@ class OmenSubgraphHandler(BaseSubgraphHandler):
348
348
  created_after: DatetimeUTC | None = None,
349
349
  excluded_questions: set[str] | None = None, # question titles
350
350
  collateral_token_address_in: (
351
- tuple[ChecksumAddress, ...] | None
351
+ t.Sequence[ChecksumAddress] | None
352
352
  ) = SAFE_COLLATERAL_TOKENS_ADDRESSES,
353
353
  category: str | None = None,
354
354
  creator_in: t.Sequence[HexAddress] | None = None,
@@ -416,7 +416,7 @@ class OmenSubgraphHandler(BaseSubgraphHandler):
416
416
  sort_by_field: FieldPath | None = None,
417
417
  sort_direction: str | None = None,
418
418
  collateral_token_address_in: (
419
- tuple[ChecksumAddress, ...] | None
419
+ t.Sequence[ChecksumAddress] | None
420
420
  ) = SAFE_COLLATERAL_TOKENS_ADDRESSES,
421
421
  category: str | None = None,
422
422
  include_categorical_markets: bool = True,
@@ -62,6 +62,7 @@ class PolymarketAgentMarket(AgentMarket):
62
62
  created_after: t.Optional[DatetimeUTC] = None,
63
63
  excluded_questions: set[str] | None = None,
64
64
  fetch_categorical_markets: bool = False,
65
+ fetch_scalar_markets: bool = False,
65
66
  ) -> t.Sequence["PolymarketAgentMarket"]:
66
67
  if sort_by != SortBy.NONE:
67
68
  raise ValueError(f"Unsuported sort_by {sort_by} for Polymarket.")
@@ -1,8 +1,9 @@
1
1
  import typing as t
2
2
  from datetime import timedelta
3
+ from typing import Annotated
3
4
  from urllib.parse import urljoin
4
5
 
5
- from pydantic import BaseModel, ConfigDict, Field
6
+ from pydantic import BaseModel, BeforeValidator, ConfigDict, Field
6
7
  from web3 import Web3
7
8
  from web3.constants import ADDRESS_ZERO
8
9
 
@@ -50,6 +51,17 @@ class CreateCategoricalMarketsParams(BaseModel):
50
51
  SEER_BASE_URL = "https://app.seer.pm"
51
52
 
52
53
 
54
+ def seer_normalize_wei(value: int | None) -> int | None:
55
+ # See https://github.com/seer-pm/demo/blob/main/web/netlify/edge-functions/utils/common.ts#L22
56
+ if value is None:
57
+ return value
58
+ is_in_wei = value > 1e10
59
+ return value if is_in_wei else value * 10**18
60
+
61
+
62
+ SeerNormalizedWei = Annotated[Wei | None, BeforeValidator(seer_normalize_wei)]
63
+
64
+
53
65
  class SeerMarket(BaseModel):
54
66
  model_config = ConfigDict(populate_by_name=True)
55
67
 
@@ -70,6 +82,8 @@ class SeerMarket(BaseModel):
70
82
  payout_reported: bool = Field(alias="payoutReported")
71
83
  payout_numerators: list[int] = Field(alias="payoutNumerators")
72
84
  outcomes_supply: int = Field(alias="outcomesSupply")
85
+ upper_bound: SeerNormalizedWei = Field(alias="upperBound", default=None)
86
+ lower_bound: SeerNormalizedWei = Field(alias="lowerBound", default=None)
73
87
 
74
88
  @property
75
89
  def has_valid_answer(self) -> bool:
@@ -32,6 +32,9 @@ from prediction_market_agent_tooling.markets.blockchain_utils import store_trade
32
32
  from prediction_market_agent_tooling.markets.data_models import ExistingPosition
33
33
  from prediction_market_agent_tooling.markets.market_fees import MarketFees
34
34
  from prediction_market_agent_tooling.markets.omen.omen import OmenAgentMarket
35
+ from prediction_market_agent_tooling.markets.omen.omen_constants import (
36
+ SDAI_CONTRACT_ADDRESS,
37
+ )
35
38
  from prediction_market_agent_tooling.markets.omen.omen_contracts import (
36
39
  SeerAgentResultMappingContract,
37
40
  )
@@ -62,6 +65,7 @@ from prediction_market_agent_tooling.tools.contract import (
62
65
  to_gnosis_chain_contract,
63
66
  )
64
67
  from prediction_market_agent_tooling.tools.cow.cow_order import (
68
+ NoLiquidityAvailableOnCowException,
65
69
  get_buy_token_amount_else_raise,
66
70
  get_orders_by_owner,
67
71
  get_trades_by_owner,
@@ -128,10 +132,41 @@ class SeerAgentMarket(AgentMarket):
128
132
  )
129
133
 
130
134
  def get_token_in_usd(self, x: CollateralToken) -> USD:
131
- return get_token_in_usd(x, self.collateral_token_contract_address_checksummed)
135
+ try:
136
+ return get_token_in_usd(
137
+ x, self.collateral_token_contract_address_checksummed
138
+ )
139
+ except NoLiquidityAvailableOnCowException as e:
140
+ logger.warning(
141
+ f"Could not get quote for {self.collateral_token_contract_address_checksummed} from Cow, exception {e=}. Falling back to pools. "
142
+ )
143
+ token_price = self.get_colateral_price_from_pools()
144
+ if token_price is None:
145
+ raise RuntimeError(
146
+ "Both CoW and pool-fallback way of getting price failed."
147
+ ) from e
148
+ return USD(x.value * token_price.value)
149
+
150
+ def get_colateral_price_from_pools(self) -> CollateralToken | None:
151
+ p = PriceManager.build(HexBytes(HexStr(self.id)))
152
+ token_price = p.get_token_price_from_pools(token=SDAI_CONTRACT_ADDRESS)
153
+ return token_price
132
154
 
133
155
  def get_usd_in_token(self, x: USD) -> CollateralToken:
134
- return get_usd_in_token(x, self.collateral_token_contract_address_checksummed)
156
+ try:
157
+ return get_usd_in_token(
158
+ x, self.collateral_token_contract_address_checksummed
159
+ )
160
+ except NoLiquidityAvailableOnCowException as e:
161
+ logger.warning(
162
+ f"Could not get quote for {self.collateral_token_contract_address_checksummed} from Cow, exception {e=}. Falling back to pools. "
163
+ )
164
+ token_price = self.get_colateral_price_from_pools()
165
+ if not token_price:
166
+ raise RuntimeError(
167
+ "Both CoW and pool-fallback way of getting price failed."
168
+ ) from e
169
+ return CollateralToken(x.value / token_price.value)
135
170
 
136
171
  def get_buy_token_amount(
137
172
  self, bet_amount: USD | CollateralToken, outcome_str: OutcomeStr
@@ -165,14 +200,26 @@ class SeerAgentMarket(AgentMarket):
165
200
  return CollateralToken.zero()
166
201
 
167
202
  wrapped_outcome_token = self.get_wrapped_token_for_outcome(outcome)
168
-
169
- # We calculate how much collateral we would get back if we sold `amount` of outcome token.
170
- value_outcome_token_in_collateral = get_buy_token_amount_else_raise(
171
- sell_amount=amount.as_outcome_wei.as_wei,
172
- sell_token=wrapped_outcome_token,
173
- buy_token=self.collateral_token_contract_address_checksummed,
174
- )
175
- return value_outcome_token_in_collateral.as_token
203
+ try:
204
+ # We calculate how much collateral we would get back if we sold `amount` of outcome token.
205
+ value_outcome_token_in_collateral = get_buy_token_amount_else_raise(
206
+ sell_amount=amount.as_outcome_wei.as_wei,
207
+ sell_token=wrapped_outcome_token,
208
+ buy_token=self.collateral_token_contract_address_checksummed,
209
+ )
210
+ return value_outcome_token_in_collateral.as_token
211
+ except NoLiquidityAvailableOnCowException as e:
212
+ logger.warning(
213
+ f"No liquidity available on Cow for {wrapped_outcome_token} -> {self.collateral_token_contract_address_checksummed}."
214
+ )
215
+ p = PriceManager.build(market_id=HexBytes(HexStr(self.id)))
216
+ price = p.get_token_price_from_pools(token=wrapped_outcome_token)
217
+ if not price:
218
+ logger.info(
219
+ f"Could not get price for token from pools for {wrapped_outcome_token}"
220
+ )
221
+ raise e
222
+ return CollateralToken(price.value * amount.value)
176
223
 
177
224
  @staticmethod
178
225
  def get_trade_balance(api_keys: APIKeys) -> USD:
@@ -346,6 +393,8 @@ class SeerAgentMarket(AgentMarket):
346
393
  resolution=None,
347
394
  volume=None,
348
395
  probabilities=probability_map,
396
+ upper_bound=model.upper_bound,
397
+ lower_bound=model.lower_bound,
349
398
  )
350
399
 
351
400
  return market
@@ -358,6 +407,7 @@ class SeerAgentMarket(AgentMarket):
358
407
  created_after: t.Optional[DatetimeUTC] = None,
359
408
  excluded_questions: set[str] | None = None,
360
409
  fetch_categorical_markets: bool = False,
410
+ fetch_scalar_markets: bool = False,
361
411
  ) -> t.Sequence["SeerAgentMarket"]:
362
412
  seer_subgraph = SeerSubgraphHandler()
363
413
  markets = seer_subgraph.get_markets(
@@ -365,6 +415,8 @@ class SeerAgentMarket(AgentMarket):
365
415
  sort_by=sort_by,
366
416
  filter_by=filter_by,
367
417
  include_categorical_markets=fetch_categorical_markets,
418
+ include_only_scalar_markets=fetch_scalar_markets,
419
+ include_conditional_markets=False,
368
420
  )
369
421
 
370
422
  # We exclude the None values below because `from_data_model_with_subgraph` can return None, which
@@ -496,7 +548,11 @@ class SeerAgentMarket(AgentMarket):
496
548
  )
497
549
  return order_metadata.uid.root
498
550
 
499
- except (UnexpectedResponseError, TimeoutError) as e:
551
+ except (
552
+ UnexpectedResponseError,
553
+ TimeoutError,
554
+ NoLiquidityAvailableOnCowException,
555
+ ) as e:
500
556
  # We don't retry if not enough balance.
501
557
  if "InsufficientBalance" in str(e):
502
558
  raise e
@@ -506,6 +562,10 @@ class SeerAgentMarket(AgentMarket):
506
562
  f"Exception occured when swapping tokens via Cowswap, doing swap via pools. {e}"
507
563
  )
508
564
 
565
+ if not self.has_liquidity():
566
+ logger.error(f"Market {self.id} has no liquidity. Cannot place bet.")
567
+ raise e
568
+
509
569
  tx_receipt = SwapPoolHandler(
510
570
  api_keys=api_keys,
511
571
  market_id=self.id,