-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow to submit job results #541
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,15 +1,14 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import typing as t | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from web3 import Web3 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from prediction_market_agent_tooling.config import APIKeys | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from prediction_market_agent_tooling.deploy.betting_strategy import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Currency, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
KellyBettingStrategy, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
ProbabilisticAnswer, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
TradeType, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from prediction_market_agent_tooling.gtypes import Probability | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from prediction_market_agent_tooling.jobs.jobs_models import JobAgentMarket | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from prediction_market_agent_tooling.markets.agent_market import ProcessedTradedMarket | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from prediction_market_agent_tooling.markets.data_models import PlacedTrade, Trade | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
from prediction_market_agent_tooling.markets.omen.omen import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
BetAmount, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OmenAgentMarket, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -36,7 +35,20 @@ def deadline(self) -> DatetimeUTC: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return self.close_time | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def get_reward(self, max_bond: float) -> float: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return compute_job_reward(self, max_bond) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
trade = self.get_job_trade( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
max_bond, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
result="", # Pass empty result, as we are computing only potential reward at this point. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
reward = ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.get_buy_token_amount( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bet_amount=BetAmount( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
amount=trade.amount.amount, currency=trade.amount.currency | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
direction=trade.outcome, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
).amount | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- trade.amount.amount | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return reward | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@classmethod | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def get_jobs( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -50,6 +62,45 @@ def get_jobs( | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return [OmenJobAgentMarket.from_omen_market(market) for market in markets] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@staticmethod | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def get_job(id: str) -> "OmenJobAgentMarket": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return OmenJobAgentMarket.from_omen_agent_market( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
OmenJobAgentMarket.get_binary_market(id=id) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def submit_job_result(self, max_bond: float, result: str) -> ProcessedTradedMarket: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
trade = self.get_job_trade(max_bond, result) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
buy_id = self.buy_tokens(outcome=trade.outcome, amount=trade.amount) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
processed_traded_market = ProcessedTradedMarket( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
answer=self.get_job_answer(result), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
trades=[PlacedTrade.from_trade(trade, id=buy_id)], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+84
to
+85
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Implement the The method Consider adding the following implementation: def get_job_answer(self, result: str) -> bool:
# Convert the result string to the expected answer format
return result.lower() == "yes" Also applies to: 84-84 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
keys = APIKeys() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
self.store_trades(processed_traded_market, keys) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return processed_traded_market | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add error handling for token purchase operation. The def submit_job_result(self, max_bond: float, result: str) -> ProcessedTradedMarket:
trade = self.get_job_trade(max_bond, result)
- buy_id = self.buy_tokens(outcome=trade.outcome, amount=trade.amount)
+ try:
+ buy_id = self.buy_tokens(outcome=trade.outcome, amount=trade.amount)
+ except Exception as e:
+ raise ValueError(f"Failed to purchase tokens: {str(e)}") from e 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def get_job_trade(self, max_bond: float, result: str) -> Trade: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Because jobs are powered by prediction markets, potentional reward depends on job's liquidity and our will to bond (bet) our xDai into our job completion. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strategy = KellyBettingStrategy(max_bet_amount=max_bond) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
required_trades = strategy.calculate_trades( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
existing_position=None, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
answer=self.get_job_answer(result), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
market=self, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
assert ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
len(required_trades) == 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
), f"Shouldn't process same job twice: {required_trades}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
trade = required_trades[0] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
assert trade.trade_type == TradeType.BUY, "Should only buy on job markets." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
assert trade.outcome, "Should buy only YES on job markets." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
assert ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
trade.amount.currency == Currency.xDai | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+105
to
+108
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Replace assertions with explicit exception handling The assertions in Consider replacing the assertions with exceptions: if trade.trade_type != TradeType.BUY:
raise ValueError("Only 'BUY' trade types are supported on job markets.")
if not trade.outcome:
raise ValueError("Trade outcome must be 'YES' on job markets.")
if trade.amount.currency != Currency.xDai:
raise ValueError("Only xDai currency is supported for trades.") |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
), "Should work only on real-money markets." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return required_trades[0] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
@staticmethod | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def from_omen_market(market: OmenMarket) -> "OmenJobAgentMarket": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return OmenJobAgentMarket.from_omen_agent_market( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -77,38 +128,3 @@ def from_omen_agent_market(market: OmenAgentMarket) -> "OmenJobAgentMarket": | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
finalized_time=market.finalized_time, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
fees=market.fees, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
def compute_job_reward( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
market: OmenAgentMarket, max_bond: float, web3: Web3 | None = None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) -> float: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# Because jobs are powered by prediction markets, potentional reward depends on job's liquidity and our will to bond (bet) our xDai into our job completion. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
strategy = KellyBettingStrategy(max_bet_amount=max_bond) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
required_trades = strategy.calculate_trades( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
existing_position=None, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
# We assume that we finish the job and so the probability of the market happening will be 100%. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
answer=ProbabilisticAnswer(p_yes=Probability(1.0), confidence=1.0), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
market=market, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
assert ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
len(required_trades) == 1 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
), f"Shouldn't process same job twice: {required_trades}" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
trade = required_trades[0] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
assert trade.trade_type == TradeType.BUY, "Should only buy on job markets." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
assert trade.outcome, "Should buy only YES on job markets." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
assert ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
trade.amount.currency == Currency.xDai | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
), "Should work only on real-money markets." | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
reward = ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
market.get_buy_token_amount( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
bet_amount=BetAmount( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
amount=trade.amount.amount, currency=trade.amount.currency | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
direction=trade.outcome, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
).amount | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
- trade.amount.amount | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return reward |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add basic validation for job result
The method assumes 100% confidence without validating the result. Consider adding basic validation to ensure the result is not empty or malformed before assuming perfect confidence.
📝 Committable suggestion