Files
stonks-oracle/.kiro/specs/override-trade-tab/requirements.md
T
Celes Renata 913fe8b0b3 feat: override trade tab — manual order entry with auto-registration
Backend:
- OverrideOrderRequest/Response Pydantic models with ticker, quantity, price validators
- POST /api/trading/override/order endpoint (enqueue to Redis broker queue)
- auto_register_symbol() module for untracked ticker registration via Symbol Registry
- Unit tests (17) and property-based tests (3 x 100 examples)

Frontend:
- OverrideTradePanel component (order form + positions display)
- Override tab in TradingEngine page with URL search param navigation
- Override Trade button on Trading Controls page
- useSubmitOverrideOrder mutation hook
- MSW handler and 13 component/integration tests

Steering:
- Updated steering docs for Ubuntu dev machine with nvm/Node 24
2026-04-17 07:02:30 +00:00

11 KiB

Requirements Document

Introduction

The Override Trade Tab adds a manual trading interface to the Stonks Oracle trading engine, allowing operators to buy or sell any ticker symbol — including symbols not currently tracked by the platform. When a previously untracked symbol is traded, the system automatically registers it in the companies table, creates default data sources, and adds it to the active watchlist so the full intelligence pipeline can begin tracking it. A navigation button on the Trading Controls page provides quick access to this new tab.

Glossary

  • Trading_Engine: The FastAPI backend service at services/trading/app.py that manages autonomous and manual trading operations, exposed via the /trading/ proxy.
  • Override_Tab: A new tab within the Trading Engine frontend page (TradingEnginePage) that provides a manual order entry form.
  • Symbol_Registry: The FastAPI service at services/symbol_registry/app.py that manages the companies table, aliases, watchlists, and data sources.
  • Broker_Service: The order execution worker at services/adapters/broker_service.py that processes order jobs from the Redis broker queue, runs risk evaluation, and submits to Alpaca.
  • Broker_Queue: The Redis list (stonks:queue:broker) where order jobs are enqueued for the Broker_Service to process.
  • Order_Form: The UI component within the Override_Tab that collects ticker, side, quantity, order type, and optional limit/stop prices from the operator.
  • Auto_Registration: The backend process that creates a new company record, default data sources, and watchlist membership when a trade is submitted for an untracked ticker.
  • Positions_Display: A read-only view of current broker positions shown within the Override_Tab for context.
  • Trading_Controls_Page: The existing frontend page at /trading (Trading.tsx) that manages trading mode, risk tier, approvals, and lockouts.

Requirements

Requirement 1: Override Tab in Trading Engine

User Story: As an operator, I want a dedicated "Override" tab in the trading engine, so that I can manually submit buy and sell orders outside the autonomous trading loop.

Acceptance Criteria

  1. THE Trading_Engine frontend SHALL display an "Override" tab in the Trading Engine page tab bar alongside existing tabs (Overview, Portfolio, Trade History, Performance, Backtest, Micro-Trading, Notifications).
  2. WHEN the operator selects the Override tab, THE Override_Tab SHALL render the Order_Form and the Positions_Display.
  3. THE Override_Tab SHALL be accessible via a URL query parameter or hash fragment so that external navigation links can open it directly.

Requirement 2: Manual Order Entry Form

User Story: As an operator, I want to enter buy or sell orders for any ticker symbol with configurable order parameters, so that I can execute trades that the autonomous engine would not initiate on its own.

Acceptance Criteria

  1. THE Order_Form SHALL accept the following inputs: ticker symbol (text, required), side (buy or sell, required), quantity (positive number, required), order type (market, limit, stop, or stop_limit), limit price (required when order type is limit or stop_limit), and stop price (required when order type is stop or stop_limit).
  2. WHEN the operator enters a ticker symbol, THE Order_Form SHALL normalize the ticker to uppercase and validate that it contains only 1 to 10 alphabetic characters.
  3. WHEN the operator selects order type "limit" or "stop_limit", THE Order_Form SHALL display the limit price input field.
  4. WHEN the operator selects order type "stop" or "stop_limit", THE Order_Form SHALL display the stop price input field.
  5. WHEN the operator submits the Order_Form with valid inputs, THE Override_Tab SHALL send a POST request to the Trading_Engine backend override order endpoint.
  6. IF the operator submits the Order_Form with missing or invalid inputs, THEN THE Order_Form SHALL display inline validation errors and prevent submission.

Requirement 3: Backend Override Order Endpoint

User Story: As the frontend, I want a backend API endpoint to accept manual override orders, so that the order can be enqueued for execution through the existing broker pipeline.

Acceptance Criteria

  1. THE Trading_Engine SHALL expose a POST endpoint at /api/trading/override/order that accepts a JSON body with fields: ticker (string), side (string: "buy" or "sell"), quantity (number), order_type (string: "market", "limit", "stop", or "stop_limit"), limit_price (optional number), and stop_price (optional number).
  2. WHEN the endpoint receives a valid order request, THE Trading_Engine SHALL enqueue a job on the Broker_Queue with the order parameters, a generated idempotency key, and the source marked as "manual_override".
  3. WHEN the endpoint receives a valid order request for a ticker that does not exist in the companies table, THE Trading_Engine SHALL invoke the Auto_Registration process before enqueuing the order.
  4. WHEN the endpoint successfully enqueues the order, THE Trading_Engine SHALL return a 202 response with the generated order job ID and a status of "queued".
  5. IF the endpoint receives an invalid request (missing required fields, invalid ticker format, non-positive quantity, missing limit_price for limit orders), THEN THE Trading_Engine SHALL return a 422 response with descriptive validation errors.
  6. IF the Broker_Queue is unreachable, THEN THE Trading_Engine SHALL return a 503 response with an error message indicating the broker queue is unavailable.

Requirement 4: Auto-Registration of Untracked Symbols

User Story: As an operator, I want the system to automatically register a new symbol when I trade it for the first time, so that the platform begins tracking, assessing, and monitoring the new symbol without manual setup.

Acceptance Criteria

  1. WHEN the Trading_Engine receives an override order for a ticker not present in the companies table, THE Auto_Registration process SHALL create a new company record in the companies table with the ticker, a legal name set to the ticker as a placeholder, and active status set to true.
  2. WHEN the Auto_Registration process creates a new company, THE Auto_Registration process SHALL create default data sources for the company: a "market_api" source for price data and a "news_api" source for news coverage.
  3. WHEN the Auto_Registration process creates a new company, THE Auto_Registration process SHALL add the company to the first active watchlist (or create a "Manual Overrides" watchlist if none exists).
  4. THE Auto_Registration process SHALL use the Symbol_Registry service endpoints to create the company, sources, and watchlist membership.
  5. IF the ticker already exists in the companies table, THEN THE Auto_Registration process SHALL skip registration and proceed with order enqueuing.
  6. IF the Symbol_Registry returns a 409 conflict (company already exists due to a race condition), THEN THE Auto_Registration process SHALL treat the conflict as a successful registration and proceed with order enqueuing.

Requirement 5: Navigation from Trading Controls Page

User Story: As an operator, I want a button on the Trading Controls page that navigates to the Override tab in the trading engine, so that I can quickly access manual trading from the controls dashboard.

Acceptance Criteria

  1. THE Trading_Controls_Page SHALL display a navigation button labeled "Override Trade" within the Trading Mode card section.
  2. WHEN the operator clicks the "Override Trade" button, THE Trading_Controls_Page SHALL navigate to the Trading Engine page with the Override tab selected.
  3. THE navigation button SHALL use the TanStack Router Link component for client-side navigation.

Requirement 6: Current Positions Display

User Story: As an operator, I want to see my current positions when placing an override trade, so that I have context about existing holdings before buying or selling.

Acceptance Criteria

  1. THE Override_Tab SHALL display a table of current positions fetched from the existing positions API endpoint (/api/positions).
  2. THE Positions_Display SHALL show for each position: ticker, quantity, average entry price, current price, and unrealized P&L.
  3. WHEN the positions data is loading, THE Positions_Display SHALL show a loading indicator.
  4. IF no positions exist, THEN THE Positions_Display SHALL show a message indicating no current positions.

Requirement 7: Order Submission Feedback

User Story: As an operator, I want clear feedback after submitting an override order, so that I know whether the order was accepted, queued, or rejected.

Acceptance Criteria

  1. WHEN the Trading_Engine backend returns a 202 response, THE Override_Tab SHALL display a success notification with the order job ID and "queued" status.
  2. WHEN the Trading_Engine backend returns a 422 response, THE Override_Tab SHALL display the validation error messages from the response body.
  3. WHEN the Trading_Engine backend returns a 503 response, THE Override_Tab SHALL display an error message indicating the broker service is unavailable.
  4. IF a network error occurs during order submission, THEN THE Override_Tab SHALL display a generic connectivity error message.
  5. WHEN an order is successfully submitted, THE Override_Tab SHALL reset the Order_Form fields to their default values.
  6. THE Override_Tab SHALL disable the submit button and show a loading state while the order request is in flight to prevent duplicate submissions.

Requirement 8: Error Handling for Invalid Tickers

User Story: As an operator, I want the system to handle invalid or non-existent tickers gracefully, so that I receive clear feedback when a trade cannot be processed.

Acceptance Criteria

  1. WHEN the operator enters a ticker that does not match the pattern of 1 to 10 uppercase alphabetic characters, THE Order_Form SHALL display a validation error before submission.
  2. IF the Broker_Service rejects the order because the broker (Alpaca) does not recognize the ticker, THEN THE Broker_Service SHALL persist the order with a "rejected" status and the rejection reason.
  3. THE operator SHALL be able to view rejected override orders in the existing Trade History tab with the rejection reason visible.

Requirement 9: Override Order Audit Trail

User Story: As an operator, I want override orders to be fully auditable, so that I can distinguish manual trades from autonomous ones and review the decision history.

Acceptance Criteria

  1. WHEN the Trading_Engine enqueues an override order, THE order job SHALL include a source field set to "manual_override" to distinguish it from autonomous orders.
  2. THE Broker_Service SHALL persist override orders in the orders table with the same schema as autonomous orders, including the decision_trace field containing the override source marker.
  3. WHEN the operator views order details for an override order, THE order detail view SHALL display the "manual_override" source in the decision trace.