Skip to content

BUG: protected BUY market orders can become unfillable due to round_up in _compute_market_order_amounts #300

Description

@FluxNimbusAi

Bug

When prepare_market_order_draft encounters a protected BUY (where max_price is set), _compute_market_order_amounts() uses round_up for the final taker-amount step after verifying the implied price would exceed max_price. Since implied price = maker / taker, inflating taker drives the implied price below max_price, making the order unfillable at the target ask level.

Example

  • Amount: 1 USD, Price: $0.07/share
  • Current behavior: round_up(0.07 * 1e6, ...) → 14,285,714 shares
  • Implied price: $1,000,000 / 14,285,714 = $0.06999… (below target, unfillable)
  • Fix: round_down → implied ≥ $0.07 (fillable)

Root Cause File

src/polymarket/_internal/actions/orders/market.py line ~364 in _compute_market_order_amounts():

if decimal_places(raw_taker) > config.amount:
    raw_taker = (
        round_up(raw_taker, config.amount)      # BUG: should be round_down
        if protect_price
        else round_down(raw_taker, config.amount)
    )

Proposed Fix

Remove protect_price parameter, use round_down uniformly. This matches:

  • The unprotected path (already uses round_down)
  • TypeScript reference implementation
  • py-clob-client v0.34.6 fix (PR #323)

Reproduction

Any protected BUY market order where raw_maker * price produces a result requiring decimal truncation will exhibit the bug. Problematic prices include any fraction with repeating decimals in base-10 (all primes except 2 and 5): 0.03, 0.07, 0.11, 0.13, 0.17, 0.19, 0.23, 0.29, etc.

Tests

Comprehensive test suite in tests/unit/test_issue_292_rounding_fix.py covering 24 irrational-pricer cases across 2dp and 3dp tick markets. All tests pass with the fix applied.

Related

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions