Tradext v2.20.52

Изменения v2.20.49:
- TG Новости и TG Сигналы разделены на два самостоятельных T-Terminal widget type.
- TG_NEWS_FEED сохранён для совместимости старых layout и теперь показывает только новости.
- Новый TG_SIGNAL_FEED показывает только сигналы.
- Фильтр источника хранится на уровне экземпляра виджета, поэтому News/Signals не переключают друг друга.
- Ограничен клиентский dedup state.seen: больше не растёт бесконечно при долгой работе вкладки.
- Добавлена server-side license/session handshake (работает с backend 2.18.25).

Tradext v2.20.47



v2.20.47 — Multi-level Robot sorting
---------------------------------------
- Added an explicit «Сорт.» control to the Robots widget; no Shift-click knowledge is required.
- Up to four ordered sort levels can be configured, each with its own ascending/descending direction.
- Supported fields include ticker, BUY/SELL, lots, period, money/minute, lots/minute, packet money, first/last trade, cumulative lots and cumulative money.
- ACTIVE robots remain above inactive robots; configured levels sort rows inside each lifecycle group.
- The selected sort is saved in localStorage and restored after terminal/browser restart.
- A normal click on a sortable table header remains a quick one-level shortcut and now persists too.
- Sort priority numbers/arrows are shown in matching table headers.
- v2.20.46 self-healing widget lifecycle changes are preserved unchanged. Backend protocol/detectors are unchanged.


v2.20.46 — Self-healing restored widgets
- Content script now starts at document_start so Tradext registers before/while T-Terminal restores the saved layout.
- Added an init concurrency guard to prevent duplicate registerExtension races around SDK_READY.
- Mounted widgets re-announce their module set every 15 s and immediately on pageshow/focus/visibility restore.
- Background no longer treats an in-terminal SPA URL change as an unmount.
- Same-terminal reload no longer sends a synthetic empty widget set; transient empty activity during layout restore has a 2 s grace period.
- Startup/state recovery now retries the widget-activity handshake after tab discard, BFCache restore, page reload, or MV3 worker restart.
- No widget UI, filters, alerts, scanners, or server protocol semantics changed.

v2.20.45 — Independent Robot filters by market group
-----------------------------------------------------
- Robot money filters are now independent for Shares, Futures, and Currency + currency futures.
- Each profile has its own enable switch, minimum packet money, money/minute, cumulative money, and AND/OR logic.
- The «Все» tab evaluates every row using the profile that belongs to that instrument type.
- Existing v2.20.44 global money-filter values are migrated into all three profiles on first load, so current settings are preserved.
- Confirmation level, whitelist/blacklist, columns, STOP policy and backend detector logic are unchanged.
- Backend remains server v2.18.19.




v2.20.44 — Fuel ETIS execution-index fix
-----------------------------------------
- SPIMEX fuel source switched from ETIP to ETIS, matching the MOEX fuel-futures execution index family.
- AJAX body now uses group=etis and index=petroleum_etis.
- Mapping remains REG/PRM/DTL: ETIS_EVR_REG ↔ 92, ETIS_EVR_PRM ↔ 95, ETIS_EVR_DTL ↔ DL.
- Fuel rows now explicitly display SPIMEX ETIS next to the index date.
- MOEX realtime BID/ASK logic, executable LONG/SHORT formulas and backend are unchanged.
Изменение:
- В виджете «Акция / Фьючерс» добавлен внутренний вертикальный скролл таблицы.
- Заголовок виджета и строка колонок остаются неподвижными; прокручиваются только строки данных.
- Backend без изменений: server v2.18.19.

Tradext v2.20.42 — Widget lifecycle + resource optimization

- Added explicit mounted-widget activity protocol for News, Robots, Limits, Icebergs, Fuel, Stock/Futures and Clock.
- The Chrome WebSocket is open only while at least one Tradext widget is actually mounted in a T-Terminal workspace.
- Server market workers are demand-driven across all connected computers: a module stays active while at least one client has that widget mounted.
- Heavy T-Invest paths are lazy: Robots/limits shared trades, Limits metadata, Icebergs orderbooks/shadow, Fuel depth=1/watchdog and Stock/Futures depth=1/watchdog sleep while their widgets are absent.
- Shared Robots/Limits/Icebergs trade stream rebuilds its subscription when the mounted module set changes; Icebergs-only uses the small iceberg universe instead of the full market universe.
- Runtime caches for Robots, Limits, Icebergs, Fuel and Stock/Futures are reset when the last corresponding widget disappears, preventing stale rows/false Robot OFF after remount.
- TradingTools RBRU/IBRU/LIM DOM reference observers/pollers now run only with the matching Tradext widget mounted.
- Robot countdown and precise-clock UI timers now start/stop with their widget lifecycle.
- Fuel SPIMEX local polling remains mounted-only; initial activation ordering was hardened to avoid a delayed first fetch.
- News WebSocket delivery, browser sound and desktop notifications are mounted-only. Telegram collection/cache intentionally remains always on at the VPS so reopening the News widget does not lose messages.
- Server v2.18.19 adds /health widget_activity + per-module runtime_active diagnostics and rolling-upgrade compatibility for older extensions.
- JSONL writer threads now start lazily on the first actual record instead of creating idle writer threads for unused diagnostics.
- Two lightweight core services intentionally remain independent of widget mounting: Telegram collection/cache (to preserve the current-day News history) and server NTP sync (shared by Robot timing/freshness as well as the Clock widget). No News WS delivery/alerts occur without a mounted News widget.
- Existing Robot OFF policy, Iceberg v1.4 model/thresholds, Fuel formulas, Stock/Futures formulas and news filtering are unchanged.

Tradext v2.20.41 — Stable stock/futures settings editor focus

- Fixed the «Спред Акция / Фьючерс» settings field losing focus during realtime updates.
- While the settings panel is open, incoming stock/futures snapshots update in memory but do not rebuild the editor DOM.
- The latest table is rendered immediately after Save or after closing the settings panel.
- Pointer/mouse/click events inside the settings panel are stopped from bubbling to T-Terminal widget-level drag/focus handlers.
- Minimum-spread default/filter semantics (>= 1.00%), K R A K E N 1 -> «Сигналы» UI alias, and all other modules are unchanged.
- Backend remains v2.18.18.

Tradext v2.20.40 — Stock/future minimum-spread filter + signal source alias

- Stock / front-future widget now defaults to a minimum executable spread of 1.00%.
- Only fresh actionable LONG FUT / SHORT FUT rows at or above the configured threshold are shown.
- The threshold is configurable from the widget gear; 0% shows every positive executable spread.
- Setting is stored locally in T-Terminal as tradextStockFuturesWidgetV1 and survives page reloads/new unpacked builds.
- Telegram source id:3752356964 (server title K R A K E N 1) is displayed in Tradext simply as «Сигналы». The internal source id and include_any filtering are unchanged.
- Backend remains v2.18.18; no server-side trading/news logic changed.

Tradext v2.20.39 — Stock / front-future spread widget

- Added widget: «Спред Акция / Фьючерс» (MOEX_STOCK_FUTURES_SPREAD).
- Backend v2.18.18 resolves TQBR shares to the nearest non-expired SPBFUT via T-Invest underlying metadata.
- Futures BID/ASK are normalized by basic_asset_size before comparison with one-share stock prices.
- Executable SHORT FUT = normalized FUT BID - STOCK ASK.
- Executable LONG FUT = STOCK BID - normalized FUT ASK.
- Spread shown in points and percent; LONG green, SHORT red.
- Existing News, Robots, Limits, Icebergs, Fuel and Clock behavior preserved.

Tradext v2.20.38 — Fuel spread points + percent

- Fuel expiry signal color semantics corrected: LONG is green, SHORT is red.
- SPIMEX today-only, Bitrix CSRF refresh, MOEX realtime pricing and robot-filter logic are unchanged.
- Backend/server.py unchanged.

Tradext v2.20.35 — SPIMEX exact response schema + Bitrix session diagnostics

- SPIMEX remains today-only (MSK); no previous-day values are used for the expiry signal.
- Parses the current official response directly from data.values.EVR_REG / EVR_PRM / EVR_DTL, with the recursive parser only as a compatibility fallback.
- Bitrix status/errors are now handled explicitly and are no longer mislabeled as “indexes not published”.
- User-opened SPIMEX pages are preferred over Tradext-owned relay tabs, avoiding stale BX.bitrix_sessid()/PHPSESSID state when a fresh site session exists.
- A Tradext-owned relay is reloaded once on an explicit Bitrix/session error and retried with a fresh token.
- If HTTP/Bitrix says success but expected keys are absent, the widget exposes response diagnostics instead of hiding the parser mismatch.
- Backend/server.py unchanged. Robot filter fixes from v2.20.32 are preserved.

Tradext v2.20.34 — SPIMEX today-only expiry data

- Fuel expiry scanner requests only the current Moscow date from SPIMEX; no previous-day fallback is used for the trading signal.
- AI-92 / AI-95 / DTL may still appear independently, but every accepted value must belong to the requested current date.
- Stale SPIMEX rows are cleared when today's index is unavailable or after the MSK date rolls over.
- SPIMEX JSON parsing searches exact EVR_REG / EVR_PRM / EVR_DTL keys through the response tree, so a harmless Bitrix nesting change does not blank the widget.
- Empty state now reports that today's index is not yet published instead of showing the last day of a historical lookup window.
- Backend/server.py unchanged. Robot filter fixes from v2.20.32 are preserved.

Tradext v2.20.18 — Icebergs OOS UI + new voice WAVs

- Icebergs v1.4 remains Beta; detector formula and thresholds are unchanged.
- Conservative default after the 2026-09-01 OOS session: HIGH on, ACTIVE off, WATCH off.
- Separate HIGH / ACTIVE / WATCH toggles, BUY/SELL filter and Q threshold.
- Table labels clarified: Turnover, Восст., Погл., Время.
- Optional sound and system notification only for a fresh NEW HIGH event; both are OFF by default. Initial/replayed snapshots never alert.
- Robot STOP notification is server-authoritative only (backend v2.15 five missed cycles); obsolete browser-side inactivity watcher removed.
- Replaced bundled neural voice WAVs with the user-provided recordings:
  * Новость -> sounds/voice_news.wav
  * Сигнал -> sounds/voice_signal.wav
  * Отключение робота -> sounds/voice_robot.wav (compatibility id preserved)
  * Планка -> sounds/voice_limit.wav
- Ordinary News source sound uses «Новость»; ordinary Signals source sound uses «Сигнал».
- Alerts remain terminal-session scoped: no T-Terminal tab = no backend WebSocket and no operational notifications.

Tradext v2.20.17 — Terminal-session alerts + Robot STOP 5-cycle + Icebergs Beta

- Operational sounds/desktop notifications work only while at least one https://www.tbank.ru/terminal/* tab is open.
- When the last T-Terminal tab closes, the extension closes its backend WebSocket and stops reconnecting; reopening T-Terminal reconnects and restores snapshots from the VPS.
- Robot STOP is driven by backend v2.15: exact watched robot id, five missed expected cycles, minimum 5 seconds; family/harmonic veto is not used for alerts.
- Adds the MOEX Icebergs (Beta) widget fed by the v1.4 physical-quality snapshot: ACTIVE/HIGH by default, WATCH optional, BUY/SELL and Q filters. No iceberg sound alerts yet.

Tradext v2.20.16 — Robot STOP Family Guard

- STOP alerts are now family-aware across detector aliases and simple period harmonics.
- Honors backend v2.14 off_alert_suppressed_by_family / off_family_active_count.
- Keeps robot table/lifecycle unchanged; only audible/desktop STOP confirmation is suppressed while a compatible family member remains active.
- Final family OFF still alerts even when the watched server id was an earlier alias.

