Skip to content
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

Auto-verify that buy trades wouldn't cause guaranted loss #488

Merged
merged 7 commits into from
Oct 17, 2024
Merged

Conversation

kongzii
Copy link
Contributor

@kongzii kongzii commented Oct 10, 2024

No description provided.

Copy link

coderabbitai bot commented Oct 10, 2024

Walkthrough

The pull request introduces enhancements to the BettingStrategy class and its subclasses in the betting_strategy.py file. A new static method, assert_buy_trade_wont_be_guaranteed_loss, is added to check for guaranteed losses in buy trades. The check_trades method consolidates previous checks into one. The MaxAccuracyBettingStrategy class's calculate_trades method is updated to include a liquidity constraint, while the KellyBettingStrategy class gains two new methods for calculating bet amounts and price impacts.

Changes

File Path Change Summary
prediction_market_agent_tooling/deploy/betting_strategy.py - Added assert_buy_trade_wont_be_guaranteed_loss and check_trades methods in BettingStrategy.
- Updated calculate_trades in MaxAccuracyBettingStrategy to include liquidity check.
- Added calculate_bet_amount_for_price_impact and calculate_price_impact_for_bet_amount methods in KellyBettingStrategy.
prediction_market_agent_tooling/markets/agent_market.py - Added get_buy_token_amount method in AgentMarket.
- Corrected indentation of buy_tokens method.
tests/test_betting_strategy.py - Added liquidity_amount variable in test_rebalance.
- Introduced test_attacking_market for testing strategy behavior under varying conditions.

Possibly related PRs

Suggested reviewers

  • evangriffiths

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (2)
prediction_market_agent_tooling/deploy/betting_strategy.py (2)

Line range hint 192-200: Add error handling for potential division by zero.

In the calculate_price_impact_for_bet_amount method, total_outcome_tokens is calculated as yes + no. If both yes and no are zero, this will result in a division by zero when computing expected_price and subsequently price_impact.

Consider adding a check to prevent division by zero:

Apply this diff to handle the division by zero case:

     total_outcome_tokens = yes + no
+    if total_outcome_tokens == 0:
+        raise ValueError("Total outcome tokens cannot be zero.")
     expected_price = (
         no / total_outcome_tokens if buy_direction else yes / total_outcome_tokens
     )

Line range hint 210-221: Verify optimization success before using the result.

In the calculate_bet_amount_for_price_impact method, after calling minimize_scalar, the optimization might fail to converge. Using optimized_bet_amount.x without checking can lead to unexpected behavior.

Ensure that the optimization was successful before proceeding.

Apply this diff to check the optimization result:

     optimized_bet_amount = minimize_scalar(
         calculate_price_impact_deviation_from_target_price_impact,
         bounds=(0, 1000 * (yes_outcome_pool_size + no_outcome_pool_size)),
         method="bounded",
         tol=1e-11,
         options={"maxiter": 10000},
     )
+    if not optimized_bet_amount.success:
+        logger.warning("Optimization did not converge. Using original Kelly bet size.")
+        return kelly_bet.size
     return float(optimized_bet_amount.x)
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 3ccf31a and c30b7dc.

📒 Files selected for processing (1)
  • prediction_market_agent_tooling/deploy/betting_strategy.py (1 hunks)
🧰 Additional context used

prediction_market_agent_tooling/deploy/betting_strategy.py Outdated Show resolved Hide resolved
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (2)
tests/test_betting_strategy.py (2)

37-37: LGTM! Consider adding a comment explaining the liquidity amount.

The introduction of liquidity_amount enhances the test by providing a realistic liquidity context. This aligns well with the PR objective of fixing the bet amount for MaxAccuracyBettingStrategy.

Consider adding a brief comment explaining why 100 xDai was chosen as the liquidity amount. This would help other developers understand the reasoning behind this specific value.


Line range hint 1-63: Overall, the changes enhance the test case effectively.

The introduction of the liquidity context in the test_rebalance function aligns well with the PR objective of fixing the bet amount for MaxAccuracyBettingStrategy. The changes are minimal, focused, and do not introduce unnecessary complexity to the test suite.

Consider adding a new test case that specifically verifies the behavior of MaxAccuracyBettingStrategy with different liquidity scenarios. This would further strengthen the test coverage for the bet amount fix.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between c30b7dc and 2bdb66c.

📒 Files selected for processing (1)
  • tests/test_betting_strategy.py (2 hunks)
🧰 Additional context used
🔇 Additional comments (1)
tests/test_betting_strategy.py (1)

49-49: LGTM! Verify the impact on the test assertions.

The update to mock_market.get_liquidity to return the liquidity_amount is consistent with the introduction of the liquidity context. This change enhances the realism of the test scenario for the MaxAccuracyBettingStrategy.

Please verify that the existing assertions in the test case (lines 56-63) still hold true with this new liquidity context. Run the following script to check if there are any assertions that might need updating:

If the script reveals any assertions that might be affected by the new liquidity context, please review and update them accordingly.

@kongzii kongzii changed the title Bet amount fix for MaxAccuracyBettingStrategy Auto-verify that buy trades wouldn't cause guaranted loss Oct 14, 2024
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Outside diff range and nitpick comments (3)
tests/test_betting_strategy.py (2)

52-52: LGTM! Consider parameterizing the liquidity amount.

The addition of liquidity_amount enhances the test by introducing a realistic liquidity constraint. This aligns well with the PR objective of auto-verifying that buy trades wouldn't cause guaranteed loss.

Consider parameterizing the liquidity amount to allow for more comprehensive testing across different liquidity scenarios. This could be achieved by adding a parameter to the test function or using pytest's parametrize decorator.

Also applies to: 64-64


82-143: Excellent addition of comprehensive test cases!

The new test_attacking_market function significantly enhances the test coverage by checking various edge cases related to market conditions. It directly addresses the PR objective of auto-verifying that buy trades wouldn't cause guaranteed loss.

The use of parameterized testing is a great practice for covering multiple scenarios efficiently. The test cases cover both positive and negative scenarios, which is crucial for thorough testing.

Consider adding a comment or docstring to explain the reasoning behind each test case in the parametrize decorator. This would make it easier for other developers to understand the purpose of each scenario and potentially add more test cases in the future.

prediction_market_agent_tooling/markets/agent_market.py (1)

169-172: Approve the addition of get_buy_token_amount method with a suggestion for improvement.

The new get_buy_token_amount method is a good addition to the AgentMarket class. It provides a way to convert a bet amount to a token amount, which is essential for market operations.

Consider adding a docstring to clarify the purpose of the method and explain the direction parameter. Here's a suggested implementation:

def get_buy_token_amount(
    self, bet_amount: BetAmount, direction: bool
) -> TokenAmount:
    """
    Convert a bet amount to a token amount for a buy operation.

    Args:
        bet_amount (BetAmount): The amount of the bet.
        direction (bool): The direction of the bet (True for YES, False for NO).

    Returns:
        TokenAmount: The amount of tokens to be bought.

    Raises:
        NotImplementedError: This method should be implemented by subclasses.
    """
    raise NotImplementedError("Subclasses must implement this method")
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 2bdb66c and 49b9dc3.

📒 Files selected for processing (3)
  • prediction_market_agent_tooling/deploy/betting_strategy.py (2 hunks)
  • prediction_market_agent_tooling/markets/agent_market.py (1 hunks)
  • tests/test_betting_strategy.py (4 hunks)
🧰 Additional context used
🔇 Additional comments (5)
tests/test_betting_strategy.py (2)

24-30: LGTM! Imports and file structure are well-organized.

The new imports for OMEN-related classes and contracts are necessary for the added functionality in the test_attacking_market function. The file structure maintains good practices by grouping related imports and keeping a clear separation between different test functions.


Line range hint 1-143: Overall, excellent additions to the test suite!

The changes in this file significantly enhance the test coverage for the MaxAccuracyBettingStrategy class, particularly in relation to market conditions that could potentially lead to guaranteed losses. The new test_attacking_market function, along with the addition of liquidity constraints in the existing test_rebalance function, directly address the PR objective of auto-verifying that buy trades wouldn't cause guaranteed loss.

The code is well-structured, follows good testing practices, and effectively uses parameterized testing to cover multiple scenarios. These improvements will greatly contribute to the robustness of the betting strategy implementation.

prediction_market_agent_tooling/markets/agent_market.py (1)

Line range hint 1-324: Summary of changes and their impact.

The changes made to the AgentMarket class are minimal but significant:

  1. The addition of the get_buy_token_amount method provides a new abstraction layer for converting bet amounts to token amounts.
  2. This new method aligns well with the existing structure and purpose of the class.
  3. There's potential for refactoring the buy_tokens method to use the new get_buy_token_amount method, which could improve consistency and reduce duplication.

Overall, these changes enhance the flexibility and extensibility of the AgentMarket class, allowing for more specific implementations in subclasses.

prediction_market_agent_tooling/deploy/betting_strategy.py (2)

66-70: Consolidation of trade checks enhances maintainability

The new check_trades method effectively consolidates trade validations, improving code organization and reducing redundancy. This approach enhances maintainability and readability.


119-122: Ensure check_trades does not introduce unintended side effects

Calling BettingStrategy.check_trades(market, trades) after building the trades adds an extra validation step, which is beneficial for preventing unreasonable bets. However, confirm that this additional check does not introduce performance bottlenecks or alter the behavior in edge cases, especially in high-frequency trading scenarios.

If needed, run performance benchmarks to assess the impact:

Comment on lines 174 to 175
def sell_tokens(self, outcome: bool, amount: TokenAmount) -> str:
raise NotImplementedError("Subclasses must implement this method")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider refactoring buy_tokens to use get_buy_token_amount.

The buy_tokens method could potentially be refactored to use the newly added get_buy_token_amount method. This would improve consistency and reduce potential duplication of logic. Here's a suggested implementation:

def buy_tokens(self, outcome: bool, amount: TokenAmount) -> str:
    bet_amount = self.get_bet_amount(amount.amount)
    token_amount = self.get_buy_token_amount(bet_amount, outcome)
    return self.place_bet(outcome=outcome, amount=token_amount)

This refactoring assumes that get_buy_token_amount will be implemented in subclasses to handle the conversion from BetAmount to TokenAmount. Please verify if this aligns with the intended usage of get_buy_token_amount.

@kongzii kongzii mentioned this pull request Oct 17, 2024
@kongzii kongzii merged commit fb5bd28 into main Oct 17, 2024
14 checks passed
@kongzii kongzii deleted the peter/betfix branch October 17, 2024 13:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants