Polytraders Dev Guide
internal
v3 spine Phase 1 · Shared contracts 9 demo-wired · 0 shadow-ready · 0 production-live · 100 pending · 109 total 15/33 infra tasks the plan status board
HomeBy LayerExecution2.14 FeeSlippageEstimator

2.14 FeeSlippageEstimator

Execution ExecutionUtility Annotate PLANNED Spec ready capital · Direct P5 · Execution rails pending stub

Stamps every approved OrderIntent with an explicit fee + slippage estimate before the order shaper sees it. The estimate is a structured object (maker_fee_bps, taker_fee_bps, expected_slippage_bps, total_cost_usd) that downstream tools and UIs all read instead of guessing.

v3 readiness

Docs27/27
donehow scored
Impl0/15
pendinghow scored
Backtest0/4
pendinghow scored
Runtime0/8
pendinghow scored

A bot is done when all four scores are. What does done mean?

1. Bot Identity

LayerExecution  Execution
Bot classExecutionUtility
AuthorityAnnotate
StatusPLANNED
ReadinessSpec ready
Runs beforeexec.smart_router, exec.order_shaper
Runs afterintel.orderflowanalyzer
Applies toPer OrderIntent
Default modeshadow
User-visibleYes
Developer ownerExecution pod

Operational profile

OwnershipExecution pod · on-call exec-oncall · #polytraders-exec · escalates to Head of Execution · P2
Latency budgetp50: 4ms · p99: 15ms
Modes supportedoffshadowadvisoryenforcedquarantine
Data freshnessmax_market_data_age_ms=2000 · max_orderbook_age_ms=2000 · on stale → Stamp cost_estimate with method='conservative_default'.
Human overrideno · by · logs · time-bound: — · scope: — · single approver

2. Purpose

Stamps every approved OrderIntent with an explicit fee + slippage estimate before the order shaper sees it. The estimate is a structured object (maker_fee_bps, taker_fee_bps, expected_slippage_bps, total_cost_usd) that downstream tools and UIs all read instead of guessing.

3. Why This Bot Matters

  • Hidden cost surprises

    Without a per-order estimate, post-trade reports are the first place anyone learns the order was unprofitable after fees.

  • Inconsistent cost models

    Each strategy inventing its own cost estimate produces inconsistent reports and dashboards.

  • Affiliate/builderCode accounting

    The builder-fee component on V2 must be visible per order to track attribution correctly.

No worked examples on this bot yet. Worked examples are optional but strongly recommended — they turn an abstract failure mode into something a developer can verify in a fixture.

4. Required Polymarket Inputs

InputSourceRequired?Use
Live OrderBookSnapshotintel.orderflowanalyzerYesEstimate slippage from depth profile.
Polymarket fee schedule (maker/taker/builder)ConfigYesCurrent tier fees.

5. Required Internal Inputs

InputSourceRequired?Use
OrderIntentStrategy botYesThe order to estimate.
Market microstructure priorintel.liquidity_decay_monitorNoImproves slippage estimate when available.

6. Parameter Guide

ParameterDefaultWarningHardWhat it controls
maker_fee_bps0Polymarket maker fee in basis points (0 today on V2 binary).
taker_fee_bps200250400Polymarket taker fee in basis points.
builder_fee_bps0Polytraders builderCode fee in basis points.
slippage_safety_factor1.51.03.0Multiplier applied to the linear slippage estimate to account for adverse selection.

7. Detailed Parameter Instructions

maker_fee_bps

What it means

Polymarket maker fee in basis points (0 today on V2 binary).

Default

{ "maker_fee_bps": 0 }

Why this default matters

Polymarket V2 currently does not charge a maker fee on binary markets.

Threshold logic

ConditionAction
0Default

Developer check

fee += notional * p.maker_fee_bps/10000;

User-facing English

(Internal.)

taker_fee_bps

What it means

Polymarket taker fee in basis points.

Default

{ "taker_fee_bps": 200 }

Why this default matters

200 bps (2%) is the V2 binary taker default.

Threshold logic

ConditionAction
200Default

Developer check

fee += notional * p.taker_fee_bps/10000;

User-facing English

(Internal.)

builder_fee_bps

What it means

Polytraders builderCode fee in basis points.

Default

{ "builder_fee_bps": 0 }

Why this default matters

Set by config; defaults to 0 until builderCode is registered.

Threshold logic

ConditionAction
0Until registered

Developer check

fee += notional * p.builder_fee_bps/10000;

User-facing English

(Internal.)

slippage_safety_factor

What it means

Multiplier applied to the linear slippage estimate to account for adverse selection.

Default

{ "slippage_safety_factor": 1.5 }

Why this default matters

1.5 is the empirical median across Polymarket binary markets.

Threshold logic

ConditionAction
1.0Optimistic
1.5Default
2.0+Defensive

Developer check

slip_bps *= p.slippage_safety_factor;