Tradext v2.20.14 — UI cleanup / limits liquidity guard / branding

- Product name changed to Tradext (Trade Extension).
- Extension badge/icon changed to EXT where the T-Terminal SDK uses the supplied extension icon.
- Robot Scanner numeric settings are plain text fields (no HTML number input/spinners); numeric parsing is preserved.
- Price Limits: built-in system blacklist includes RFU6 and UZSRUB_TOM, in addition to the editable user blacklist.
- Price Limits: "Desktop" renamed to "Системное уведомление".
- Existing bundled voice WAV files are unchanged in this build; high-quality neural replacements can be dropped in later without changing alert logic.

MOEX Toolkit v2.20.7 — Price Limits Alert Cooldown

- Price Limits: first zone-entry alert starts a fixed 5-minute per-instrument notification cooldown.
- Existing hysteresis remains active, preventing boundary chatter.
- Direct exchange price-limit touch is a separate one-shot alert: «TICKER ↑/↓ ПЛАНКА».
- A direct jump to the limit produces only the touch alert, not duplicate zone + touch notifications.
- Touch alert is re-armed only after price leaves the configured notification zone plus hysteresis.
- Server unchanged; based on v2.20.6 unified Limits UI and v2.20.5 voice alerts.

MOEX Toolkit v2.20.6 — Unified Price Limits UI

- Price Limits widget restyled to match News/Robot Scanner/T-Terminal visual language.
- Header, table, hover states, scrollbars and settings use the shared transparent dark theme.
- Limits settings now open as a compact overlay, like Robot Scanner settings.
- Native browser number spinners replaced with compact − / + controls (0.1 step).
- Tracking and alert controls regrouped into clear compact sections.
- Keeps v2.20.5 voice alerts and new VPS backend.

MOEX Toolkit v2.20.5 — Robot voice selector hotfix

- Robot STOP sound selector now includes voice alerts: «Новость», «Робот», «Планка».
- Default robot STOP sound remains «Голос: Робот».
- Server unchanged.

MOEX Toolkit v2.20.4 — voice alerts

MOEX Toolkit v2.20.3 — Price Limits Scanner (stable)

MOEX Toolkit v2.19

- News/Signals: auto-focuses the correct first-level tab and source for every Signal and for News matching keyword/special keyword lists.
- Priority guard: special keyword > keyword > ordinary signal for 5 seconds, so a lower-priority event cannot immediately steal focus.
- Focused important item is visibly highlighted for 10 seconds; unread counters are preserved until explicitly cleared.
- Sources with "лента" disabled are hidden from the second-level source header but remain configurable in Settings.

MOEX Toolkit v2.17.1

Hotfix: News/Signals settings panel is no longer re-rendered while open, so keyword textareas keep focus and scroll position during auto-save/live updates.

MOEX Toolkit v2.16

Состав:
- Новости / Сигналы
  - источники задаются администратором на VPS;
  - настройки ленты, звука, Chrome-уведомлений и подсветки;
  - обычные и особые ключевые слова;
  - выбираемые встроенные звуки;
  - автосохранение настроек и резервное сохранение в T-Terminal localStorage;
  - встроенная справка ?.

- Сканер роботов MOEX
  - компактный режим таблицы;
  - акции / фьючерсы / валюта, валютные фьючерсы во вкладке «В»;
  - наблюдение 🔔 и подтверждённые STOP-уведомления;
  - настраиваемый звук остановки с предпрослушиванием;
  - сохранение настроек;
  - встроенная справка ?.

- Точное время MSK
  - серверная/NTP-синхронизация;
  - встроенная справка ?.

v2.15.1:
- Полностью удалён виджет «Онлайн статистика».
- Полностью удалён виджет «Сделки Пульса».
- Удалён связанный клиентский код, регистрация виджетов, справка и CSS.
- Серверная часть не меняется.

Hotfix v2.15.1: restored shared/news/robot CSS accidentally removed during v2.15 cleanup. Pulse Trades and Online Statistics remain unregistered and inactive.


