prediction-market-agent-tooling 0.49.0__tar.gz → 0.49.1__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 (94) hide show
  1. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/PKG-INFO +2 -1
  2. prediction_market_agent_tooling-0.49.1/prediction_market_agent_tooling/abis/debuggingcontract.abi.json +29 -0
  3. prediction_market_agent_tooling-0.49.1/prediction_market_agent_tooling/abis/omen_agentresultmapping.abi.json +171 -0
  4. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/benchmark/benchmark.py +0 -93
  5. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/config.py +16 -0
  6. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/deploy/agent.py +61 -6
  7. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/agent_market.py +3 -3
  8. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/data_models.py +1 -1
  9. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/metaculus/metaculus.py +1 -1
  10. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/omen/data_models.py +240 -5
  11. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/omen/omen.py +43 -25
  12. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/omen/omen_contracts.py +179 -33
  13. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +35 -0
  14. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/monitor/monitor.py +3 -3
  15. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/monitor/monitor_app.py +2 -2
  16. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/contract.py +50 -1
  17. prediction_market_agent_tooling-0.49.1/prediction_market_agent_tooling/tools/ipfs/ipfs_handler.py +33 -0
  18. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/langfuse_client_utils.py +23 -8
  19. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/utils.py +28 -4
  20. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/web3_utils.py +7 -0
  21. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/pyproject.toml +2 -1
  22. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/LICENSE +0 -0
  23. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/README.md +0 -0
  24. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/abis/depositablewrapper_erc20.abi.json +0 -0
  25. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/abis/erc20.abi.json +0 -0
  26. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/abis/erc4626.abi.json +0 -0
  27. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/abis/omen_dxdao.abi.json +0 -0
  28. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/abis/omen_fpmm.abi.json +0 -0
  29. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/abis/omen_fpmm_conditionaltokens.abi.json +0 -0
  30. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/abis/omen_fpmm_factory.abi.json +0 -0
  31. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/abis/omen_kleros.abi.json +0 -0
  32. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/abis/omen_oracle.abi.json +0 -0
  33. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/abis/omen_realitio.abi.json +0 -0
  34. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/abis/omen_thumbnailmapping.abi.json +0 -0
  35. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/abis/proxy.abi.json +0 -0
  36. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/benchmark/__init__.py +0 -0
  37. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/benchmark/agents.py +0 -0
  38. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/benchmark/utils.py +0 -0
  39. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/deploy/agent_example.py +0 -0
  40. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/deploy/betting_strategy.py +0 -0
  41. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/deploy/constants.py +0 -0
  42. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/deploy/gcp/deploy.py +0 -0
  43. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py +0 -0
  44. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/deploy/gcp/utils.py +0 -0
  45. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/gtypes.py +0 -0
  46. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/jobs/__init__.py +0 -0
  47. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/jobs/jobs.py +0 -0
  48. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/jobs/jobs_models.py +0 -0
  49. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/jobs/omen/omen_jobs.py +0 -0
  50. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/loggers.py +0 -0
  51. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/categorize.py +0 -0
  52. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/manifold/__init__.py +0 -0
  53. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/manifold/api.py +0 -0
  54. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/manifold/data_models.py +0 -0
  55. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/manifold/manifold.py +0 -0
  56. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/manifold/utils.py +0 -0
  57. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/markets.py +0 -0
  58. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/metaculus/api.py +0 -0
  59. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/metaculus/data_models.py +0 -0
  60. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/omen/__init__.py +0 -0
  61. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/omen/omen_resolving.py +0 -0
  62. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/polymarket/api.py +0 -0
  63. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/polymarket/data_models.py +0 -0
  64. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/polymarket/data_models_web.py +0 -0
  65. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/polymarket/polymarket.py +0 -0
  66. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/markets/polymarket/utils.py +0 -0
  67. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/monitor/markets/manifold.py +0 -0
  68. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/monitor/markets/metaculus.py +0 -0
  69. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/monitor/markets/omen.py +0 -0
  70. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/monitor/markets/polymarket.py +0 -0
  71. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/monitor/monitor_settings.py +0 -0
  72. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/py.typed +0 -0
  73. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/balances.py +0 -0
  74. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/betting_strategies/kelly_criterion.py +0 -0
  75. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/betting_strategies/market_moving.py +0 -0
  76. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/betting_strategies/minimum_bet_to_win.py +0 -0
  77. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/betting_strategies/stretch_bet_between.py +0 -0
  78. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/betting_strategies/utils.py +0 -0
  79. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/cache.py +0 -0
  80. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/costs.py +0 -0
  81. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/gnosis_rpc.py +0 -0
  82. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/google.py +0 -0
  83. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/hexbytes_custom.py +0 -0
  84. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/image_gen/image_gen.py +0 -0
  85. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/image_gen/market_thumbnail_gen.py +0 -0
  86. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/is_predictable.py +0 -0
  87. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/langfuse_.py +0 -0
  88. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/omen/reality_accuracy.py +0 -0
  89. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/parallelism.py +0 -0
  90. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/safe.py +0 -0
  91. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/singleton.py +0 -0
  92. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/streamlit_user_login.py +0 -0
  93. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/tavily_storage/tavily_models.py +0 -0
  94. {prediction_market_agent_tooling-0.49.0 → prediction_market_agent_tooling-0.49.1}/prediction_market_agent_tooling/tools/tavily_storage/tavily_storage.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: prediction-market-agent-tooling
3
- Version: 0.49.0
3
+ Version: 0.49.1
4
4
  Summary: Tools to benchmark, deploy and monitor prediction market agents.
5
5
  Author: Gnosis
6
6
  Requires-Python: >=3.10,<3.12
@@ -29,6 +29,7 @@ Requires-Dist: loguru (>=0.7.2,<0.8.0)
29
29
  Requires-Dist: loky (>=3.4.1,<4.0.0)
30
30
  Requires-Dist: numpy (>=1.26.4,<2.0.0)
31
31
  Requires-Dist: openai (>=1.0.0,<2.0.0) ; extra == "openai"
32
+ Requires-Dist: pinatapy-vourhey (>=0.2.0,<0.3.0)
32
33
  Requires-Dist: prompt-toolkit (>=3.0.43,<4.0.0)
33
34
  Requires-Dist: psycopg2-binary (>=2.9.9,<3.0.0)
34
35
  Requires-Dist: pydantic (>=2.6.1,<3.0.0)
@@ -0,0 +1,29 @@
1
+ [
2
+ {
3
+ "constant": false,
4
+ "inputs": [],
5
+ "name": "inc",
6
+ "outputs": [],
7
+ "payable": false,
8
+ "stateMutability": "nonpayable",
9
+ "type": "function"
10
+ },
11
+ {
12
+ "constant": true,
13
+ "inputs": [],
14
+ "name": "counter",
15
+ "outputs": [{ "name": "", "type": "uint256" }],
16
+ "payable": false,
17
+ "stateMutability": "view",
18
+ "type": "function"
19
+ },
20
+ {
21
+ "constant": true,
22
+ "inputs": [],
23
+ "name": "getNow",
24
+ "outputs": [{ "name": "", "type": "uint32" }],
25
+ "payable": false,
26
+ "stateMutability": "view",
27
+ "type": "function"
28
+ }
29
+ ]
@@ -0,0 +1,171 @@
1
+ [
2
+ {
3
+ "type": "constructor",
4
+ "inputs": [],
5
+ "stateMutability": "nonpayable"
6
+ },
7
+ {
8
+ "type": "function",
9
+ "name": "addPrediction",
10
+ "inputs": [
11
+ {
12
+ "name": "marketAddress",
13
+ "type": "address",
14
+ "internalType": "address"
15
+ },
16
+ {
17
+ "name": "prediction",
18
+ "type": "tuple",
19
+ "internalType": "struct Prediction",
20
+ "components": [
21
+ {
22
+ "name": "publisherAddress",
23
+ "type": "address",
24
+ "internalType": "address"
25
+ },
26
+ {
27
+ "name": "ipfsHash",
28
+ "type": "bytes32",
29
+ "internalType": "bytes32"
30
+ },
31
+ {
32
+ "name": "txHashes",
33
+ "type": "bytes32[]",
34
+ "internalType": "bytes32[]"
35
+ },
36
+ {
37
+ "name": "estimatedProbabilityBps",
38
+ "type": "uint16",
39
+ "internalType": "uint16"
40
+ }
41
+ ]
42
+ }
43
+ ],
44
+ "outputs": [],
45
+ "stateMutability": "nonpayable"
46
+ },
47
+ {
48
+ "type": "function",
49
+ "name": "getPredictionByIndex",
50
+ "inputs": [
51
+ {
52
+ "name": "marketAddress",
53
+ "type": "address",
54
+ "internalType": "address"
55
+ },
56
+ {
57
+ "name": "index",
58
+ "type": "uint256",
59
+ "internalType": "uint256"
60
+ }
61
+ ],
62
+ "outputs": [
63
+ {
64
+ "name": "",
65
+ "type": "tuple",
66
+ "internalType": "struct Prediction",
67
+ "components": [
68
+ {
69
+ "name": "publisherAddress",
70
+ "type": "address",
71
+ "internalType": "address"
72
+ },
73
+ {
74
+ "name": "ipfsHash",
75
+ "type": "bytes32",
76
+ "internalType": "bytes32"
77
+ },
78
+ {
79
+ "name": "txHashes",
80
+ "type": "bytes32[]",
81
+ "internalType": "bytes32[]"
82
+ },
83
+ {
84
+ "name": "estimatedProbabilityBps",
85
+ "type": "uint16",
86
+ "internalType": "uint16"
87
+ }
88
+ ]
89
+ }
90
+ ],
91
+ "stateMutability": "view"
92
+ },
93
+ {
94
+ "type": "function",
95
+ "name": "getPredictions",
96
+ "inputs": [
97
+ {
98
+ "name": "marketAddress",
99
+ "type": "address",
100
+ "internalType": "address"
101
+ }
102
+ ],
103
+ "outputs": [
104
+ {
105
+ "name": "",
106
+ "type": "tuple[]",
107
+ "internalType": "struct Prediction[]",
108
+ "components": [
109
+ {
110
+ "name": "publisherAddress",
111
+ "type": "address",
112
+ "internalType": "address"
113
+ },
114
+ {
115
+ "name": "ipfsHash",
116
+ "type": "bytes32",
117
+ "internalType": "bytes32"
118
+ },
119
+ {
120
+ "name": "txHashes",
121
+ "type": "bytes32[]",
122
+ "internalType": "bytes32[]"
123
+ },
124
+ {
125
+ "name": "estimatedProbabilityBps",
126
+ "type": "uint16",
127
+ "internalType": "uint16"
128
+ }
129
+ ]
130
+ }
131
+ ],
132
+ "stateMutability": "view"
133
+ },
134
+ {
135
+ "type": "event",
136
+ "name": "PredictionAdded",
137
+ "inputs": [
138
+ {
139
+ "name": "marketAddress",
140
+ "type": "address",
141
+ "indexed": true,
142
+ "internalType": "address"
143
+ },
144
+ {
145
+ "name": "estimatedProbabilityBps",
146
+ "type": "uint16",
147
+ "indexed": false,
148
+ "internalType": "uint16"
149
+ },
150
+ {
151
+ "name": "publisherAddress",
152
+ "type": "address",
153
+ "indexed": true,
154
+ "internalType": "address"
155
+ },
156
+ {
157
+ "name": "txHashes",
158
+ "type": "bytes32[]",
159
+ "indexed": false,
160
+ "internalType": "bytes32[]"
161
+ },
162
+ {
163
+ "name": "ipfsHash",
164
+ "type": "bytes32",
165
+ "indexed": false,
166
+ "internalType": "bytes32"
167
+ }
168
+ ],
169
+ "anonymous": false
170
+ }
171
+ ]
@@ -1,7 +1,6 @@
1
1
  import concurrent.futures
