StackTrading Docs

SRS: UC_6.2.3 — Flow 27-29: Solvency & EOD

BA in ChargeDate CreatedVersionDocument References
Trang Nguyen2026-10-12v1Zapier Integration V7.pdf (§3.1 Table C, §3.1.3 Firm_PnL_Snapshots, §3.1.4 Firm_Sim_Funnel_Snapshots, §3.1.5 Ledgers, §Flow 27, §Flow 28, §Flow 29) · RFQ_ Stack Trading Prop Tech V7.pdf (§API FCM Health Monitor, §API Run Capital Rebalance, §API Execute Treasury Transfer, §API Generate Daily Snapshots) · CHR-141 (Forex actual equity via LMAX; Net_Liquidating_Value computation — STAGE4-024) · CHR-138 (Flow 29 community_metrics — Applied) · QnA from clients 05_STAGE4_LIVE_TRADING_RISK STAGE4-004…STAGE4-024 · QnA from clients 07_STAGE6_CAREER_PATH POD-WAIT-01/POD-WAIT-15 (source for waitlist_queue, confirmed per CHR-138) · CR-15.2 · CR-20260728-005

UC_6.2.3 — Flow 27-29: Solvency & EOD

This UC owns the firm-level treasury health engine (not trader-level risk): (1) Flow 27 — an hourly, read-only Solvency Monitor that compares each institutional broker's actual equity (Ironbeam, LMAX — CHR-141) against the margin the firm must hold for its live traders; (2) Flow 28 — an hourly Treasury Sweep that acts on that comparison by queuing a Mercury pendingApproval Draft Wire for a SEV1 Deposit (CEO/CFO approves manually) and posting a Slack-only alert for a SEV3 Withdrawal (no Mercury call) and recording every event in the treasury_transfer_log table; (3) Flow 29 — a daily EOD snapshot that writes Firm_PnL_Snapshots and Firm_Sim_Funnel_Snapshots and posts the Firm Health Report. All three flows run as background crons with no UI — output goes to Slack #ops-treasury (Ref: CR-15.2). Trader-level liquidation (including Profit Target liquidation through the MT5 plugin) is not part of this UC and has no effect on its logic (BR_6.2.3.14). Business Intelligence dashboards (PowerBI) are out of scope (BR_6.2.3.14).

📌 Note — Live-only scope. All three flows belong to the firm's Live treasury engine and exist because Live accounts hold real money at real institutional brokers (Ironbeam/LMAX — CHR-141). SIM accounts have no FCM margin, no broker equity and no treasury transfer, so Flow 27 (Solvency Monitor) and Flow 28 (Treasury Sweep) never read, evaluate, or act on SIM data in any way. Flow 29's "Simulation Funnel Snap" (BR_6.2.3.17) does not change this: it does not monitor or operate on SIM accounts — it only counts that day's SIM outcomes (challenges passed/failed, new sales/resets) as a business metric reported alongside the Live Performance Snap in the same EOD report, the same way the report also lists trader_count or total_pnl. No SIM account is evaluated, flagged, or acted upon by any of the three flows.

📌 CR — CHR-141 (2026-10-20, Active — ✅ confirmed by the client). For Forex, the liquidation provider is LMAX, replacing Forex.com and Interactive Brokers; Futures (Ironbeam) is unchanged. Every place in this document that names LMAX as the Forex institution is marked CHR-141 and derives from this CR, which the client has confirmed. The CR's Open Questions (LMAX API/credentials, required-equity formula with a single LP, effective date, handling of old treasury_transfer_log rows) are not yet answered by the client.

1. Overview

FieldContent
IDUC_6.2.3
Use CaseFlow 27-29 — Solvency & EOD
DescriptionFlow 27 (hourly): GET /financial/fcm-health evaluates the two institutions (Ironbeam, LMAX — CHR-141) independently and posts one Solvency Report block per institution to Slack. Flow 28 (hourly): POST /financial/run-rebalance re-evaluates from a fresh snapshot, queues a Mercury Draft Wire awaiting CEO/CFO approval for a SEV1 Deposit, or returns a Slack-only surplus alert for a SEV3 Withdrawal (no Mercury call), skips duplicates, and logs every event to treasury_transfer_log. Flow 29 (daily, 5:05 PM EST): POST /financial/daily-snap aggregates live and simulation performance, writes both snapshot tables, and posts the EOD Firm Health Report.
Zapier FlowFlow 27 — Hourly Solvency Monitor · Flow 28 — Hourly Automated Treasury Sweep · Flow 29 — Daily EOD Performance and Funnel Report
Zapier TableTable C (Global_Var_FCM_Margin_Ratio, Global_Var_FCM_Target_Buffer, Global_Var_FCM_Danger_Buffer, Global_Var_FCM_Withdraw_Threshold) · Ledgers (§3.1.5, read) · Firm_PnL_Snapshots (§3.1.3, write) · Firm_Sim_Funnel_Snapshots (§3.1.4, write) · treasury_transfer_log (new, read/write)
3rd PartyIronbeam API (Net Liquidating Value) · LMAX API (Net Liquidating Value, Forex — CHR-141) · YourBourse Bridge API (aggregate open Forex notional at LMAX) · Mercury Banking API (request-send-money Draft Wire, SEV1 Deposit only) · AWS Secrets Manager (Mercury UUIDs) · Slack (#ops-treasury) · Rithmic/MT5 API (per-trader open/closed P&L for Flow 29)

No wireframe — status_design = No Need Screen (background crons; the only output surface is Slack).


2. Trigger

FlowTriggerEndpoint
Flow 27Schedule by Zapier — hourlyGET /financial/fcm-health
Flow 28Schedule by Zapier — hourly, payload force_execution: truePOST /financial/run-rebalance
Flow 29Schedule by Zapier — daily at 5:05 PM EST (5 minutes after market close)POST /financial/daily-snap

The schedules are fixed in Zapier. These are background crons: there is no UI from which a user can observe or trigger them (BR_6.2.3.15).


3. Pre-conditions

IDCondition
P-1Table C contains Global_Var_FCM_Margin_Ratio, Global_Var_FCM_Target_Buffer, Global_Var_FCM_Danger_Buffer, Global_Var_FCM_Withdraw_Threshold (BR_6.2.3.1).
P-2Live traders are recorded in Ledgers with is_active = TRUE (Flow 27/28 required-equity input, Flow 29 aggregation input).
P-3Ironbeam, LMAX (CHR-141), YourBourse Bridge, and Mercury API credentials plus the Mercury destination config (opaque UUIDs MERCURY_SOURCE_ACCOUNT_ID, MERCURY_IRONBEAM_RECIPIENT_ID, MERCURY_BOFA_RECIPIENT_ID in AWS Secrets Manager, recipients pre-configured in the Mercury dashboard — BR_6.2.3.10) are available to the middleware. Per-institution unavailability is handled by BR_6.2.3.6.
P-4Slack channel #ops-treasury (ID C0BRCCMN1MG) is reachable.
P-5PostgreSQL tables Firm_PnL_Snapshots, Firm_Sim_Funnel_Snapshots, and treasury_transfer_log exist.

4. Post-conditions

Flow 27 — A Solvency Report block per returned institution is posted to #ops-treasury. No money moves and no data is written.

Flow 28 — For every institution with severity = SEV1, a Mercury Draft Wire (pendingApproval, awaiting CEO/CFO approval) has been queued; for every institution with action = WITHDRAW, a surplus alert has been returned for manual CEO/CFO withdrawal (no Mercury call), unless skipped by BR_6.2.3.9. Every queued Draft Wire and every Withdrawal alert has one row in treasury_transfer_log. A treasury report is posted to #ops-treasury.

Flow 29 — One day's rows exist in Firm_PnL_Snapshots (one row per level_id) and one row in Firm_Sim_Funnel_Snapshots; the EOD Firm Health Report is posted to #ops-treasury. If the job failed to run or write, a Severity 1 alert has been pushed to #ops-treasury (BR_6.2.3.13).


5. Basic Flow

5.1 Flow 27 — Hourly Solvency Monitor

📌 Live-only. This entire flow operates on Live accounts only. SIM accounts never have institutional broker equity or FCM margin, so SIM data is never read, evaluated, or reported by Flow 27.

  1. Trigger. Zapier fires the hourly schedule and calls GET /financial/fcm-health. No input payload (see Trigger table).

  2. Calculate required equity per institution. Both asset classes now use the identical formula, read directly from the PostgreSQL Ledgers table (BR_6.2.3.2):

    Ironbeam_Required_Equity   = SUM(allocated_capital of ALL active Live Futures traders in Ledgers) × Global_Var_FCM_Margin_Ratio
    Forex_LMAX_Required_Equity = SUM(allocated_capital of ALL active Live Forex traders in Ledgers)   × Global_Var_FCM_Margin_Ratio   ⚠️ CHR-141

    ⚠️ CHR-141: Forex now has a single institution, LMAX (CHR-141), so one Forex formula replaces the former per-LP pair (Forex_Com_Required / IBKR_Required). Per client confirmation (STAGE4-022), Forex_LMAX_Required_Equity is now computed directly from Ledgers, identical to Futures — it is no longer derived from LMAX aggregate open notional via the YourBourse Bridge API. The Bridge is no longer queried for this calculation.

    ComponentMeaningSource
    allocated_capitalCapital allocated to each active Live trader (Futures or Forex)Ledgers table, rows where is_active = TRUE
    Global_Var_FCM_Margin_Ratio0.10 — % of allocated capital required as margin backing. One shared variable for both Futures and Forex, read dynamically from Table C every run (never hardcoded)Zapier Table C

    This step queries the PostgreSQL Ledgers table directly for both institutions and does not depend on the MT5 platform (BR_6.2.3.14).

  3. Get actuals. For Ironbeam, call Ironbeam's own API for Net_Liquidating_Value directly — the institution's actual equity (Actual in step 4). For LMAX (Forex — ⚠️ CHR-141), LMAX exposes no single Net_Liquidating_Value field, so it must be computed from two LMAX calls — ⚠️ STAGE4-024:

    LMAX_Wallet_Cash  = GET /v1/account/wallets → USD wallet's `cash` field (or `balance` if `credit` = 0)
    LMAX_Open_MTM_PnL  = GET /v1/account/positions (getInstrumentPositions) → for each open net position
                         (instrument_id, open_quantity, open_cost, side: BID/ASK):
                         **unrealized MTM = Current_Market_Value(open_quantity) − open_cost**
                         (priced off the live LMAX/TraderEvolution feed, or summed as live `open_pnl`
                         across active Live Forex sub-accounts on TraderEvolution/MT5)
    Net_Liquidating_Value (LMAX) = LMAX_Wallet_Cash + LMAX_Open_MTM_PnL
                                    (= LMAX_Settled_Cash alone if there are no open positions)

    If a call (Ironbeam's single call, or either of LMAX's two calls) times out or errors, that institution is dropped from the result array for this run and the error is written to the error log; the other institution's processing is unaffected. See BR_6.2.3.6.

    📌 CHR-141: for Forex, the actual equity is retrieved from the LMAX API (computed per STAGE4-024 above); the Forex.com and Interactive Brokers APIs are no longer called. The Ironbeam call is unchanged. Per-institution failure handling (BR_6.2.3.6) applies to LMAX as well — a failure in either of LMAX's two underlying calls drops LMAX from the result array for that run. See CHR-141.

  4. Evaluate — for each institution still present after step 3, independently compute three threshold lines from its Required_Equity (step 2), then classify against its Actual (step 3):

    Target_Line = Required_Equity × Global_Var_FCM_Target_Buffer      (1.3)
    Danger_Line = Target_Line     × Global_Var_FCM_Danger_Buffer      (0.80)
    Excess_Line = Target_Line     × Global_Var_FCM_Withdraw_Threshold (1.25)
    ComponentMeaningSource
    Required_EquityOutput of step 2 for this institutionStep 2
    Global_Var_FCM_Target_Buffer1.3 — ideal operating balance multiplier over the bare required equityTable C
    Global_Var_FCM_Danger_Buffer0.80 — fraction of Target_Line below which the institution is under-funded (SEV1)Table C
    Global_Var_FCM_Withdraw_Threshold1.25 — multiple of Target_Line above which surplus becomes eligible for withdrawalTable C

    Then, per the case table below (same cases as BR_6.2.3.3), set action, severity, amount and build slack_message:

    CaseConditionactionseverityamountslack_message
    Deposit (chunking)Actual < Danger_LineDEPOSITSEV1Deposit_Amount = MAX(Shortfall, $50,000), Shortfall = Target_Line − Actual🚨 CRITICAL: [Institution] SOLVENCY RISK. Initiating Emergency Deposit of $[Deposit_Amount].
    Withdrawal (floors)Actual > Excess_Line AND Actual > $100,000, and Surplus = Actual − Target_Line ≥ $50,000WITHDRAWSEV3Withdraw_Amount = Surplus💰 Surplus: Excess capital detected at [Institution]. Withdrawal of $[Withdraw_Amount] available.
    NoneotherwiseNONENONE0summary string stating no action required
  5. Return the array of institution objects to Zapier — one object per institution that survived step 3, each carrying institution, fcm_equity (= Actual), required (= Required_Equity), action, amount, severity, slack_message. See BR_6.2.3.4.

  6. Operations Report (Always Run). This step always executes, every hour, regardless of what action came back. Zapier iterates dynamically over the returned array and posts one distinct block per institution to Slack #ops-treasury (Ref: CR-15.2) — Ironbeam and LMAX (CHR-141) are always separate blocks. For each institution, Zapier first derives buffer_health from severity (SEV1 → "DANGER", NONE → "HEALTHY", SEV3 → "SURPLUS") and sets required_equity = the payload's required field (BR_6.2.3.5), then posts:

    Hourly Solvency Report: [institution]
    Status: [buffer_health]
    FCM Equity: $[fcm_equity]
    Required Buffer: $[required_equity]
    Action Required: [action] ($[amount])

    An institution missing from the step-5 array (because step 3 dropped it) simply produces no block that hour. See BR_6.2.3.7.

5.2 Flow 28 — Hourly Automated Treasury Sweep

📌 Live-only. This entire flow operates on Live accounts only — the institutions, Mercury Draft Wires, and treasury_transfer_log rows it manages all belong to the firm's real-money Live treasury. SIM accounts have no institutional broker presence and are never touched by this flow.

  1. Trigger. Zapier fires the hourly schedule and calls POST /financial/run-rebalance with input force_exec (Boolean) set to force_execution: true. This flag is fixed by the cron — there is no manual invocation path with it set to false for this UC.

  2. Fresh snapshot. The endpoint re-runs the entire step-2/3/4 calculation of Flow 27 (5.1) from scratch at the moment it fires — same formulas, same Table C variables, same Ledgers/YourBourse Bridge/institution-API sources — producing its own Required_Equity, Target_Line, Danger_Line, Excess_Line, action, severity, amount per institution. It deliberately does not reuse Flow 27's output: Flow 28 moves real money, so it must act on the real-time account state at the moment it fires, even if that differs slightly (a few seconds) from Flow 27's last report. See BR_6.2.3.8.

  3. Loop through the returned institutions and, per institution:

    1. Duplicate check (runs first, before any transfer is created) — Deposit only. Query treasury_transfer_log (BR_6.2.3.11) for this institution: does a Deposit row for this institution already exist with timestamp on the current calendar day? If yes → skip this institution for this hour, no Slack alert (the skip is silent).

    2. Act per case, by institution's action/severity from step 2:

      CaseConditionDuplicate check (3.1)Mercury calltreasury_transfer_log row (3.3)Slack message
      SEV1 Depositseverity = SEV1Runs. Deposit row for this institution already logged today? → skip (silent), go to next institutionPOST .../request-send-money (domesticWire, pendingApproval) via the shared execute-treasury-transfer sub-routine, amount = Deposit_Amount, direction = "Deposit". recipientId = MERCURY_IRONBEAM_RECIPIENT_ID (Ironbeam) or MERCURY_BOFA_RECIPIENT_ID (Forex/LMAX — Mercury → BofA, CEO/CFO forwards BofA → LMAX)direction = Deposit, Mercury ID = draft_id (empty if the call failed)✅ Draft Treasury Wire generated via Mercury. Awaiting CEO or CFO Approval. Amount: $[amount], Direction: [direction], Destination: [Institution]. Link: [Mercury_Draft_Link]
      SEV3 Withdrawalaction = WITHDRAWDoes not run (no Draft Wire exists for a Withdrawal, so nothing to dedupe)None — a bank cannot pull a wire from a broker/LPdirection = Withdrawal, amount = Surplus, Mercury ID = empty💰 Surplus: Excess capital detected at [Institution]. Withdrawal of $[Withdraw_Amount] available. Awaiting CEO/CFO manual withdrawal to [Mercury / BofA].
      Noneaction = NONE—NoneNo row writtenPlain "no action required" summary string

      Detail per case:

      • SEV1 Deposit — call the shared execute-treasury-transfer sub-routine with amount = Deposit_Amount (computed in step 2, same formula as Flow 27 step 4), direction = "Deposit", institution = <name>. The sub-routine reads the opaque Mercury UUIDs from AWS Secrets Manager and calls Mercury's approval-queue endpoint POST https://api.mercury.com/api/v1/account/{accountId}/request-send-money with paymentMethod = "domesticWire", recipientId, amount = Deposit_Amount and an idempotencyKey. accountId = MERCURY_SOURCE_ACCOUNT_ID; recipientId = MERCURY_IRONBEAM_RECIPIENT_ID for Ironbeam (Futures) or MERCURY_BOFA_RECIPIENT_ID for the Forex institution (LMAX requires wires to come from the firm's Bank of America account, which has no draft-wire API — Mercury → BofA is queued and the CEO/CFO forwards the wire from BofA to LMAX). Mercury creates a pendingApproval Draft Wire — money has not moved; the CEO/CFO must approve it in Mercury (no auto-execution of live wires). The sub-routine returns { "draft_id": "string", "slack_confirm": "string" }. See BR_6.2.3.10.
      • SEV3 Withdrawal — do not call the Mercury API. The sub-routine only returns the Slack message above, with Withdraw_Amount = Surplus (from step 2) and the return account Mercury (Ironbeam) or BofA (Forex/LMAX). The CEO/CFO withdraws manually at the institution. See BR_6.2.3.10.
    3. Record. For the SEV1 Deposit and SEV3 Withdrawal cases, insert one row into treasury_transfer_log: timestamp (now), institution, direction (Deposit or Withdrawal), amount, and Mercury ID (the draft_id of the Draft Wire for a Deposit; empty for a Withdrawal — no Mercury call). A failed Mercury call writes no Draft Wire ID. The Deposit rows this writes are what step 3.1 checks on the next run (Withdrawal rows are written for audit/history only — step 3.1 no longer reads them). See BR_6.2.3.11.

  4. Return notification. The endpoint returns { "status": "executed", "slack_alert_text": [string] } — one message per institution that was processed this hour, including institutions whose action was NONE (their summary string, e.g. "no action required", is still included). If the Mercury call in the SEV1 Deposit case (step 3.2) failed, that institution's message is prefixed ❌ FAILURE: and is posted as a SEV1 alert so the CEO/CFO can initiate the wire manually (see Exc-2). See BR_6.2.3.12.

  5. Treasury Report (Always Run). Zapier posts every string in slack_alert_text to #ops-treasury as-is (no further template substitution — the messages are already fully formed by step 4).

5.3 Flow 29 — Daily EOD Performance and Funnel Report

📌 Live-only flow; SIM appears only as a counted outcome, never as a monitored environment. This flow belongs to the Live treasury engine like Flow 27/28. Step 3 ("Simulation Funnel Snap") does not mean this flow operates on SIM accounts — it never evaluates, flags, or acts on any SIM account. It only tallies that day's SIM outcomes (how many challenges were passed/failed, new sales/resets) as a sales-funnel metric, reported in the same EOD message as the Live Performance numbers. The actual SIM challenge rules, pass/fail evaluation, and risk monitoring live entirely in the SIM-side UCs (e.g. UC_4.10.1/UC_4.10.2) — this flow only reads their end-of-day result counts.

  1. Trigger. Zapier fires daily at 5:05 PM EST (22:05 UTC, or 21:05 UTC during daylight saving time — 5 minutes after market close) and calls POST /financial/daily-snap with no input.

  2. Live Performance Snap. Build the live-trading side of the report:

    1. Identify: query Ledgers for all active Live traders (is_active = TRUE, Live account type).

    2. Group: bucket those traders by level_id.

    3. Sync P&L: for each trader, call the Rithmic/MT5 API for open_pnl (unrealized, mark-to-market) and closed_pnl_day (realized, today only).

    4. Aggregate per level: trader_count (count of traders in the level), unrealized_pnl (sum of open_pnl), realized_pnl (sum of closed_pnl_day), total_pnl = unrealized_pnl + realized_pnl, allocated_capital (sum of each trader's notional, i.e. "Level Notional"), daily_loss_limit ("Stop" — the level's configured max daily loss).

    5. Calculate the deposit requirement:

      deposit_req = Level Notional × Global_Var_FCM_Target_Buffer
      ComponentMeaningSource
      Level Notionalallocated_capital aggregated in step 2.4 aboveLedgers
      Global_Var_FCM_Target_Buffer1.3 — same buffer multiplier Flow 27/28 use for Target_Line, read dynamically from Table C (not the RFQ's typo'd 0.80)Table C
    6. Insert one row per level_id into Firm_PnL_Snapshots: day, time, level_id, trader_count, aggregate_notional, aggregate_deposit_req (= deposit_req), aggregate_target, aggregate_stop (= daily_loss_limit), unrealized_pnl, realized_pnl, total_pnl. See BR_6.2.3.16.

  3. Simulation Funnel Snap. Build the challenge-funnel side of the report, all scoped to "today":

    MetricHow it's computedSource
    conversions_newCount of payments rows today where type = NEWpayments table
    conversions_resetsCount of payments rows today where type = RESETpayments table
    active_simsCount of users with status = SIM_ACTIVEuser/account status
    sims_passedCount of users whose status changed to PASSED todayuser/account status change log
    sims_failedCount of users whose status changed to FAILED todayuser/account status change log
    pass_percentsims_passed / (sims_passed + sims_failed)derived from the two rows above
    avg_pass_fail_durationAVG(Today's Status_Change_Date − Sim_Start_Date) across users counted in sims_passed/sims_faileduser/account dates

    Insert one row into Firm_Sim_Funnel_Snapshots: day, time, conversions_new, conversions_resets, active_sims, sims_passed, sims_failed, pass_percent, avg_pass_fail_duration. See BR_6.2.3.17. This table is the input the Pass Rate Aggregator (UC_2.1.1) later sums for cached_pass_rate, so a missing day here directly skews that number — hence step 5's hard requirement.

  4. Community & Mentorship Snap (CHR-138). Two additional lightweight queries give daily visibility on pod mentorship supply/demand:

    MetricHow it's computedSource
    waitlist_queueCOUNT(Users WHERE status = 'Waitlist') — a fresh live count, not a counterUsers table
    available_pod_slotsSUM(Max_Capacity − Current_Count) over Pod_Leader_Registry rows where Status = 'Active'Pod_Leader_Registry (Table E)

    Build the community_metrics object: { "waitlist_queue": <int>, "available_pod_slots": <int> }. This object does not write to Firm_PnL_Snapshots or Firm_Sim_Funnel_Snapshots — it is reporting-only, appended straight to the step-6 response payload. See BR_6.2.3.20.

  5. Persist. Both inserts (step 2.6 and step 3) must succeed. If the cron does not run at all, or either write to PostgreSQL fails, the Node.js middleware immediately pushes a Severity 1 alert to #ops-treasury (content: a plain alert stating the daily snapshot failed and must be triggered manually — no fixed template is specified). No automatic retry is defined; a human must re-trigger the endpoint manually. A missing day in the time-series is explicitly called out as unacceptable. See BR_6.2.3.13. Step 4's community_metrics is not persisted to a time-series table, so it is not covered by this Severity 1 gate — a failure there does not block steps 2/3's persistence.

  6. Return the response payload — built directly from steps 2, 3 and 4, with the exact field names the Flow 29 Slack template and Firm_Sim_Funnel_Snapshots expect so Zapier needs no transformation: day, trader_count, total_pnl, realized_pnl, unrealized_pnl, deposit_req, sim_metrics (new_sales, resets, passed, failed, pass_percent, avg_duration_days), and community_metrics (waitlist_queue, available_pod_slots — CHR-138). See BR_6.2.3.18.

  7. Slack report. Zapier maps the step-6 payload directly into the template placeholders and posts to #ops-treasury:

    EOD Firm Health Report: [day]
    Live Performance
      Number of Live Traders: [trader_count]
      Total Firm P&L: $[total_pnl]
      Realized P&L: $[realized_pnl]
      Unrealized P&L: $[unrealized_pnl]
      Target Buffer Requirement: $[deposit_req]
    Simulation Funnel
      Sales: [new_sales] New / [resets] Resets
      Challenge Velocity: [passed] Passed / [failed] Failed
      Pass Rate: [pass_percent]%
      Avg. Time to Outcome: [avg_duration_days] Days
    Community & Mentorship
      Total Waitlist Queue: [community_metrics.waitlist_queue]
      Available Pod Slots: [community_metrics.available_pod_slots]
    Full Level-by-Level breakdown available in PowerBI.

    The "Community & Mentorship" block (CHR-138, Applied) is inserted after "Simulation Funnel" and before the PowerBI line. The PowerBI line is informational text only — PowerBI integration itself is out of scope for this UC (BR_6.2.3.14). This flow runs before the Pass Rate Aggregator (00:00 UTC), so cached_pass_rate reads same-day data with no one-day lag. See BR_6.2.3.19.


6. Alternative Flows

  • Alt-1 — action = NONE (balance inside the safe band).

    • Context: the institution's Actual is between Danger_Line and Excess_Line, or above Excess_Line but not meeting the withdrawal floors.
    • Flow 27 still posts the institution's block (status HEALTHY); Flow 28 executes nothing for it but its summary string is still returned and posted ("Always Run").
  • Alt-2 — Surplus persists across multiple hours (no Withdrawal dedupe).

    • Context: an institution's Actual keeps meeting the Withdrawal condition hour after hour because the CEO/CFO has not yet withdrawn the surplus manually.
    • Because a Withdrawal never creates a Mercury Draft Wire, there is nothing in treasury_transfer_log for step 3.1 to dedupe against (BR_6.2.3.9). Flow 28 re-sends the surplus alert every hour the condition still holds, until the CEO/CFO withdraws the funds and Actual drops back inside the safe band. This is expected, not a defect.

7. Exceptional Flows

  • Exc-1 — One institution's API (Ironbeam / LMAX — CHR-141) times out or returns an error.

    • /financial/fcm-health returns the array containing only the institutions that succeeded and writes an error log entry for the failed one. The monitoring of the other institutions is unaffected. Flow 28 and Flow 27 operate on the returned subset. See BR_6.2.3.6.
  • Exc-2 — The Mercury request-send-money call for a SEV1 Deposit fails (API error, timeout or validation error).

    • The endpoint catches the error, prepends ❌ FAILURE: to that institution's slack_alert_text, and fires the SEV1 alert to #ops-treasury so the CEO/CFO can initiate the wire manually. (A SEV3 Withdrawal makes no Mercury call and so cannot fail this way.) See BR_6.2.3.12.
  • Exc-3 — /financial/daily-snap does not execute or fails to write to PostgreSQL.

    • The Node.js middleware immediately pushes a Severity 1 alert to #ops-treasury so the team can trigger the endpoint manually. A missing day in the time-series is not acceptable. See BR_6.2.3.13.

8. Business Rules

BR_6.2.3.1: Global variables (Table C)

Flow 27/28/29 read these Table C variables. Values are read dynamically — never hardcoded in a formula.

VariableValueUsed for
Global_Var_FCM_Margin_Ratio0.10% of allocated capital required as backing. Single shared variable for both Futures and Forex — there are no separate Global_Var_Futures_Margin_Ratio / Global_Var_Forex_Margin_Ratio variables.
Global_Var_FCM_Target_Buffer1.3Ideal operating balance multiplier. Used for Target_Line (Flow 27/28) and deposit_req (Flow 29).
Global_Var_FCM_Danger_Buffer0.80Fraction of Target_Line below which the institution is in danger (SEV1).
Global_Var_FCM_Withdraw_Threshold1.25Multiple of Target_Line above which the institution is eligible for withdrawal.

Global_Var_FCM_Excess_Buffer (1.6) is deprecated and removed from Table C and is not used anywhere in this UC. Global_Var_FCM_Danger_Buffer and Global_Var_FCM_Withdraw_Threshold are added to Table C.

(Source: QnA from clients — STAGE4-005, STAGE4-013, STAGE4-004; Zapier Integration V7.pdf §3.1 Table C, as amended)


BR_6.2.3.2: Required equity calculation

Required equity is calculated per institution, both directly from the PostgreSQL Ledgers table using the identical formula shape:

  • Futures — Ironbeam: query Ledgers for ALL active Live Futures traders. Ironbeam_Required_Equity = SUM(ledgers.allocated_capital) × Global_Var_FCM_Margin_Ratio.
  • Forex — LMAX: query Ledgers for ALL active Live Forex traders. Forex_LMAX_Required_Equity = SUM(ledgers.allocated_capital) × Global_Var_FCM_Margin_Ratio (also referred to as Global_Var_Forex_Margin_Ratio in Table C — see BR_6.2.3.1; it is the same shared variable, not a separate one). ⚠️ CHR-141 / STAGE4-022 (confirmed by client): LMAX replaces Forex.com and Interactive Brokers as the Forex institution, and the required-equity source switches from the YourBourse Bridge's aggregate open notional to the same Ledgers-based calculation Futures uses. The Bridge API is no longer queried for Required_Equity.

The solvency monitor reads Required_Equity for both institutions from the firm's own Ledgers table. Each institution's actual equity (Actual, step 3/BR_6.2.3.3) is still pulled live from that institution's own API (Ironbeam directly; LMAX for Forex via the computed formula in BR_6.2.3.3/STAGE4-024) and does not depend on the MT5 platform (BR_6.2.3.14).

(Source: QnA from clients — STAGE4-004, STAGE4-007, STAGE4-022; RFQ_ Stack Trading Prop Tech V7.pdf §API FCM Health Monitor steps 1-2)


BR_6.2.3.3: Line evaluation, action, amount and severity

Executed independently for each returned institution. Actual = the institution's Net_Liquidating_Value; Required_Equity per BR_6.2.3.2.

⚠️ LMAX has no direct Net_Liquidating_Value field (STAGE4-024). For Ironbeam, Actual is read directly from Ironbeam's API. For LMAX, Actual is computed:

Actual (LMAX) = LMAX_Settled_Cash + LMAX_Open_MTM_PnL
  LMAX_Settled_Cash = GET /v1/account/wallets → USD wallet `cash` (or `balance` if `credit` = 0)
  LMAX_Open_MTM_PnL = GET /v1/account/positions (getInstrumentPositions) → sum of unrealized
                      MTM (Current_Market_Value(open_quantity) − open_cost) over all open net
                      positions, priced off the live LMAX/TraderEvolution feed, or the summed
                      live open_pnl across active Live Forex sub-accounts on TraderEvolution/MT5

With no open LMAX positions, Actual (LMAX) = LMAX_Settled_Cash alone. See also BR_6.2.3.2 and Basic Flow §5.1 step 3.

Target_Line = Required_Equity × Global_Var_FCM_Target_Buffer      (1.3)
Danger_Line = Target_Line     × Global_Var_FCM_Danger_Buffer      (0.80)
Excess_Line = Target_Line     × Global_Var_FCM_Withdraw_Threshold (1.25)
CaseConditionactionseverityamountslack_message
Deposit (chunking)Actual < Danger_LineDEPOSITSEV1Deposit_Amount = MAX(Shortfall, $50,000), Shortfall = Target_Line − Actual🚨 CRITICAL: [Institution] SOLVENCY RISK. Initiating Emergency Deposit of $[Deposit_Amount].
Withdrawal (floors)Actual > Excess_Line AND Actual > $100,000, and Surplus = Actual − Target_Line ≥ $50,000WITHDRAWSEV3Withdraw_Amount = Surplus💰 Surplus: Excess capital detected at [Institution]. Withdrawal of $[Withdraw_Amount] available.
NoneotherwiseNONENONE0summary string stating no action required

(Source: RFQ_ Stack Trading Prop Tech V7.pdf §API FCM Health Monitor steps 4-7; the typo Global_Var_FCM_Target_Buffer (0.80) in that source is corrected to the Table C value 1.3; QnA from clients — STAGE4-005, STAGE4-024 (LMAX Actual computation))


BR_6.2.3.4: /financial/fcm-health response contract

GET /financial/fcm-health — no input (scheduled hourly). Returns an array of up to two objects (one per successfully queried institution):

FieldTypeNotes
institutionString"Ironbeam" or "LMAX" (CHR-141)
fcm_equityFloatActual Net_Liquidating_Value
requiredFloatRequired_Equity (BR_6.2.3.2)
actionStringDEPOSIT, WITHDRAW, or NONE
amountFloatDeposit_Amount, Withdraw_Amount, or 0
slack_messageStringPer BR_6.2.3.3
severityStringSEV1, SEV3, or NONE

(Source: RFQ_ Stack Trading Prop Tech V7.pdf §API FCM Health Monitor)


BR_6.2.3.5: Derived Slack fields (buffer_health, required_equity)

The Slack template (Flow 27) uses two names that are not fields of the BR_6.2.3.4 payload. They are derived by the template, not returned by the endpoint:

Template fieldDerivation
required_equityEquals the payload field required
buffer_healthDerived from severity: SEV1 → "DANGER", NONE → "HEALTHY", SEV3 → "SURPLUS"

(Source: QnA from clients — STAGE4-006)


BR_6.2.3.6: Graceful degradation when an institution API fails

If one institution's API (Ironbeam or LMAX — CHR-141) times out or returns an error, /financial/fcm-health does not abort. It returns the array containing only the institutions that succeeded, and logs the error for the failed institution. Downstream flows (27, 28) operate on whatever institutions are present in the returned array.

(Source: QnA from clients — STAGE4-015)


BR_6.2.3.7: Flow 27 Slack report format (#ops-treasury)

The Operations Report always runs (every hour, regardless of action). Zapier iterates dynamically over the returned JSON array and posts one distinct block per institution — Ironbeam and LMAX (CHR-141), i.e. two blocks (previously three: Ironbeam, Forex.com, Interactive Brokers).

Per-institution block (same layout for each):

Hourly Solvency Report: [institution]
Status: [buffer_health]
FCM Equity: $[fcm_equity]
Required Buffer: $[required_equity]
Action Required: [action] ($[amount])

An institution missing from the array (BR_6.2.3.6) produces no block. Channel: #ops-treasury (Ref: CR-15.2).

(Source: Zapier Integration V7.pdf §Flow 27; QnA from clients — STAGE4-014)


BR_6.2.3.8: Flow 28 uses a fresh, independent data snapshot

POST /financial/run-rebalance step 1 re-calls /financial/fcm-health logic from scratch each run. It MUST NOT reuse Flow 27's result. Flow 28 is the financial execution step and must rely on the real-time state of the accounts at the moment it fires; a few seconds' difference from Flow 27's read-only report is acceptable.

(Source: QnA from clients — STAGE4-008; RFQ_ Stack Trading Prop Tech V7.pdf §API Run Capital Rebalance step 1)


BR_6.2.3.9: Duplicate transfer prevention

Because Flow 28 runs hourly, the middleware MUST NOT generate a duplicate transfer for the same unresolved condition:

  • SEV1 Deposit (Mercury Draft Wire): before queuing, query the database (treasury_transfer_log, BR_6.2.3.11) for an existing Deposit row for the target institution on the current calendar day. If one exists, no new Draft Wire is queued for that institution this hour. The Mercury idempotencyKey is an additional safeguard on the API call.
  • SEV3 Withdrawal (surplus alert): no dedupe check runs. A Withdrawal never creates a Mercury Draft Wire — there is nothing a duplicate Draft Wire could duplicate — so the step-3.1 duplicate check does not apply to it. Flow 28 re-sends the surplus alert every hour the surplus condition still holds, until the CEO/CFO withdraws the funds manually and Actual drops back inside the safe band.
  • A skipped Deposit is silent: no Slack alert is sent for the skip.

⚠️ Change from STAGE4-016. The client's original answer (STAGE4-016) called for dedupe on both directions. Per user instruction (BA session), this rule now dedupes Deposit only — Withdrawal dedupe is removed because a Withdrawal makes no Mercury call and so has no Draft Wire row to check for. This is a documentation-only change pending client re-confirmation; flagged here rather than silently reusing the STAGE4-016 citation for the new Withdrawal behavior.

(Source: QnA from clients — STAGE4-016, Deposit dedupe only; Withdrawal dedupe removed per user instruction, BA session 2026-10-29 — pending client re-confirmation)


BR_6.2.3.10: Emergency vs. Scheduled execution

Flow 28 treats the two directions differently:

TriggerExecutionApproval
SEV1 — Deposit (margin rescue)severity = SEV1Mercury Draft Wire via POST /api/v1/account/{accountId}/request-send-money (domesticWire, status pendingApproval) for Deposit_Amount. Ironbeam → recipientId = MERCURY_IRONBEAM_RECIPIENT_ID; Forex (LMAX) → recipientId = MERCURY_BOFA_RECIPIENT_ID (Mercury → BofA, CEO/CFO then forwards BofA → LMAX)Always requires manual CEO or CFO approval in Mercury — no live wire is ever auto-executed
SEV3 — Withdrawal (profit harvesting)force_execution = true AND action = WITHDRAWNo Mercury call. Returns a Slack-only surplus alert for Withdraw_Amount (a bank cannot pull a wire from a broker/LP)Manual CEO or CFO withdrawal at the institution, back to Mercury (Ironbeam) or BofA (LMAX)

force_execution: true is a fixed flag of the hourly cron; there is no manual or alternative invocation path with force_execution = false defined for this UC. Both directions use the same execute-treasury-transfer sub-routine, which branches on direction.

Destination Config — no raw bank details. Raw bank account numbers, ABA routing numbers and SWIFT codes are never stored in the database or codebase, or passed in payloads. Recipients are pre-configured in the Mercury web dashboard; only opaque Mercury UUIDs are stored in AWS Secrets Manager:

SecretMeaning
MERCURY_SOURCE_ACCOUNT_IDUUID of the firm's Mercury treasury account ({accountId} in the endpoint)
MERCURY_IRONBEAM_RECIPIENT_IDUUID of the pre-configured Ironbeam recipient in Mercury
MERCURY_BOFA_RECIPIENT_IDUUID of the firm's corporate Bank of America recipient in Mercury

Funding rails. Ironbeam (Futures) is funded from, and withdrawn back to, the same Mercury account. LMAX (Forex) requires wires to originate from and return to the firm's BofA account; since BofA has no draft-wire API, a LMAX SEV1 Deposit still calls Mercury /request-send-money with recipientId = MERCURY_BOFA_RECIPIENT_ID.

Failure handling. If the Mercury call fails for any reason, the message is prefixed ❌ FAILURE: and fired as a SEV1 alert to #ops-treasury (BR_6.2.3.12). A SEV3 Withdrawal returns "💰 Surplus: Excess capital detected at [Institution]. Withdrawal of $[Withdraw_Amount] available. Awaiting CEO/CFO manual withdrawal to [Mercury / BofA]."; for a Deposit the sub-routine returns slack_confirm: "✅ Draft Treasury Wire generated via Mercury. Awaiting CEO or CFO Approval. Amount: $[amount], Direction: [direction], Destination: [Institution]. Link: [Mercury_Draft_Link]" and does NOT auto-approve.

The input of POST /financial/execute-treasury-transfer is amount (float), direction (string), institution (string); output { "draft_id": "string", "slack_confirm": "string" } (Deposit) or the Slack surplus message with no draft_id (Withdrawal).

(Source: QnA from clients — STAGE4-009, STAGE4-023; RFQ_ Stack Trading Prop Tech V7.pdf §API Execute Treasury Transfer, as amended)


BR_6.2.3.11: treasury_transfer_log table

Slack and Mercury are not the system of record for corporate sweeps. Every event triggered by Flow 28 MUST be recorded in the PostgreSQL table treasury_transfer_log:

ColumnDescription
timestampWhen the event occurred
institutionIronbeam or LMAX (CHR-141); pre-CHR-141 rows may hold Forex.com / Interactive Brokers
directionDeposit or Withdrawal
amountTransfer amount
Mercury IDThe Mercury draft ID of the queued Draft Wire (Deposit); empty for a Withdrawal (no Mercury call)

This table is also the source for the duplicate check in BR_6.2.3.9.

(Source: QnA from clients — STAGE4-018)


BR_6.2.3.12: /financial/run-rebalance request and response

DirectionFields
Inputforce_exec (Boolean) — Flow 28 sends force_execution: true
Output{ "status": "executed", "slack_alert_text": [string] }

Return Notification: the endpoint returns the slack_message/confirmation of each processed institution to Zapier for the internal Ops channel. If an execution failed, the message is prepended with ❌ FAILURE:. The summary string is returned for each institution even if action = "NONE". Zapier posts the returned messages to #ops-treasury.

No upper limit is applied to the amount of a SEV1 live deposit in this UC — there is no hard cap. Note: Table C still lists Global_Var_Max_Auto_Transfer_Limit (75000, "Safety Cap ($) for auto-transfers"); this UC does not apply it, pending client confirmation of whether it is still in force (QnA STAGE4-021).

(Source: RFQ_ Stack Trading Prop Tech V7.pdf §API Run Capital Rebalance step 3; Zapier Integration V7.pdf §Flow 28; QnA from clients — STAGE4-017)


BR_6.2.3.13: No missing day — Severity 1 alert for failed daily-snap

A missing day in the historical time-series is not acceptable. If the /financial/daily-snap cron fails to execute or fails to write to PostgreSQL, the Node.js middleware MUST immediately push a Severity 1 alert to Slack #ops-treasury so the team can trigger the endpoint manually. No automatic retry is specified by the client. Because the Pass Rate Aggregator (UC_2.1.1, CR-20260728-005) sums sims_passed / sims_failed from Firm_Sim_Funnel_Snapshots, a skipped day would skew cached_pass_rate.

(Source: QnA from clients — STAGE4-020, STAGE4-011; CR-20260728-005)


BR_6.2.3.14: Scope boundaries (MT5 plugin, PowerBI)

  • MT5 Plugin: handles individual trader Profit Target liquidations via the MT5 server. It has zero impact on this UC's API logic. The solvency monitor queries the institutional broker APIs directly; the existing logic operates independently of the MT5 platform.
  • PowerBI / BI tools: out of scope. Stack Trading's internal data team connects BI tools directly to the PostgreSQL read replica. This UC's only responsibility is that the daily calculations are accurately committed to Firm_PnL_Snapshots and Firm_Sim_Funnel_Snapshots. The line "Full Level-by-Level breakdown available in PowerBI" in the Slack report is informational text only.

(Source: QnA from clients — STAGE4-007, STAGE4-012)


BR_6.2.3.15: Execution model (cron, no lock)

Flows 27, 28 and 29 are background crons with no UI; their schedules are fixed in Zapier (hourly / hourly / daily 5:05 PM EST). Zapier queues runs sequentially, and no separate lock mechanism is specified or required to prevent overlapping run-rebalance runs.

(Source: QnA from clients — STAGE4-010)


BR_6.2.3.16: /financial/daily-snap — Live Performance Snap

  1. Identify: query Ledgers for all active Live traders.
  2. Group: categorize users by level_id.
  3. Sync P&L: for each user, call the Rithmic/MT5 API to fetch open_pnl (Unrealized) and closed_pnl_day (Realized today).
  4. Aggregate per level: number of traders, unrealized P&L, realized P&L, allocated_capital (Notional), daily_loss_limit (Stop).
  5. Calculate: deposit_req = Level Notional × Global_Var_FCM_Target_Buffer (1.3, read dynamically from Table C — not hardcoded 0.80).
  6. Insert rows into Firm_PnL_Snapshots (day, time, level_id, trader_count, aggregate_notional, aggregate_deposit_req, aggregate_target, aggregate_stop, unrealized_pnl, realized_pnl, total_pnl).

(Source: RFQ_ Stack Trading Prop Tech V7.pdf §API Generate Daily Snapshots; Zapier Integration V7.pdf §3.1.3; QnA from clients — STAGE4-005)


BR_6.2.3.17: /financial/daily-snap — Simulation Funnel Snap

📌 Note: this is a read-only tally of SIM outcomes for business reporting, not a SIM monitoring/enforcement step. UC_6.2.3 itself is Live-only (Flow 27/28/29 all belong to the Live treasury engine); this step simply counts how many SIM challenges resolved today, the same way Flow 29 also reports trader_count for Live. No SIM account is evaluated or acted upon here.

  1. Payments: count rows in payments for "today" where type is NEW vs RESET.
  2. States: count users where status is SIM_ACTIVE.
  3. Outcomes: count users whose status changed to PASSED or FAILED today.
  4. Duration: AVG(Today's Status_Change_Date − Sim_Start_Date).
  5. Insert one row into Firm_Sim_Funnel_Snapshots (day, time, conversions_new, conversions_resets, active_sims, sims_passed, sims_failed, pass_percent = Passed / (Passed + Failed), avg_pass_fail_duration).

(Source: RFQ_ Stack Trading Prop Tech V7.pdf §API Generate Daily Snapshots; Zapier Integration V7.pdf §3.1.4)


BR_6.2.3.18: /financial/daily-snap response contract

POST /financial/daily-snap — no input. The response MUST match exactly the variables required by the Flow 29 Slack template and the Firm_Sim_Funnel_Snapshots table so Zapier can map the payload without transformation:

FieldTypeMaps to
dayString YYYY-MM-DD[day] / Firm_*_Snapshots.day
trader_countIntegerNumber of Live Traders
total_pnlFloatTotal Firm P&L
realized_pnlFloatRealized P&L
unrealized_pnlFloatUnrealized P&L
deposit_reqFloatSlack [Deposit_Req] — value of the target-buffer requirement (BR_6.2.3.16 step 5)
sim_metrics.new_salesIntegerSlack [New] / conversions_new
sim_metrics.resetsIntegerSlack [Resets] / conversions_resets
sim_metrics.passedIntegerSlack [Passed] / sims_passed
sim_metrics.failedIntegerSlack [Failed] / sims_failed
sim_metrics.pass_percentFloatSlack [Pass_Percent] / pass_percent
sim_metrics.avg_duration_daysFloatSlack [Avg_Duration] / avg_pass_fail_duration
community_metrics.waitlist_queueIntegerSlack Total Waitlist Queue (CHR-138)
community_metrics.available_pod_slotsIntegerSlack Available Pod Slots (CHR-138)

community_metrics is additive to the response (BR_6.2.3.20) — it does not replace or rename any existing field above.

(Source: QnA from clients — STAGE4-019; CHR-138 for community_metrics)


BR_6.2.3.19: Flow 29 Slack report format (#ops-treasury)

EOD Firm Health Report: [day]
Live Performance
  Number of Live Traders: [trader_count]
  Total Firm P&L: $[total_pnl]
  Realized P&L: $[realized_pnl]
  Unrealized P&L: $[unrealized_pnl]
  Target Buffer Requirement: $[deposit_req]
Simulation Funnel
  Sales: [new_sales] New / [resets] Resets
  Challenge Velocity: [passed] Passed / [failed] Failed
  Pass Rate: [pass_percent]%
  Avg. Time to Outcome: [avg_duration_days] Days
Community & Mentorship
  Total Waitlist Queue: [community_metrics.waitlist_queue]
  Available Pod Slots: [community_metrics.available_pod_slots]
Full Level-by-Level breakdown available in PowerBI.

The "Community & Mentorship" block (CHR-138, Applied) — see BR_6.2.3.20 for the confirmed data sources.

Schedule ordering: Flow 29 (5:05 PM EST = 22:05 UTC, or 21:05 UTC during daylight saving time) runs before the Pass Rate Aggregator (00:00 UTC), so cached_pass_rate has no one-day lag. The current schedule is maintained.

(Source: Zapier Integration V7.pdf §Flow 29; QnA from clients — STAGE4-019, STAGE4-011)


BR_6.2.3.20: community_metrics — Waitlist Queue & Available Pod Slots (CHR-138 — Applied)

/financial/daily-snap appends a community_metrics object to its response, and Flow 29 Slack adds one new block ("Community & Mentorship") between "Simulation Funnel" and the PowerBI line. Two lightweight queries, run fresh each day:

MetricFormulaSource
waitlist_queueCOUNT(Users WHERE status = 'Waitlist')Users table
available_pod_slotsSUM(Max_Capacity − Current_Count) over all Pod_Leader_Registry rows where Status = 'Active'Pod_Leader_Registry (Table E)

Both formulas are client-confirmed (relayed by user, BA session, 2026-10-26), resolving the two naming/source questions the original CR left open (CHR-138 Answered Questions):

  • waitlist_queue: the client's CR text (verbatim in CR_original.md) specified COUNT(Users WHERE status = 'Pod_Waitlist'), or alternatively a global Pod_Waitlist_Count integer. Both conflicted with the client's own earlier, confirmed decision on the Pod System:

    • UC_8.2.1 (QnA POD-WAIT-15) confirms the waitlist status is named Waitlist, not Pod_Waitlist.
    • The same confirmation removes the global counter entirely (POD-WAIT-15) — Middleware does not maintain Pod_Waitlist_Count or any global counter, specifically to avoid it drifting out of sync with the real queue (risk flagged in POD-WAIT-01).

    Client confirmed: Flow 29 queries exactly COUNT(Users WHERE status = 'Waitlist') — the already-confirmed Pod System name, a fresh row count taken at query time, no counter of any kind (Pod_Waitlist_Count is not restored for this or any other purpose).

  • available_pod_slots: Max_Capacity, Current_Count and Status on Pod_Leader_Registry are exactly the fields UC_8.2.1 and UC_8.2.8 already use for pod matching, with the same Status = 'Active' filter — raising no naming conflict. The only open question was whether to spell out the exclusion of Suspended/Terminated/Permanently_Ineligible leaders explicitly, or rely on the positive Status = 'Active' filter alone. Client confirmed: the literal CR condition Status = 'Active' is sufficient as written — no separate exclusion list is required, since a positive filter on one allowed value already excludes every other value by construction (including any status the Pod System might add later, without needing this query updated).

This object does not persist to Firm_PnL_Snapshots or Firm_Sim_Funnel_Snapshots — it is reporting-only, read fresh on each /financial/daily-snap call and returned directly in the response (BR_6.2.3.18). A failure in either of these two queries does not block the Live Performance Snap or Simulation Funnel Snap persistence (BR_6.2.3.13) — no fixed failure-handling behavior has been specified by the client for this reporting-only step, consistent with its non-blocking status.

(Source: CHR-138, client request relayed by user (BA session) 2026-10-26, both Open Questions answered 2026-10-26; cross-ref QnA — POD-WAIT-01, POD-WAIT-15)


9. Update History

DateVersionSectionChange FromChange ToSource
2026-10-12v1All (new)UC_6.2.3 not yet written; Flow 27-29 existed only in Zapier Integration V7.pdf / RFQ_ Stack Trading Prop Tech V7.pdf with unresolved variable and schema conflictsInitial SRS for UC_6.2.3. Applies client answers: single shared Global_Var_FCM_Margin_Ratio; Table C adds Danger_Buffer (0.80) and Withdraw_Threshold (1.25) and drops Excess_Buffer; Target_Buffer = 1.3 (RFQ's 0.80 is a typo); buffer_health derived from severity; Flow 27 Slack iterates 3 institution blocks; graceful degradation on broker failure; SEV1 live transfer vs SEV3 Draft Wire; draft/transfer dedupe; new treasury_transfer_log; daily-snap response expanded (deposit_req, passed, failed, pass_percent, avg_duration_days); Severity 1 alert for a missed daily snapshot; PowerBI out of scope; MT5 plugin independentQnA_init_docs.md (client answers 2026-10-12); Zapier Integration V7.pdf §Flow 27-29; RFQ_ Stack Trading Prop Tech V7.pdf §API FCM Health Monitor / Run Capital Rebalance / Execute Treasury Transfer / Generate Daily Snapshots
2026-10-12v1§5 Basic FlowEach step only named the formula/table it used and pointed to the BR for detailExpanded every Basic Flow step in-line: full formula per step, a component table showing where each formula input comes from and what it means, and the exact Slack message/template text sent at each notification point. BR_6.2.3.1-19 unchanged (still the normative detail); §5 now restates them inline for readabilityNo new source — restates BR_6.2.3.1 through BR_6.2.3.19 and their underlying sources (QnA STAGE4-004…021, Zapier Integration V7.pdf, RFQ_ Stack Trading Prop Tech V7.pdf) in Basic Flow form
2026-10-26v1§5.1 step 2, BR_6.2.3.2Forex required-equity formulas (Forex_Com_Required, IBKR_Required) stated without caveat, implying Forex.com + IBKR are the complete LP setAdded inline ⚠️ pending-confirmation note next to both Forex formulas (Basic Flow §5.1 step 2 and BR_6.2.3.2): assumes Forex.com/IBKR are the only two LPs the YourBourse Bridge routes to; unconfirmed whether another LP exists or is planned, cross-referenced to the client's undecided "consolidate Forex to one broker" remark (STAGE4-014). Raised new open question STAGE4-022New open question STAGE4-022 added to QnA_STAGE4_LIVE_TRADING_RISK.md; _QNA_INDEX.md counts updated
2026-10-26v1Overview blockquote, §5.1, §5.2, §5.3, BR_6.2.3.17Live-only scope of Flow 27/28/29 was implicit (derivable only from is_active/Ledgers wording) and not stated explicitly; Flow 29's "Simulation Funnel Snap" name could be misread as this UC monitoring/operating on SIM accountsAdded explicit 📌 notes: Overview blockquote states all three flows belong to the Live treasury engine and never read/evaluate/act on SIM data; Flow 27 and Flow 28 section headers each get a one-line Live-only note; Flow 29 section header and BR_6.2.3.17 both clarify that "Simulation Funnel Snap" only counts that day's SIM outcomes (passed/failed/new/resets) as a business metric reported alongside Live Performance — it is not SIM monitoring or enforcement, and no SIM account is evaluated or acted upon by this UCUser instruction (BA session) — clarified that "Live-only" describes the treasury engine itself; Simulation Funnel Snap remains a read-only daily tally of SIM outcomes, consistent with existing BR_6.2.3.17 logic (no behavior change, documentation-only)
2026-10-20v1Document References, Overview, 3rd Party, §5.1 step 3 (history; rest of body rewritten 2026-10-23)Forex actual equity (Net_Liquidating_Value) was sourced from Forex.com and Interactive Brokers APIs; no reference to LMAXAdded reference to CR CHR-141 : Forex actuals come from the new liquidation provider LMAX, replacing Forex.com and IBKR. Notes added at Document References, Overview, 3rd Party and Basic Flow §5.1 step 3 only — the rest of the body (Forex.com/IBKR wording in step 2, BR_6.2.3.2/.6/.7/.10/.11, Slack blocks, Exc-1) is NOT yet rewritten, pending the CR Open QuestionsCHR-141 — client change relayed by user (BA session) 2026-10-20
2026-10-23v1Overview, 3rd Party, P-3, §4 Flow 28, §5.2 steps 3-4, Alt-2, Exc-2, BR_6.2.3.9, BR_6.2.3.10, BR_6.2.3.11SEV1 Deposit = live, immediately-processing Mercury transfer with no approval; SEV3 Withdrawal = Mercury Draft Wire; Mercury destination config unspecifiedSEV1 Deposit = Mercury pendingApproval Draft Wire via request-send-money (CEO/CFO approves manually; Ironbeam to MERCURY_IRONBEAM_RECIPIENT_ID, LMAX to MERCURY_BOFA_RECIPIENT_ID); SEV3 Withdrawal = no Mercury call, Slack-only surplus alert; destination config = opaque Mercury UUIDs in AWS Secrets Manager (no raw bank details); Mercury failure = ❌ FAILURE: SEV1 alert; treasury_transfer_log Mercury ID empty for Withdrawal. Source: QnA STAGE4-023.
2026-10-23v1CR code, Overview, 3rd Party, P-3, §5.1 steps 2/3/6, Exc-1, BR_6.2.3.2/.4/.6/.7/.11, all source linesCR code written as CHR-41; Forex.com / Interactive Brokers still named as Forex institutions (3 institutions, 3 Slack blocks); CR-20261012-001 cited as a CR across the UCCR code corrected to CHR-141; Forex institution is LMAX everywhere (2 institutions: Ironbeam + LMAX, 2 Slack blocks, institution = Ironbeam/LMAX, single LMAX_Required formula) marked CHR-141; CR-20261012-001 citations removed (no CR other than CHR-141 applies to the Flow 27-29 treasury content; SEV1 Deposit follows the original spec: Mercury Draft Wire + manual CEO/CFO approval).CHR-141
2026-10-27v1§5.1 step 2, BR_6.2.3.2Forex required equity (LMAX_Required) computed from LMAX aggregate open notional via the YourBourse Bridge API × Global_Var_FCM_Margin_Ratio; open question STAGE4-022 on whether the Bridge still routes to other LPsForex required equity now computed identically to Futures, directly from Ledgers: Forex_LMAX_Required_Equity = SUM(ledgers.allocated_capital for all Active Live Forex Traders) × Global_Var_FCM_Margin_Ratio. The Bridge API is no longer queried for Required_Equity (it remains unused elsewhere in this UC). Renamed LMAX_Required → Forex_LMAX_Required_Equity for symmetry with Ironbeam_Required_EquityClient answer confirming STAGE4-022, relayed by user (BA session) 2026-10-27 — QnA_STAGE4_LIVE_TRADING_RISK.md
2026-10-27v1§5.3 step 4 (new), BR_6.2.3.18, BR_6.2.3.19, BR_6.2.3.20 (new)/financial/daily-snap response and Flow 29 Slack report had no pod/mentorship metrics; no community_metrics object existedDocumented CHR-138: new §5.3 step 4 "Community & Mentorship Snap" computing waitlist_queue (count of Users in waitlist status) and available_pod_slots (SUM(Max_Capacity − Current_Count) over active Pod_Leader_Registry rows); community_metrics object appended to the daily-snap response (BR_6.2.3.18); new Slack block "Community & Mentorship" inserted before the PowerBI line (BR_6.2.3.19); new BR_6.2.3.20 with full detail. Not yet Applied — available_pod_slots has no conflict, but waitlist_queue's source is an open question: the CR's literal status = 'Pod_Waitlist' / Pod_Waitlist_Count wording conflicts with UC_8.2.1's already-confirmed Waitlist status name and removal of any global counter (POD-WAIT-15). This UC documents the formula using the confirmed Waitlist name pending client confirmation, rather than silently applying the CR's literal field names. (CR code corrected from the client's stated CHR-138 after an initial internal filing mistakenly used CHR-139 — folder and all references renamed to CHR-138 per BA correction.)CHR-138 — client request relayed by user (BA session) 2026-10-26, formula/BR written 2026-10-27; cross-ref UC_8.2.1_v1.md POD-WAIT-01/POD-WAIT-15
2026-10-26v1Document References, §5.3 step 4, BR_6.2.3.18, BR_6.2.3.19, BR_6.2.3.20Both CHR-138 Open Questions were unresolved; §5.3 step 4 and BR_6.2.3.20 marked community_metrics/waitlist_queue as "Active, not yet Applied", with the waitlist_queue formula stated only as the BA's interim recommendation pending client confirmationClient answered both Open Questions (relayed by user, BA session, 2026-10-26) — see CHR-138 CR_summary.md Answered Questions. (1) waitlist_queue = exactly COUNT(Users WHERE status = 'Waitlist'), the already-confirmed Pod System name, no counter of any kind — client rejected restoring Pod_Waitlist_Count. (2) available_pod_slots's Status = 'Active' filter is sufficient as literally written in the CR — no need to separately enumerate excluding Suspended/Terminated/Permanently_Ineligible. Removed every "⚠️ not yet Applied" / "Open Question" marker across §5.3 step 4, BR_6.2.3.18, BR_6.2.3.19, and rewrote BR_6.2.3.20 in full as a confirmed, Applied rule — this UC's community_metrics content is now finalCHR-138 CR_summary.md Answered Questions — client confirmation relayed by user (BA session) 2026-10-26
2026-10-29v1§5.1 step 4, §5.2 step 3, Alt-2, BR_6.2.3.9Flow 27 step 4 and Flow 28 step 3 described the Deposit/Withdraw/None cases as prose bullets; Flow 28 step 3.1 ran the duplicate check for both Deposit and Withdrawal (per STAGE4-016); Alt-2 described a Withdrawal-dedupe skip scenarioReadability: Flow 27 step 4 now uses the same case table as BR_6.2.3.3 instead of bullets; Flow 28 step 3 now presents Deposit/Withdrawal/None as one case table (duplicate check / Mercury call / log row / Slack message per case), with prose detail kept below it. Logic change: step 3.1's duplicate check now runs for SEV1 Deposit only — a Withdrawal never creates a Mercury Draft Wire, so there is nothing to dedupe against; Flow 28 now re-sends the surplus alert every hour the condition holds. BR_6.2.3.9 rewritten accordingly (Deposit-only dedupe) with an inline ⚠️ note that this overrides the client's original STAGE4-016 answer (which covered both directions) and is pending client re-confirmation. Alt-2 rewritten from "Withdrawal alert already sent today → skip" to "surplus persists, alert repeats hourly, expected behavior."User instruction (BA session) 2026-10-29 — requested table format for both case sets and removal of the Withdrawal duplicate-check step since Withdrawal creates no Draft Wire; ⚠️ not yet re-confirmed by client against STAGE4-016
2026-10-26v1§5.1 step 3, BR_6.2.3.2, BR_6.2.3.3LMAX's Net_Liquidating_Value (Actual) was described as pulled from "LMAX's own API" the same way as Ironbeam, with no formula — implying LMAX exposes an equity field directly, like Ironbeam doesClarified, not a logic change in intent, but a new formula: LMAX does not expose Net_Liquidating_Value directly. Added the computation: Net_Liquidating_Value (LMAX) = Settled Cash (GET /v1/account/wallets, USD wallet cash/balance) + Intraday Open Position MTM (GET /v1/account/positions, unrealized MTM per open net position priced off the live LMAX/TraderEvolution feed, or summed live open_pnl across active Live Forex sub-accounts on TraderEvolution/MT5); with no open positions, Actual = settled cash alone. Applied to Basic Flow §5.1 step 3 and BR_6.2.3.2/BR_6.2.3.3. Credentials for the LMAX wallets/positions API (and TraderEvolution/MT5 open_pnl feed, if used) are still open — added to CHR-141's Open Questions.Client answer, pasted by BA 2026-10-26 — STAGE4-024; resolves part of CHR-141's open LMAX-API question

On this page