UseDocumentation Index
Fetch the complete documentation index at: https://docs.simmer.markets/llms.txt
Use this file to discover all available pages before exploring further.
client.ensure_can_trade() alongside position sizing: sizing decides how much, this pre-flight decides whether to trade at all given current wallet balance.
client.ensure_can_trade()
A one-call pre-flight that catches underfunded wallets before you try to place an order. Every rejected trade round-trips to the backend, logs a failure, and gets retried on the next cron tick — replacing the loop with a single status fetch per run is a pure win for skill reliability and observability.
Available in
simmer-sdk >= 0.11.1. Collateral-agnostic — reads pUSD on V2 (post-2026-04-28 cutover), USDC.e on V1, so it keeps working across the migration without any code change on your side.Quick start
Arguments
| Arg | Default | Meaning |
|---|---|---|
min_usd | 1.0 | Minimum viable trade size in active collateral. Below this, ok=False. |
venue | client’s venue | Only "polymarket" runs the check. Other venues short-circuit to ok=True. |
safety_buffer | 0.02 | Fraction of balance kept as fee/slippage buffer. max_safe_size = balance × (1 − safety_buffer). |
Returns
A dict with the following keys:| Field | Meaning |
|---|---|
ok | True if balance ≥ min_usd (or non-polymarket venue). |
balance | Active collateral balance in USD-equivalent units. |
collateral | "pUSD" (V2), "USDC.e" (V1), or "" (non-polymarket). |
exchange_version | "v1" or "v2" — matches server-side flag. |
reason | "ok", "insufficient_balance", "no_wallet", "balance_unavailable", or "skipped_non_polymarket". |
max_safe_size | balance × (1 − safety_buffer), or 0.0 when ok=False. |
When to call it
Callensure_can_trade() once per skill run, before any market discovery or signal generation. Running it at the top of your loop costs one REST call and eliminates every downstream rejected order when the wallet is under-funded.
- Underfunded → emit a skip report (
skip_reason="insufficient_balance") andreturn. The automaton reporter will surface this cleanly, distinct from “skill broken.” - Sized correctly → clamp your per-run
MAX_BET_USD(or equivalent) tomax_safe_sizeso you leave headroom for fees + price slippage.
Why not just trust client.get_portfolio()?
You can — but ensure_can_trade() bundles three things you’d otherwise re-implement in every skill:
- Collateral-agnostic balance selection: reads the correct token for the active
exchange_version(pUSD on V2, USDC.e on V1). - Failure-mode distinction: returns a stable
reasonstring across RPC outages, missing wallets, and genuine zero-balance cases. - Safety buffer math: the
max_safe_sizereturn is already clamped for fees and slippage — no off-by-one between skills.
Sell pre-flight pattern
ensure_can_trade() covers buys (do I have collateral?). For sells, the equivalent pre-flight is “re-fetch positions immediately before each attempt.” This catches the most common sell-side bug: a stop-loss / take-profit loop that fires every N seconds with a cached shares value, then submits stale orders after a previous sell already filled. Polymarket rejects the second attempt with Insufficient shares to sell.
Pattern
polymarket-weather-trader skill uses this pattern in its exit logic.