2
2
  import os
3
3
  import typing as t
4
- from collections import defaultdict
5
4
 
6
5
  import numpy as np
7
6
  import pandas as pd
@@ -436,92 +435,6 @@ class Benchmarker:
436
435
  ],
437
436
  }
438
437
 
439
- def calculate_expected_returns(
440
- self, prediction: Prediction, market: AgentMarket
441
- ) -> float | None:
442
- """
443
- The expected value if betting on a binary market in its initialized state of 50:50 'yes' and 'no' shares, with the assumption that the correct `p_yes` is that of the market.
444
- """
445
- if not prediction.is_answered:
446
- return None
447
-
448
- # TODO: Add support for different bet sizes -- if we bet a low amount (such as <10 units), the real shares will be very close to that we calculate below (bet_units / share_price),
449
- # but if one bets a lot, it will change the share price along the way, and so he/she receives less than `bet_units / share_price`, but it's more complicated to calculate.
450
- bet_units = 10 # Assuming the agent always bet 10 units per market.
451
-
452
- assert prediction.outcome_prediction is not None
453
- # Assume that market starts at 50/50 and so the price is 0.5 at the time we are buying it,
454
- # we can't use {yes,no}_outcome_price atm, because it would just cancel out to EV = 0.0,
455
- # as it's the same as the probability.
456
- yes_shares = (
457
- bet_units / 0.5 # market.yes_outcome_price
458
- if prediction.outcome_prediction.probable_resolution == Resolution.YES
459
- and market.yes_outcome_price > 0
460
- else 0
461
- )
462
- no_shares = (
463
- bet_units / 0.5 # market.no_outcome_price
464
- if prediction.outcome_prediction.probable_resolution == Resolution.NO
465
- and market.no_outcome_price > 0
466
- else 0
467
- )
468
-
469
- # If we don't bet, we don't have any expected returns.
470
- if yes_shares == 0 and no_shares == 0:
471
- return None
472
-
473
- expected_value = (
474
- yes_shares * market.current_p_yes
475
- + no_shares * (1 - market.current_p_yes)
476
- - bet_units
477
- )
478
- expected_returns_perc = 100 * expected_value / bet_units
479
-
480
- return expected_returns_perc
481
-
482
- def compute_expected_returns_summary(
483
- self,
484
- ) -> t.Tuple[dict[str, list[str | float]], dict[str, list[str | float | None]]]:
485
- overall_summary: dict[str, list[str | float]] = defaultdict(list)
486
-
487
- for agent in self.registered_agents:
488
- expected_returns = []
489
-
490
- for market in self.markets:
491
- if (
492
- prediction := self.get_prediction(agent.agent_name, market.question)
493
- ).is_answered and (
494
- expected_return := self.calculate_expected_returns(
495
- prediction, market
496
- )
497
- ) is not None:
498
- expected_returns.append(expected_return)
499
-
500
- overall_summary["Agent"].append(agent.agent_name)
501
- overall_summary["Mean expected returns"].append(
502
- float(np.mean(expected_returns))
503
- )
504
- overall_summary["Median expected returns"].append(
505
- float(np.median(expected_returns))
506
- )
507
- overall_summary["Total expected returns"].append(
508
- float(np.sum(expected_returns))
509
- )
510
-
511
- per_market: dict[str, list[str | float | None]] = defaultdict(list)
512
-
513
- for market in self.markets:
514
- per_market["Market Question"].append(market.question)
515
-
516
- for agent in self.registered_agents:
517
- per_market[agent.agent_name].append(
518
- self.calculate_expected_returns(
519
- self.get_prediction(agent.agent_name, market.question), market
520
- )
521
- )
522
-
523
- return dict(overall_summary), dict(per_market)
524
-
525
438
  def generate_markdown_report(self) -> str:
