# Northbeam Markets — Product Requirements (v1.8)

Northbeam Markets is a brokerage over a deterministic simulated market of 34 fictional tickers and the NB 100 index. Investors keep watchlists, study candlestick symbol pages, place market, limit, stop and stop-limit orders behind a trade-PIN step-up, follow open and partially filled orders, review the portfolio and FIFO realised profit, and set price alerts. Market time only moves with the Market time control.

**Problem.** Investors need to trust every quote, order, fill and profit figure: orders must never fill at a worse price than requested, cash reserved by working orders must not be spent twice, and realised profit must follow the oldest purchase lots.

## Users
- **Active investor** — Place orders quickly, see exactly what they will cost and follow fills as the market moves.
- **Portfolio watcher** — Track watchlists, positions, allocation and alerts without placing trades.
- **Tax-minded investor** — Read realised profit and loss by lot, computed first-in first-out.

## Goals
- Orders fill only at prices their type and limit allow.
- Buying power always equals cash minus cash reserved by working orders.
- Realised profit and loss is computed per FIFO lot and totals reconcile.
- Trading is protected by a trade PIN that locks after repeated failures.

## Sign-in and trade PIN (AUTH)

Account sign-in and the PIN step-up required before an order is placed.

- **FR-AUTH-01** (Must) A valid sign-in opens Watchlists with the navigation rail and the market clock.
  - Heading "Watchlists"; navigation lists Watchlists, Portfolio, Orders (with the count of open orders, 4 for the seeded account), Activity, Alerts
  - Topbar shows "Mon 19 Oct 2026 · 10:00", "Open" and "Buying power" $4,526.70
- **FR-AUTH-02** (Should) Sign-in reports missing and wrong credentials separately and does not sign in.
  - Empty fields: "Enter your username and password"
  - Wrong credentials: "Invalid username or password" and the sign-in page stays
- **FR-AUTH-03** (Must) The first order of a session requires the 6-digit trade PIN before it is placed.
  - "Place order" opens "Confirm trade PIN"
  - Empty PIN: "Enter your 6-digit trade PIN"
  - A correct PIN closes the dialog and the toast starts with "Order ORD-<n> placed"
- **FR-AUTH-04** (Must) Three wrong PINs lock trading for the session.
  - First wrong PIN: "Incorrect trade PIN. 2 attempts left"; second: "Incorrect trade PIN. 1 attempt left"
  - Third: "Trade PIN locked after 3 incorrect attempts. Reset the demo data to unlock."

## Watchlists (WCH)

Named lists of tickers with live quotes.

- **FR-WCH-01** (Must) Each watchlist row shows the last price and the day change measured against the previous close, with the 52-week range.
  - NB 100 index: 4,800.00, change -10.56 (-0.22%)
  - Core holdings in order: NBRX $142.30 -4.10%, ORIN $88.75 +0.26%, KELP $58.40 +0.05%, HALC $76.10 +1.56%, SOLR $26.45 -4.72%, DRVN $109.90 +0.71%
  - NBRX 52-week range $127.17 to $217.29
- **FR-WCH-02** (Could) The Momentum list is separate, with gains green with an up arrow and losses red with a down arrow, and a range bar marker per row.
  - Momentum rows: QUVA $214.60 +1.73%, TELM $63.20 +0.83%, ARCS $176.40 -0.34%, LITH $38.60 +0.89%, MRIN $61.45 -1.00%
  - Direction is never shown by colour alone
- **FR-WCH-03** (Should) A ticker can be added to a watchlist; duplicates and empty input are refused.
  - Adding QUVA appends a seventh row at $214.60 +1.73%
  - Adding it again shows an error and the list keeps seven rows
  - Empty input: "Enter a ticker symbol"
- **FR-WCH-04** (Should) Rows can be moved up or down and removed, and the result persists in the session.
  - Removing a row shows the toast "<SYM> removed from Core holdings"
  - The first row’s "Move up" is disabled
  - After navigating away and back the order and membership are unchanged

## Symbol page and chart (SYM)

Quote, statistics, order book and candlestick chart.

- **FR-SYM-01** (Must) The symbol header shows the company name, last price, change from previous close, bid and ask, sector, session and the held position.
  - NBRX: "Northbeam Robotics", $142.30, -$6.08, -4.10%, "Bid $142.27 · Ask $142.33", Technology, Open, 40 shares held
- **FR-SYM-02** (Should) The Statistics card and ten-level order book match the market data.
  - NBRX: Open $144.05, Previous close $148.38, Day range $142.06 – $144.09, Volume 322,143, Average volume 4.20M, Market cap $91.07B, P/E ratio 34.5, Dividend yield —
  - Best bid $142.27 (200), $142.26 (1,900), $142.25 (2,800); best ask $142.33 (1,300), $142.34 (1,500)
  - Ten bid and ten ask levels
- **FR-SYM-03** (Should) Chart range tabs 1D, 5D, 1M and 1Y redraw the chart, and SMA 20 and SMA 50 toggles add overlay lines.
  - The selected range shows as selected; returning to 1D restores intraday candles
  - Both SMA toggles show pressed and two overlay lines are drawn
- **FR-SYM-04** (Could) Candles are green or red with wicks, volume bars and a dashed previous-close line; hovering shows a crosshair with an OHLC readout that disappears when the pointer leaves.
  - Last NBRX 1D candle: O $142.42 H $142.46 L $142.26 C $142.30, Vol 13,586

## Order ticket (ORD)

Entering, validating and placing orders.

- **FR-ORD-01** (Must) A market buy shows an estimate at the ask, fills at the ask after the PIN step, debits cash and adds shares.
  - 5 NBRX: Estimated price (ask) $142.33, cost $711.65, commission $0.65, total $712.30
  - Review shows Buying power after $3,814.40; toast "Order ORD-1005 placed: Buy 5 NBRX"
  - Topbar buying power $3,814.40; History shows ORD-1005 Filled; the NBRX position is 45 shares
- **FR-ORD-02** (Must) An order whose cost exceeds buying power is refused before review.
  - 40 QUVA: "Insufficient buying power: this order needs $8,586.65 but you have $4,526.70 available"; no review dialog
- **FR-ORD-03** (Must) Buying power equals cash minus the cash reserved by working orders.
  - Seeded account: Cash $11,847.35, $7,320.65 reserved by open orders, Buying power $4,526.70
- **FR-ORD-04** (Must) A limit buy fills only at or below its limit price; otherwise it rests as Working.
  - Limit $142.00 against an ask of $142.33 (10 NBRX): estimated cost $1,420.00, total $1,420.65; status Working with nothing filled
  - A limit of $142.30 against the same ask also stays Working and does not fill at $142.33
  - The order remains Working after the clock advances while the ask stays above the limit
- **FR-ORD-05** (Should) The ticket validates quantity, dollar amount and prices with specific messages.
  - Empty or fractional quantity: "Enter a whole number of shares"
  - Quantity 0: "Quantity must be a whole number between 1 and 10,000"
  - Missing limit: "Enter a limit price like 142.50"; missing stop: "Enter a stop price like 138.00"
  - Dollar amount below $1: "Minimum dollar order is $1.00"
- **FR-ORD-06** (Could) A dollar-amount order buys fractional shares at the ask.
  - $250 of NBRX: Estimated shares 1.7564, cost $250.00, commission $0.65, total $250.65; Buying power after $4,276.05
- **FR-ORD-07** (Could) Ticket fields follow the order type.
  - Market: Quantity and Order by only; Limit adds Limit price; Stop adds Stop price; Stop limit shows both
  - Sell uses the labels "Estimated proceeds" and "Estimated net proceeds"
- **FR-ORD-08** (Could) The Review order dialog is a centred modal with muted labels, right-aligned values, an emphasised total, a secondary Back button and a filled Place order button with focus; Escape closes it and keeps the ticket values.
- **FR-ORD-09** (Should) A pattern day trader warning appears once the account has made three day trades in five trading days and must be acknowledged before the next order.
  - Portfolio Margin card shows "Day trades (5 days)" as "2 of 3" before and "3 of 3" after a same-day buy and sell
  - Warning: "Pattern day trader warning: you have made 3 day trades in the last 5 trading days. Another day trade may restrict your account."
  - "Place order" stays disabled until "I understand the pattern day trader warning" is ticked

## Open orders (OPN)

Working orders, fills, cancel and modify.

- **FR-OPN-01** (Should) Open orders lists working orders newest first with fill progress; History lists completed ones.
  - Open: ORD-1004 ORIN Sell Limit $95.00 Working; ORD-1003 HALC Buy Limit $77.00 Partially filled ("40 of 100"); ORD-1002 NBRX Sell Stop $120.00 Working; ORD-1001 KELP Buy Limit $54.00 Working
  - History: ORD-999 ORIN Buy Market Filled, ORD-998 TELM Buy Limit Cancelled, ORD-997 SOLR Buy Market Filled
- **FR-OPN-02** (Must) A partially filled order fills further on each market tick until complete, then moves to History.
  - +1m: clock 10:01, toast "Bought 40 HALC at $76.13 — partial fill", order shows "80 of 100"
  - +1m again: toast "Bought 20 HALC at $76.23 — order filled"; the order leaves Open and the Orders count becomes 3
  - History shows ORD-1003 Filled "100 of 100"
- **FR-OPN-03** (Should) Cancelling an order asks for confirmation and moves it to History as Cancelled.
  - Dialog "Cancel order?" with "Keep order" and "Cancel order"
  - Toast "Order ORD-1001 cancelled"; three open orders remain
- **FR-OPN-04** (Should) A working order’s quantity and limit price can be modified and the change is validated.
  - Empty limit: "Enter a limit price like 54.00"
  - Saving 96.00 on ORD-1004 shows "Order ORD-1004 modified" and the order stays Working at $96.00
- **FR-OPN-05** (Must) A sell stop triggers only when the price falls to the stop price, never while the price is above it.
  - NBRX sell stop at $120.00 stays Working while NBRX trades near $142 and four open orders remain after a market tick

