Глава 167: InfoNCE в трейдинге
1. Введение
InfoNCE (Information Noise-Contrastive Estimation) — это контрастивная функция потерь, впервые предложенная ван ден Оордом и соавторами в их основополагающей статье 2018 года Representation Learning with Contrastive Predictive Coding. Основная идея элегантно проста: обучать представления, заставляя модель отличать истинный (положительный) сигнал от набора отвлекающих (отрицательных) примеров. В контексте финансовых рынков этот принцип оказывается удивительно мощным.
Традиционные подходы к прогнозированию рынка с учителем требуют явных меток — будущую доходность, флаги направления, теги режимов — все они зашумлены, запаздывают и по своей природе субъективны. InfoNCE обходит эту проблему. Вместо предсказания целевого значения он обучает пространство вложений, в котором похожие рыночные условия группируются вместе, а различные — отталкиваются друг от друга. Модели никогда не нужно знать «правильный ответ»; ей достаточно понимать, какие состояния похожи друг на друга.
Почему это важно для трейдинга?
- Рыночные режимы размыты. Чёткой границы между трендовым рынком и рынком возврата к среднему не существует. Контрастивное обучение обнаруживает эти границы из данных, а не навязывает их.
- Метки дороги. Размечать каждую 5-минутную свечу как «бычью» или «медвежью» — упрощение. InfoNCE обучает структуру без меток.
- Transfer learning становится естественным. Имея хороший энкодер, его можно дообучить для множества задач — генерации сигналов, управления рисками, построения портфелей — все они разделяют один и тот же базовый энкодер представлений.
- Устойчивость к шуму. Контрастивная функция потерь по своей природе более устойчива к зашумлённым входным данным, поскольку оперирует относительными сравнениями, а не абсолютными целями.
В этой главе мы построим полную систему обучения представлений на основе InfoNCE для данных криптовалютного рынка с использованием Rust. Мы загрузим реальные OHLCV-данные с биржи Bybit, построим контрастивные пары, обучим энкодер и исследуем полученное пространство вложений.
2. Математическое обоснование
2.1 Функция потерь InfoNCE
Имея представление запроса q, один положительный ключ k+ и N-1 отрицательных ключей k-, функция потерь InfoNCE определяется как:
L = -log( exp(sim(q, k+) / τ) / Σᵢ₌₁ᴺ exp(sim(q, kᵢ) / τ) )где:
sim(a, b)— функция сходства (обычно косинусное сходство)τ(тау) — гиперпараметр температуры- Сумма в знаменателе охватывает положительный ключ и все отрицательные ключи
По сути, это softmax кросс-энтропийная функция потерь, где «правильный класс» — это положительная пара. Модель обучается назначать высокое сходство положительной паре и низкое — всем отрицательным парам.
2.2 Косинусное сходство
В качестве функции сходства мы используем косинусное сходство:
sim(a, b) = (a · b) / (‖a‖ · ‖b‖)Косинусное сходство варьируется от -1 (противоположные направления) до +1 (одинаковое направление) и инвариантно к величине векторов. Это желательно, поскольку нас интересует направление представлений рыночного состояния, а не их масштаб.
2.3 Температурное масштабирование
Параметр температуры τ управляет «остротой» распределения:
- Низкая τ (напр., 0.05): Модель становится очень избирательной — сильно штрафует даже небольшие отклонения от положительной пары. Это приводит к более плотным кластерам, но может затруднить обучение.
- Высокая τ (напр., 1.0): Распределение становится более равномерным, и модель терпимее к различиям. Обучение проходит плавнее, но представления могут быть менее дискриминативными.
На практике τ ∈ [0.07, 0.5] работает хорошо. Для финансовых данных мы считаем τ = 0.1 хорошей отправной точкой, потому что рыночные состояния имеют тонкие различия, требующие достаточно резкой температуры.
2.4 Связь с взаимной информацией
Замечательное свойство InfoNCE состоит в том, что его минимизация максимизирует нижнюю границу взаимной информации между запросом и положительным ключом:
I(q; k+) ≥ log(N) - L_InfoNCEПо мере роста числа отрицательных примеров N эта граница становится более точной. Это означает, что энкодер обучает представления, сохраняющие максимум информации о взаимосвязи между парными рыночными состояниями.
3. Торговое применение
3.1 Построение контрастивных пар
Ключевое проектное решение при применении InfoNCE к трейдингу — как строить положительные и отрицательные пары. Мы определяем:
Положительные пары: Два рыночных окна, принадлежащих к похожему режиму. Конкретно:
- Временны́е соседи: Окна, близкие по времени (в пределах нескольких свечей друг от друга). Предположение: рыночные условия меняются медленно относительно размера окна.
- Схожая доходность: Окна с похожей реализованной доходностью на горизонте прогнозирования.
- Совпадение волатильности: Окна с похожей реализованной волатильностью.
Отрицательные пары: Окна из разных временных периодов или режимов. На практике мы берём случайные окна из набора данных — при достаточном количестве данных случайные выборки почти наверняка принадлежат к разным режимам.
В нашей реализации мы используем временну́ю близость как основной сигнал для положительных пар: если два окна находятся в пределах настраиваемого расстояния друг от друга, они считаются положительными. Все остальные окна в батче служат отрицательными примерами.
3.2 Инженерия признаков для энкодера
Каждое рыночное окно представлено вектором признаков, извлечённых из OHLCV-данных:
| Признак | Описание |
|---|---|
| Нормализованная доходность | (close - open) / open для каждой свечи |
| Диапазон high-low | (high - low) / open — прокси для волатильности |
| Коэффициент объёма | Объём относительно скользящего среднего |
| Коэффициент тела | abs(close - open) / (high - low) — доля тела свечи |
| Верхняя тень | (high - max(open, close)) / (high - low) |
| Нижняя тень | (min(open, close) - low) / (high - low) |
Эти признаки выбраны потому, что они инвариантны к масштабу — описывают форму и характер ценового действия, а не абсолютные уровни. Это критически важно для контрастивного обучения, поскольку мы хотим, чтобы модель группировала рыночные поведения, а не ценовые уровни.
3.3 Архитектура энкодера
Мы используем простой полносвязный энкодер:
Вход (window_size × features) → Выпрямление → Dense(128, ReLU) → Dense(64, ReLU) → Dense(32) → L2-нормализацияФинальная L2-нормализация гарантирует, что все представления лежат на единичной гиперсфере, что является стандартной практикой при использовании косинусного сходства. 32-мерное выходное пространство достаточно компактно для интерпретации и достаточно выразительно для захвата рыночной структуры.
3.4 Использование в задачах
После обучения энкодер может применяться для:
- Определение режимов: Кластеризация вложений (напр., K-means) для обнаружения рыночных режимов.
- Поиск по сходству: По текущему рыночному состоянию найти наиболее похожие исторические состояния и изучить, что произошло далее.
- Извлечение признаков: Использовать вложения как входные признаки для последующей торговой модели (напр., предсказатель доходности или модель рисков).
- Обнаружение аномалий: Отмечать рыночные состояния, вложения которых далеки от любого центра кластера.
4. Описание реализации
4.1 Основные структуры данных
Определяем основные типы в Rust:
pub struct OhlcvCandle { pub timestamp: u64, pub open: f64, pub high: f64, pub low: f64, pub close: f64, pub volume: f64,}
pub struct InfoNCEConfig { pub temperature: f64, pub embedding_dim: usize, pub window_size: usize, pub positive_range: usize, pub num_negatives: usize, pub learning_rate: f64,}4.2 Вычисление функции потерь InfoNCE
Вычисление потерь следует формуле напрямую:
pub fn infonce_loss( query: &Array1<f64>, positive: &Array1<f64>, negatives: &[Array1<f64>], temperature: f64,) -> f64 { let pos_sim = cosine_similarity(query, positive) / temperature; let neg_sims: Vec<f64> = negatives .iter() .map(|n| cosine_similarity(query, n) / temperature) .collect();
let max_sim = pos_sim.max(neg_sims.iter().cloned().fold(f64::NEG_INFINITY, f64::max)); let pos_exp = (pos_sim - max_sim).exp(); let neg_sum: f64 = neg_sims.iter().map(|&s| (s - max_sim).exp()).sum();
-(pos_exp / (pos_exp + neg_sum)).ln()}Обратите внимание на приём log-sum-exp (вычитание max_sim перед возведением в степень) для числовой стабильности.
4.3 Загрузка данных с Bybit
Мы загружаем OHLCV-данные через Bybit V5 API:
pub async fn fetch_bybit_klines( symbol: &str, interval: &str, limit: usize,) -> Result<Vec<OhlcvCandle>> { let url = format!( "https://api.bybit.com/v5/market/kline?category=linear&symbol={}&interval={}&limit={}", symbol, interval, limit ); let response: BybitResponse = reqwest::get(&url).await?.json().await?; // Парсинг и возврат свечей...}4.4 Генерация контрастивных пар
Окна извлекаются из серии OHLCV. Для каждого якорного окна выбирается ближайшее окно как положительное и случайные отдалённые окна как отрицательные:
pub fn generate_contrastive_pairs( candles: &[OhlcvCandle], config: &InfoNCEConfig,) -> Vec<ContrastiveSample> { // Для каждой допустимой якорной позиции: // 1. Извлечь окно признаков в позиции i // 2. Выбрать положительный пример из [i-range, i+range] // 3. Выбрать num_negatives из отдалённых позиций // ...}4.5 Цикл обучения
Цикл обучения проходит по контрастивным примерам, вычисляет функцию потерь и обновляет энкодер методом градиентного спуска. Поскольку мы реализуем простую полносвязную сеть с нуля на ndarray, вычисление градиентов использует конечные разности для простоты (в продакшн-системе использовалось бы автоматическое дифференцирование).
5. Интеграция с криптоданными Bybit
Bybit V5 API предоставляет бесплатный доступ без авторизации к историческим данным свечей (kline). Используемый эндпоинт:
GET https://api.bybit.com/v5/market/klineПараметры:
category:"linear"для USDT бессрочных фьючерсовsymbol: напр.,"BTCUSDT"interval:"1"(1 мин),"5"(5 мин),"15","60","240","D","W"limit: Количество свечей (макс. 200)
Структура ответа:
{ "retCode": 0, "result": { "list": [ ["timestamp", "open", "high", "low", "close", "volume", "turnover"], ... ] }}Свечи возвращаются в обратном хронологическом порядке (сначала самые новые), поэтому мы разворачиваем их перед обработкой. Данные поступают в реальном времени и не требуют API-ключа, что делает их идеальными для образовательных и исследовательских целей.
Лимиты запросов: Публичный эндпоинт допускает приблизительно 10 запросов в секунду, что более чем достаточно для наших задач.
Аспекты интеграции
При интеграции данных Bybit в режиме реального времени в конвейер InfoNCE:
- Нормализация данных: Сырые значения OHLCV различаются на порядки между активами. Наша инженерия признаков (раздел 3.2) решает это, используя отношения вместо абсолютных значений.
- Пропущенные данные: Если API возвращает меньше свечей, чем запрошено, мы соответственно корректируем расчёты окон.
- Выравнивание временных меток: Временные метки Bybit — в миллисекундах. Мы конвертируем в секунды для единообразия.
- Кэширование: Для обучения рекомендуется кэшировать загруженные данные, чтобы не превышать лимиты запросов и обеспечить воспроизводимость.
6. Ключевые выводы
-
InfoNCE предоставляет безлейбловую функцию обучения для финансовых рынков. Обучая модель отличать похожие рыночные состояния от различных, мы получаем богатые представления без необходимости явных целей прогнозирования.
-
Параметр температуры критически важен. Слишком низкий — и модель переобучается на тривиальных различиях; слишком высокий — и она не обучает значимую структуру. Начните с
τ = 0.1для финансовых данных и подбирайте далее. -
Проектирование контрастивных пар — важнейшее инженерное решение. Временна́я близость — разумная отправная точка, но включение схожести доходности, совпадения волатильности или меток режимов (при их наличии) может значительно улучшить качество представлений.
-
Rust обеспечивает гарантии производительности и безопасности, ценные для продакшн-торговых систем. Система типов отлавливает ошибки на этапе компиляции, а отсутствие сборщика мусора гарантирует предсказуемую задержку.
-
Обученные представления универсальны. Один обученный энкодер может поддерживать определение режимов, поиск по сходству, извлечение признаков и обнаружение аномалий — что делает его фундаментальным компонентом современной торговой системы.
-
Увеличение числа отрицательных примеров улучшает границу взаимной информации. Используйте столько отрицательных примеров, сколько позволяет оборудование. Размеры батчей 256-1024 типичны в литературе по контрастивному обучению.
-
Комбинируйте с другими функциями потерь. InfoNCE хорошо работает как функция потерь предобучения. После предобучения дообучите энкодер с небольшим количеством размеченных данных для конкретной торговой задачи, чтобы получить лучшее из обоих подходов.
Ссылки
- van den Oord, A., Li, Y., & Vinyals, O. (2018). Representation Learning with Contrastive Predictive Coding. arXiv:1807.03748.
- Chen, T., Kornblith, S., Norouzi, M., & Hinton, G. (2020). A Simple Framework for Contrastive Learning of Visual Representations. ICML 2020.
- He, K., Fan, H., Wu, Y., Xie, S., & Girshick, R. (2020). Momentum Contrast for Unsupervised Visual Representation Learning. CVPR 2020.