Alpaca Sign-Off

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).

#RequirementStatusEvidence
1Retrieving AssetsPASSGET /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.
2Execute Buy OrderPASSLimit + 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.
3Execute Sell OrderPASSSame fix as buy: notional passthrough to Alpaca, overnight guards enforced. Fixed 2026-04-17.
4Time in ForcePASSDefault TIF=day. Crypto restricted to gtc/ioc, fixed_income to day, equities default day. Enforced at exchange_routes.go:560-597.
5Cancel OrderPASSPOST /v1/ats/orders/{id}/cancel at exchange_routes.go:941. Ledger release on cancel.
6DisclosurePASSdisclosures.ts exports ALPACA_DISCLOSURES constant. Footer renders all 4 links (exchange.tsx:615-626) — Extended Hours, Market Data, Crypto, ACATS. Visible on every page.
7Update OrdersPASSPATCH /v1/ats/orders/{id} propagates to Alpaca replace-order API. Fixed 2026-04-17: forwards updates using broker_order_id/alpaca_order_id fallback.
8Check DisclosuresPASSAlpaca Extended Hours & Overnight Trading Risk Disclosure linked at ALPACA_DISCLOSURES.EXTENDED_HOURShttps://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=3

Response 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}     -- update

All 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/):

FileShows
disclosures-footer.pngExchange page footer w/ all 4 clickable disclosure links
disclosures-footer-fullpage.pngSame, full-page context
disclosure-pdf-extended-hours.pngThe 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.pngThe OLD wrong URL returning S3 AccessDenied (proof of the bug we fixed)

Fixes Applied (2026-04-17)

ItemSeverityStatusFix
#1 (asset sync)P0PASSHanzo Tasks-based 12h sync. Overnight flags stay current.
#2/#3 (overnight guards)P0PASSovernight_halted, overnight_tradable, fractional_eh_enabled checked during order placement.
#2/#3 (notional mode)P0PASSNotional field passed through to Alpaca (Alpaca handles conversion server-side).
#7 (update propagation)P0PASSPATCH 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

Asset Detail

Order form with TIF dropdown (equities default to DAY)

Order form

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

TIF options

Disclosures footer

On this page