prediction-market-agent-tooling 0.49.2__py3-none-any.whl → 0.50.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. prediction_market_agent_tooling/benchmark/agents.py +6 -6
  2. prediction_market_agent_tooling/deploy/agent.py +4 -4
  3. prediction_market_agent_tooling/deploy/gcp/kubernetes_models.py +3 -4
  4. prediction_market_agent_tooling/gtypes.py +3 -2
  5. prediction_market_agent_tooling/jobs/jobs_models.py +3 -3
  6. prediction_market_agent_tooling/jobs/omen/omen_jobs.py +2 -2
  7. prediction_market_agent_tooling/markets/agent_market.py +11 -17
  8. prediction_market_agent_tooling/markets/data_models.py +3 -3
  9. prediction_market_agent_tooling/markets/manifold/api.py +6 -6
  10. prediction_market_agent_tooling/markets/manifold/data_models.py +13 -23
  11. prediction_market_agent_tooling/markets/manifold/manifold.py +2 -2
  12. prediction_market_agent_tooling/markets/markets.py +7 -3
  13. prediction_market_agent_tooling/markets/metaculus/api.py +2 -3
  14. prediction_market_agent_tooling/markets/metaculus/data_models.py +11 -10
  15. prediction_market_agent_tooling/markets/metaculus/metaculus.py +2 -2
  16. prediction_market_agent_tooling/markets/omen/data_models.py +35 -22
  17. prediction_market_agent_tooling/markets/omen/omen.py +11 -8
  18. prediction_market_agent_tooling/markets/omen/omen_contracts.py +3 -2
  19. prediction_market_agent_tooling/markets/omen/omen_resolving.py +2 -3
  20. prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +36 -33
  21. prediction_market_agent_tooling/markets/polymarket/data_models.py +5 -6
  22. prediction_market_agent_tooling/markets/polymarket/data_models_web.py +14 -14
  23. prediction_market_agent_tooling/markets/polymarket/polymarket.py +2 -2
  24. prediction_market_agent_tooling/monitor/markets/manifold.py +2 -2
  25. prediction_market_agent_tooling/monitor/markets/metaculus.py +2 -2
  26. prediction_market_agent_tooling/monitor/markets/omen.py +2 -2
  27. prediction_market_agent_tooling/monitor/markets/polymarket.py +2 -2
  28. prediction_market_agent_tooling/monitor/monitor.py +5 -15
  29. prediction_market_agent_tooling/monitor/monitor_app.py +7 -8
  30. prediction_market_agent_tooling/tools/contract.py +3 -7
  31. prediction_market_agent_tooling/tools/datetime_utc.py +74 -0
  32. prediction_market_agent_tooling/tools/langfuse_client_utils.py +16 -11
  33. prediction_market_agent_tooling/tools/tavily_storage/tavily_models.py +4 -4
  34. prediction_market_agent_tooling/tools/utils.py +28 -52
  35. {prediction_market_agent_tooling-0.49.2.dist-info → prediction_market_agent_tooling-0.50.0.dist-info}/METADATA +4 -2
  36. {prediction_market_agent_tooling-0.49.2.dist-info → prediction_market_agent_tooling-0.50.0.dist-info}/RECORD +39 -38
  37. {prediction_market_agent_tooling-0.49.2.dist-info → prediction_market_agent_tooling-0.50.0.dist-info}/LICENSE +0 -0
  38. {prediction_market_agent_tooling-0.49.2.dist-info → prediction_market_agent_tooling-0.50.0.dist-info}/WHEEL +0 -0
  39. {prediction_market_agent_tooling-0.49.2.dist-info → prediction_market_agent_tooling-0.50.0.dist-info}/entry_points.txt +0 -0
@@ -1,12 +1,12 @@
1
1
  import random
2
2
  import typing as t
3
- from datetime import datetime
4
3
 
5
4
  from prediction_market_agent_tooling.benchmark.utils import (
6
5
  OutcomePrediction,
7
6
  Prediction,
8
7
  )
9
8
  from prediction_market_agent_tooling.gtypes import Probability
9
+ from prediction_market_agent_tooling.tools.utils import DatetimeUTC
10
10
 
11
11
 
12
12
  class AbstractBenchmarkedAgent:
@@ -41,7 +41,7 @@ class AbstractBenchmarkedAgent:
41
41
  def is_predictable_restricted(
42
42
  self,
43
43
  market_question: str,
44
- time_restriction_up_to: datetime,
44
+ time_restriction_up_to: DatetimeUTC,
45
45
  ) -> bool:
