prediction-market-agent-tooling 0.29.0__tar.gz → 0.32.0__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 (71) hide show
  1. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/PKG-INFO +47 -13
  2. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/README.md +46 -12
  3. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/deploy/agent.py +2 -2
  4. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/loggers.py +11 -2
  5. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/agent_market.py +5 -0
  6. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/manifold/manifold.py +5 -0
  7. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/omen/omen.py +5 -1
  8. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +14 -1
  9. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/tools/is_predictable.py +6 -1
  10. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/pyproject.toml +1 -1
  11. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/LICENSE +0 -0
  12. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/abis/erc20.abi.json +0 -0
  13. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/abis/omen_dxdao.abi.json +0 -0
  14. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/abis/omen_fpmm.abi.json +0 -0
  15. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/abis/omen_fpmm_conditionaltokens.abi.json +0 -0
  16. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/abis/omen_fpmm_factory.abi.json +0 -0
  17. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/abis/omen_kleros.abi.json +0 -0
  18. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/abis/omen_oracle.abi.json +0 -0
  19. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/abis/omen_realitio.abi.json +0 -0
  20. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/abis/wxdai.abi.json +0 -0
  21. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/benchmark/__init__.py +0 -0
  22. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/benchmark/agents.py +0 -0
  23. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/benchmark/benchmark.py +0 -0
  24. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/benchmark/utils.py +0 -0
  25. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/config.py +0 -0
  26. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/deploy/agent_example.py +0 -0
  27. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/deploy/constants.py +0 -0
  28. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/deploy/gcp/deploy.py +0 -0
  29. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py +0 -0
  30. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/deploy/gcp/utils.py +0 -0
  31. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/gtypes.py +0 -0
  32. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/categorize.py +0 -0
  33. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/data_models.py +0 -0
  34. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/manifold/__init__.py +0 -0
  35. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/manifold/api.py +0 -0
  36. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/manifold/data_models.py +0 -0
  37. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/manifold/utils.py +0 -0
  38. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/markets.py +0 -0
  39. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/omen/__init__.py +0 -0
  40. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/omen/data_models.py +0 -0
  41. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/omen/omen_contracts.py +0 -0
  42. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/omen/omen_resolving.py +0 -0
  43. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/polymarket/api.py +0 -0
  44. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/polymarket/data_models.py +0 -0
  45. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/polymarket/data_models_web.py +0 -0
  46. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/polymarket/polymarket.py +0 -0
  47. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/markets/polymarket/utils.py +0 -0
  48. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/monitor/langfuse/langfuse_wrapper.py +0 -0
  49. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/monitor/markets/manifold.py +0 -0
  50. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/monitor/markets/omen.py +0 -0
  51. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/monitor/markets/polymarket.py +0 -0
  52. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/monitor/monitor.py +0 -0
  53. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/monitor/monitor_app.py +0 -0
  54. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/monitor/monitor_settings.py +0 -0
  55. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/py.typed +0 -0
  56. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/tools/balances.py +0 -0
  57. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/tools/betting_strategies/kelly_criterion.py +0 -0
  58. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/tools/betting_strategies/market_moving.py +0 -0
  59. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/tools/betting_strategies/minimum_bet_to_win.py +0 -0
  60. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/tools/betting_strategies/stretch_bet_between.py +0 -0
  61. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/tools/cache.py +0 -0
  62. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/tools/contract.py +0 -0
  63. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/tools/costs.py +0 -0
  64. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/tools/gnosis_rpc.py +0 -0
  65. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/tools/google.py +0 -0
  66. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/tools/hexbytes_custom.py +0 -0
  67. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/tools/parallelism.py +0 -0
  68. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/tools/safe.py +0 -0
  69. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/tools/singleton.py +0 -0
  70. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/tools/utils.py +0 -0
  71. {prediction_market_agent_tooling-0.29.0 → prediction_market_agent_tooling-0.32.0}/prediction_market_agent_tooling/tools/web3_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: prediction-market-agent-tooling
3
- Version: 0.29.0
3
+ Version: 0.32.0
4
4
  Summary: Tools to benchmark, deploy and monitor prediction market agents.
5
5
  Author: Gnosis
6
6
  Requires-Python: >=3.10,<3.12
@@ -61,7 +61,6 @@ Deploying and monitoring agents using GCP requires that you set up the gcloud CL
61
61
 
62
62
  ```bash
63
63
  MANIFOLD_API_KEY=...
64
- BET_FROM_ADDRESS=...
65
64
  BET_FROM_PRIVATE_KEY=...
66
65
  OPENAI_API_KEY=...
67
66
  ```
@@ -76,46 +75,54 @@ For example:
76
75
 
77
76
  ```python
78
77
  import prediction_market_agent_tooling.benchmark.benchmark as bm
78
+ from prediction_market_agent_tooling.benchmark.agents import RandomAgent
79
79
  from prediction_market_agent_tooling.markets.markets import MarketType, get_binary_markets
80
80
 
81
81
  benchmarker = bm.Benchmarker(
82
82
  markets=get_binary_markets(limit=10, market_type=MarketType.MANIFOLD),
83
- agents=[...],
83
+ agents=[RandomAgent(agent_name="a_random_agent")],
84
84
  )
85
85
  benchmarker.run_agents()
86
86
  md = benchmarker.generate_markdown_report()
87
87
  ```
88
88
 
89
- This produces a markdown report comparing agents:
89
+ This produces a markdown report that you can use for comparing agents side-by-side, like:
90
90
 
91
91
  ![Benchmark results](assets/comparison-report.png)
92
92
 
93
93
  ## Deploying
94
94
 
95
- Create a deployable agent by subclassing the `DeployableAgent` base class, and implementing the
95
+ > **Deprecated**: We suggest using your own infrastructure to deploy, but you may still find this useful.
96
+
97
+ Create a deployable agent by subclassing the `DeployableTraderAgent` base class, and implementing the `answer_binary_market` method.
96
98
 
97
99
  For example, deploy an agent that randomly picks an outcome:
98
100
 
99
101
  ```python
100
102
  import random
101
- from prediction_market_agent_tooling.deploy.agent import DeployableAgent
103
+ from prediction_market_agent_tooling.deploy.agent import DeployableTraderAgent
102
104
  from prediction_market_agent_tooling.markets.agent_market import AgentMarket
103
105
 
104
- class DeployableCoinFlipAgent(DeployableAgent):
106
+ class DeployableCoinFlipAgent(DeployableTraderAgent):
105
107
  def answer_binary_market(self, market: AgentMarket) -> bool | None:
106
108
  return random.choice([True, False])
107
109
 
108
110
  DeployableCoinFlipAgent().deploy_gcp(...)
109
111
  ```
110
112
 
