prediction-market-agent-tooling 0.61.2.dev479__py3-none-any.whl → 0.62.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 (50) hide show
  1. prediction_market_agent_tooling/config.py +2 -3
  2. prediction_market_agent_tooling/deploy/agent.py +4 -5
  3. prediction_market_agent_tooling/deploy/betting_strategy.py +53 -69
  4. prediction_market_agent_tooling/gtypes.py +105 -27
  5. prediction_market_agent_tooling/jobs/jobs_models.py +5 -7
  6. prediction_market_agent_tooling/jobs/omen/omen_jobs.py +13 -17
  7. prediction_market_agent_tooling/markets/agent_market.py +96 -53
  8. prediction_market_agent_tooling/markets/blockchain_utils.py +1 -27
  9. prediction_market_agent_tooling/markets/data_models.py +40 -44
  10. prediction_market_agent_tooling/markets/manifold/api.py +2 -6
  11. prediction_market_agent_tooling/markets/manifold/data_models.py +33 -25
  12. prediction_market_agent_tooling/markets/manifold/manifold.py +13 -11
  13. prediction_market_agent_tooling/markets/market_fees.py +6 -2
  14. prediction_market_agent_tooling/markets/omen/data_models.py +66 -57
  15. prediction_market_agent_tooling/markets/omen/omen.py +222 -250
  16. prediction_market_agent_tooling/markets/omen/omen_contracts.py +31 -53
  17. prediction_market_agent_tooling/markets/omen/omen_resolving.py +7 -14
  18. prediction_market_agent_tooling/markets/omen/omen_subgraph_handler.py +20 -14
  19. prediction_market_agent_tooling/markets/polymarket/data_models.py +3 -3
  20. prediction_market_agent_tooling/markets/polymarket/data_models_web.py +4 -4
  21. prediction_market_agent_tooling/markets/polymarket/polymarket.py +3 -5
  22. prediction_market_agent_tooling/markets/seer/data_models.py +8 -8
  23. prediction_market_agent_tooling/markets/seer/seer.py +85 -71
  24. prediction_market_agent_tooling/markets/seer/seer_contracts.py +10 -5
  25. prediction_market_agent_tooling/markets/seer/seer_subgraph_handler.py +5 -2
  26. prediction_market_agent_tooling/monitor/monitor.py +2 -2
  27. prediction_market_agent_tooling/tools/_generic_value.py +261 -0
  28. prediction_market_agent_tooling/tools/balances.py +14 -11
  29. prediction_market_agent_tooling/tools/betting_strategies/kelly_criterion.py +12 -10
  30. prediction_market_agent_tooling/tools/betting_strategies/market_moving.py +31 -24
  31. prediction_market_agent_tooling/tools/betting_strategies/utils.py +3 -1
  32. prediction_market_agent_tooling/tools/contract.py +14 -10
  33. prediction_market_agent_tooling/tools/cow/cow_manager.py +3 -4
  34. prediction_market_agent_tooling/tools/cow/cow_order.py +51 -7
  35. prediction_market_agent_tooling/tools/langfuse_client_utils.py +13 -1
  36. prediction_market_agent_tooling/tools/omen/sell_positions.py +6 -3
  37. prediction_market_agent_tooling/tools/safe.py +5 -6
  38. prediction_market_agent_tooling/tools/tokens/auto_deposit.py +36 -27
  39. prediction_market_agent_tooling/tools/tokens/auto_withdraw.py +4 -25
  40. prediction_market_agent_tooling/tools/tokens/main_token.py +2 -2
  41. prediction_market_agent_tooling/tools/tokens/token_utils.py +46 -0
  42. prediction_market_agent_tooling/tools/tokens/usd.py +79 -0
  43. prediction_market_agent_tooling/tools/utils.py +14 -8
  44. prediction_market_agent_tooling/tools/web3_utils.py +24 -41
  45. {prediction_market_agent_tooling-0.61.2.dev479.dist-info → prediction_market_agent_tooling-0.62.0.dist-info}/METADATA +2 -1
  46. {prediction_market_agent_tooling-0.61.2.dev479.dist-info → prediction_market_agent_tooling-0.62.0.dist-info}/RECORD +49 -47
  47. prediction_market_agent_tooling/abis/gvp2_settlement.abi.json +0 -89
  48. {prediction_market_agent_tooling-0.61.2.dev479.dist-info → prediction_market_agent_tooling-0.62.0.dist-info}/LICENSE +0 -0
  49. {prediction_market_agent_tooling-0.61.2.dev479.dist-info → prediction_market_agent_tooling-0.62.0.dist-info}/WHEEL +0 -0
  50. {prediction_market_agent_tooling-0.61.2.dev479.dist-info → prediction_market_agent_tooling-0.62.0.dist-info}/entry_points.txt +0 -0