46
46
  """
47
47
  Override if the agent can decide to not predict the question, before doing the hard work.
@@ -53,7 +53,7 @@ class AbstractBenchmarkedAgent:
53
53
  def predict_restricted(
54
54
  self,
55
55
  market_question: str,
56
- time_restriction_up_to: datetime,
56
+ time_restriction_up_to: DatetimeUTC,
57
57
  ) -> Prediction:
58
58
  """
59
59
  Predict the outcome of the market question.
@@ -65,7 +65,7 @@ class AbstractBenchmarkedAgent:
65
65
  def check_and_predict_restricted(
66
66
  self,
67
67
  market_question: str,
68
- time_restriction_up_to: datetime,
68
+ time_restriction_up_to: DatetimeUTC,
69
69
  ) -> Prediction:
70
70
  """
71
71
  Data used must be restricted to the time_restriction_up_to.
@@ -94,7 +94,7 @@ class RandomAgent(AbstractBenchmarkedAgent):
94
94
  )
95
95
 
96
96
  def predict_restricted(
97
- self, market_question: str, time_restriction_up_to: datetime
97
+ self, market_question: str, time_restriction_up_to: DatetimeUTC
98
98
  ) -> Prediction:
99
99
  return self.predict(market_question)
100
100
 
@@ -117,6 +117,6 @@ class FixedAgent(AbstractBenchmarkedAgent):
117
117
  )
118
118
 
119
119
  def predict_restricted(
120
- self, market_question: str, time_restriction_up_to: datetime
120
+ self, market_question: str, time_restriction_up_to: DatetimeUTC
121
121
  ) -> Prediction:
122
122
  return self.predict(market_question)
@@ -4,7 +4,7 @@ import os
4
4
  import tempfile
5
5
  import time
6
6
  import typing as t
7
- from datetime import datetime, timedelta
7
+ from datetime import timedelta
8
8
  from enum import Enum
9
9
  from functools import cached_property
10
10
 
@@ -67,7 +67,7 @@ from prediction_market_agent_tooling.tools.hexbytes_custom import HexBytes
67
67
  from prediction_market_agent_tooling.tools.ipfs.ipfs_handler import IPFSHandler
68
68
  from prediction_market_agent_tooling.tools.is_predictable import is_predictable_binary
69
69
  from prediction_market_agent_tooling.tools.langfuse_ import langfuse_context, observe
70
- from prediction_market_agent_tooling.tools.utils import DatetimeWithTimezone, utcnow
70
+ from prediction_market_agent_tooling.tools.utils import DatetimeUTC, utcnow
71
71
  from prediction_market_agent_tooling.tools.web3_utils import ipfscidv0_to_byte32
72
72
 
73
73
  MAX_AVAILABLE_MARKETS = 20
@@ -215,7 +215,7 @@ class DeployableAgent:
215
215
  secrets: dict[str, str] | None = None,
216
216
  cron_schedule: str | None = None,
217
217
  gcp_fname: str | None = None,
218
- start_time: DatetimeWithTimezone | None = None,
218
+ start_time: DatetimeUTC | None = None,
219
219
  timeout: int = 180,
220
220
  ) -> None:
221
221
  path_to_agent_file = os.path.relpath(inspect.getfile(self.__class__))
@@ -287,7 +287,7 @@ def {entrypoint_function_name}(request) -> str:
287
287
  raise NotImplementedError("This method must be implemented by the subclass.")
288
288
 
289
289
  def get_gcloud_fname(self, market_type: MarketType) -> str:
290
- return f"{self.__class__.__name__.lower()}-{market_type}-{datetime.now().strftime('%Y-%m-%d--%H-%M-%S')}"
290
+ return f"{self.__class__.__name__.lower()}-{market_type}-{utcnow().strftime('%Y-%m-%d--%H-%M-%S')}"
291
291
 
292
292
 
293
293
  class DeployableTraderAgent(DeployableAgent):
@@ -1,11 +1,10 @@
1
- from datetime import datetime
2
1
  from typing import Any
3
2
 
4
3
  from pydantic import BaseModel
5
4
 
6
5
 
7
6
  class Metadata(BaseModel):
8
- creationTimestamp: datetime
7
+ creationTimestamp: int
9
8
  generation: int
10
9
  name: str
11
10
  namespace: str
@@ -15,12 +14,12 @@ class Metadata(BaseModel):
15
14
 
16
15
 
17
16
  class Metadata1(BaseModel):
18
- creationTimestamp: datetime | None
17
+ creationTimestamp: int | None
19
18
  name: str
20
19
 
21
20
 
22
21
  class Metadata2(BaseModel):
23
- creationTimestamp: datetime | None
22
+ creationTimestamp: int | None
24
23
  name: str
25
24
 
26
25
 
@@ -1,5 +1,4 @@
1
1
  import typing as t
2
- from datetime import datetime
3
2
  from typing import NewType, Union
4
3
 
5
4
  from eth_typing.evm import ( # noqa: F401 # Import for the sake of easy importing with others from here.
@@ -17,6 +16,9 @@ from web3.types import ( # noqa: F401 # Import for the sake of easy importing
17
16
  Wei,
18
17
  )
19
18
 
19
+ from prediction_market_agent_tooling.tools.datetime_utc import ( # noqa: F401 # Import for the sake of easy importing with others from here.
20
+ DatetimeUTC,
21
+ )
20
22
  from prediction_market_agent_tooling.tools.hexbytes_custom import ( # noqa: F401 # Import for the sake of easy importing with others from here.
21
23
  HexBytes,
22
24
  )
@@ -32,7 +34,6 @@ OutcomeStr = NewType("OutcomeStr", str)
32
34
  Probability = NewType("Probability", float)
33
35
  Mana = NewType("Mana", float) # Manifold's "currency"
34
36
  USDC = NewType("USDC", float)
35
- DatetimeWithTimezone = NewType("DatetimeWithTimezone", datetime)
36
37
  ChainID = NewType("ChainID", int)
37
38
  IPFSCIDVersion0 = NewType("IPFSCIDVersion0", str)
38
39
 
@@ -1,6 +1,5 @@
1
1
  import typing as t
2
2
  from abc import ABC, abstractmethod
3
- from datetime import datetime
4
3
 
5
4
  from pydantic import BaseModel
6
5
 
@@ -9,6 +8,7 @@ from prediction_market_agent_tooling.markets.omen.omen_subgraph_handler import (
9
8
  FilterBy,
10
9
  SortBy,
11
10
  )
11
+ from prediction_market_agent_tooling.tools.utils import DatetimeUTC
12
12
 
13
13
 
14
14
  class SimpleJob(BaseModel):
@@ -16,7 +16,7 @@ class SimpleJob(BaseModel):
16
16
  job: str
17
17
  reward: float
18
18
  currency: str
19
- deadline: datetime
19
+ deadline: DatetimeUTC
20
20
 
21
21
 
22
22
  class JobAgentMarket(AgentMarket, ABC):
@@ -29,7 +29,7 @@ class JobAgentMarket(AgentMarket, ABC):
29
29
 
30
30
  @property
31
31
  @abstractmethod
32
- def deadline(self) -> datetime:
32
+ def deadline(self) -> DatetimeUTC:
33
33
  """Deadline for the job completion."""
34
34
 
35
35
  @abstractmethod
@@ -1,5 +1,4 @@
1
1
  import typing as t
2
- from datetime import datetime
3
2
 
4
3
  from web3 import Web3
5
4
 
@@ -21,6 +20,7 @@ from prediction_market_agent_tooling.markets.omen.omen_subgraph_handler import (
21
20
  OmenSubgraphHandler,
22
21
  SortBy,
23
22
  )
23
+ from prediction_market_agent_tooling.tools.utils import DatetimeUTC
24
24
 
25
25
 
26
26
  class OmenJobAgentMarket(OmenAgentMarket, JobAgentMarket):
@@ -32,7 +32,7 @@ class OmenJobAgentMarket(OmenAgentMarket, JobAgentMarket):
32
32
  return self.question
33
33
 
34
34
  @property
35
- def deadline(self) -> datetime:
35
+ def deadline(self) -> DatetimeUTC:
36
36
  return self.close_time
37
37
 
38
38
  def get_reward(self, max_bond: float) -> float:
@@ -1,5 +1,4 @@
1
1
  import typing as t
2
- from datetime import datetime
3
2
  from enum import Enum
4
3
 
5
4
  from eth_typing import ChecksumAddress
@@ -18,8 +17,8 @@ from prediction_market_agent_tooling.markets.data_models import (
18
17
  TokenAmount,
19
18
  )
20
19
  from prediction_market_agent_tooling.tools.utils import (
20
+ DatetimeUTC,
21
21
  check_not_none,
22
- convert_to_utc_datetime,
23
22
  should_not_happen,
24
23
  utcnow,
25
24
  )
@@ -52,23 +51,16 @@ class AgentMarket(BaseModel):
52
51
  question: str
53
52
  description: str | None
54
53
  outcomes: list[str]
55
- outcome_token_pool: dict[
56
- str, float
57
- ] | None # Should be in currency of `currency` above.
54
+ outcome_token_pool: (
55
+ dict[str, float] | None
56
+ ) # Should be in currency of `currency` above.
58
57
  resolution: Resolution | None
59
- created_time: datetime | None
60
- close_time: datetime | None
58
+ created_time: DatetimeUTC | None
59
+ close_time: DatetimeUTC | None
61
60
  current_p_yes: Probability
62
61
  url: str
63
62
  volume: float | None # Should be in currency of `currency` above.
64
63
 
65
- _add_timezone_validator_created_time = field_validator("created_time")(
66
- convert_to_utc_datetime
67
- )
68
- _add_timezone_validator_close_time = field_validator("close_time")(
69
- convert_to_utc_datetime
70
- )
71
-
72
64
  @field_validator("outcome_token_pool")
73
65
  def validate_outcome_token_pool(
74
66
  cls,
@@ -182,7 +174,7 @@ class AgentMarket(BaseModel):
182
174
  limit: int,
183
175
  sort_by: SortBy,
184
176
  filter_by: FilterBy = FilterBy.OPEN,
185
- created_after: t.Optional[datetime] = None,
177
+ created_after: t.Optional[DatetimeUTC] = None,
186
178
  excluded_questions: set[str] | None = None,
187
179
  ) -> t.Sequence["AgentMarket"]:
188
180
  raise NotImplementedError("Subclasses must implement this method")
@@ -193,13 +185,15 @@ class AgentMarket(BaseModel):
193
185
 
194
186
  @staticmethod
195
187
  def get_bets_made_since(
196
- better_address: ChecksumAddress, start_time: datetime
188
+ better_address: ChecksumAddress, start_time: DatetimeUTC
197
189
  ) -> list[Bet]:
198
190
  raise NotImplementedError("Subclasses must implement this method")
199
191
 
200
192
  @staticmethod
201
193
  def get_resolved_bets_made_since(
202
- better_address: ChecksumAddress, start_time: datetime, end_time: datetime | None
194
+ better_address: ChecksumAddress,
195
+ start_time: DatetimeUTC,
196
+ end_time: DatetimeUTC | None,
203
197
  ) -> list[ResolvedBet]:
204
198
  raise NotImplementedError("Subclasses must implement this method")
205
199
 
@@ -1,10 +1,10 @@
1
- from datetime import datetime
2
1
  from enum import Enum
3
2
  from typing import Annotated, TypeAlias
4
3
 
5
4
  from pydantic import BaseModel, BeforeValidator, computed_field
6
5
 
7
6
  from prediction_market_agent_tooling.gtypes import OutcomeStr, Probability
7
+ from prediction_market_agent_tooling.tools.utils import DatetimeUTC
8
8
 
9
9
 
10
10
  class Currency(str, Enum):
@@ -40,7 +40,7 @@ class Bet(BaseModel):
40
40
  id: str
41
41
  amount: BetAmount
42
42
  outcome: bool
43
- created_time: datetime
43
+ created_time: DatetimeUTC
44
44
  market_question: str
45
45
  market_id: str
46
46
 
@@ -50,7 +50,7 @@ class Bet(BaseModel):
50
50
 
51
51
  class ResolvedBet(Bet):
52
52
  market_outcome: bool
53
- resolved_time: datetime
53
+ resolved_time: DatetimeUTC
54
54
  profit: ProfitAmount
55
55
 
56
56
  @computed_field # type: ignore[prop-decorator]
@@ -1,5 +1,4 @@
1
1
  import typing as t
2
- from datetime import datetime
3
2
 
4
3
  import requests
5
4
  import tenacity
@@ -20,6 +19,7 @@ from prediction_market_agent_tooling.markets.manifold.data_models import (
20
19
  )
21
20
  from prediction_market_agent_tooling.tools.parallelism import par_map
22
21
  from prediction_market_agent_tooling.tools.utils import (
22
+ DatetimeUTC,
23
23
  response_list_to_model,
24
24
  response_to_model,
25
25
  )
@@ -47,7 +47,7 @@ def get_manifold_binary_markets(
47
47
  ]
48
48
  | None
49
49
  ) = "open",
50
- created_after: t.Optional[datetime] = None,
50
+ created_after: t.Optional[DatetimeUTC] = None,
51
51
  excluded_questions: set[str] | None = None,
52
52
  ) -> list[ManifoldMarket]:
53
53
  all_markets: list[ManifoldMarket] = []
@@ -167,8 +167,8 @@ def get_manifold_market(market_id: str) -> FullManifoldMarket:
167
167
  )
168
168
  def get_manifold_bets(
169
169
  user_id: str,
170
- start_time: datetime,
171
- end_time: t.Optional[datetime],
170
+ start_time: DatetimeUTC,
171
+ end_time: t.Optional[DatetimeUTC],
172
172
  ) -> list[ManifoldBet]:
173
173
  url = f"{MANIFOLD_API_BASE_URL}/v0/bets"
174
174
 
@@ -182,8 +182,8 @@ def get_manifold_bets(
182
182
 
183
183
  def get_resolved_manifold_bets(
184
184
  user_id: str,
185
- start_time: datetime,
186
- end_time: t.Optional[datetime],
185
+ start_time: DatetimeUTC,
186
+ end_time: t.Optional[DatetimeUTC],
187
187
  ) -> tuple[list[ManifoldBet], list[ManifoldMarket]]:
188
188
  bets = get_manifold_bets(user_id, start_time, end_time)
189
189
  markets: list[ManifoldMarket] = par_map(
@@ -1,8 +1,7 @@
1
1
  import typing as t
2
- from datetime import datetime, timedelta
3
2
  from enum import Enum
4
3
 
5
- from pydantic import BaseModel, field_validator
4
+ from pydantic import BaseModel
6
5
 
7
6
  from prediction_market_agent_tooling.gtypes import Mana, Probability
8
7
  from prediction_market_agent_tooling.markets.data_models import (
@@ -10,7 +9,7 @@ from prediction_market_agent_tooling.markets.data_models import (
10
9
  ProfitAmount,
11
10
  Resolution,
12
11
  )
13
- from prediction_market_agent_tooling.tools.utils import should_not_happen
12
+ from prediction_market_agent_tooling.tools.utils import DatetimeUTC, should_not_happen
14
13
 
15
14
  MANIFOLD_BASE_URL = "https://manifold.markets"
16
15
 
@@ -33,7 +32,7 @@ class ManifoldAnswersMode(str, Enum):
33
32
 
34
33
 
35
34
  class ManifoldAnswer(BaseModel):
36
- createdTime: datetime
35
+ createdTime: DatetimeUTC
37
36
  avatarUrl: str
38
37
  id: str
39
38
  username: str
@@ -55,17 +54,17 @@ class ManifoldMarket(BaseModel):
55
54
  id: str
56
55
  question: str
57
56
  creatorId: str
58
- closeTime: datetime
59
- createdTime: datetime
57
+ closeTime: DatetimeUTC
58
+ createdTime: DatetimeUTC
60
59
  creatorAvatarUrl: t.Optional[str] = None
61
60
  creatorName: str
62
61
  creatorUsername: str
63
62
  isResolved: bool
64
63
  resolution: t.Optional[Resolution] = None
65
- resolutionTime: t.Optional[datetime] = None
66
- lastBetTime: t.Optional[datetime] = None
67
- lastCommentTime: t.Optional[datetime] = None
68
- lastUpdatedTime: datetime
64
+ resolutionTime: t.Optional[DatetimeUTC] = None
65
+ lastBetTime: t.Optional[DatetimeUTC] = None
66
+ lastCommentTime: t.Optional[DatetimeUTC] = None
67
+ lastUpdatedTime: DatetimeUTC
69
68
  mechanism: str
70
69
  outcomeType: str
71
70
  p: t.Optional[float] = None
@@ -100,15 +99,6 @@ class ManifoldMarket(BaseModel):
100
99
  def __repr__(self) -> str:
101
100
  return f"Manifold's market: {self.question}"
102
101
 
103
- @field_validator("closeTime", mode="before")
104
- def clip_timestamp(cls, value: int) -> datetime:
105
- """
106
- Clip the timestamp to the maximum valid timestamp.
107
- """
108
- max_timestamp = (datetime.max - timedelta(days=1)).timestamp()
109
- value = int(min(value / 1000, max_timestamp))
110
- return datetime.fromtimestamp(value)
111
-
112
102
 
113
103
  class FullManifoldMarket(ManifoldMarket):
114
104
  # Some of these fields are available only in specific cases, see https://docs.manifold.markets/api#get-v0marketmarketid.
@@ -137,7 +127,7 @@ class ManifoldUser(BaseModel):
137
127
  """