User-facing English

(Internal.)

8. Default Configuration

{
  "maker_fee_bps": 0,
  "taker_fee_bps": 200,
  "builder_fee_bps": 0,
  "slippage_safety_factor": 1.5
}

9. Implementation Flow

— not yet authored —

10. Reference Implementation

Pseudocode is language-agnostic. FETCH = read input. EMIT = produce output. IF/THEN/ELSE = decision. Translate directly to TypeScript, Python, Go, or Rust.

depth = walk_book(book, intent.side, intent.price, intent.size_usd)
slip_bps = (depth.vwap - book.mid) / book.mid * 10000 * p.slippage_safety_factor
fee_bps = p.taker_fee_bps + p.builder_fee_bps
stamp(intent, cost_estimate={maker:p.maker_fee_bps, taker:p.taker_fee_bps, builder:p.builder_fee_bps, slip:slip_bps, total_bps:fee_bps+slip_bps, total_usd: ...})

11. Wire Examples

Input — what arrives on the wire

{
  "intent_id": "intent_004",
  "market_id": "0xabc",
  "size_usd": 500,
  "side": "BUY",
  "price": 0.62
}

Output — what the bot emits

{
  "intent_id": "intent_004",
  "cost_estimate": {
    "slippage_bps": 35,
    "total_cost_bps": 235,
    "total_cost_usd": 11.75
  },
  "vote": "ANNOTATE"
}

12. Decision Logic

APPROVE

Compute marketable_depth at intent.price + side. Estimate fill VWAP and slippage_bps. Compute fee_bps from configured schedule. Stamp the OrderIntent and pass it through unchanged otherwise.

RESHAPE_REQUIRED

This bot does not reshape orders.

REJECT

No reject path defined for this bot — it is observe-only.

WARNING_ONLY

No warn-only path defined.

13. Standard Decision Output

This bot returns a RiskVote object. See RiskVote schema.

{
  "intent_id": "intent_004",
  "cost_estimate": {
    "maker_fee_bps": 0,
    "taker_fee_bps": 200,
    "builder_fee_bps": 0,
    "slippage_bps": 35,
    "total_cost_bps": 235,
    "total_cost_usd": 2.35,
    "method": "linear_with_safety_factor"
  },
  "vote": "ANNOTATE"
}

14. Reason Codes

CodeSeverityMeaningActionUser-facing message
EXEC_COST_ESTIMATEDP2Exec Cost EstimatedSee decision output and developer log for context.Estimated total cost of this order, including fees and the price impact of moving the market.
EXEC_COST_FALLBACKP2Exec Cost FallbackSee decision output and developer log for context.Estimated total cost of this order, including fees and the price impact of moving the market.
EXEC_COST_FEE_SCHEDULE_STALEP2Exec Cost Fee Schedule StaleSee decision output and developer log for context.Estimated total cost of this order, including fees and the price impact of moving the market.

15. Metrics & Logs

Metrics emitted

MetricTypeUnitLabelsMeaning
estimates_totalcountereventbot_idEstimates total.
estimated_vs_realised_bps_histogramcountereventbot_idEstimated vs realised bps histogram.
fallback_estimates_totalcountereventbot_idFallback estimates total.

Dashboards

  • 2.14 overview dashboard

16. Developer Reporting

"Per estimate: intent_id, market_id, size_usd, marketable_depth_usd, slippage_bps, fee_bps, total_cost_bps."

17. Plain-English Reporting

SituationUser-facing explanation
When this bot actsEstimated total cost of this order, including fees and the price impact of moving the market.

18. Failure-Mode Block

main_failure_modeUnderestimating slippage for orders larger than top-of-book.
false_positive_riskOver-conservative estimate suppresses orders that would have been profitable; mitigation: track realised vs estimated cost and re-tune safety factor weekly.
false_negative_riskStale fee schedule misses a fee change; mitigation: validate fee schedule against on-chain CTFExchangeV2 storage at startup.
safe_fallbackOn any failure, stamp cost_estimate.method='conservative_default' with a generous flat estimate. Never strip the field.
required_dependencies

19. Failure-Injection Recipes

ScenarioHow to injectExpected behaviourRecovery
Strip the live book and assert fallback estimate is stamped, not absentStrip the live book and assert fallback estimate is stamped, not absent.Bot detects within its latency budget and emits the corresponding reason code.Remove the injected fault; bot returns to healthy state within one debounce window.
Inject a fee-schedule mismatch and assert the stale code firesInject a fee-schedule mismatch and assert the stale code fires.Bot detects within its latency budget and emits the corresponding reason code.Remove the injected fault; bot returns to healthy state within one debounce window.

20. State & Persistence

Stateless. Reads live book + config; no persistence required.

State stores

NameKindKeyValue shapeTTLDurability
fee_slippage_estimator_statein-memory + fast KV mirrorbot_idStateless. Reads live book + config; no persistence required.24hcrash-safe via KV mirror

