docs(research): can keel trade Coinbase's new asset classes? - #163
Merged
Conversation
…asses Coinbase now lists futures, perp-style futures, equity/thematic indices, commodities and US equities alongside spot. This records a probe of what is actually reachable from the deployment's own CDP key, and what keel would need to trade any of it. Findings: FX does not exist on Coinbase at all; the "stocks" are real US equities on venue CCM (not the non-US tokenized-stock product) and are unbuildable — no candles, HTTP 500 on book and trades, preview refused by design; all 99 futures are EXPIRING contracts, so the "perps" are long-dated contracts carrying funding and still need a roll. Futures market data works and is blocked only by CFM onboarding paperwork. Also records a live fragility: guards._asset reduces ADA-28AUG26-CDE to "ADA", which is allowlisted on the live config, so rail 1 passes a futures contract today. Only rail 13 catches it, and rail 13 is BUY-only and paper-exempt. No code changed, no product admitted, allowlist unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two independent reviews found the document's evidence base was unreachable (it cited files in the gitignored scratchpad) and that four claims were wrong. Fixes: - Commit the probe as a re-runnable, read-only script and re-cite every empirical claim against it. It never places, cancels or edits an order. - Rail 12 does not do what was claimed: last_feed_ts is an agent-loop heartbeat stamped every poll (agent.py:740), so a closed market cannot trip it. The real 24/7 assumption is market_feed.is_fresh, and it skips a product for the cycle rather than breaching a rail. Downgraded. - "keel can never name a futures product" was false. --products takes raw unvalidated strings, so `keel rules seed --products ADA-28AUG26-CDE` names one today. Added to the do-not-do list. - The halal screen gates allowlist admission through a human CLI workflow; nothing on the order path calls it. Corrected. - Options: OPTION_GROUP=0 proved nothing (FUTURE_GROUP is also 0 while FUTURE is 99). Restated on the real evidence: OPTION is not a member of the product_type enum at all. - qabd is triply sourced on the operative test, not quadruply; s66.2 explicitly declines to settle it. - Equity universe: cursor pagination walks thousands past the 1000 cap but never converges, so no reproducible snapshot is obtainable. - A SELL of ADA-28AUG26-CDE passes every rail on the live config, verified by execution. Rail 13 is BUY-only and paper-exempt. Plus corrected citations, de-double-counted the futures table, and made the FX section distinguish fiat-quoted crypto spot from an FX offering. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The independent review found the probe did not emit ten of the claims that cited it, and that its hardcoded contract ids expire in 23 days -- which would have broken the recurring re-run the document asks for. - Enforce the read-only property instead of asserting it: post/put/delete are wrapped so anything but the preview endpoint raises before it reaches the network. The probe demonstrates the guard on itself at the end. - Select front-month contracts dynamically, so the script survives rolls. - Emit what the document cites: the FX/FOREX enum rejections, the accounts census, expiry + funding_rate + open_interest + settlement leg per perp-style contract, cik and venue_id, the alias-id market data probe, and the price fields on futures as well as equities. - Replace the 2-call stability check with 4 calls plus the offset window and a cursor walk -- a single pair can hit a cached response and read as perfectly stable, which would make a re-runner think the document lied. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…question The independent whole-branch review returned APPROVE WITH CHANGES: the analysis reproduced, but the document claimed more of its probe than the probe delivered, and two recommendations were under-specified. - Re-cite every empirical claim against the section that actually emits it. - Add R1: reject any intent whose quote_currency_of() is not in the adapter's declared quote_currencies. Measured, that one check kills all 99 futures ids (quote resolves to "CDE") and all 1000 equity ids (None) on both sides, using machinery already trusted at guards.py:423 -- about an hour, against the 2-4 days of the fuller gate, which becomes R2. It also rejects 120 non-USD/USDC spot pairs, disclosed rather than left to be discovered at implementation. - R2 must return a violation, never raise: guards._asset runs over every historical filled order, so raising turns a veto into a crashed cycle. - The live-fragility section omitted that a SELL needs a held position from a filled live BUY, which rail 13 vetoes. Reframed: onboarding leaves the rails as the only thing remaining, which is the do-not-onboard argument. - Mark the CFM onboarding cost UNVERIFIED -- the futures-vs-equities split rests on it and nothing measured it. - Caveat the two HTTP 500s as server errors rather than refusals. Closes the last open question: equity market data was re-probed at 13:35 UTC, five minutes into the NORMAL session, across SPY/QQQ/AAPL/NVDA/TSLA on both quote legs. Identical to pre-market -- zero candles, empty pricebooks, 500s, empty price fields. The absence is not a market-hours artifact. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
Author
|
Reviewed by three independent agents (code-citation audit, live API re-verification, and a fresh-context whole-branch review). All findings applied:
Lint clean, 1678 tests pass. Documentation only; no source code changed. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Question
Coinbase now lists futures, perp-style futures, equity/thematic indices, commodities and US equities alongside spot. Can keel trade all or some of them?
Answer
No — none of them today. Only the crypto-futures family is even a candidate for a future build.
The document records a live, read-only probe of
GET /api/v3/brokerage/productsand the market-data/preview endpoints, run against the deployment's own CDP key on 2026-08-05, plus a file-by-file audit of what keel assumes.EXPIRINGThree distinct blocker classes are separated deliberately, because they cost very different things: account paperwork (CFM onboarding), venue capability gaps (equities), and keel architecture gaps (13 areas — instrument identity, position/margin model, direction model, lot rounding, expiry/roll, 24-7 assumptions).
Incidental finding worth acting on
guards._asset("ADA-28AUG26-CDE")returns"ADA", which is allowlisted on the live config — so rail 1, the un-overridable halal gate, passes a futures contract today. Only rail 13 catches it, and rail 13 is BUY-only and skipped in paper mode. keel refuses these products by accident (it never constructs such an id), not by design. The doc recommends closing this regardless of whether anything else is ever built.Scope
Documentation only. No code changed, no product admitted, allowlist unchanged.
create_orderwas deliberately never exercised against equities — that would have placed a real order.🤖 Generated with Claude Code