138
128
 
139
129
  id: str
140
- createdTime: datetime
130
+ createdTime: DatetimeUTC
141
131
  name: str
142
132
  username: str
143
133
  url: str
@@ -154,7 +144,7 @@ class ManifoldUser(BaseModel):
154
144
  userDeleted: t.Optional[bool] = None
155
145
  balance: Mana
156
146
  totalDeposits: Mana
157
- lastBetTime: t.Optional[datetime] = None
147
+ lastBetTime: t.Optional[DatetimeUTC] = None
158
148
  currentBettingStreak: t.Optional[int] = None
159
149
  profitCached: ProfitCached
160
150
 
@@ -193,7 +183,7 @@ class ManifoldBet(BaseModel):
193
183
  loanAmount: Mana | None
194
184
  orderAmount: t.Optional[Mana] = None
195
185
  fills: t.Optional[list[ManifoldBetFills]] = None
196
- createdTime: datetime
186
+ createdTime: DatetimeUTC
197
187
  outcome: Resolution
198
188
 
199
189
  def get_resolved_boolean_outcome(self) -> bool:
@@ -237,4 +227,4 @@ class ManifoldContractMetric(BaseModel):
237
227
  userUsername: str
238
228
  userName: str
239
229
  userAvatarUrl: str
240
- lastBetTime: datetime
230
+ lastBetTime: DatetimeUTC
@@ -1,5 +1,4 @@
1
1
  import typing as t
2
- from datetime import datetime
3
2
  from math import ceil
4
3
 
5
4
  from prediction_market_agent_tooling.config import APIKeys
@@ -23,6 +22,7 @@ from prediction_market_agent_tooling.markets.manifold.data_models import (
23
22
  from prediction_market_agent_tooling.tools.betting_strategies.minimum_bet_to_win import (
24
23
  minimum_bet_to_win,
25
24
  )
25
+ from prediction_market_agent_tooling.tools.utils import DatetimeUTC
26
26
 
27
27
 
28
28
  class ManifoldAgentMarket(AgentMarket):
@@ -83,7 +83,7 @@ class ManifoldAgentMarket(AgentMarket):
83
83
  limit: int,
84
84
  sort_by: SortBy,
85
85
  filter_by: FilterBy = FilterBy.OPEN,
86
- created_after: t.Optional[datetime] = None,
86
+ created_after: t.Optional[DatetimeUTC] = None,
87
87
  excluded_questions: set[str] | None = None,
88
88
  ) -> t.Sequence["ManifoldAgentMarket"]:
89
89
  sort: t.Literal["newest", "close-date"] | None
@@ -1,5 +1,5 @@
1
1
  import typing as t
2
- from datetime import datetime, timedelta
2
+ from datetime import timedelta
3
3
  from enum import Enum
