Four shapes, one portfolio. Live data auto-refreshes hourly (engines write once per bar); use "Refresh now" for on-demand.
Connecting…

Injection Ledger — Real vs Ghost

Real = cash actually deposited (reconciles with Exness balance). Ghost = virtual capital used to raise UM without depositing real money. Per-engine UM = 1 + ⌊(v_rpnl + real + ghost) ÷ cap_need⌋.
⚠ What-if mode active — panels reflect your edited values, not live data. Click "What-if mode" again to return to live.
Total margin used
USD-axis bias
loss = bias² →
Asset-axis bias
loss = bias² →
Imbalance verdict
Net floating P&L

1. Compass

vector sum on USD × asset axes
How to readEach engine becomes an arrow from the center. The angle tells you which quadrant it lives in (USD direction × asset class). The length is its share of margin used. The bold red arrow is the vector sum — the portfolio's net pull.
HealthyRed arrow short and near the center → engines are cancelling out.
WarningRed arrow long and pointing into one quadrant → portfolio is leaning that way; one shock in the wrong direction will hit everything at once.

2. Simplex

centroid = perfectly balanced
How to readEach active engine becomes a corner of a shape — line for 2, triangle for 3, polygon for 4+. The black dot is where your portfolio sits, weighted by margin. The grey cross is the centroid — the ideal of equal sharing.
HealthyDot sits near the centroid → margin is spread fairly across engines.
WarningDot drifts toward one corner → that engine dominates the account. If it draws down, the whole portfolio does.

3. Radar

4 health axes
How to readFour spokes measure four risks: USD bias, asset bias, margin pressure (% of equity in use), and concentration (largest single engine's share). 0 is at the center, 1 at the edge. Today's portfolio is the blue polygon. The amber ring is caution, the red ring is danger.
HealthySmall, roughly symmetric polygon hugging the center.
WarningA long spike on any one axis means that specific risk is dominant. Multiple spikes = stacked risk.

4. Heat-band

margin pressure to liquidation
How to readOne horizontal bar, 0% to 100% of equity. Engines stack left to right. The colored zones are universal: green is safe, amber is watch, red is danger. The dashed line at 80% is the warning threshold; 100% is the liquidation line.
HealthyAll stacked segments live in the green zone — plenty of headroom for both engines to grow positions simultaneously.
WarningAny segment crosses into amber or red, or the cumulative bar approaches 80%. Time to inject capital, pause adds, or sell down.

5. Position Effect — Constellation

P&L on the correlation plane · scales to 10+ pairs
How to readEach engine is a bubble on the (USD direction, asset class) plane. Bubble size = position effect magnitude (√|floating|/equity), fill color = sign of floating (green profit, red loss), border thickness = margin weight on equity. Pairs in the same quadrant are correlated (same sign on both axes); diagonally opposite quadrants are anti-correlated; adjacent quadrants are partially correlated. Lines connect same-quadrant pairs to show clusters; line color shows whether the cluster is moving together (green/red) or split (grey).
HealthyBubbles small, scattered across quadrants, net center-of-mass (red ⊕) near origin. Big and bleeding red? Look for the matching margin border to see if it's also a heavily-loaded pair.
WarningA correlated cluster (two big bubbles connected by a thick line) all in the red — every loss compounds with the next. Or center-of-mass drifting far from origin = portfolio P&L is concentrated in one quadrant, not diversified.

6. Phase Trajectory

where the portfolio has been · floating P&L plane
View:
Window:
older newer NOW
How to read2D plane: X = AUDUSD floating P&L (USC), Y = USDCHF floating P&L (USC). Each dot is one hourly bar; lines connect adjacent bars with arrowheads showing the direction of motion. Hue encodes time (deep blue oldest → warm orange newest); hover any dot for the exact bar timestamp.
HealthyPath stays near the origin or hovers diagonally in top-left (AUD down, CHF up) — the validated USD-direction hedge: AUD shorts make money when CHF longs lose, and vice versa.
WarningPath drifts deep into bottom-left (both negative) or top-right (both positive) — engines are co-moving rather than hedging. Brief excursions are normal; sustained drift means the diversification math has decoupled from price reality.

7. Derivative Series

how fast it's moving · per-bar Δfloating
Smoothing:
scroll = zoom · drag = pan · dbl-click = reset — full history loaded; drag left to the oldest bar (both charts share the time axis)
PairCurrentPreviousΔ (rate of change)
need ≥ 2 hourly snapshots
Combined net rate of change · % of equity per bar
Combined net rate of change · % of equity — moving average (weekends excluded)
Avg window:
ReadoutCurrent = the latest derivative value (last plotted point's distance from the zero line, signed). Previous = the prior bar's derivative. Δ = current − previous, the rate of change of the derivative (acceleration). Values use the chart's unsmoothed per-bar deltas regardless of the smoothing pill.
Sub-graphOne indigo line = the combined net rate of change across both pairs, expressed as a percentage of account equity at that bar: at each hourly bar, [(dAUD[i] − dAUD[i−1]) + (dCHF[i] − dCHF[i−1])] ÷ equity × 100 — the portfolio-wide acceleration of floating P&L scaled by the account's total equity at that timestamp. Crosses the zero baseline when the engines collectively flip from accelerating to decelerating. Raw unsmoothed deltas, so the line is unaffected by the Smoothing pill. Note: the readout table above stays in absolute units — only this sub-graph is in % of equity.
AverageThe teal line (third chart) is a moving average of the combined net rate of change above, over the last N active bars set by the Avg window pills (24h / 7 day / 30 day). Weekend / market-closed bars (frozen floating → flat, zero rate of change) are excluded from the average — they consume no window slot — and the line connects straight across the weekend gaps (no break). Smooths the per-bar signal into the portfolio's recent average acceleration.
How to readTwo lines: green = dAUD/dt (Δfloating per hour for AUDUSD), blue = dCHF/dt. Zero line is the reference. Spikes above 2σ are marked with a circle — those are acceleration moments (news, gap, illiquid bar). When both lines move opposite signs, the engines are hedging; when they move same sign, the portfolio is exposed.
HealthyLines oscillate around zero with mostly-opposite signs. The vertical band between them stays narrow.
WarningBoth lines spike same-sign together → both engines lost (or gained) on the same bar → not a hedge for that hour. Multiple consecutive same-sign bars = regime where the diversification thesis is breaking.

Formula reference

Every calculation used on this page. Values match what the engines actually compute on EC2.

Variables glossary

All values come from shared_pool.json on EC2, updated each bar by the live traders.

E = total account equity (USC, all engines share one Exness account) m_i = margin used by engine i's open positions (USC) — broker truth w_i = m_i / E (engine i's weight in the pool, dimensionless 0..1) s_USD,i = sign of engine i on the USD axis (+1 short-USD, −1 long-USD) s_asset,i = sign of engine i on the asset axis (+1 commodity, −1 financial) v_i = engine i's virtual realized PnL (USC, from VirtualExchange grid) I = shared total_injected (USC, cumulative real-money deposits) cap = base_cap = 140,700 USC (AUDUSD's cap_need, the backtest's pool unit)
Per-pair signs are hard-coded in server.js::PAIR_GEOMETRY and mirrored in this page's PAIRS map. AUDUSD = (+1, +1). USDCHF = (−1, −1). The four panels read the same w_i, s_USD,i, s_asset,i values; each one visualizes a different angle.

Summary strip top of page

The four cards above the panels are direct sums over engines.

Total margin used = Σ m_i / E shown as a percent USD-axis bias = Σ ( s_USD,i × w_i ) range typically −1 .. +1 Asset-axis bias = Σ ( s_asset,i × w_i ) range typically −1 .. +1 loss (per axis) = bias² (CEO's parabola: y = x²) Imbalance verdict = total_loss = bias_USD² + bias_asset² Balanced if total_loss < 0.0005 Slight tilt if total_loss < 0.005 Concentrated otherwise
A bias of 0 on an axis means engines on that axis cancel out perfectly. AUDUSD = (+1,+1) and USDCHF = (−1,−1) are diagonally opposite, so equal weights on both pull both biases to 0.

1. Compass vector sum

Each engine becomes an arrow from the origin into its quadrant. The bold red arrow is the vector sum — the portfolio's net pull on the (USD, asset) plane.

For each active engine i: dx_i = s_USD,i × w_i dy_i = −s_asset,i × w_i (negated because SVG y-axis points down) Net arrow = ( Σ dx_i , Σ dy_i ) Arrows scaled so w_i = 0.20 (20% of equity in margin) reaches the outer ring.
A short red arrow near the center = engines cancel out. A long arrow into one quadrant = the portfolio leans that way; one shock in the wrong direction will hit everything at once.

2. Simplex barycentric centroid

Each active engine is a vertex of a shape (line for 2, triangle for 3, N-gon for ≥4). The black dot is the weighted-average position; the grey cross is the geometric centroid (equal-weight ideal).

For N active engines (i = 1..N): vertex_i = on an N-gon inscribed in radius R around (cx, cy) Engine share share_i = m_i / Σ m_j Black dot position = Σ ( share_i × vertex_i ) Grey cross centroid = mean(vertex_i) (equal-weight ideal) Imbalance = distance(dot, centroid) / max_distance_to_corner 0% = dot sits on the centroid 100% = dot sits on a single corner Verdict: < 10% centered < 30% slight drift ≥ 30% concentrated
Drives off margin share, not absolute size. Two engines at $10k each = 50/50, dot on centroid. Two engines at $1k/$9k = 10/90, dot pulled toward the bigger corner.

3. Radar 4 health axes

Four spokes measuring four distinct risks. Each spoke is 0 (center) → 1 (outer edge). Today's portfolio is the blue polygon.

Axis 1 — USD bias = min(1, |Σ s_USD,i × w_i|) Axis 2 — Asset bias = min(1, |Σ s_asset,i × w_i|) Axis 3 — Margin used = min(1, (Σ m_i / E) / 0.5) (full spoke = 50% of equity in margin) Axis 4 — Concentration: ideal = 1 / N_active max_share = max(share_i) axis = max(0, (max_share − ideal) / (1 − ideal)) 0 = perfectly even 1 = one engine holds everything Caution ring at 0.50 (amber) Danger ring at 0.75 (red)
A small symmetric blue polygon hugging the center = healthy. A long spike on any one axis = that specific risk is dominant. Multiple spikes = stacked risk.

4. Heat-band margin pressure

One horizontal bar, 0% to 100% of equity. Engines stack left-to-right by margin %. Universal traffic-light zones.

For each active engine, segment width = m_i / E (as percent) Segments stack left-to-right. Zones: 0 – 30% green safe 30 – 70% amber watch 70 –100% red danger Markers: 80% dashed red line = WARNING threshold 100% right edge = liquidation Headroom-to-warning = max(0, 0.80 − Σ m_i / E) Headroom-to-liq = max(0, 1.00 − Σ m_i / E)
Reads real broker margin when available (set by Exness via leverage). Bigger leverage means smaller m_i for the same position, so the bar stays shorter — leverage doesn't change size, only how much margin is locked to hold that size.

5. Position Effect — Constellation scales to N pairs

2D scatter on the sign plane. Each engine becomes a bubble at its (USD, asset) quadrant. Encodes three things at once: P&L magnitude (bubble size), P&L direction (fill color), margin loading (border thickness). Designed to remain readable at 10+ pairs by jittering same-quadrant pairs around a small ring and connecting them with relationship-typed lines.

For each active engine i with broker floating P&L f_i and margin m_i: Position on plane: base_x = cx + s_USD,i × R R ≈ 145 px from center base_y = cy − s_asset,i × R (SVG y points down) If N pairs share a quadrant, spread them on a 30-px ring: angle = 2π × i/N − π/2 x = base_x + 30·cos(angle) y = base_y + 30·sin(angle) Bubble radius r = 6 + (√|pct_i| / √max|pct|) × 22 (sqrt so big losses don't crush small ones) Bubble fill green if f_i > 0, red if < 0 Bubble border width = clamp( (m_i/E) × 40, 1.5, 6 ) px engine's signature color Cluster lines (same quadrant): Both pairs profitable → green solid Both losing → red solid Mixed → grey dashed P&L center of mass (floating-weighted): CoM = Σ (pos_i × |f_i|) / Σ |f_i| Far from origin → portfolio P&L concentrated in one quadrant Near origin → P&L spread across the plane NET P&L = Σ f_i / E shown in footer
The (USD, asset) sign plane is a taxonomy proxy for correlation: same quadrant = correlated; diagonally opposite = anti-correlated; orthogonal quadrants = uncorrelated. A future enhancement could swap in measured price-return correlations from the baseline files. The viz layout doesn't change — the bubbles just move based on whatever similarity metric is feeding it.
Reading at 10 pairs: scan for (a) any one big bubble = single position dominating P&L; (b) a clustered constellation (multiple big bubbles in same quadrant) connected by thick coloured lines = same-direction risk; (c) the CoM ⊕ — its distance from origin is your "diversification score" of P&L right now.

6. Phase Trajectory portfolio path · floating P&L plane

2D path on the (AUD_floating, CHF_floating) plane over the selected window. Each bar is a dot; lines connect consecutive bars; color fades from old (faint) to recent (bold). The pulsing red dot is the most recent snapshot.

Per-bar point: p_t = ( AUDUSD.floating_t , USDCHF.floating_t ) in USC Quadrant interpretation: AUD− / CHF+ → HEDGE (USD-direction hedge — validated good) AUD+ / CHF− → HEDGE (mirror image) AUD+ / CHF+ → CO-MOVE (both winning, exposed if USD reverses) AUD− / CHF− → CO-MOVE (both losing — diversification thesis broken) Data source: shared_pool_history.csv, written hourly by shared_pool_history.py cron @ :04 from the live shared_pool.json.
Brief excursions into co-move quadrants are normal (FX is correlated short-term). Sustained drift means the AUD/CHF hedge thesis has broken for the current regime.

7. Derivative Series rate of change · per-bar Δfloating

Calculus view of the same data: per-bar deltas of each engine's floating P&L. White-circle markers flag |Δ| beyond 2σ — acceleration moments.

Per-bar derivatives: dAUD/dt[i] = AUDUSD.floating[i] − AUDUSD.floating[i−1] dCHF/dt[i] = USDCHF.floating[i] − USDCHF.floating[i−1] Smoothing (3-bar / 6-bar moving avg toggleable): smooth_W[i] = (Σ over last W non-null values) / W Spike detection — σ of the smoothed series: flag if |smooth_W[i]| > 2 × σ(smooth_W) Reading the dual line: opposite signs (one up, one down) → engines hedging on this bar same signs together → exposed bar; both moved same way
Same data source as Panel 6. The legend strip shows current σ for each engine — high σ means the engine has been moving more than usual.

Per-engine UM decimal · 0.1 step · masking-safe

As of 2026-05-18 UM supports decimal precision in 0.1 increments (was integer-only). The change is safe because the DQN agent already operates on a clean 1× virtual world via the masking architecture (2026-04-19 decision) — only the broker-side mirror is scaled, so the agent never sees fractional UM in its state space.

Per-engine universe multiplier (decimal, 0.1-step): own_v_rpnl_i = this engine's virtual realized PnL (USC) own_real_i = real cash injected into this engine (USC) own_ghost_i = ghost (virtual) injection into this engine (USC) own_cap_need_i = AUDUSD: 140,700 · USDCHF: 255,850 UM_i = round( 1.0 + max(0, v_rpnl_i + real_i + ghost_i) / cap_need_i , 1 ) Each engine sizes as: target_units_i = (CEIL_i − price_int_i) × size_mult_i × UM_i broker_lots_i = floor_to_2dp(target_units_i × LOT_SCALE) (LOT_SCALE = 0.01) ↑ rounds DOWN toward zero so a decimal UM never inflates the position past the math Inverse mapping — given a target UM (typed directly in the panel), ghost auto-fills so the formula is consistent: ghost_needed = max(0, (target_UM − 1) × cap_need − real − v_rpnl) Real vs Ghost: real_i = cash actually deposited at the broker (reconciles with balance) ghost_i = virtual capital to raise UM without depositing real money Both feed UM identically; the split is bookkeeping honesty, not math. Examples (CHF, cap_need=255,850, v_rpnl=520): target UM 1.5 → ghost = 0.5 × 255,850 − 0 − 520 = 127,405 USC ($1,274) target UM 2.0 → ghost = 1.0 × 255,850 − 0 − 520 = 255,330 USC ($2,553) target UM 2.5 → ghost = 1.5 × 255,850 − 0 − 520 = 383,255 USC ($3,833)
The math here is independent of leverage. Leverage only changes the margin the broker locks for the resulting position, not the position size itself.

What the numbers don't say honest caveats

The heat-band, radar, and simplex all read margin and equity in account units (USC for the Exness Cent account). All four panels are diagnostic, not predictive — they show how the pool is currently distributed, not what it will do next bar.

The validated backtest peak margin of 8.82% was computed on a 140,700-USC pool. The live account is smaller (~278k USC), so equivalent positions show as a larger margin %. Both are safe (Exness Cent stop-out is 0%), but reading the bar without that context will overstate concern.