v2.16:
- News/Signals: explicit $TICKER tokens are rendered in bold.
- Client-side cleanup for channel id 1816763737 (Акулы трейдинга): removes recurring subscription footer.
- Client-side cleanup for channel id 2422569793 (Сделки Пульса 2.0): removes recurring promo footer.
- The same cleaned text is used for keyword matching and Chrome desktop notification previews, while VPS/Telegram source text is unchanged.


v2.18.1: themed scrollbar in Robot Scanner settings; clearer Russian label for countdown display threshold.


NEW v2.20:
- Widget: Планки MOEX.
- T-Invest limit_up/limit_down + live trade price.
- Separate upper/lower percent thresholds.
- Shares/Currency/Futures filters.
- Sound + Chrome notification.
- Hysteresis anti-spam re-arm.
- Closest instrument sorted first.


Server compatibility:
- Recommended server: v2.18.1 Price Limits Stable on top of v2.17.2 realtime fast-path.
- limit_up/limit_down metadata is polled independently at low rate.
- Current price comes from the existing realtime T-Invest trade stream.
- The limits feature does NOT require continuous order-book subscription or order-book disk logging.


v2.20.3 stable additions:
- Separate enable switches for upper/lower limit zones.
- Stale limit metadata is hidden client-side (15 min safety window).
- Row tooltip shows both exchange limits and price source.
- Empty state distinguishes initial loading from no instruments in the zone.
- Existing v2.19 news autofocus/source hiding and robot UI behavior preserved.


v2.20.3 migration build:
- default backend moved to wss://app.tradext.ru/ws
- stored legacy direct ws:// addresses are migrated automatically
- custom server URLs are preserved

Voice alerts added: «Новость», «Робот», «Планка». Existing tone sounds remain selectable.


v2.20.8
- Виджет «Планки»: добавлен чёрный список тикеров в настройках.
- Тикеры из чёрного списка не отображаются и не создают звуковые/desktop-уведомления.
- Разделители: запятая, точка с запятой, пробел или новая строка; регистр не важен.


v2.20.9
- Robot table readability: slightly larger and heavier text in normal and compact modes.
- No backend/protocol changes.


v2.20.10
- В настройках виджета «Роботы» добавлен выбор отображаемых столбцов.
- Тикер остаётся всегда видимым; остальные колонки можно включать/скрывать независимо.
- Ширина таблицы автоматически уменьшается вместе с числом видимых колонок.


v2.20.11
- Robot table typography brought closer to TradingTools readability.
- System UI font with tabular numbers replaces thin-looking Consolas in robot rows.
- Larger/bolder headers, tickers and values, including compact mode.


v2.20.12
- News and Signals feed redesigned as clearly separated compact cards.
- Message text is visually primary; source and time moved into a compact footer.
- News/Signal source dots, subtle borders/backgrounds, ticker badges and hashtag chips added.
- Existing unread highlighting, keyword auto-focus, source filters and alerts are preserved.


v2.20.13
- Fixed phantom News voice alerts from sources disabled with the feed/лента switch.
- Keyword and special-keyword sounds now respect the per-source show preference.
- No backend changes required.


v2.20.16:
- Robot STOP: family/harmonic veto removed; backend v2.15 confirms OFF after 5 missed expected cycles (min 5s). Browser only debounces duplicate frames.
- Added MOEX Icebergs (Beta) widget using server v1.4 physical-quality snapshot. ACTIVE/HIGH shown by default; WATCH optional. No iceberg sound alerts yet.

v2.20.19
- Добавлен отдельный виджет "Топливо MOEX / SPIMEX".
- SPIMEX читается напрямую из официального AJAX JSON endpoint каждые 5 секунд.
- Индексы: ETIS_EVR_REG (АИ-92), ETIS_EVR_PRM (АИ-95), ETIS_EVR_DTL (ДТ летнее), etis / evr / руб./т / с НДС.
- Сопоставление с текущими месячными фьючерсами MOEX 92/95/DL из уже существующего realtime-кэша Tradext.
- Показываются индекс, последняя цена MOEX, basis в руб./т и %, дневное изменение индекса, объём и число сделок SPIMEX.
- Если данных за сегодня ещё нет, запрос автоматически пробует до 6 предыдущих дней.


v2.20.22 — локальный SPIMEX v1
- Источник EVR_REG / EVR_PRM / EVR_DTL запрашивается напрямую из Chrome, без VPS.
- Опрос инициирует content script каждые 5 секунд, поэтому работает, пока открыт T-Terminal.
- Добавлены оба hostname spimex.com и www.spimex.com, warm-up GET, cookies/credentials и AJAX headers.
- При ошибке виджет показывает этап/hostname (GET/POST, HTTP/timeout/Failed to fetch) для диагностики.
- MOEX пока берётся как last из уже существующего realtime-потока Tradext; bid/ask — следующим этапом.

v2.20.23 — SPIMEX local tab relay
---------------------------------
- Убран прямой POST к SPIMEX из MV3 service worker: на части сетей он зависал с timeout, хотя обычная страница SPIMEX открывалась.
- Tradext автоматически переиспользует открытую вкладку SPIMEX либо создаёт одну неактивную закреплённую вкладку.
- AJAX к индексам выполняется content script'ом прямо внутри origin spimex.com, то есть так же, как запрос самой страницы.
- VPS для SPIMEX не используется.


v2.20.24: SPIMEX fuel fetch is executed in the actual spimex.com page MAIN world via chrome.scripting.executeScript. It uses BX.bitrix_sessid(), BX-Ajax:true, X-Bitrix-Csrf-Token, X-Bitrix-Site-Id:s1, the current browser cookies/session, and the exact /indexes/petroleum/territorial/ referrer.


v2.20.25 — MOEX fuel price fallback
-----------------------------------
- Исправлены пустые столбцы MOEX / Basis, когда 92U6 / 95U6 / DLU6 отсутствуют в общем limits realtime universe backend.
- Приоритет остаётся за существующей realtime-ценой Tradext/T-Invest.
- Если realtime-цены нет, расширение локально запрашивает официальный MOEX ISS для текущих 92/95/DL контрактов и заполняет LAST; BID/OFFER также сохраняются для следующего этапа.
- Публичный MOEX ISS fallback в интерфейсе помечается как ISS ~15м, поскольку публичные котировки MOEX могут отображаться с задержкой.
- Basis = MOEX LAST - SPIMEX index; сервер менять не требуется.


v2.20.26 — Fuel executable edges
- SPIMEX remains local in the browser through the Bitrix MAIN-world relay.
- MOEX primary source is dedicated realtime depth=1 T-Invest quotes from server v2.18.14.
- Shows BID/ASK, quantities, quote age, nearest contract and DTE.
- SHORT edge = BID - SPIMEX; LONG edge = SPIMEX - ASK.
- MOEX ISS remains display-only delayed fallback and is not treated as a realtime trading edge.


v2.20.29 — Fuel production freshness
- MOEX BID/ASK остаются realtime T-Invest; серверный watchdog подтверждает неизменившийся стакан.
- Edge скрывается, если T-Invest книга не проверялась более 30 секунд.
- В UI отдельно показаны свежесть проверки и возраст последнего изменения B/A.
- Исправлено null -> 0 в SHORT/LONG edge.
- Убран горизонтальный scrollbar fuel-таблицы.


v2.20.29: SPIMEX relay self-healing: if the hidden tab lands on a Chrome error page, Tradext reloads/recreates it and retries MAIN-world Bitrix fetch.


v2.20.30 — Fuel widget lazy activation
- SPIMEX polling/relay starts only after MOEX_SPIMEX_FUEL is actually mounted.
- Removing the last fuel widget stops 5-second refreshes.
- A relay tab created by Tradext is closed when the last fuel widget is removed; a user-opened SPIMEX tab is never closed.
- TG_REQUEST_STATE no longer starts SPIMEX/MOEX ISS work by itself.