4
4
 
5
5
  from prediction_market_agent_tooling.config import APIKeys
@@ -26,7 +26,11 @@ from prediction_market_agent_tooling.markets.omen.omen_subgraph_handler import (
26
26
  from prediction_market_agent_tooling.markets.polymarket.polymarket import (
27
27
  PolymarketAgentMarket,
28
28
  )
29
- from prediction_market_agent_tooling.tools.utils import should_not_happen, utcnow
29
+ from prediction_market_agent_tooling.tools.utils import (
30
+ DatetimeUTC,
31
+ should_not_happen,
32
+ utcnow,
33
+ )
30
34
 
31
35
 
32
36
  class MarketType(str, Enum):
@@ -57,7 +61,7 @@ def get_binary_markets(
57
61
  filter_by: FilterBy = FilterBy.OPEN,
58
62
  sort_by: SortBy = SortBy.NONE,
59
63
  excluded_questions: set[str] | None = None,
60
- created_after: datetime | None = None,
64
+ created_after: DatetimeUTC | None = None,
61
65
  ) -> t.Sequence[AgentMarket]:
62
66
  agent_market_class = MARKET_TYPE_TO_AGENT_MARKET[market_type]
63
67
  markets = agent_market_class.get_binary_markets(
@@ -1,4 +1,3 @@
1
- from datetime import datetime
2
1
  from typing import Union
3
2
 
4
3
  import requests
@@ -9,7 +8,7 @@ from prediction_market_agent_tooling.markets.metaculus.data_models import (
9
8
  MetaculusQuestion,
10
9
  MetaculusQuestions,
11
10
  )
12
- from prediction_market_agent_tooling.tools.utils import response_to_model
11
+ from prediction_market_agent_tooling.tools.utils import DatetimeUTC, response_to_model
13
12
 
14
13
  METACULUS_API_BASE_URL = "https://www.metaculus.com/api2"
15
14
 
@@ -65,7 +64,7 @@ def get_questions(
65
64
  order_by: str | None = None,
66
65
  offset: int = 0,
67
66
  tournament_id: int | None = None,
68
- created_after: datetime | None = None,
67
+ created_after: DatetimeUTC | None = None,
69
68
  status: str | None = None,
70
69
  ) -> list[MetaculusQuestion]:
71
70
  """
@@ -1,9 +1,10 @@
1
- from datetime import datetime
2
1
  from enum import Enum
3
2
  from typing import Any
4
3
 
5
4
  from pydantic import BaseModel
6
5
 
6
+ from prediction_market_agent_tooling.tools.utils import DatetimeUTC
7
+
7
8
 
8
9
  class QuestionType(str, Enum):
9
10
  forecast = "forecast"
@@ -33,7 +34,7 @@ class CommunityPrediction(BaseModel):
33
34
 
34
35
 
35
36
  class Prediction(BaseModel):
36
- t: datetime
37
+ t: DatetimeUTC
37
38
  x: float
38
39
 
39
40
 
@@ -68,20 +69,20 @@ class MetaculusQuestion(BaseModel):
68
69
  group_label: str | None = None
69
70
  resolution: int | None
70
71
  resolved_option: int | None
71
- created_time: datetime
72
- publish_time: datetime | None = None
73
- close_time: datetime | None = None
74
- effected_close_time: datetime | None
75
- resolve_time: datetime | None = None
72
+ created_time: DatetimeUTC
73
+ publish_time: DatetimeUTC | None = None
74
+ close_time: DatetimeUTC | None = None
75
+ effected_close_time: DatetimeUTC | None
76
+ resolve_time: DatetimeUTC | None = None
76
77
  possibilities: dict[Any, Any] | None = None
77
78
  scoring: dict[Any, Any] = {}
78
79
  type: QuestionType | None = None
79
80
  user_perms: Any
80
81
  weekly_movement: float | None
81
82
  weekly_movement_direction: int | None = None
82
- cp_reveal_time: datetime | None = None
83
- edited_time: datetime
84
- last_activity_time: datetime
83
+ cp_reveal_time: DatetimeUTC | None = None
84
+ edited_time: DatetimeUTC
85
+ last_activity_time: DatetimeUTC
85
86
  activity: float
86
87
  comment_count: int
87
88
  votes: int
@@ -1,5 +1,4 @@
1
1
  import typing as t
2
- from datetime import datetime
3
2
 
4
3
  from prediction_market_agent_tooling.config import APIKeys
5
4
  from prediction_market_agent_tooling.gtypes import Probability
@@ -17,6 +16,7 @@ from prediction_market_agent_tooling.markets.metaculus.api import (
17
16
  from prediction_market_agent_tooling.markets.metaculus.data_models import (
18
17
  MetaculusQuestion,
19
18
  )
19
+ from prediction_market_agent_tooling.tools.utils import DatetimeUTC
20
20
 
21
21
 
22
22
  class MetaculusAgentMarket(AgentMarket):
@@ -52,7 +52,7 @@ class MetaculusAgentMarket(AgentMarket):
52
52
  limit: int,
53
53
  sort_by: SortBy = SortBy.NONE,
54
54
  filter_by: FilterBy = FilterBy.OPEN,
55
- created_after: t.Optional[datetime] = None,
55
+ created_after: t.Optional[DatetimeUTC] = None,
56
56
  excluded_questions: set[str] | None = None,
57
57
  tournament_id: int | None = None,
58
58
  ) -> t.Sequence["MetaculusAgentMarket"]: