Skip to content
08Кейс-стадіSW · 08 з 10

Календар звітностей і гамма-експозиція SPX, злиті в одну панель.

Кількісній трейдинговій фірмі треба було бачити дві речі на одному екрані — календар звітностей, достатньо точний, щоб торгувати проти нього, і живу дилерську гамма-експозицію SPX. Жодного з них не існувало в готовому вигляді. Ми побудували обидва й з'єднали їх.

КлієнтКонфіденційно
Рік2022 — 2026
Тривалість5 yrs
СтекTypeScript · Next.js · React · Node · Python · FastAPI · Redis
Hero image for earnings-gamma-dashboardМАЛ 01 · ГЕРОЙ

Дві поверхні. Одне трейдингове рішення.

Кількісна трейдингова фірма мала справу зі справжнім, але буденним роздратуванням: дані, потрібні їм для одного рішення, лежали у двох окремих інструментах, які гадки не мали про існування одне одного.

З одного боку — календар звітностей. Чотири основні публічні джерела, кожне трохи інакше — інші тикери, інші конвенції щодо часу дзвінка, час від часу дублікати, час від часу суперечності. Команда вручну звіряла їх між собою, перш ніж щось торгувати.

З іншого боку — дилерська гамма-експозиція SPX. Індикатор структури опціонного ринку, що показує, де концентрується систематичний тиск хеджування — які страйки стають магнітними, коли ринок рухається до них, де дилери купуватимуть слабкість і продаватимуть силу, який буфер має індекс, перш ніж увімкнеться механічний продаж. Для цього немає поля Bloomberg. Ви виводите його. Свіжим, із опціонного ланцюга біржі, з гаммою за Блеком-Шоулзом, обчисленою за страйком і агрегованою через дельта-коригування. І ви робите це кожні п'ятнадцять хвилин протягом касової сесії, інакше число, яке у вас є, уже неправильне.

Бриф був конкретним: один екран, обидва сигнали, синхронізовані. Наведіть курсор на подію звітності. Побачте гамма-картину для цієї дати. Готові продукти роблять одне або інше. Ніхто не робив обидва в одному поданні.

Злите подання: календар подій згори, гамма-експозиція знизу.

Панель давала трейдерам фірми календар звітностей, що виводив тикери з чотирьох незалежних джерел даних — дедубльовані, звірені, з індикаторами часу дзвінка — поверх живого графіка гамма-експозиції для SPX. Дві поверхні були синхронізовані: наведіть курсор на дату звітності, і графік гамми перемикався на картину експозиції для цієї сесії.

Графік гамми показував сукупну дилерську експозицію за страйком, дельта-скориговану, з лінією чистої гамми, що робила перехід плюс/мінус помітним з першого погляду. Нульова гамма — точка, де дилерське хеджування перемикається зі стабілізувального на підсилювальне — була позначена як константа. Денне відкриття й попереднє закриття були опорними лініями. Кластери страйків, де концентрувалася експозиція, з'являлися як піки.

Календар звітностей показував підтверджені й попередні події з індикаторами часу дзвінка (BMO, AMC, непідтверджено). Фільтрування на рівні тикера, селектор діапазону дат і подання списку відстеження дозволяли трейдеру звузити календар до свого портфеля, не торкаючись шару гамми. Два подання поділяли одну вісь дат. У цьому й була вся суть.

Фронтенд працював на Next.js 16 і React 19, D3.js відповідав за рендеринг гамми, а Zustand керував спільним станом календаря/графіка. Vercel Analytics було підключено з першого тижня продакшну.

F · 01Багатоджерельний календар звітностей
Чотири незалежні джерела, дедубльовані за тикером, датою й часом дзвінка. Обробка повторних спроб і backoff на рівні джерела плавно деградує календар, коли джерело ламається — подання трейдера ніколи не гасне.
F · 02Живий графік гамма-експозиції SPX
Гамма за Блеком-Шоулзом обчислюється свіжою на повному опціонному ланцюзі SPX кожні п'ятнадцять хвилин у ринкові години. Агрегована за страйком, дельта-скоригована. Нульова гамма й ключові опорні лінії позначені.
F · 03Синхронізована вісь дат
Наведіть курсор на подію звітності, і графік гамми перемикається на картину експозиції для цієї сесії. Злиття — у взаємодії, а не лише в макеті.
F · 04Гаряче сховище лише на Redis
Жодної холодної бази даних. Обидва конвеєри пишуть у Redis JSON, з ключем за датою й тикером. Субмілісекундне читання на фронтенді. Патерну доступу ніколи не було потрібно нічого більшого.
F · 05Телеметрія на рівні джерела
Кожен парсер звітностей виставляє свій стан повторних спроб як метрику. Зламаний парсер з'являється в моніторинговій панелі протягом одного циклу оновлення — раніше, ніж це помітить будь-хто, хто торгує проти цих даних.
F · 06Двомовний бекенд
Node/Express для скрейпінгу й дедублікації. Python/FastAPI для кількісного шару — scipy.stats, numpy, pandas. Кожна мова володіє проблемою, якій вона пасує. Один кеш зберігає результат.

