# TF Market Intelligence Suite — specification lock

Version: 1.1.0  
Locked: 2026-09-05 before implementation and visual tuning  
Floating-point parity tolerance: absolute `1e-10`, relative `1e-8`, except displayed values rounded by the terminal.

## Regime Persistence Map

- Windows: efficiency ratio and sign entropy at 20, 50, 100 closed bars; use their median.
- Realized volatility: sample standard deviation of 20 log returns. Percentile compares the current value with the strictly older 252 rolling observations using midpoint rank for ties.
- Range expansion: median true range of the latest five bars divided by median true range of the preceding 60 bars. Flat/flat returns 1.0; positive/flat returns `DBL_MAX`.
- Raw states: SHOCK when volatility percentile >= 90 or expansion >= 1.8; otherwise TREND when median ER >= 0.35 and median entropy <= 0.90; otherwise RANGE when median ER <= 0.20 and median entropy >= 0.95; otherwise TRANSITION.
- Hysteresis: SHOCK activates on one bar. Every other different raw state must occur on two consecutive closed bars before the state changes.
- Bar 0 is shown as `PRELIMINARY`; closed-bar buffers use only same-bar and older data.

## Currency Network Strength

- Currencies: USD, EUR, GBP, JPY, CHF, CAD, AUD, NZD.
- Default graph: EURUSD, GBPUSD, USDJPY, USDCHF, USDCAD, AUDUSD, NZDUSD, EURGBP, EURJPY, GBPJPY, AUDJPY, EURCHF.
- Horizons and weights: 1/5/20/60 bars with 0.20/0.25/0.30/0.25.
- Per-horizon scaling: each horizon return is divided by `1.4826 * MAD` of one-bar log returns over 126 observations times the square root of the horizon, with a scale floor of `1e-6`.
- Pair weight: 1.0 normally; 0.5 when current spread exceeds three times its 126-observation median where spread history is available. Missing spread history does not invent a penalty.
- Solve weighted normal equations with the NZD node fixed temporarily to zero, then subtract the eight-score mean so all scores sum to zero. Require connected rank 7.
- Composite values are winsorized cross-sectionally to median +/- three cross-sectional robust standard deviations. Confidence is `max(0, 1 - residual_RMS/3)`.

## Portfolio Exposure & Stress

- Forex exposure includes only symbols whose broker base/profit currencies are recognized ISO-like three-letter codes and have a resolvable conversion to account currency.
- Stop risk uses `OrderCalcProfit` from current price to SL and reports absolute adverse P/L. No SL is `UNBOUNDED`, never zero.
- Stress scenarios use `OrderCalcProfit`: USD +1%, USD -1%, chart base +1%, and one daily true-range mean against every position as a deterministic conservative proxy.
- Missing conversion/specification is `UNKNOWN` and excluded from numeric totals with an explicit count.

## Economic Event Risk Map

- Query range: trade-server time -24 hours to +7 days; default filter is high importance for chart base and quote currencies.
- Refresh period: 60 seconds minimum. Cache age and the last successful server time are shown. Failed refresh retains prior entries only while explicitly marked stale.
- Events within the same currency and minute are grouped; alerts are off by default and de-duplicated per event ID and threshold.

## Liquidity Friction Monitor

- Use the chart's closed-bar `spread[]`, `tick_volume[]`, OHLC and `_Point`; no Level II data, tick reconstruction or invented real volume.
- Baseline: the strictly older 240 bars. A percentile uses midpoint rank for ties. At least 60 positive spread observations and 60 positive tick-volume observations are required.
- Spread cost: `10000 * spread_points * _Point / close`. Spread percentile compares this cost with the same measure on the older baseline.
- Volume drought percentile: `100 - percentile(log(1 + tick_volume))`, so a low relative activity bar has a high drought value.
- Price-gap ratio: `abs(open - previous_close) / median(true_range)` using the strictly older 120 bars. Flat/flat returns 0; positive/flat returns `DBL_MAX`.
- Gap pressure: `clamp(100 * gap_ratio / 3, 0, 100)`. Composite friction is `0.50 * spread_percentile + 0.35 * volume_drought_percentile + 0.15 * gap_pressure`.
- States: `DISLOCATED` when spread percentile >= 97.5 or gap ratio >= 3; otherwise `THIN` at composite >= 70, `NORMAL` at composite >= 40, and `LIQUID` below 40.
- Bar 0 is labelled `PRELIMINARY`. Closed bars use only same-bar and older observations. Alerts are off by default and only fire on a newly closed transition into THIN or DISLOCATED.

## Jump & Tail Risk Decomposition

- Work on 20 same-symbol log returns ending at the evaluated bar. `RV = sum(r^2)`.
- Bipower variation is `(pi/2) * (20/19) * sum(|r_j|*|r_(j+1)|)` across the 19 adjacent return pairs.
- Jump variation is `max(RV - BV, 0)` and jump share is `100 * jump_variation / RV`; an exactly flat window returns zero, not missing risk.
- Downside share is `100 * sum(r^2 for r < 0) / RV`; an exactly flat window returns 50 as a neutral convention and is flagged by zero window volatility.
- Window volatility is `100 * sqrt(RV)` and is deliberately not annualized so the value remains tied to the selected chart timeframe.
- Robust tail surprise is `abs(r_current - median(prior_252_returns)) / max(1.4826*MAD(prior_252_returns), 1e-10)` using only strictly older returns.
- States, in precedence order: `TAIL EVENT` for tail surprise >= 6; `JUMP DOMINATED` for jump share >= 35; `DOWNSIDE ASYMMETRY` for downside share >= 70 and the current return < 0; otherwise `ROUTINE`.
- Bar 0 is labelled `PRELIMINARY`; alerts are off by default and only fire on a newly closed TAIL EVENT.

## Locked edge cases

Short history, flat prices, zero denominators, zero/missing historical spread, zero tick volume, weekend price gaps, extreme returns, missing symbols, prefixes/suffixes, unsynchronized pair bars, calendar timeout/offline state, hedging/netting, JPY digits, non-FX positions, missing SL, missing conversion, chart resize, history extension, and terminal restart must resolve to a documented safe state rather than a fabricated normal condition.