Cold-start recovery

Cold-start hydrates from fast KV; missing keys default to safe fallback.

On restart

All in-flight decisions are re-evaluated; no bot decision is trusted across restart without re-emit.

21. Concurrency & Idempotency

AspectSpecification
Execution modelPure function over (book, intent, fees). Trivially concurrent.
Max in-flight32
Idempotency keyorder_intent_id
Replay-safeTrue
DeduplicationBy idempotency_key within a 60s window.
Ordering guaranteesPer-market_id FIFO; cross-market unordered.
Per-call timeout (ms)250
Backpressure strategyBounded queue; oldest-dropped with metric increment when full.
Locking / mutual exclusionPer-market_id mutex; no global locks.

22. Dependencies

Depends on (must run first)

Emits to (downstream consumers)

BotWhyContract
exec.smart_router
exec.order_shaper

Requires (graph.requires)

intel.orderflowanalyzer

Required before (graph.required_before)

exec.smart_router exec.order_shaper

ConsumesOrderIntent OrderBookSnapshot
EmitsAnnotatedOrderIntent
Blocks ordersno

23. Security Surfaces

No external surface; reads internal config + live book.

Signing surface

None — bot does not sign or submit.

Mitigations

  • Rate-limit per source
  • Audit-log every override
  • Require role-based authz on admin paths

24. Polymarket V2 Compatibility

AspectValue
CLOB versionV2
Collateral assetpUSD
EIP-712 Exchange domain version2
Aware of builderCode fieldyes
Aware of negative-risk marketsyes
Multi-chain readyyes
SDK usedPolymarket CLOB V2 SDK
Settlement contractCTFExchangeV2
NotesReads V2 fee schedule (maker_fee_bps, taker_fee_bps, builder_fee_bps).

25. Versioning & Migration

FieldValue
current0.1.0
contract_version1.0.0
last_breaking_changenone
deprecation_window_days30

26. Acceptance Tests

Unit Tests

TestSetupExpected result
For an order at top-of-book ≤ depth, slippage estimate is < 5 bps.Synthetic fixture per template.Behaviour matches the rule described in the test name.
For an order > 2x top-of-book depth, slippage estimate exceeds 50 bps.Synthetic fixture per template.Behaviour matches the rule described in the test name.

Integration Tests

TestExpected result
End-to-end: estimate vs realised cost on 100 historical orders agrees within ±25%.End-to-end behaviour matches the spec without manual intervention.

Property Tests

PropertyRequired behaviour
Total cost is monotonically non-decreasing in size_usd for a fixed book.Always true across all generated inputs.

27. Operational Runbook

If estimated-vs-realised drifts > 25%, re-tune slippage_safety_factor on a weekly cadence.

On-call actions

AlertFirst stepDiagnosisMitigationEscalate to
2.14_anomalyOpen the bot's reporting page and confirm the alert is real (not a metric hiccup).Inspect developer log entries for the affected market_id over the last 30 minutes.Force-clear via Admin UI if the rule is clearly stale; otherwise leave engaged and notify owner.Execution pod

Manual overrides

  • polytraders bot pause 2.14 — Disables the bot's enforcement layer; downstream consumers fall back to safe defaults.

Healthcheck

GET /healthz/fee_slippage_estimator → 200 if last successful evaluation < 60s ago.

28. Promotion Gates

A bot does not advance to the next readiness state until every gate below is green. Gates are observable from production data — no subjective sign-off.

Promote to Shadow

GateHow measuredThreshold
Stubdeterministic on synthetic books.Documented threshold met for the full window.

Promote to Limited live

GateHow measuredThreshold
Shadow14 days against historical orders.Documented threshold met for the full window.
Advisory7 days; downstream tools may consume.Documented threshold met for the full window.

Promote to General live

GateHow measuredThreshold
Enforcedrequired field on every OrderIntent.Documented threshold met for the full window.

29. Developer Checklist

Ready-to-ship score: 27/27 sections complete · 100%

RequirementStatus
Purpose defined✓ done
Required inputs listed✓ done
Parameters defined✓ done
Defaults defined✓ done
Warning thresholds defined✓ done
Hard thresholds defined✓ done
Safe fallback defined✓ done
Structured output defined✓ done
Developer log defined✓ done
Plain-English explanation✓ done
Unit tests defined✓ done
Integration tests defined✓ done
Property tests defined✓ done
Failure-mode block complete✓ done
Reference implementation pseudocode✓ done
Wire examples (input + output)✓ done
Reason codes listed✓ done
Metrics & logs defined✓ done
State & persistence defined✓ done
Concurrency & idempotency defined✓ done
Dependencies declared✓ done
Security surfaces declared✓ done
Polymarket V2 compatibility declared✓ done
Version & migration history declared✓ done
Operational runbook defined✓ done
Promotion gates defined✓ done
Failure-injection recipes defined✓ done