Один кеш, два конвеєри, дві мови.

Проблема злиття даних під панеллю була архітектурним вибором із чіткою відповіддю: два незалежні конвеєри, жоден не блокує інший, що пишуть в єдине гаряче сховище.

Конвеєр звітностей працював на Node і Express. Сервіс-скрейпер витягував дані з чотирьох незалежних публічних календарів кожні три години. Кожне джерело мало власний парсер — ізольований, з обробкою повторних спроб і backoff, щоб тимчасовий збій на одному джерелі не псував інших. Дедублікація проводилася за тикером плюс датою плюс часом дзвінка; тикер, що з'являвся у трьох джерелах із незначними відмінностями у форматуванні дати, зводився до одного канонічного запису. Телеметрія на рівні джерела означала, що зламаний парсер було видно в моніторинговій панелі ще до того, як трейдер помічав щось не так.

Конвеєр гамми працював на Python. FastAPI обслуговував кількісний шар: свіжий опціонний ланцюг SPX, витягнутий із CSV-фіду біржі кожні п'ятнадцять хвилин у ринкові години, проведений через обчислення гамми за Блеком-Шоулзом із використанням scipy.stats і numpy, агрегований за страйком і дельта-скоригований. Python був тут правильним інструментом — scipy.stats, наукова екосистема Python і те, як кількісна команда вже мислила про обчислення. Переписування цього на TypeScript додало б тертя без жодної вигоди.

Щойно не стало холодної бази даних, на яку можна відкотитися, кожен конвеєр мусив бути коректним на момент запису. Цей тиск дав чистіші парсери й чіткішу історію on-call.

Обидва конвеєри писали в Redis. Жодної холодної бази даних — за задумом, а не через недогляд. Телеметрія з перших тижнів продакшну підтвердила те, що припускала архітектура: патерн доступу завжди був «як картина виглядає прямо зараз», ніколи «як вона виглядала шість тижнів тому». Redis JSON, з ключем за датою й тикером, давав фронтенду субмілісекундне читання поточного стану. Кеш був усім сховищем.

Чотири роки у продакшні. Досі оновлюється кожні п'ятнадцять хвилин.

Панель випустила своє перше продакшн-розгортання у 2022 році й відтоді працює безперервно. Архітектура з двох конвеєрів пережила три роки змін селекторів на джерелах звітностей, зміни формату біржового фіду з боку гамми й повну перебудову фронтенду, коли відбулася міграція на React 19.

Покриття звітностей сягає 5 000+ тикерів із чотирьох незалежних джерел. Гамма-рушій опрацьовує 3 000+ страйків SPX за цикл експірації. Каданси оновлення не змінилися: звітності кожні три години, гамма кожні п'ятнадцять хвилин протягом касової сесії.

Телеметрія circuit-breaker на рівні джерела виявилася найкориснішою з операційного погляду функцією. Парсери джерел ламаються тихо — редизайн календаря чи зміна API без оголошення. Телеметрія позначає деградоване джерело протягом одного циклу оновлення. Подання календаря в трейдера деградує плавно; воно не гасне.

Кодова база фронтенду досягла 325 комітів до кінця 2024 року. Бекенд перетнув 541. Гамма-рушій, що змінився найменше, стоїть на 59. Це співвідношення — чесна карта того, де насправді була робота: не в кількісній математиці — вона усталилася рано — а в безперервному обслуговуванні шару даних під нею.

Цитата / 04
Ми перестали вести окрему таблицю для цього протягом тижня після запуску. Воно робить звірку, яку ми робили вручну, і знає, як виглядає ринок, коли це робить.
Портфельний менеджерКількісна трейдингова фірма
Outcome
Earnings sources reconciled
4
Symbols covered
5,000+
Gamma refresh (market hours)
every 15 min
Years in continuous production
4
NEXTКейс-стаді 09SW · 09 з 10
AdTech2026

Три середовища виконання, одна команда, один місяць: мережа цифрового вивісного контенту для майданчика, рекламодавця й екрана.