111
- For deploying a Safe manually for a given agent, run the script below:
113
+ ### Safe
114
+
115
+ Agents can control funds via a wallet primary key only, or optionally via a [Safe](https://safe.global/) as well. For deploying a Safe manually for a given agent, run the script below:
112
116
 
113
117
  ```commandline
114
118
  poetry run python scripts/create_safe_for_agent.py --from-private-key <YOUR_AGENT_PRIVATE_KEY> --salt-nonce 42
115
119
  ```
120
+
116
121
  This will output the newly created Safe in the terminal, and it can then be copied over to the deployment part (e.g. Terraform).
117
122
  Note that `salt_nonce` can be passed so that the created safe is deterministically created for each agent, so that, if the same `salt_nonce` is used, the script will not create a new Safe for the agent, instead it will output the previously existent Safe.
118
123
 
124
+ You can then specify this agent's Safe address with the `SAFE_ADDRESS` environment variable.
125
+
119
126
  ## Monitoring
120
127
 
121
128
  Monitor the performance of the agents deployed to GCP, as well as meta-metrics of the prediction market platforms they are deployed to.
@@ -132,15 +139,42 @@ Which launches in the browser:
132
139
 
133
140
  ## The Market Platforms
134
141
 
135
- The following markets platforms are supported:
142
+ The following prediction market platforms are supported:
143
+
144
+ | Platform | Benchmarking | Deployment | Monitoring |
145
+ |---------------------------------------|--------------|------------|------------|
146
+ | [Manifold](https://manifold.markets/) | ✅ | ✅ | ✅ |
147
+ | [AIOmen](https://aiomen.eth.limo/) | ✅ | ✅ | ✅ |
148
+ | [Polymarket](https://polymarket.com/) | ✅ | ❌ | ❌ |
149
+
150
+ ## Prediction Markets Python API
151
+
152
+ We have built clean abstractions for taking actions on the different prediction market platforms (retrieving markets, buying and selling tokens, etc.). This is currently undocumented, but for now, inspecting the [`AgentMarket`](https://github.com/gnosis/prediction-market-agent-tooling/blob/1e497fff9f2b53e4e3e1beb5dda08b4d49da881b/prediction_market_agent_tooling/markets/agent_market.py) class and its methods is your best bet.
153
+
154
+ For example:
155
+
156
+ ```python
157
+ from prediction_market_agent_tooling.config import APIKeys
158
+ from prediction_market_agent_tooling.markets.agent_market import SortBy
159
+ from prediction_market_agent_tooling.markets.omen.omen import OmenAgentMarket
160
+
161
+ # Place a bet on the market closing soonest
162
+ market = OmenAgentMarket.get_binary_markets(limit=1, sort_by=SortBy.CLOSING_SOONEST)[0]
163
+ market.place_bet(outcome=True, amount=market.get_bet_amount(0.1))
164
+
165
+ # View your positions
166
+ my_positions = OmenAgentMarket.get_positions(user_id=APIKeys().bet_from_address)
167
+ print(my_positions)
168
+
169
+ # Sell position (accounting for fees)
170
+ market.sell_tokens(outcome=True, amount=market.get_bet_amount(0.095))
171
+ ```
136
172
 
137
- - [Manifold](https://manifold.markets/)
138
- - [AIOmen](https://aiomen.eth.limo/)
139
- - [Polymarket](https://polymarket.com/) - Benchmarking only. Deploy and monitor TODO
173
+ This API can be built on top of to create your application. See [here](https://github.com/gnosis/prediction-market-agent/tree/main/prediction_market_agent/agents/microchain_agent) for an example.
140
174
 
141
175
  ## Contributing
142
176
 
143
- See the [Issues](https://github.com/gnosis/prediction-market-agent-tooling/issues) for ideas of things that need fixing or implementing. Or come up with your own :D.
177
+ See the [Issues](https://github.com/gnosis/prediction-market-agent-tooling/issues) for ideas of things that need fixing or implementing. The team is also receptive to new issues and PRs.
144
178
 
145
179
  We use `mypy` for static type checking, and `isort`, `black` and `autoflake` for linting. These all run as steps in CI.
146
180
 
@@ -18,7 +18,6 @@ Deploying and monitoring agents using GCP requires that you set up the gcloud CL
18
18
 
19
19
  ```bash
20
20
  MANIFOLD_API_KEY=...
21
- BET_FROM_ADDRESS=...
22
21
  BET_FROM_PRIVATE_KEY=...
23
22
  OPENAI_API_KEY=...
24
23
  ```
@@ -33,46 +32,54 @@ For example:
33
32
 
34
33
  ```python
35
34
  import prediction_market_agent_tooling.benchmark.benchmark as bm
35
+ from prediction_market_agent_tooling.benchmark.agents import RandomAgent
36
36
  from prediction_market_agent_tooling.markets.markets import MarketType, get_binary_markets
37
37
 
38
38
  benchmarker = bm.Benchmarker(
39
39
  markets=get_binary_markets(limit=10, market_type=MarketType.MANIFOLD),
40
- agents=[...],
40
+ agents=[RandomAgent(agent_name="a_random_agent")],
41
41
  )
42
42
  benchmarker.run_agents()
43
43
  md = benchmarker.generate_markdown_report()
44
44
  ```
45
45
 
46
- This produces a markdown report comparing agents:
46
+ This produces a markdown report that you can use for comparing agents side-by-side, like:
47
47
 
48
48
  ![Benchmark results](assets/comparison-report.png)
49
49
 
50
50
  ## Deploying
51
51
 
52
- Create a deployable agent by subclassing the `DeployableAgent` base class, and implementing the
52
+ > **Deprecated**: We suggest using your own infrastructure to deploy, but you may still find this useful.
53
+
54
+ Create a deployable agent by subclassing the `DeployableTraderAgent` base class, and implementing the `answer_binary_market` method.
53
55
 
54
56
  For example, deploy an agent that randomly picks an outcome:
55
57
 
56
58
  ```python
57
59
  import random
58
- from prediction_market_agent_tooling.deploy.agent import DeployableAgent
60
+ from prediction_market_agent_tooling.deploy.agent import DeployableTraderAgent
59
61
  from prediction_market_agent_tooling.markets.agent_market import AgentMarket
60
62
 
61
- class DeployableCoinFlipAgent(DeployableAgent):
63
+ class DeployableCoinFlipAgent(DeployableTraderAgent):
62
64
  def answer_binary_market(self, market: AgentMarket) -> bool | None:
63
65
  return random.choice([True, False])
64
66
 
65
67
  DeployableCoinFlipAgent().deploy_gcp(...)
66
68
  ```
67
69
 
68
- For deploying a Safe manually for a given agent, run the script below:
70
+ ### Safe
71
+
72
+ Agents can control funds via a wallet primary key only, or optionally via a [Safe](https://safe.global/) as well. For deploying a Safe manually for a given agent, run the script below:
69
73
 
70
74
  ```commandline
71
75
  poetry run python scripts/create_safe_for_agent.py --from-private-key <YOUR_AGENT_PRIVATE_KEY> --salt-nonce 42
72
76
  ```
77
+
73
78
  This will output the newly created Safe in the terminal, and it can then be copied over to the deployment part (e.g. Terraform).
74
79
  Note that `salt_nonce` can be passed so that the created safe is deterministically created for each agent, so that, if the same `salt_nonce` is used, the script will not create a new Safe for the agent, instead it will output the previously existent Safe.
75
80
 
81
+ You can then specify this agent's Safe address with the `SAFE_ADDRESS` environment variable.
82
+
76
83
  ## Monitoring
77
84
 
78
85
  Monitor the performance of the agents deployed to GCP, as well as meta-metrics of the prediction market platforms they are deployed to.
@@ -89,14 +96,41 @@ Which launches in the browser:
89
96
 
90
97
  ## The Market Platforms
91
98
 
92
- The following markets platforms are supported:
99
+ The following prediction market platforms are supported:
100
+
101
+ | Platform | Benchmarking | Deployment | Monitoring |
102
+ |---------------------------------------|--------------|------------|------------|
103
+ | [Manifold](https://manifold.markets/) | ✅ | ✅ | ✅ |
104
+ | [AIOmen](https://aiomen.eth.limo/) | ✅ | ✅ | ✅ |
105
+ | [Polymarket](https://polymarket.com/) | ✅ | ❌ | ❌ |
106
+
107
+ ## Prediction Markets Python API
108
+
109
+ We have built clean abstractions for taking actions on the different prediction market platforms (retrieving markets, buying and selling tokens, etc.). This is currently undocumented, but for now, inspecting the [`AgentMarket`](https://github.com/gnosis/prediction-market-agent-tooling/blob/1e497fff9f2b53e4e3e1beb5dda08b4d49da881b/prediction_market_agent_tooling/markets/agent_market.py) class and its methods is your best bet.
110
+
111
+ For example:
112
+
113
+ ```python
114
+ from prediction_market_agent_tooling.config import APIKeys
115
+ from prediction_market_agent_tooling.markets.agent_market import SortBy
116
+ from prediction_market_agent_tooling.markets.omen.omen import OmenAgentMarket
117
+
118
+ # Place a bet on the market closing soonest
119
+ market = OmenAgentMarket.get_binary_markets(limit=1, sort_by=SortBy.CLOSING_SOONEST)[0]
120
+ market.place_bet(outcome=True, amount=market.get_bet_amount(0.1))
121
+
122
+ # View your positions
123
+ my_positions = OmenAgentMarket.get_positions(user_id=APIKeys().bet_from_address)
124
+ print(my_positions)
125
+
126
+ # Sell position (accounting for fees)
127
+ market.sell_tokens(outcome=True, amount=market.get_bet_amount(0.095))
128
+ ```
93
129
 
94
- - [Manifold](https://manifold.markets/)
95
- - [AIOmen](https://aiomen.eth.limo/)
96
- - [Polymarket](https://polymarket.com/) - Benchmarking only. Deploy and monitor TODO
130
+ This API can be built on top of to create your application. See [here](https://github.com/gnosis/prediction-market-agent/tree/main/prediction_market_agent/agents/microchain_agent) for an example.
97
131
 
98
132
  ## Contributing
99
133
 
100
- See the [Issues](https://github.com/gnosis/prediction-market-agent-tooling/issues) for ideas of things that need fixing or implementing. Or come up with your own :D.
134
+ See the [Issues](https://github.com/gnosis/prediction-market-agent-tooling/issues) for ideas of things that need fixing or implementing. The team is also receptive to new issues and PRs.
101
135
 
102
136
  We use `mypy` for static type checking, and `isort`, `black` and `autoflake` for linting. These all run as steps in CI.
@@ -273,11 +273,11 @@ class DeployableTraderAgent(DeployableAgent):
273
273
  for market in markets:
274
274
  result = self.answer_binary_market(market)
275
275
  if result is None:
276
- logger.debug(f"Skipping market {market} as no answer was provided")
276
+ logger.info(f"Skipping market {market} as no answer was provided")
277
277
  continue
278
278
  if self.place_bet:
279
279
  amount = self.calculate_bet_amount(result, market)
280
- logger.debug(
280
+ logger.info(
281
281
  f"Placing bet on {market} with result {result} and amount {amount}"
282
282
  )
283
283
  market.place_bet(
@@ -14,12 +14,21 @@ class LogFormat(str, Enum):
14
14
  GCP = "gcp"
15
15
 
16
16
 
17
+ class LogLevel(str, Enum):
18
+ CRITICAL = "CRITICAL"
19
+ ERROR = "ERROR"
20
+ WARNING = "WARNING"
21
+ INFO = "INFO"
22
+ DEBUG = "DEBUG"
23
+
24
+
17
25
  class LogConfig(BaseSettings):
18
26
  model_config = SettingsConfigDict(
19
27
  env_file=".env", env_file_encoding="utf-8", extra="ignore"
20
28
  )
21
29
 
22
30
  LOG_FORMAT: LogFormat = LogFormat.DEFAULT
31
+ LOG_LEVEL: LogLevel = LogLevel.DEBUG
23
32
 
24
33
 
25
34
  GCP_LOG_LOGURU_FORMAT = (
@@ -49,7 +58,7 @@ def patch_logger() -> None:
49
58
  # Change built-in logging.
50
59
  if format_logging is not None:
51
60
  logging.basicConfig(
52
- level=logging.DEBUG, format=format_logging, datefmt=datefmt_logging
61
+ level=config.LOG_LEVEL.value, format=format_logging, datefmt=datefmt_logging
53
62
  )
54
63
 
55
64
  # Change loguru.
@@ -58,7 +67,7 @@ def patch_logger() -> None:
58
67
  logger.add(
59
68
  sys.stdout,
60
69
  format=format_loguru,
61
- level="DEBUG", # Can be the lowest level, higher ones will use by default this one.
70
+ level=config.LOG_LEVEL.value,
62
71
  colorize=True,
63
72
  )
64
73
 
@@ -5,6 +5,7 @@ from enum import Enum
5
5
  from eth_typing import ChecksumAddress
6
6
  from pydantic import BaseModel, field_validator
7
7
 
8
+ from prediction_market_agent_tooling.config import APIKeys
8
9
  from prediction_market_agent_tooling.gtypes import Probability
9
10
  from prediction_market_agent_tooling.markets.data_models import (
10
11
  Bet,
@@ -196,3 +197,7 @@ class AgentMarket(BaseModel):
196
197
  if self.is_closed() or not self.has_liquidity():
197
198
  return False
198
199
  return True
200
+
201
+ @classmethod
202
+ def get_user_url(cls, keys: APIKeys) -> str:
203
+ raise NotImplementedError("Subclasses must implement this method")
@@ -11,6 +11,7 @@ from prediction_market_agent_tooling.markets.agent_market import (
11
11
  )
12
12
  from prediction_market_agent_tooling.markets.data_models import BetAmount, Currency
13
13
  from prediction_market_agent_tooling.markets.manifold.api import (
14
+ get_authenticated_user,
14
15
  get_manifold_binary_markets,
15
16
  place_bet,
16
17
  )
@@ -108,3 +109,7 @@ class ManifoldAgentMarket(AgentMarket):
108
109
  excluded_questions=excluded_questions,
109
110
  )
110
111
  ]
112
+
113
+ @classmethod
114
+ def get_user_url(cls, keys: APIKeys) -> str:
115
+ return get_authenticated_user(keys.manifold_api_key.get_secret_value()).url
@@ -156,7 +156,7 @@ class OmenAgentMarket(AgentMarket):
156
156
  )
157
157
 
158
158
  def sell_tokens(
159
- self, outcome: bool, amount: TokenAmount, auto_withdraw: bool = True
159
+ self, outcome: bool, amount: TokenAmount, auto_withdraw: bool = False
160
160
  ) -> None:
161
161
  if not self.can_be_traded():
162
162
  raise ValueError(
@@ -369,6 +369,10 @@ class OmenAgentMarket(AgentMarket):
369
369
 
370
370
  return positions
371
371
 
372
+ @classmethod
373
+ def get_user_url(cls, keys: APIKeys) -> str:
374
+ return f"https://gnosisscan.io/address/{keys.bet_from_address}"
375
+
372
376
 
373
377
  def pick_binary_market(
374
378
  sort_by: SortBy = SortBy.CLOSING_SOONEST, filter_by: FilterBy = FilterBy.OPEN
@@ -205,8 +205,9 @@ class OmenSubgraphHandler(metaclass=SingletonMeta):
205
205
  finalized_before
206
206
  )
207
207
 
208
+ # `excluded_question_titles` can not be an empty list, otherwise the API bugs out and returns nothing.
208
209
  excluded_question_titles = [""]
209
- if excluded_questions is not None:
210
+ if excluded_questions:
210
211
  excluded_question_titles = [i for i in excluded_questions]
211
212
 
212
213
  where_stms["question_"]["title_not_in"] = excluded_question_titles
@@ -439,6 +440,8 @@ class OmenSubgraphHandler(metaclass=SingletonMeta):
439
440
  market_id: t.Optional[ChecksumAddress] = None,
440
441
  filter_by_answer_finalized_not_null: bool = False,
441
442
  type_: t.Literal["Buy", "Sell"] | None = None,
443
+ market_opening_after: datetime | None = None,
444
+ collateral_amount_more_than: Wei | None = None,
442
445
  ) -> list[OmenBet]:
443
446
  if not end_time:
444
447
  end_time = utcnow()
@@ -457,6 +460,12 @@ class OmenSubgraphHandler(metaclass=SingletonMeta):
457
460
  where_stms.append(trade.fpmm == market_id.lower())
458
461
  if filter_by_answer_finalized_not_null:
459
462
  where_stms.append(trade.fpmm.answerFinalizedTimestamp != None)
463
+ if market_opening_after is not None:
464
+ where_stms.append(
465
+ trade.fpmm.openingTimestamp > to_int_timestamp(market_opening_after)
466
+ )
467
+ if collateral_amount_more_than is not None:
468
+ where_stms.append(trade.collateralAmount > collateral_amount_more_than)
460
469
 
461
470
  trades = self.trades_subgraph.Query.fpmmTrades(
462
471
  first=sys.maxsize, where=where_stms
@@ -473,6 +482,8 @@ class OmenSubgraphHandler(metaclass=SingletonMeta):
473
482
  end_time: t.Optional[datetime] = None,
474
483
  market_id: t.Optional[ChecksumAddress] = None,
475
484
  filter_by_answer_finalized_not_null: bool = False,
485
+ market_opening_after: datetime | None = None,
486
+ collateral_amount_more_than: Wei | None = None,
476
487
  ) -> list[OmenBet]:
477
488
  return self.get_trades(
478
489
  better_address=better_address,
@@ -481,6 +492,8 @@ class OmenSubgraphHandler(metaclass=SingletonMeta):
481
492
  market_id=market_id,
482
493
  filter_by_answer_finalized_not_null=filter_by_answer_finalized_not_null,
483
494
  type_="Buy", # We consider `bet` to be only the `Buy` trade types.
495
+ market_opening_after=market_opening_after,
496
+ collateral_amount_more_than=collateral_amount_more_than,
484
497
  )
485
498
 
486
499
  def get_resolved_bets(
@@ -1,5 +1,6 @@
1
1
  from loguru import logger
2
2
 
3
+ from prediction_market_agent_tooling.config import APIKeys
3
4
  from prediction_market_agent_tooling.tools.cache import persistent_inmemory_cache
4
5
 
5
6
  # I tried to make it return a JSON, but it didn't work well in combo with asking it to do chain of thought.
@@ -44,7 +45,11 @@ def is_predictable_binary(
44
45
  logger.info("langchain not installed, skipping is_predictable_binary")
45
46
  return True
46
47
 
47
- llm = ChatOpenAI(model=engine, temperature=0.0)
48
+ llm = ChatOpenAI(
49
+ model=engine,
50
+ temperature=0.0,
51
+ api_key=APIKeys().openai_api_key.get_secret_value(),
52
+ )
48
53
 
49
54
  prompt = ChatPromptTemplate.from_template(template=prompt_template)
50
55
  messages = prompt.format_messages(question=question)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "prediction-market-agent-tooling"
3
- version = "0.29.0"
3
+ version = "0.32.0"
4
4
  description = "Tools to benchmark, deploy and monitor prediction market agents."
5
5
  authors = ["Gnosis"]
6
6
  readme = "README.md"