@@ -1,5 +1,7 @@
1
1
  from pydantic import BaseModel, Field
2
2
 
3
+ from prediction_market_agent_tooling.gtypes import CollateralToken
4
+
3
5
 
4
6
  class MarketFees(BaseModel):
5
7
  bet_proportion: float = Field(
@@ -32,5 +34,7 @@ class MarketFees(BaseModel):
32
34
  total_fee = self.total_fee_absolute_value(bet_amount)
33
35
  return total_fee / bet_amount
34
36
 
35
- def get_bet_size_after_fees(self, bet_amount: float) -> float:
36
- return bet_amount - self.total_fee_absolute_value(bet_amount)
37
+ def get_after_fees(self, bet_amount: CollateralToken) -> CollateralToken:
38
+ return bet_amount - CollateralToken(
39
+ self.total_fee_absolute_value(bet_amount.value)
40
+ )
@@ -6,20 +6,19 @@ from web3 import Web3
6
6
  from prediction_market_agent_tooling.gtypes import (
7
7
  USD,
8
8
  ChecksumAddress,
9
+ CollateralToken,
9
10
  HexAddress,
10
11
  HexBytes,
11
12
  HexStr,
12
- OmenOutcomeToken,
13
+ OutcomeStr,
14
+ OutcomeWei,
13
15
  Probability,
14
16
  Wei,
15
- wei_type,
16
17
  xDai,
18
+ xDaiWei,
17
19
  )
18
20
  from prediction_market_agent_tooling.markets.data_models import (
19
21
  Bet,
20
- BetAmount,
21
- Currency,
22
- ProfitAmount,
23
22
  Resolution,
24
23
  ResolvedBet,
25
24
  )
@@ -28,6 +27,7 @@ from prediction_market_agent_tooling.tools.contract import (
28
27
  init_collateral_token_contract,
29
28
  to_gnosis_chain_contract,
30
29
  )
30
+ from prediction_market_agent_tooling.tools.tokens.usd import get_token_in_usd
31
31
  from prediction_market_agent_tooling.tools.utils import (
32
32
  BPS_CONSTANT,
33
33
  DatetimeUTC,
@@ -35,11 +35,13 @@ from prediction_market_agent_tooling.tools.utils import (
35
35
  should_not_happen,
36
36
  utcnow,
37
37
  )
38
- from prediction_market_agent_tooling.tools.web3_utils import wei_to_xdai
39
38
 
40
- OMEN_TRUE_OUTCOME = "Yes"
41
- OMEN_FALSE_OUTCOME = "No"
42
- OMEN_BINARY_MARKET_OUTCOMES = [OMEN_TRUE_OUTCOME, OMEN_FALSE_OUTCOME]
39
+ OMEN_TRUE_OUTCOME = OutcomeStr("Yes")
40
+ OMEN_FALSE_OUTCOME = OutcomeStr("No")
41
+ OMEN_BINARY_MARKET_OUTCOMES: t.Sequence[OutcomeStr] = [
42
+ OMEN_TRUE_OUTCOME,
43
+ OMEN_FALSE_OUTCOME,
44
+ ]
43
45
  INVALID_ANSWER = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
44
46
  INVALID_ANSWER_HEX_BYTES = HexBytes(INVALID_ANSWER)
45
47
  INVALID_ANSWER_STR = HexStr(INVALID_ANSWER_HEX_BYTES.hex())
@@ -78,7 +80,7 @@ class Question(BaseModel):
78
80
  title: str
79
81
  data: str
80
82
  templateId: int
81
- outcomes: list[str]
83
+ outcomes: t.Sequence[OutcomeStr]
82
84
  isPendingArbitration: bool
83
85
  openingTimestamp: int
84
86
  answerFinalizedTimestamp: t.Optional[DatetimeUTC] = None
@@ -187,9 +189,9 @@ class OmenPosition(BaseModel):
187
189
  class OmenUserPosition(BaseModel):
188
190
  id: HexBytes
189
191
  position: OmenPosition
190
- balance: Wei
191
- wrappedBalance: Wei
192
- totalBalance: Wei
192
+ balance: OutcomeWei
193
+ wrappedBalance: OutcomeWei
194
+ totalBalance: OutcomeWei
193
195
 
194
196
  @property
195
197
  def redeemable(self) -> bool:
@@ -209,8 +211,6 @@ class OmenMarket(BaseModel):
209
211
  5. redeeming - a user withdraws collateral tokens from the market
210
212
  """
211
213
 
212
- BET_AMOUNT_CURRENCY: t.ClassVar[Currency] = Currency.xDai
213
-
214
214
  id: HexAddress
215
215
  title: str
216
216
  creator: HexAddress
@@ -224,9 +224,9 @@ class OmenMarket(BaseModel):
224
224
  liquidityParameter: Wei
225
225
  usdVolume: USD
226
226
  collateralToken: HexAddress
227
- outcomes: list[str]
228
- outcomeTokenAmounts: list[OmenOutcomeToken]
229
- outcomeTokenMarginalPrices: t.Optional[list[xDai]]
227
+ outcomes: t.Sequence[OutcomeStr]
228
+ outcomeTokenAmounts: list[OutcomeWei]
229
+ outcomeTokenMarginalPrices: t.Optional[list[CollateralToken]]
230
230
  fee: t.Optional[Wei]
231
231
  resolutionTimestamp: t.Optional[int] = None
232
232
  answerFinalizedTimestamp: t.Optional[int] = None
@@ -367,7 +367,11 @@ class OmenMarket(BaseModel):
367
367
  )
368
368
 
369
369
  return Probability(
370
- 1 - self.outcomeTokenAmounts[self.yes_index] / sum(self.outcomeTokenAmounts)
370
+ 1
371
+ - (
372
+ self.outcomeTokenAmounts[self.yes_index]
373
+ / sum(self.outcomeTokenAmounts, start=OutcomeWei(0))
374
+ )
371
375
  )
372
376
 
373
377
  def __repr__(self) -> str:
@@ -466,22 +470,22 @@ class OmenMarket(BaseModel):
466
470
 
467
471
 
468
472
  def calculate_liquidity_parameter(
469
- outcome_token_amounts: list[OmenOutcomeToken],
473
+ outcome_token_amounts: list[OutcomeWei],
470
474
  ) -> Wei:
471
475
  """
472
476
  Converted to Python from https://github.com/protofire/omen-subgraph/blob/f92bbfb6fa31ed9cd5985c416a26a2f640837d8b/src/utils/fpmm.ts#L171.
473
477
  """
474
- amounts_product = 1.0
478
+ amounts_product = Wei(1)
475
479
  for amount in outcome_token_amounts:
476
- amounts_product *= amount
480
+ amounts_product *= amount.as_wei
477
481
  n = len(outcome_token_amounts)
478
- liquidity_parameter = amounts_product ** (1.0 / n)
479
- return wei_type(liquidity_parameter)
482
+ liquidity_parameter = amounts_product.value ** (1.0 / n)
483
+ return Wei(liquidity_parameter)
480
484
 
481
485
 
482
486
  def calculate_marginal_prices(
483
- outcome_token_amounts: list[OmenOutcomeToken],
484
- ) -> list[xDai] | None:
487
+ outcome_token_amounts: list[OutcomeWei],
488
+ ) -> list[CollateralToken] | None:
485
489
  """
486
490
  Converted to Python from https://github.com/protofire/omen-subgraph/blob/f92bbfb6fa31ed9cd5985c416a26a2f640837d8b/src/utils/fpmm.ts#L197.
487
491
  """
@@ -490,19 +494,19 @@ def calculate_marginal_prices(
490
494
  return None
491
495
 
492
496
  n_outcomes = len(outcome_token_amounts)
493
- weights = []
497
+ weights: list[Wei] = []
494
498
 
495
499
  for i in range(n_outcomes):
496
- weight = 1.0
500
+ weight = Wei(1)
497
501
  for j in range(n_outcomes):
498
502
  if i != j:
499
- weight *= outcome_token_amounts[j]
503
+ weight *= outcome_token_amounts[j].as_wei.value
500
504
  weights.append(weight)
501
505
 
502
- sum_weights = sum(weights)
506
+ sum_weights = sum(weights, start=Wei(0))
503
507
 
504
- marginal_prices = [weights[i] / sum_weights for i in range(n_outcomes)]
505
- return [xDai(mp) for mp in marginal_prices]
508
+ marginal_prices = [weights[i].value / sum_weights.value for i in range(n_outcomes)]
509
+ return [CollateralToken(mp) for mp in marginal_prices]
506
510
 
507
511
 
508
512
  class OmenBetCreator(BaseModel):
@@ -513,22 +517,25 @@ class OmenBet(BaseModel):
513
517
  id: HexAddress # A concatenation of: FPMM contract ID, trader ID and nonce. See https://github.com/protofire/omen-subgraph/blob/f92bbfb6fa31ed9cd5985c416a26a2f640837d8b/src/FixedProductMarketMakerMapping.ts#L109
514
518
  title: str
515
519
  collateralToken: HexAddress
516
- outcomeTokenMarginalPrice: xDai
517
- oldOutcomeTokenMarginalPrice: xDai
520
+ outcomeTokenMarginalPrice: CollateralToken
521
+ oldOutcomeTokenMarginalPrice: CollateralToken
518
522
  type: str
519
523
  creator: OmenBetCreator
520
524
  creationTimestamp: int
521
525
  collateralAmount: Wei
522
526
  feeAmount: Wei
523
527
  outcomeIndex: int
524
- outcomeTokensTraded: Wei
528
+ outcomeTokensTraded: OutcomeWei
525
529
  transactionHash: HexBytes
526
530
  fpmm: OmenMarket
527
531
 
528
532
  @property
529
- def collateral_amount_usd(self) -> USD:
530
- # Convert manually instad of using the field `collateralAmountUSD` available on the graph, because it's bugged, it's 0 for non-xDai markets.
531
- return USD(wei_to_xdai(self.collateralAmount))
533
+ def collateral_amount_token(self) -> CollateralToken:
534
+ return self.collateralAmount.as_token
535
+
536
+ @property
537
+ def collateral_token_checksummed(self) -> ChecksumAddress:
538
+ return Web3.to_checksum_address(self.collateralToken)
532
539
 
533
540
  @property
534
541
  def creation_datetime(self) -> DatetimeUTC:
@@ -548,23 +555,25 @@ class OmenBet(BaseModel):
548
555
  # Marginal price is the probability of the outcome after placing this bet.
549
556
  return Probability(float(self.outcomeTokenMarginalPrice))
550
557
 
551
- def get_profit(self) -> ProfitAmount:
552
- bet_amount_xdai = wei_to_xdai(self.collateralAmount)
558
+ def get_collateral_amount_usd(self) -> USD:
559
+ return get_token_in_usd(
560
+ self.collateral_amount_token, self.collateral_token_checksummed
561
+ )
562
+
563
+ def get_profit(self) -> CollateralToken:
564
+ bet_amount = self.collateral_amount_token
553
565
  profit = (
554
- wei_to_xdai(self.outcomeTokensTraded) - bet_amount_xdai
566
+ self.outcomeTokensTraded.as_outcome_token.as_token - bet_amount
555
567
  if self.boolean_outcome == self.fpmm.boolean_outcome
556
- else -bet_amount_xdai
557
- )
558
- return ProfitAmount(
559
- amount=profit,
560
- currency=Currency.xDai,
568
+ else -bet_amount
561
569
  )
570
+ return profit
562
571
 
563
572
  def to_bet(self) -> Bet:
564
573
  return Bet(
565
574
  id=str(self.transactionHash),
566
575
  # Use the transaction hash instead of the bet id - both are valid, but we return the transaction hash from the trade functions, so be consistent here.
567
- amount=BetAmount(amount=self.collateral_amount_usd, currency=Currency.xDai),
576
+ amount=self.collateral_amount_token,
568
577
  outcome=self.boolean_outcome,
569
578
  created_time=self.creation_datetime,
570
579
  market_question=self.title,
@@ -580,7 +589,7 @@ class OmenBet(BaseModel):
580
589
  return ResolvedBet(
581
590
  id=self.transactionHash.hex(),
582
591
  # Use the transaction hash instead of the bet id - both are valid, but we return the transaction hash from the trade functions, so be consistent here.
583
- amount=BetAmount(amount=self.collateral_amount_usd, currency=Currency.xDai),
592
+ amount=self.collateral_amount_token,
584
593
  outcome=self.boolean_outcome,
585
594
  created_time=self.creation_datetime,
586
595
  market_question=self.title,
@@ -658,7 +667,7 @@ class RealityResponse(BaseModel):
658
667
  answer: HexBytes
659
668
  isUnrevealed: bool
660
669
  isCommitment: bool
661
- bond: Wei
670
+ bond: xDaiWei
662
671
  user: HexAddress
663
672
  historyHash: HexBytes
664
673
  question: RealityQuestion
@@ -667,7 +676,7 @@ class RealityResponse(BaseModel):
667
676
 
668
677
  @property
669
678
  def bond_xdai(self) -> xDai:
670
- return wei_to_xdai(self.bond)
679
+ return self.bond.as_xdai
671
680
 
672
681
  @property
673
682
  def user_checksummed(self) -> ChecksumAddress:
@@ -684,7 +693,7 @@ class RealityAnswersResponse(BaseModel):
684
693
 
685
694
  def format_realitio_question(
686
695
  question: str,
687
- outcomes: list[str],
696
+ outcomes: t.Sequence[str],
688
697
  category: str,
689
698
  language: str,
690
699
  template_id: int,
@@ -711,7 +720,7 @@ def parse_realitio_question(question_raw: str, template_id: int) -> "ParsedQuest
711
720
  """If you add a new template id here, also add to the encoding function above."""
712
721
  if template_id == 2:
713
722
  question, outcomes_raw, category, language = question_raw.split("␟")
714
- outcomes = [o.strip('"') for o in outcomes_raw.split(",")]
723
+ outcomes = [OutcomeStr(o.strip('"')) for o in outcomes_raw.split(",")]
715
724
  return ParsedQuestion(
716
725
  question=question, outcomes=outcomes, category=category, language=language
717
726
  )
@@ -721,7 +730,7 @@ def parse_realitio_question(question_raw: str, template_id: int) -> "ParsedQuest
721
730
 
722
731
  class ParsedQuestion(BaseModel):
723
732
  question: str
724
- outcomes: list[str]
733
+ outcomes: t.Sequence[OutcomeStr]
725
734
  language: str
726
735
  category: str
727
736
 
@@ -783,13 +792,13 @@ class ConditionPreparationEvent(BaseModel):
783
792
 
784
793
  class FPMMFundingAddedEvent(BaseModel):
785
794
  funder: HexAddress
786
- amountsAdded: list[OmenOutcomeToken]
795
+ amountsAdded: list[Wei]
787
796
  sharesMinted: Wei
788
797
 
789
798
  @property
790
- def outcome_token_amounts(self) -> list[OmenOutcomeToken]:
799
+ def outcome_token_amounts(self) -> list[OutcomeWei]:
791
800
  # Just renaming so we remember what it is.
792
- return self.amountsAdded
801
+ return [OutcomeWei(x.value) for x in self.amountsAdded]
793
802
 
794
803
 
795
804
  class CreatedMarket(BaseModel):
@@ -801,7 +810,7 @@ class CreatedMarket(BaseModel):
801
810
  condition_event: ConditionPreparationEvent | None
802
811
  initial_funds: Wei
803
812
  fee: Wei
804
- distribution_hint: list[OmenOutcomeToken] | None
813
+ distribution_hint: list[OutcomeWei] | None
805
814
 
806
815
  @property
807
816
  def url(self) -> str: