You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
First live run of scripts/robinhood_smoke.py (#216) against a real credential. 10 requests, zero 401s — so signing, headers, the timestamp window, the base URL, and pagination are all confirmed correct. The response shapes, however, are substantially wrong, and one of them is a live defect.
Confirmed working
Ed25519 signing is accepted by the venue. The circularity in the offline tests is closed.
Every endpoint path is correct, including /api/v2/crypto/trading/estimated_price/. This settles the B3 question from Robinhood adapter: close the independent review findings #196 empirically: the original code was right and the review finding was wrong.
Pagination works — four cursor pages of trading_pairs followed correctly.
fee_tier_status is real, with exactly the key names the fixture guessed (fee_ratio, thirty_day_volume, next_fee_tier_ratio, next_fee_tier_threshold). The shape the review called "the single most load-bearing invented shape here" is corroborated.
F1 — _estimated_price reads a field the venue does not send (blocker)
adapter.py:_estimated_price reads _field(rows[0], "price", "0"). The venue's actual row:
There is no price. It is ask. Proven end-to-end against the live venue:
est_quote_size = 0.000
est_fee = 0E-7
errors = ('robinhood returned no usable estimated price for this order; ...')
Every preview against this venue is unpriced. Confirm mode is unusable here today.
The #194 S1 fix is what makes this survivable: _estimated_price returns None rather than Decimal("0"), so this surfaces as a populated Preview.errors instead of a silent $0.00 at the confirm gate. That fix was correct and is doing exactly its job.
The venue also hands us est_fee and est_total_cost directly, so the fix is not just renaming price → ask: the preview can stop deriving cost and fee and read both from the response. Note est_total_cost should not be assumed to include or exclude the fee without checking it against ask × quantity + est_fee.
F2 — money fields are unquoted JSON numbers, not strings
Every money value arrives as a JSON number (Decimal in the report, because #194's S3 fix parses with parse_float=Decimal). All eight committed fixtures quote them as strings.
#194's parse_float=Decimal change is load-bearing against the real venue — without it every one of these would have been a binary float before Decimal saw it. The fixtures should be corrected to unquoted numbers so the suite exercises the path the venue actually produces.
F3 — trading_pairs.min_order_amount does not exist
The fixture invents it; the venue sends neither min_order_amount nor min_order_size. Every other field is confirmed (symbol, asset_code, quote_code, asset_increment, quote_increment, max_order_size, status, is_api_tradable). This removes the assumed source for the pre-flight minimum-size check in #198.
F4 — the best_bid_ask fixture is substantially invented
Venue sends bid and ask. The fixture has price, buy_spread, sell_spread, ask_inclusive_of_buy_spread, bid_inclusive_of_sell_spread — none of which exist. Harmless today because the adapter never calls get_best_bid_ask, and dangerous the moment anything does.
F5 — the probe script reports a false positive (my bug, not the venue's)
next/previous are reported MISSING AT VENUE on all five probes. That is an artifact: _paginate deliberately returns {"results": [...]} and strips them, and all five probes route through it, so the script compares a post-pagination aggregate against a single-page raw fixture. The script must compare like with like, or it will cry wolf on every future run.
First live run of
scripts/robinhood_smoke.py(#216) against a real credential. 10 requests, zero 401s — so signing, headers, the timestamp window, the base URL, and pagination are all confirmed correct. The response shapes, however, are substantially wrong, and one of them is a live defect.Confirmed working
/api/v2/crypto/trading/estimated_price/. This settles the B3 question from Robinhood adapter: close the independent review findings #196 empirically: the original code was right and the review finding was wrong.trading_pairsfollowed correctly.fee_tier_statusis real, with exactly the key names the fixture guessed (fee_ratio,thirty_day_volume,next_fee_tier_ratio,next_fee_tier_threshold). The shape the review called "the single most load-bearing invented shape here" is corroborated.F1 —
_estimated_pricereads a field the venue does not send (blocker)adapter.py:_estimated_pricereads_field(rows[0], "price", "0"). The venue's actual row:There is no
price. It isask. Proven end-to-end against the live venue:Every preview against this venue is unpriced. Confirm mode is unusable here today.
The #194 S1 fix is what makes this survivable:
_estimated_pricereturnsNonerather thanDecimal("0"), so this surfaces as a populatedPreview.errorsinstead of a silent $0.00 at the confirm gate. That fix was correct and is doing exactly its job.The venue also hands us
est_feeandest_total_costdirectly, so the fix is not just renamingprice→ask: the preview can stop deriving cost and fee and read both from the response. Noteest_total_costshould not be assumed to include or exclude the fee without checking it againstask × quantity + est_fee.F2 — money fields are unquoted JSON numbers, not strings
Every money value arrives as a JSON number (
Decimalin the report, because #194's S3 fix parses withparse_float=Decimal). All eight committed fixtures quote them as strings.#194's
parse_float=Decimalchange is load-bearing against the real venue — without it every one of these would have been a binary float beforeDecimalsaw it. The fixtures should be corrected to unquoted numbers so the suite exercises the path the venue actually produces.F3 —
trading_pairs.min_order_amountdoes not existThe fixture invents it; the venue sends neither
min_order_amountnormin_order_size. Every other field is confirmed (symbol,asset_code,quote_code,asset_increment,quote_increment,max_order_size,status,is_api_tradable). This removes the assumed source for the pre-flight minimum-size check in #198.F4 — the
best_bid_askfixture is substantially inventedVenue sends
bidandask. The fixture hasprice,buy_spread,sell_spread,ask_inclusive_of_buy_spread,bid_inclusive_of_sell_spread— none of which exist. Harmless today because the adapter never callsget_best_bid_ask, and dangerous the moment anything does.F5 — the probe script reports a false positive (my bug, not the venue's)
next/previousare reportedMISSING AT VENUEon all five probes. That is an artifact:_paginatedeliberately returns{"results": [...]}and strips them, and all five probes route through it, so the script compares a post-pagination aggregate against a single-page raw fixture. The script must compare like with like, or it will cry wolf on every future run.