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:
—
oldernewerNOW
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.
How to readIsolated view: X = time (oldest left → newest right), Y = floating P&L (USC) for the selected pair. Each dot is one hourly bar; the line connects bars in order. Hue encodes time the same way as the combined view (deep blue oldest → warm orange newest); hover any dot for the exact bar timestamp. The pulsing red marker is the most recent bar.
HealthyFloating P&L oscillates around zero or stays mildly positive. Brief dips below zero are normal in a grid — the engine accumulates inventory while price is below avg-entry and waits for mean reversion.
WarningFloating P&L makes a sustained one-way drift deeper negative without recovery, or the gap between consecutive bars widens (acceleration into DD). Look at Panel 7's derivative series for the per-bar rate of change.
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)
Pair
Current
Previous
Δ (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.
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.