Store - TradingStore

abstract

Central global state for live trading data — active account selection, open positions, pending orders, recent AI signals, kill-switch status, and broker clock skew. Persists activeAccountId to localStorage so account selection survives page refresh.

File

frontend/src/hooks/use-trading-store.ts

State Shape

interface TradingState {
  // — State —
  accounts: Account[];
  activeAccountId: number | null;
  balance: AccountBalance | null;
  openPositions: Position[];
  pendingOrders: PendingOrder[];
  recentSignals: AISignal[];
  killSwitch: KillSwitchStatus;
  brokerClockSkewMs: number;
 
  // — Actions —
  setAccounts: (accounts: Account[]) => void;
  setActiveAccount: (accountId: number | null) => void;
  updateAccount: (id: number, updates: Partial<Account>) => void;
  removeAccount: (id: number) => void;
  setBalance: (balance: AccountBalance) => void;
  setOpenPositions: (positions: Position[]) => void;
  setPendingOrders: (orders: PendingOrder[]) => void;
  addSignal: (signal: AISignal) => void;
  setKillSwitch: (status: KillSwitchStatus) => void;
  setBrokerClockSkewMs: (skewMs: number) => void;
}

State Fields

FieldTypeInitialDescription
accountsAccount[][]All registered MT5 accounts
activeAccountIdnumber | nullnullCurrently selected account ID (persisted)
balanceAccountBalance | nullnullLive balance for active account
openPositionsPosition[][]Currently open MT5 positions
pendingOrdersPendingOrder[][]Limit/stop orders awaiting fill
recentSignalsAISignal[][]Last 50 AI signals (capped via slice(0, 50))
killSwitchKillSwitchStatus{ is_active: false, reason: null, activated_at: null }Kill-switch state
brokerClockSkewMsnumber0brokerNow - Date.now() offset in ms to correct local clock drift

Actions

ActionParametersWhat it doesSide Effects
setAccounts(a)a: Account[]Replaces full accounts listNone
setActiveAccount(id)id: number | nullSets active account; persisted to localStoragePersisted via trading-store key
updateAccount(id, u)id: number, u: Partial<Account>Merges updates into matching accountNone
removeAccount(id)id: numberRemoves account; clears activeAccountId if it was activeNone
setBalance(b)b: AccountBalanceUpdates balance for active accountNone
setOpenPositions(p)p: Position[]Replaces open positions listNone
setPendingOrders(o)o: PendingOrder[]Replaces pending orders listNone
addSignal(s)s: AISignalPrepends signal; trims to 50 itemsNone
setKillSwitch(s)s: KillSwitchStatusUpdates kill-switch stateNone
setBrokerClockSkewMs(ms)ms: numberUpdates broker clock offsetNone

Persistence

PropertyValue
PersistedYes (partial)
StoragelocalStorage
Storage Keytrading-store
Excluded from persistaccounts, balance, openPositions, pendingOrders, recentSignals, killSwitch, brokerClockSkewMs
Included in persistactiveAccountId only

Data Flow

Consumers

Page / ComponentFields ReadActions Used
Page - DashboardactiveAccountId, openPositions, recentSignals, balance, killSwitchsetBalance, setOpenPositions, setKillSwitch
Page - Accountsaccounts, activeAccountIdsetAccounts, setActiveAccount, removeAccount
AppHeaderactiveAccountId, accountssetActiveAccount
KillSwitchBannerkillSwitchsetKillSwitch
DashboardProviderAll live dataAll setters (WebSocket handler)
use-websocket.tsaddSignal, setBalance, setOpenPositions, setBrokerClockSkewMs