526
439
  md = "# Comparison Report\n\n"
527
440
  md += "## Market Results\n\n"
@@ -533,10 +446,4 @@ class Benchmarker:
533
446
  md += "\n\n"
534
447
  md += "### Markets\n\n"
535
448
  md += pd.DataFrame(self.get_markets_summary()).to_markdown(index=False)
536
- md += "\n\n"
537
- md += "### Expected value\n\n"
538
- overall_summary, per_market = self.compute_expected_returns_summary()
539
- md += pd.DataFrame(overall_summary).to_markdown(index=False)
540
- md += "\n\n"
541
- md += pd.DataFrame(per_market).to_markdown(index=False)
542
449
  return md
@@ -35,6 +35,7 @@ class APIKeys(BaseSettings):
35
35
  SAFE_ADDRESS: t.Optional[ChecksumAddress] = None
36
36
  OPENAI_API_KEY: t.Optional[SecretStr] = None
37
37
  GRAPH_API_KEY: t.Optional[SecretStr] = None
38
+ TENDERLY_FORK_RPC: t.Optional[str] = None
38
39
 
39
40
  GOOGLE_SEARCH_API_KEY: t.Optional[SecretStr] = None
40
41
  GOOGLE_SEARCH_ENGINE_ID: t.Optional[SecretStr] = None
@@ -44,6 +45,9 @@ class APIKeys(BaseSettings):
44
45
  LANGFUSE_HOST: t.Optional[str] = None
45
46
  LANGFUSE_DEPLOYMENT_VERSION: t.Optional[str] = None
46
47
 
48
+ PINATA_API_KEY: t.Optional[SecretStr] = None
49
+ PINATA_API_SECRET: t.Optional[SecretStr] = None
50
+
47
51
  TAVILY_API_KEY: t.Optional[SecretStr] = None
48
52
 
49
53
  SQLALCHEMY_DB_URL: t.Optional[SecretStr] = None