v2.20.31 — Expiry-only fuel scanner
- Fuel widget reduced to three columns: SPB, MOEX, СПРЕД.
- Each row contains the instrument name inside the SPB cell; volume, deals, daily index change, percentages, DTE, quote age and other analytics are removed from the visible table.
- LONG signal = SPB index - executable MOEX ASK. SHORT signal = executable MOEX BID - SPB index.
- Only a positive executable spread is shown as a green opportunity together with ЛОНГ/ШОРТ. If the index is inside the MOEX bid/ask spread or realtime is unavailable, the signal is hidden.
- Delayed MOEX ISS fallback is no longer requested by the fuel widget; trading signals use realtime T-Invest only.
- SPIMEX/SPB polling remains lazy: it starts only when the fuel widget is mounted and stops when the last fuel widget is removed.


v2.20.32 — Robot filter correctness + total turnover filter
- Robot filters are now applied to raw server robot rows before visual alias/dedupe consolidation, so an arbitrary alias representative can no longer decide whether the whole group passes a threshold.
- Live UPDATEs now trigger a fast table reconcile when a robot crosses a filter boundary instead of leaving a stale visible/hidden row until the slower periodic reconcile.
- Added monetary filter "Совокупный объём больше, млн ₽" based on server `total_money` (accumulated matched robot turnover). Zero disables this criterion.
- The new total-turnover criterion participates in the existing AND/OR aggregation together with packet money and money-per-minute filters.
- Backend changes are not required.


v2.20.33 — SPIMEX partial-date fuel fix
- Fuel SPIMEX lookup no longer requires EVR_REG, EVR_PRM and EVR_DTL to be present in the same daily response.
- Each of AI-92 / AI-95 / DTL independently takes the newest available index from the existing 7-calendar-day lookup window.
- One delayed/missing product no longer blanks the whole fuel widget; available products remain visible and continue to combine with realtime MOEX BID/ASK.
- Each SPB row now shows the actual SPIMEX index date. Missing products are explicitly marked as not found in the 7-day window.
- If no required index is found at all, the empty-state message describes the whole lookup window instead of incorrectly displaying only the last attempted date (for example 27.08.26).
- Backend/server.py unchanged.

v2.20.36
- SPIMEX: исправлена ротация Bitrix CSRF. При invalid_csrf расширение берет новый токен из errors[].customData.csrf, обновляет BX.bitrix_sessid и один раз повторяет сегодняшний POST.
- Токены/секреты в UI и логах не выводятся.
- Today-only логика индексов EVR_REG / EVR_PRM / EVR_DTL сохранена.


v2.20.38 — Fuel spread points + percent
- В колонке СПРЕД положительный исполнимый спред теперь показывается одновременно в пунктах и процентах, например: 1 250 · 1,70%.
- Процент рассчитывается относительно сегодняшнего индекса SPIMEX/SPB: abs(expiry_spread) / SPB_index × 100%.
- LONG остается зеленым, SHORT красным. Формулы исполнимого спреда и realtime MOEX/SPIMEX logic не изменены.
- Backend/server.py unchanged.

v2.20.42 lifecycle/optimization audit final:
- WebSocket opens only while at least one Tradext widget is mounted in a T-Terminal tab.
- Each tab reports mounted modules; server traffic is routed only to tabs that use that module.
- Fuel/SPIMEX, TradingTools reference observers, Robot countdown and Clock timer start/stop with their widgets.
- Removed unused MOEX ISS Fuel fallback/permission and obsolete spimex_content.js.
- Removed cross-widget rerenders and reduced startup state requests to post-injection sync + one retry.


=== v2.20.50 secure WSS transport ===
- Production backend endpoint is pinned to wss://app.tradext.ru/ws.
- Legacy direct ws://2.27.48.178:8765/ws and older stored endpoints are migrated automatically.
- Popup no longer exposes an editable backend URL.
- Manifest/CSP no longer allow arbitrary ws:// or wss:// destinations; only app.tradext.ru WSS is allowed.
- Widget/detector/business logic is unchanged from v2.20.49.
