- name
- quotient
- description
- Prediction-market intelligence for Polymarket agents. Quotient runs a multi-role AI forecasting pipeline over 1,600+ sources and publishes daily trade signals with side, entry prices, conviction tiers, capacity, and convergence reads. Pull forecasts (with what-changed deltas), recent sources (articles + X posts), the featured signal, the daily WTI crude oil read, and per-wallet portfolio intelligence; execute via Bankr. Pays via x402 in USDC on Base or USDG on Robinhood Chain. Triggers on: "quotient signals", "trade signals", "featured signal", "oil signal", "WTI", "crude", "what's new with my portfolio", "hold or sell", "convergence", "mispriced markets", "what does Q think", "quotient odds", "prediction market intelligence", "polymarket intelligence", "recent sources for", "what markets does quotient have", "market forecast", "should I bet on".
- emoji
- ๐ฎ
- tags
- ["polymarket","prediction-markets","trading","intelligence","x402"]
- version
- 1.0.0
- visibility
- public
- metadata
- {"clawdbot":{"emoji":"๐ฎ","homepage":"https://quotient.social","requires":{"bins":"[Truncated]"}}}
- credentials
- [{"name":"BANKR_API_KEY","description":"Only needed for signal-strategy.mjs --execute (Bankr Agent API key, read-write).","required":false,"storage":"env"}]
<!-- GENERATED from public/skill/skill.md โ edit there, then npm run skill:build -->
# Quotient API Skill
Quotient = intelligence. Bankr = execution. This skill reads Quotient's x402-paid API for
forecasts, published trade signals, sources, the oil read, and wallet portfolio
intelligence, then hands off to Bankr natural-language prompts for any trade. Nothing
here places trades directly.
## Base URL & Discovery
- `QUOTIENT_BASE_URL`: `https://quotient-api-gateway.onrender.com`. The scripts enforce an
exact HTTPS origin allowlist on it โ the default gateway origin is hardcoded, and extra
origins can be added only through the local policy file
(`references/payments-policy.md`), never via env or fetched content.
- Discovery, same origin: `/openapi.json` (canonical routes + params), `GET /api/public/pricing`
(billing metadata), `/llms.txt` (AI index), `/skill/*` (these docs + scripts)
- Treat OpenAPI as canonical invocation metadata; treat the runtime `402` challenge as the
authoritative price.
## How Q Works
Quotient's forecasting agent (Q) runs a multi-role analysis pipeline on every market it
covers: question analysis, research, base-rate analysis, bull/bear advocacy, contrarian
examination, and synthesis, pulling from 1,600+ sources. Each run produces an independent
probability estimate, a BLUF (bottom-line-up-front) thesis, key drivers with citations,
and delta-from-prior reasoning. A separate publisher watches for markets where Q diverges
materially from the venue price and publishes a small number of trade signals per day.
See https://quotient.social for the current live track record.
Coverage is strongest on world-events markets โ Iran, tariffs, elections, central-bank
policy, conflict escalation, diplomatic negotiations. If it moves geopolitical risk, Q
probably has a view.
## Key Concepts
**Markets** โ Prediction markets Quotient covers. Each has a `slug` (Polymarket slug),
question, current `market_odds`, dispute status, and Q's forecast history.
**Forecasts** โ Q's probability estimate for a market, refreshed as new material lands.
Every forecast carries the change primitives: `delta_from_prior` (how much Q moved),
`delta_reasoning` (a deterministic sentence saying why), `refresh_reason` /
`refresh_triggered_by` (non-null = the rerun was triggered, not scheduled), plus
`headline`/`bluf`/`crux` and conviction inputs (`draw_std_log_odds`, `draw_count`,
`band25`/`band75`). "What changed" is read straight off the node โ never inferred.
**Trade signals** โ Published `:QuotientSignal` entries: Q's actual calls, a handful per
day. A signal can remain active for up to seven days; the latest forecast can refresh many
times during that hold. Read `published_at`/`is_new_today` for publication context,
`forecast_updated_at`/`is_fresh` for research freshness (six-hour threshold), and
`is_active` for lifecycle state. The `/signals` `window` filters forecast updates, not
publication time, and its default feed omits `paused`, `done`, and `retired`
rows. It returns at most one signal per market: the newest publication is selected before
side/status/conviction filters, with no fallback to an older signal when that newest call is
ineligible. Each signal also has a `side` (YES/NO), entry prices (`entry_q` = Q at publish,
`entry_pm` = market at publish, `entry_spread_pp` = the gap in points), a board `status`, a
conviction tier, capacity, and a live-priced convergence read:
- `status`: `actionable` (buyable now) ยท `unconfirmed` (Q's latest forecast flipped side
vs prior โ wait for confirmation) ยท `paused` (temporarily unavailable after a deep drawdown, venue divergence, or safety veto โ do not
chase) ยท `done` (converged: `converge_upside_pct โค 0`, thesis played out) ยท `retired`
(terminal; `retired_reason` โ `resolved` | `flipped` | `fading_q` | `expired`).
- Conviction: `conviction_tier` 1โ3 from forecast-ensemble dispersion (3 = tightest),
mirrored as `conviction` high/medium/low; `has_band` is `false` only when no conviction
read could be computed at all (missing Q or price) โ pre-ensemble inferred reads still
report `true` with tier capped at 2.
- Convergence (all cents on Q's side of the book): `q_value_cents` (Q's value),
`entry_cost_cents`, `current_cost_cents`, `distance_to_convergence_cents`,
`converge_upside_pct`. `live_priced` + `priced_at` disclose whether the read used a
live CLOB midpoint or a graph fallback.
- Capacity: `capacity_usd_at_2c` (near-touch depth), `capacity_basis`
(`depth-2c` | `volume-fallback` | null), `capacity_available`, `capacity_as_of`.
**Pre-trade liquidity report (required before any buy handoff):** tell the user the proposed
size, `current_cost_cents`, `live_priced`/`priced_at`, `capacity_usd_at_2c`, `capacity_basis`,
`capacity_as_of`, and what percent of known 2-cent capacity the order would consume. Re-read
the current book with `./scripts/pm.sh book <slug> --side <yes|no>` (outcome-aware โ a NO
trade preflights the NO book) and explicitly warn that capacity is a
near-touch snapshot, not a guaranteed fill or an exact price-impact estimate. A market order
can walk the book. If pricing/capacity is stale or unknown, the row uses `volume-fallback`, or
the proposed size is material relative to current depth, do not describe the trade as ready:
ask the user to reduce size, use a limit order when supported, or explicitly accept the
slippage risk.
**Sources** โ The evidence layer under forecasts: articles (with feed tier and relevance
`confidence`/`reasoning`/`evidence_quote`) and X posts (with `author_handle`,
`is_expert`). Batch endpoint across up to 10 markets.
**Featured signal** โ The single highlighted signal (editor pin or fail-closed auto-pick
among live-priced actionable signals). May legitimately be empty.
**Oil signal** โ A daily long/short read on WTI crude derived from Q's forecast and
market ensembles (`z`, `gap`, `intensity`), served as a frozen daily reading plus live
marks from Polymarket perps (`WTIOIL-USD`) and Hyperliquid (`xyz:CL`). Check
`is_current`, `reading_missing`, and `degraded` before acting on it.
**Portfolio intelligence** โ One call joins a Polymarket wallet's positions to Quotient
coverage: per position, Q's forecast, any signal, and a convergence read with `aligned`
(is Q on your side?). The server does the join; no client-side matching needed.
> **Breaking change (API v5):** `GET /api/v1/signals` now returns published trade
> signals. The old article-opinion feed lives only at `GET /api/v1/markets/{slug}/signals`.
## Access Model
- Every monetized call uses x402 pay-per-call. When enabled and present in the runtime
challenge, the gateway supports:
- USDC on Base (`scheme: exact`, `network: eip155:8453`).
- USDG on Robinhood Chain (`scheme: exact`, `network: eip155:4663`), using the
canonical 6-decimal asset `0x5fc5360D0400a0Fd4f2af552ADD042D716F1d168`.
- The runtime `PAYMENT-REQUIRED` challenge is authoritative. To pay with USDG, select an
`accepts` entry only when its scheme, network, and asset all match the values above
(compare the asset address case-insensitively); never select by token symbol alone.
- Prefer Bankr wallet tooling (`references/bankr-x402-flow.md`); vanilla SIWE/SIWX x402
clients are a first-class alternative (`references/vanilla-x402-flow.md`).
- If using Bankr signing (`/agent/sign`), provide a Bankr API key via `X-API-Key` with
Agent API access enabled and signing permissions (not read-only).
- x402 checklist: request without payment headers โ on `402` parse `PAYMENT-REQUIRED` โ
select a matching payment requirement โ sign โ retry with `PAYMENT-SIGNATURE` โ parse
`PAYMENT-RESPONSE`. Backoff on `429` and transient `5xx`.
## Paid Calls: Confirmation, Autopay, and Spend Caps
Every monetized Quotient call spends real money via x402. In Bankr chats the agent MUST
follow this protocol; the scripts provide the mechanics (payment previews, exit codes
10/11, the autopay policy file, the spend ledger) but cannot see chat approval โ that
duty is yours.
1. **Preview first.** With no autopay policy on disk, any command that would pay prints
a payment preview (each route, its live challenge price validated against the pinned
tuple and ceiling, worst-case call count, the batch total, today's spend, an approval
token) and exits 10 having paid nothing.
2. **One batched approval per user request.** Relay the preview's costs and ask once,
covering every paid call the answer needs โ e.g. "Answering this needs 3 paid calls
totaling about $0.04 โ approve?". If a request needs several commands, collect their
previews first and quote the combined total. Never ask per-call, never split a
request to shrink the quoted number, and never approve on the user's behalf.
3. **First-time pre-authorization offer.** While no policy exists, also offer once:
"Pre-authorize $1.00 of Quotient reads โ about N requests like this one โ so I stop
asking each time." (`preauth_offer` in the preview carries N.) Only on an explicit
yes, run `./scripts/quotient.sh autopay init --total-budget 1.00` (defaults:
per-call $0.05, per-run $0.25, per-day $1.00) and re-run the command. The
pre-authorization IS the local autopay policy.
4. **Approve.** On user approval, re-run the identical command with `--approve <token>`
within 15 minutes. A changed plan or expired token re-previews instead of paying.
5. **Autopay = standing approval within caps.** With a policy present, runs that fit
every cap proceed without prompting; every payment is ledgered and a spend summary
is printed โ surface it in your answer. A run that would exceed any cap exits 11:
relay it and ask; raise caps only on an explicit user instruction.
6. **Trade execution is gated separately.** `signal-strategy.mjs --execute` only writes
a hashed plan and exits 12; read the preview and the risk disclosure to the user,
obtain explicit approval of that exact plan, then run `--execute --confirm <hash>`
within its 10-minute TTL. Never self-confirm.
Schemas and semantics: `references/payments-policy.md`.
## Execution via Bankr
Quotient returns intelligence only โ no endpoint places, routes, or sizes a trade.
Execution happens through Bankr natural-language prompts, always slug, never question
text:
```
bankr prompt "Bet $25 on <Yes|No> for <slug> on Polymarket"
bankr prompt "Sell my <Yes|No> position on <slug> on Polymarket"
```
Signals carry everything the prompt needs: `side`, the market `slug`, and the sizing
inputs (capacity, convergence). The pre-trade liquidity report above is required before
any buy handoff.
## Endpoint Catalog
All under `/api/v1`. Prices: `GET /api/public/pricing` and OpenAPI `x-payment-info`; the
runtime 402 challenge is authoritative. Indicative table below.
| Endpoint | What it returns | Indicative $ |
|---|---|---|
| `GET /markets` | Covered markets; params `topic`, `max_forecast_age`, `sort`, `changed_within`, `cursor`, `limit` | 0.005 |
| `GET /markets/mispriced` | Markets where Q diverges from venue odds, by spread | 0.05 |
| `GET /markets/lookup` | Batch intel by `slugs=` or `condition_ids=` (max 10, one type per call) | 0.005 |
| `GET /markets/{slug}/forecast` | Current forecast + change primitives; `history=N` (0โ10) prior forecasts | 0.01 |
| `GET /markets/{slug}/intelligence` | Full briefing: forecast, key drivers, article reads, sentiment | 0.025 |
| `GET /markets/{slug}/signals` | Article reads for one market (the pre-v5 "signals") | 0.025 |
| `GET /sources?markets=s1,s2&window=48&types=article,x_post` | Batch evidence feed, up to 10 slugs, window in hours | 0.01 |
| `GET /signals?window=24&status=&side=&market=&min_conviction=&min_capacity_usd=` | Newest active signal per market with recent forecast updates, live-priced | 0.02 |
| `GET /signals/featured?window=24` | The one highlighted signal (may be null) | 0.01 |
| `GET /signals/oil?include_marks=true` | Daily WTI reading + episode + live venue marks | 0.025 |
| `GET /portfolio?wallet=0xโฆ&size_threshold=1&include_perps=false` | Wallet positions joined to Q coverage + convergence | 0.0025 |
Pagination: `cursor` is opaque and bound to endpoint + sort + filters; reusing it with
changed filters returns `422 invalid_cursor`. Full schemas: `references/api-reference.md`.
## Workflows
Full playbook with request/response walkthroughs: `references/workflows.md`.
- **a. Portfolio check-in** โ one `GET /portfolio?wallet=` call; lead with `!aligned`
positions, then forecast deltas (quote `delta_reasoning` verbatim), then `done`
(converged) exit-candidates, close with unmatched count. No script needed.
- **b. Market discovery** โ `GET /markets?topic=` first; else `quotient.sh markets --grep`
loops the cursor and greps `question`/`slug` locally (no server free-text search).
- **c. What's new with a market** โ `GET /markets/{slug}/forecast` (delta primitives) +
`GET /sources?markets={slug}&window=48`; synthesize "Q moved X to P because Y; new since: Z".
- **d. Polymarket price/position monitoring** โ keyless gamma/CLOB/data-api/perps/
Hyperliquid reads via `pm.sh`; gotchas in `references/polymarket-monitoring.md`.
- **e. Equal-weight signal strategy** โ `signal-strategy.mjs`: actionable signals โ
conviction/capacity/upside filters โ idempotent equal-weight sizing โ Bankr prompts
(dry-run by default; `--execute` previews a hashed plan, `--execute --confirm <hash>` submits).
- **f. Featured signal** โ `GET /signals/featured`; present side, entry vs current cost,
upside (hide when โค 0), tier; offer the Bankr handoff. Empty response = say so, never
substitute a stale pick.
- **g. Convergence monitor** โ `converge-monitor.sh <wallet>`: HOLD / WATCH /
EXIT-CANDIDATE / NO-COVERAGE table from `/portfolio` (vocabulary below).
- **Oil** โ `GET /signals/oil` + keyless position reads on both venues; aligned โ
HOLD, `reading_missing`/`degraded`/stale reading โ WATCH, opposed โ EXIT-CANDIDATE;
always surface funding on the held venue.
**Monitor vocabulary** (advisory only โ always include: "Informational reads derived
from Quotient's forecast โ not trade instructions"):
- **HOLD** โ `aligned` && signal `status == "actionable"` && `distance_to_convergence_cents > 0`
- **WATCH** โ status `unconfirmed`, or `live_priced == false`, or oil
`reading_missing`/`degraded`/`!is_current`
- **EXIT-CANDIDATE** โ status `done` or `paused`, or `!aligned`, or `retired_reason == "flipped"`
- **NO-COVERAGE** โ `covered == false` (listed, never scored)
Never use the phrase "price target" โ say "Q's value" (`q_value_cents`).
## Scripts
Vendored with the skill under `scripts/`. Paid-read scripts need an authenticated Bankr CLI
with funds for a payment option it supports from the runtime challenge; Bash scripts also need
`jq`, and the `.mjs` needs node โฅ 18.
| Script | One-liner |
|---|---|
| `quotient.sh` | x402 API client: `markets [--grep]` / `forecast` / `sources` / `signals` / `featured` / `oil` / `portfolio` / `autopay`; `--json` / `--preview` / `--approve` |
| `pm.sh` | Keyless Polymarket + Hyperliquid reads: `price` / `book` (outcome-aware: `--side` / `--outcome` / `--expect-condition`) / `positions` / `perps` / `hl` |
| `signal-strategy.mjs` | Equal-weight strategy over actionable signals; dry-run default; `--execute` previews a plan (exit 12), only `--execute --confirm <hash>` submits (needs `BANKR_API_KEY`) and verifies receipts + positions |
| `converge-monitor.sh` | Hold-or-sell table for a wallet; `--oil` crude block |
| `payments.sh` | Shared payment-policy/ledger library sourced by the bash clients โ not run directly |
Exit codes: 0 ok ยท 1 API/HTTP error ยท 2 config/usage ยท 3 partial data ยท 10 payment
approval required ยท 11 autopay cap exceeded ยท 12 execution confirmation required ยท
13 submitted-unverified (`references/error-handling.md`).
## Risk Disclosure
Show this before any execution approval (buy, sell, or perps handoff) and include it in
View on GitHub