## Portfolio (PRT)

Equity, positions, margin and allocation.

- **FR-PRT-01** (Must) Portfolio shows equity, day change, unrealised P/L, cash, buying power and per-position figures that reconcile.
  - Total equity $40,496.45, Day change -$346.71 (-1.20%), Unrealised P/L +$1,288.39 (+4.71%), Cash $11,847.35, Buying power $4,526.70 ("$7,320.65 reserved by open orders")
  - KELP 100 avg $55.10 last $58.40 value $5,840.00 +$330.00; NBRX 40 avg $132.41 last $142.30 value $5,692.00 +$395.50; SOLR 153.5217 avg $24.37 last $26.45 value $4,060.65 +$320.04
  - Margin requirement $8,594.73, Margin excess $31,901.72, Day trades (5 days) "2 of 3", Realised P/L all time +$450.75
- **FR-PRT-02** (Could) Sector allocation is a flat-colour donut with a legend whose percentages match the slices.
  - Technology 27.2%, Healthcare 12.2%, Financials 14.4%, Energy 10.0%, Industrials 6.9%, Cash 29.3% (largest)

## Activity and statements (STM)

Ledger of trades, deposits and dividends, with FIFO realised profit.

- **FR-STM-01** (Must) A sale closes the oldest purchase lots first, and realised profit equals proceeds minus the cost of those lots.
  - Sell 30 ORIN at market: estimated price (bid) $88.73, proceeds $2,661.90, net proceeds $2,661.25
  - Statements: one lot LOT-003, 30 shares at $79.20, Cost basis $2,376.00, P/L +$285.90
  - Realised P/L (FIFO) rises from +$450.75 to +$736.65; 30 ORIN shares remain
- **FR-STM-02** (Should) Statements show realised sales, totals and lot detail for This month and All time.
  - All time: Realised P/L (FIFO) +$450.75, Trades 8, Commissions $5.20, Dividends $31.25, Deposits $5,000.00
  - Sales: MRIN 30 -$21.00, TELM 50 +$42.50, ARCS 20 +$346.00, TRNV 15 +$83.25
  - MRIN lot LOT-014: 30 shares at $63.10, proceeds $1,872.00, basis $1,893.00, P/L -$21.00; ARCS lot LOT-015: 20 at $171.10, proceeds $3,768.00, basis $3,422.00, P/L +$346.00
- **FR-STM-03** (Should) Activity lists ten entries newest first and the Type filter narrows them.
  - First entry: HALC buy 40 at $76.10 on Mon 19 Oct, then MRIN sell 30 at $62.40
  - Trades 8 rows, Deposits 1 ("ACH deposit"), Dividends 1 ("KELP dividend $0.3125/sh"), All activity 10

## Price alerts (ALR)

Alerts that trigger as market time advances.

- **FR-ALR-01** (Must) An alert triggers when the price crosses its threshold as market time advances, rings the bell and shows a toast.
  - Seeded: AL-1 NBRX above $145.00 and AL-2 KELP below $58.00, both Active, no bell badge
  - At 14:00 both are still Active; at 15:00 the toast "Alert: NBRX rose above $145.00 (now $145.14)" appears, the bell shows 1, AL-1 is Triggered
  - "Clear triggered" removes AL-1 and the badge
- **FR-ALR-02** (Could) Alerts can be created with validation and deleted after confirmation.
  - Empty price: "Enter a price like 145.00"
  - Creating KELP at or above 60.00 shows "Alert set: KELP above $60.00" and a new Active row
  - Delete asks "Delete alert?" with "Keep alert" and "Delete alert"

## Market time (CLK)

The simulated market clock and sessions.

- **FR-CLK-01** (Should) The Market time control advances the clock by step or continuously and the session label follows the time.
  - +1m: 10:00 to 10:01; +1h: 10:01 to 11:01
  - Play advances about one minute per second until Pause; the button then reads "Play"
  - After 16:00 the label changes from "Open" to "After-hours"

## Non-functional requirements

- **NFR-01** (Must) Day change and percentage change are measured from the previous close, never from today’s open.
  - NBRX shows -4.10% in Watchlists and on its symbol page; SOLR shows -4.72%
- **NFR-02** (Could) The app is dark by default and offers a light theme that stays legible and persists after reload.
  - Toggle reads "Switch to light theme" / "Switch to dark theme"
- **NFR-03** (Could) Keyboard support: "/" focuses Search symbol, Enter opens the symbol, Enter in Quantity opens Review order with focus on Place order, Escape closes dialogs.
- **NFR-04** (Could) At 390 px width the app keeps one column, bottom navigation and no horizontal page scroll; summary tiles wrap two per row.

## Glossary and rules

- **Buying power** — Cash minus cash reserved by working buy orders.
- **FIFO** — First in, first out: sales consume the oldest purchase lots first.
- **Working order** — An accepted order that has not filled completely and has not been cancelled.

## Out of scope

- Real market data
- Real brokerage settlement
- Native mobile apps