@@ -147,6 +151,18 @@ class APIKeys(BaseSettings):
147
151
  and self.LANGFUSE_HOST is not None
148
152
  )
149
153
 
154
+ @property
155
+ def pinata_api_key(self) -> SecretStr:
156
+ return check_not_none(
157
+ self.PINATA_API_KEY, "PINATA_API_KEY missing in the environment."
158
+ )
159
+
160
+ @property
161
+ def pinata_api_secret(self) -> SecretStr:
162
+ return check_not_none(
163
+ self.PINATA_API_SECRET, "PINATA_API_SECRET missing in the environment."
164
+ )
165
+
150
166
  @property
151
167
  def tavily_api_key(self) -> SecretStr:
152
168
  return check_not_none(
@@ -10,6 +10,7 @@ from functools import cached_property
10
10
 
11
11
  from pydantic import BaseModel, BeforeValidator, computed_field
12
12
  from typing_extensions import Annotated
13
+ from web3 import Web3
13
14
 
14
15
  from prediction_market_agent_tooling.config import APIKeys
15
16
  from prediction_market_agent_tooling.deploy.betting_strategy import (
@@ -30,7 +31,7 @@ from prediction_market_agent_tooling.deploy.gcp.utils import (
30
31
  gcp_function_is_active,
31
32
  gcp_resolve_api_keys_secrets,
32
33
  )
33
- from prediction_market_agent_tooling.gtypes import xDai, xdai_type
34
+ from prediction_market_agent_tooling.gtypes import HexStr, xDai, xdai_type
34
35
  from prediction_market_agent_tooling.loggers import logger
35
36
  from prediction_market_agent_tooling.markets.agent_market import (
36
37
  AgentMarket,
@@ -47,17 +48,27 @@ from prediction_market_agent_tooling.markets.markets import (
47
48
  MarketType,
48
49
  have_bet_on_market_since,
49
50
  )
51
+ from prediction_market_agent_tooling.markets.omen.data_models import (
52
+ ContractPrediction,
53
+ IPFSAgentResult,
54
+ )
50
55
  from prediction_market_agent_tooling.markets.omen.omen import (
51
56
  is_minimum_required_balance,
52
57
  redeem_from_all_user_positions,
53
58
  withdraw_wxdai_to_xdai_to_keep_balance,
54
59
  )
60
+ from prediction_market_agent_tooling.markets.omen.omen_contracts import (
61
+ OmenAgentResultMappingContract,
62
+ )
55
63
  from prediction_market_agent_tooling.monitor.monitor_app import (
56
64
  MARKET_TYPE_TO_DEPLOYED_AGENT,
57
65
  )
66
+ from prediction_market_agent_tooling.tools.hexbytes_custom import HexBytes
67
+ from prediction_market_agent_tooling.tools.ipfs.ipfs_handler import IPFSHandler
58
68
  from prediction_market_agent_tooling.tools.is_predictable import is_predictable_binary
59
69
  from prediction_market_agent_tooling.tools.langfuse_ import langfuse_context, observe
60
70
  from prediction_market_agent_tooling.tools.utils import DatetimeWithTimezone, utcnow
71
+ from prediction_market_agent_tooling.tools.web3_utils import ipfscidv0_to_byte32
61
72
 
62
73
  MAX_AVAILABLE_MARKETS = 20
63
74
  TRADER_TAG = "trader"
@@ -291,6 +302,7 @@ class DeployableTraderAgent(DeployableAgent):
291
302
  ) -> None:
292
303
  super().__init__(enable_langfuse=enable_langfuse)
293
304
  self.place_bet = place_bet
305
+ self.ipfs_handler = IPFSHandler(APIKeys())
294
306
 
295
307
  def get_betting_strategy(self, market: AgentMarket) -> BettingStrategy:
296
308
  user_id = market.get_user_id(api_keys=APIKeys())
@@ -461,7 +473,7 @@ class DeployableTraderAgent(DeployableAgent):
461
473
  placed_trades = []
462
474
  if self.place_bet:
463
475
  for trade in trades:
464
- logger.info(f"Executing trade {trade}")
476
+ logger.info(f"Executing trade {trade} on market {market.id}")
465
477
 
466
478
  match trade.trade_type:
467
479
  case TradeType.BUY:
@@ -476,18 +488,61 @@ class DeployableTraderAgent(DeployableAgent):
476
488
  raise ValueError(f"Unexpected trade type {trade.trade_type}.")
477
489
  placed_trades.append(PlacedTrade.from_trade(trade, id))
478
490
 
479
- self.after_process_market(market_type, market)
480
-
481
491
  processed_market = ProcessedMarket(answer=answer, trades=placed_trades)
482
492
  self.update_langfuse_trace_by_processed_market(market_type, processed_market)
483
493
 
494
+ self.after_process_market(
495
+ market_type, market, processed_market=processed_market
496
+ )
497
+
484
498
  logger.info(f"Processed market {market.question=} from {market.url=}.")
485
499
  return processed_market
486
500
 
487
501
  def after_process_market(
488
- self, market_type: MarketType, market: AgentMarket
502
+ self,
503
+ market_type: MarketType,
504
+ market: AgentMarket,
505
+ processed_market: ProcessedMarket,
489
506
  ) -> None:
490
- pass
507
+ if market_type != MarketType.OMEN:
508
+ logger.info(
509
+ f"Skipping after_process_market since market_type {market_type} != OMEN"
510
+ )
511
+ return
512
+ keys = APIKeys()
513
+ self.store_prediction(
514
+ market_id=market.id, processed_market=processed_market, keys=keys
515
+ )
516
+
517
+ def store_prediction(
518
+ self, market_id: str, processed_market: ProcessedMarket, keys: APIKeys
519
+ ) -> None:
520
+ reasoning = (
521
+ processed_market.answer.reasoning
522
+ if processed_market.answer.reasoning
523
+ else ""
524
+ )
525
+ ipfs_hash = self.ipfs_handler.store_agent_result(
526
+ IPFSAgentResult(reasoning=reasoning)
527
+ )
528
+
529
+ tx_hashes = [
530
+ HexBytes(HexStr(i.id)) for i in processed_market.trades if i.id is not None
531
+ ]
532
+ prediction = ContractPrediction(
533
+ publisher=keys.public_key,
534
+ ipfs_hash=ipfscidv0_to_byte32(ipfs_hash),
535
+ tx_hashes=tx_hashes,
536
+ estimated_probability_bps=int(processed_market.answer.p_yes * 10000),
537
+ )
538
+ tx_receipt = OmenAgentResultMappingContract().add_prediction(
539
+ api_keys=keys,
540
+ market_address=Web3.to_checksum_address(market_id),
541
+ prediction=prediction,
542
+ )
543
+ logger.info(
544
+ f"Added prediction to market {market_id}. - receipt {tx_receipt['transactionHash'].hex()}."
545
+ )
491
546
 
492
547
  def before_process_markets(self, market_type: MarketType) -> None:
493
548
  """
@@ -18,8 +18,8 @@ from prediction_market_agent_tooling.markets.data_models import (
18
18
  TokenAmount,
19
19
  )
20
20
  from prediction_market_agent_tooling.tools.utils import (
21
- add_utc_timezone_validator,
22
21
  check_not_none,
22
+ convert_to_utc_datetime,
23
23
  should_not_happen,
24
24
  utcnow,
25
25
  )
@@ -61,10 +61,10 @@ class AgentMarket(BaseModel):
61
61
  volume: float | None # Should be in currency of `currency` above.
62
62
 
63
63
  _add_timezone_validator_created_time = field_validator("created_time")(
64
- add_utc_timezone_validator
64
+ convert_to_utc_datetime
65
65
  )
66
66
  _add_timezone_validator_close_time = field_validator("close_time")(
67
- add_utc_timezone_validator
67
+ convert_to_utc_datetime
68
68
  )
69
69
 
70
70
  @field_validator("outcome_token_pool")
@@ -130,7 +130,7 @@ class Trade(BaseModel):
130
130
 
131
131
 
132
132
  class PlacedTrade(Trade):
133
- id: str
133
+ id: str | None = None
134
134
 
135
135
  @staticmethod
136
136
  def from_trade(trade: Trade, id: str) -> "PlacedTrade":
@@ -100,7 +100,7 @@ class MetaculusAgentMarket(AgentMarket):
100
100
 
101
101
  if len(all_questions) >= limit:
102
102
  break
103
- return [MetaculusAgentMarket.from_data_model(q) for q in all_questions]
103
+ return [MetaculusAgentMarket.from_data_model(q) for q in all_questions[:limit]]
104
104
 
105
105
  def submit_prediction(self, p_yes: Probability, reasoning: str) -> None:
106
106
  make_prediction(self.id, p_yes)