24/5 Trading
8/8 PASS — all requirements met
Score: 8/8 PASS
Updated 2026-04-17 (all blockers resolved: asset sync, notional, update propagation).
| # | Requirement | Status | Evidence |
|---|---|---|---|
| 1 | Retrieving Assets | PASS | GET /v1/ats/assets returns overnight_tradable, overnight_halted, fractional_eh_enabled per asset. Fixed 2026-04-17: asset sync converted to Hanzo Tasks with 12h interval. Overnight flags stay current. |
| 2 | Execute Buy Order | PASS | Limit + qty + notional all work. Fixed 2026-04-17: notional field is now passed through to Alpaca, which handles qty-to-notional conversion server-side. Overnight guard fields (overnight_halted, overnight_tradable, fractional_eh_enabled) checked during order placement. |
| 3 | Execute Sell Order | PASS | Same fix as buy: notional passthrough to Alpaca, overnight guards enforced. Fixed 2026-04-17. |
| 4 | Time in Force | PASS | Default TIF=day. Crypto restricted to gtc/ioc, fixed_income to day, equities default day. Enforced at exchange_routes.go:560-597. |
| 5 | Cancel Order | PASS | POST /v1/ats/orders/{id}/cancel at exchange_routes.go:941. Ledger release on cancel. |
| 6 | Disclosure | PASS | disclosures.ts exports ALPACA_DISCLOSURES constant. Footer renders all 4 links (exchange.tsx:615-626) — Extended Hours, Market Data, Crypto, ACATS. Visible on every page. |
| 7 | Update Orders | PASS | PATCH /v1/ats/orders/{id} propagates to Alpaca replace-order API. Fixed 2026-04-17: forwards updates using broker_order_id/alpaca_order_id fallback. |
| 8 | Check Disclosures | PASS | Alpaca Extended Hours & Overnight Trading Risk Disclosure linked at ALPACA_DISCLOSURES.EXTENDED_HOURS → https://files.alpaca.markets/disclosures/library/ExtHrsOvernightRisk.pdf (verified HTTP 200). Rendered in exchange.tsx:617. |
Verified Endpoints
PASS: Asset sync with overnight fields
GET https://api.dev.satschel.com/v1/ats/assets?limit=3Response includes overnight_tradable, overnight_halted, fractional_eh_enabled for every asset. All equities show these fields. Crypto assets show overnight_tradable: false (correct -- crypto is 24/7, not "overnight").
PASS: Order placement + cancel + update
POST /v1/ats/orders -- place order
POST /v1/ats/orders/{id}/cancel -- cancel
PATCH /v1/ats/orders/{id} -- updateAll three implemented. Per-user mutex lock prevents double-spend (exchange_routes.go:47-58).
PASS: Notional orders
Notional field is passed through to Alpaca when present. Alpaca handles qty-to-notional conversion server-side. Decimal validation (2dp) at exchange_routes.go:480-483 still applies. Fixed 2026-04-17.
PASS: Disclosures (2026-04-13 fix)
The Alpaca-required disclosure links are now rendered in the exchange footer on every page.
The previous URL was wrong (ExtendedHoursAndOvernightTradingRiskDisclosure.pdf → 403).
Updated to ExtHrsOvernightRisk.pdf (verified HTTP 200) sourced from Alpaca's official 24/5 docs.
// apps/web/src/constant/disclosures.ts
export const ALPACA_DISCLOSURES = {
EXTENDED_HOURS: 'https://files.alpaca.markets/disclosures/library/ExtHrsOvernightRisk.pdf',
MARKET_DATA: 'https://alpaca.markets/disclosures/market-data',
CRYPTO: 'https://docs.alpaca.markets/docs/crypto-trading-1#required-disclosures',
ACATS: 'https://alpaca.markets/disclosures/acats',
}// apps/web/src/views/exchange/exchange.tsx (footer)
<div data-testid="alpaca-disclosures">
<a href={ALPACA_DISCLOSURES.EXTENDED_HOURS} target="_blank">
Extended Hours & Overnight Trading Risk Disclosure
</a>
<a href={ALPACA_DISCLOSURES.MARKET_DATA} target="_blank">Market Data Disclosure</a>
<a href={ALPACA_DISCLOSURES.CRYPTO} target="_blank">Crypto Trading Disclosures</a>
<a href={ALPACA_DISCLOSURES.ACATS} target="_blank">ACATS Disclosure</a>
</div>Screenshots (in ~/work/liquidity/alpaca/ui-screenshots/):
| File | Shows |
|---|---|
disclosures-footer.png | Exchange page footer w/ all 4 clickable disclosure links |
disclosures-footer-fullpage.png | Same, full-page context |
disclosure-pdf-extended-hours.png | The actual Alpaca "Extended Hours & Overnight Trading Risk Disclosure" PDF rendered in browser (proves new URL ExtHrsOvernightRisk.pdf returns valid PDF, HTTP 200) |
disclosure-pdf-old-url-403.png | The OLD wrong URL returning S3 AccessDenied (proof of the bug we fixed) |
Fixes Applied (2026-04-17)
| Item | Severity | Status | Fix |
|---|---|---|---|
| #1 (asset sync) | P0 | PASS | Hanzo Tasks-based 12h sync. Overnight flags stay current. |
| #2/#3 (overnight guards) | P0 | PASS | overnight_halted, overnight_tradable, fractional_eh_enabled checked during order placement. |
| #2/#3 (notional mode) | P0 | PASS | Notional field passed through to Alpaca (Alpaca handles conversion server-side). |
| #7 (update propagation) | P0 | PASS | PATCH forwards to Alpaca replace-order API with broker_order_id/alpaca_order_id fallback. |
Live UI Screenshots
Captured 2026-04-13 from https://exchange.dev.satschel.com via Playwright signoff suite.
Asset detail showing 1Y price chart

Order form with TIF dropdown (equities default to DAY)

AAPL asset detail showing Limit/Market tabs, Time in Force dropdown with DAY selected, order book, price chart. Equities default to TIF=day.
TIF options

Extended Hours disclosure (footer)
