Что будет, если убрать proxy-цель из трейдингового ML-пайплайна и оптимизировать напрямую то, что реально важно в торговле?

Большинство систем алгоритмической торговли на основе машинного обучения устроены по одной и той же схеме: модель предсказывает будущую доходность, вероятность движения цены или другой промежуточный сигнал, после чего отдельный слой правил превращает этот прогноз в торговую позицию. На первый взгляд схема выглядит естественно с разделением ответственности и с обучением на том, что хорошо оптимизируется.
Но в ней есть структурная проблема.
На обучении мы минимизируем MSE (mean squared error, среднеквадратичную ошибку) или кросс-энтропию. В реальной торговле стратегию оценивают по Sharpe ratio, просадке, оборотным издержкам. Эти два пространства связаны слабее, чем принято думать. Хорошая точность предсказания следующего бара не гарантирует хороший торговый результат особенно в out-of-sample режиме, где мелкие колебания рынка предсказать нельзя в принципе.
Именно этот разрыв между тем, что модель оптимизирует, и тем, по чему её оценивают, лежит в основе проекта DiffQuant.
Ключевая идея: весь путь от сырых рыночных признаков через позицию модели до итоговой торговой метрики - это единый дифференцируемый вычислительный граф. В такой постановке loss.backward() обновляет веса не через proxy-цель, а через саму торговую механику: mark-to-market PnL, транзакционные издержки и коэффициент Шарпа.
Код открыт на GitHub. Данные на HuggingFace. Любой результат из этой статьи можно воспроизвести.
Содержание
1. Проблема proxy-цели
Классическая трейдинговая ML-схема:
данные → predict(return_{t+1}) → MSE loss → обновление весов ↓ конвертация в позицию ↓ бэктестер → Sharpe / PnL / просадка
На обучении MSE. На оценке Sharpe. Этот архитектурный разрыв порождает несколько конкретных проблем.
Проблема 1: разные пространства ошибок. Модель, точно предсказывающая мелкие колебания, не гарантирует прогнозирование прибыльных позиций. Более того высокая accuracy на малоамплитудных движениях часто ведёт к гиперактивной стратегии с разрушительным оборотом.
Проблема 2: нет сигнала о размере позиции. MSE-модель учится угадывать направление, но не знает, насколько агрессивно входить. Размер позиции задаётся внешними эвристиками, которые не участвуют в обучении.
Проблема 3: издержки вне графа. Комиссия и проскальзывания применяются пост-фактум, на этапе бэктестинга. Модель не знает об их существовании и не может научиться их учитывать.
Данный проект решает все три проблемы одновременно: позиция, издержки и торговая метрика становятся частью вычислительного графа.
2. Дифференцируемый торговый симулятор
Центральный вопрос: можно ли записать торговый результат как набор тензорных операций, через которые пройдёт градиент?
В случае DiffQuant - да.
Для каждого шага горизонта симулятор вычисляет:
Все четыре операции это обычные тензорные вычисления в PyTorch. Градиент проходит от коэффициента Шарпа обратно через PnL, через позицию и через backbone модели.
Нетривиальная деталь: транзакционные издержки содержат . Обычный модуль недифференцируем в нуле и именно там, где модель часто находится в начале обучения или вблизи flat-состояния. Для сохранения
-дифференцируемости используется сглаженная аппроксимация:
При больших она совпадает с обычным модулем. В окрестности нуля остаётся гладкой, что исключает разрывы в субградиенте и снижает риск численных нестабильностей в ранних эпохах, когда политика часто находится вблизи flat-состояния.
3. Архитектура политики
Полный вычислительный граф выглядит так:
raw_features[t−ctx:t] │ ▼ per-sample z-score только по контексту (без look-ahead) normalized_window (B, ctx, F) │ ▼ iTransformerEncoder backbone_output (B, F × d_model) │ │ extras: [prev_pos, prev_delta, t/H, (H−t)/H] ▼ concat → PolicyHead → direction_head × gate_head │ ▼ position_t ∈ (−1, +1) │ ▼ DiffSimulator → HybridLoss → loss.backward()
iTransformer: внимание по каналам, а не по времени
В качестве backbone используется iTransformer (Liu et al., ICLR 2024 Spotlight). В отличие от классического Transformer, где токенами служат временны́е шаги, iTransformer инвертирует постановку: токеном становится канал признаков. Весь временной ряд одного канала кодируется в единый токен, а механизм внимания работает над каналами.
Для финансовых данных это осмысленная индуктивная гипотеза: устойчивые взаимосвязи между ценой, объёмом и волатильностью носят межканальный характер. Локальные временны́е шаблоны это вещь менее воспроизводимая.
В текущей конфигурации: d_model=32, n_layers=4, n_heads=2, d_ff=64 итого 52 354 параметра.
Direction × Gate: торговать и торговать ли вообще
Выход policy head это произведение двух независимых сигналов:
- направленный альфа-сигнал, кодирует куда торговать;
- gate-сигнал, кодирует торговать ли вообще.
Когда уверенность модели низка, , и итоговая экспозиция
независимо от направления. Это дифференцируемый аналог action masking из RL.
Инициализация gate-bias = −1.0. В начале обучения модель стартует в near-flat режиме. Позиции открываются только тогда, когда накопленный градиентный сигнал действительно оправдывает экспозицию. Это существенно стабилизирует ранние эпохи так как без этой детали первые итерации переобучаются на шуме.
Скользящий rollout без look-ahead
На каждом шаге горизонта модель видит исключительно прошлое контекстное окно. Нормализация пересчитывается на каждом шаге только по этому окну:
for t in range(H): window = full_seq[:, t : t + ctx, :] window_norm = normalize_context(window) # только прошлые ctx баров extras = [prev_pos, prev_delta, t/H, (H−t)/H] pos_t = model(window_norm, extras) positions_list.append(pos_t) positions = cat(positions_list) step_pnl = simulator.simulate(closes, positions) loss = hybrid_loss(step_pnl, positions) loss.backward()
Утечка будущей информации в трейдинговых задачах часто прячется именно в нормализации. Здесь она исключена.
4. Гибридный loss: почему одного Шарпа недостаточно
Прямая оптимизация Шарпа звучит элегантно, но на практике быстро приводит к нескольким патологическим режимам:
Патология | Симптом |
|---|---|
Churning | Модель перебалансируется каждый бар, съедая результат комиссиями |
Flat collapse | Модель уходит в постоянный кэш, Sharpe формально конечен |
Long bias | На бычьем датасете модель сводится к buy-and-hold |
Terminal exposure | Весь риск переносится в конец горизонта |
Drawdown blindness | Высокая средняя доходность ценой неприемлемой просадки |
Гибридный loss адресует каждую из этих патологий отдельным членом:
- основная торговая цель;
- штраф за оборот, борется с churning;
- контроль просадки внутри эпизода;
- штраф за открытую позицию в конце горизонта;
- мягкое удержание доли flat-состояния вблизи целевой;
- штраф за систематический long/short bias.
О компоненте : он оказался критически важным. В ранних конфигурациях без этого штрафа модель, обученная на преимущественно бычьем BTC 2024–2025, устойчиво дрейфовала в long-only поведение. Это не баг, а закономерная адаптация к данным. Штраф за bias не даёт модели принять рыночный тренд за универсальный закон.
Просадка считается в лог-пространстве для числовой устойчивости на длинных горизонтах:
Доля flat-состояния аппроксимируется дифференцируемо через сигмоиду:
5. Mirror augmentation: симметричное обучение на асимметричных данных
Обучающий период (январь 2024 - март 2025) для BTC в значительной мере бычий. Модель, обученная напрямую на таких данных, без дополнительных мер неизбежно обнаруживает простой эвристический сигнал: рынок чаще растёт, следовательно, дефолтная позиция будет LONG.
Для устранения этого смещения в train loop включена mirror augmentation: на части батчей ценовые каналы и траектория цены инвертируются зеркально. Растущий рынок превращается в падающий, и наоборот. Важно: инвертируются и признаки, и сама ценовая динамика в симуляторе одновременно. Если инвертировать только цены при неизменных признаках, то получается противоречивый градиент, который дестабилизирует обучение.
Итог: при полностью бычьем train-режиме модель на held-out периодах демонстрирует ненулевую short-экспозицию:
Test (июль–сентябрь 2025): short fraction = 17.3%
Backtest (октябрь–декабрь 2025): short fraction = 20.9%
Во многих предыдущих конфигурациях без аугментации short_fraction был близок к нулю.
6. Эксперимент: данные, сплиты, конфигурация
Датасет
Параметр | Значение |
|---|---|
Инструмент | BTCUSDT Binance Futures (USDⓈ-M perpetual) |
Исходное разрешение | 1-минутные бары, close-time convention |
Период | 2021-01-01 – 2025-12-31 |
Источник |
Агрегация до 30-минутного таймфрейма с origin="epoch" выравниванием: 87 648 баров. После нарезки на неперекрывающиеся эпизоды со stride=24 - 3 647 sample-эпизодов.
Временны́е сплиты
Сплит | Период | Назначение |
|---|---|---|
Train | 2024-01-01 → 2025-03-31 | Градиентные обновления |
Val | 2025-04-01 → 2025-06-30 | Отбор checkpoint во время обучения |
Test | 2025-07-01 → 2025-09-30 | Out-of-sample оценка |
Backtest | 2025-10-01 → 2025-12-31 | Финальная hold-out оценка |
Ключевое решение: обучающее окно намеренно ограничено 15 месяцами (январь 2024 - март 2025), а не всем доступным историческим рядом с 2021 года. Цель заключается в том чтобы удержать train-режим достаточно близко к evaluation-периодам и минимизировать distribution shift. Расширение на более ранние данные это первый рекомендованный ablation.
Конфигурация основного эксперимента
cfg.backbone.type = "itransformer" # d_model=32, n_layers=4 cfg.data.preset = "ohlcv" # 6 каналов: OHLCV + rolling_vol cfg.data.timeframe_min = 30 # 30-минутные бары cfg.data.ctx_len = 96 # контекст: 96 баров = 48 часов cfg.data.horizon_len = 24 # горизонт: 24 бара = 12 часов cfg.training.epochs = 30 cfg.training.lr = 1e-3 cfg.training.batch_size = 64 cfg.training.mirror_aug = True cfg.sim.commission = 0.0004 # 0.04% комиссия cfg.sim.slippage = 0.0003 # 0.03% slippage
Почему маленькая модель и неперекрывающиеся эпизоды? 910 train-эпизодов это намеренно малая выборка. При stride=horizon_len=24 каждый sample покрывает отдельное 12-часовое рыночное окно, не пересекаясь с другими. Модель с 52K параметрами на 910 независимых эпизодах capacity-constrained была выбрана специально, так как она хуже приспособлена к запоминанию шумной рыночной микроструктуры.
7. Динамика обучения
Одна из самых показательных частей эксперимента это не финальные метрики, а то, как именно модель приходит к рабочему режиму.
Эпоха | Val Sharpe | Val Return | Flat% | Turnover/bar |
|---|---|---|---|---|
2 | −6.49 | −14.1% | 1.6% | 0.0335 |
4 | −2.45 | −2.8% | 14.3% | 0.0003 |
8 | −0.64 | −0.4% | 77.5% | 0.0003 |
10 | −0.72 | −1.1% | 56.8% | 0.0019 |
12 | +0.46 | +0.9% | 17.7% | 0.0035 |
20 | +1.21 | +5.2% | 15.4% | 0.0101 |
30 | +1.25 | +5.8% | 13.2% | 0.0135 |

Рис. 1. Train Loss по эпохам показывает монотонное снижение с 0.1503 до отрицательных значений (loss включает −Sharpe, поэтому отрицательный loss соответствует положительному Sharpe).

Рис. 2. Validation Sharpe (ann.) по эпохам. Лучший checkpoint быд на 30 эпохе, val Sharpe = +1.254. Модель ещё не сошлась к концу run’а.
Обучение проходит через две последовательные патологические фазы, прежде чем найти рабочий режим:
Фаза 1 (эп. 2): гиперактивность. Модель слишком активна: turnover/bar = 0.0335, flat = 1.6%. Портфель торгует почти каждый бар, комиссии съедают весь результат. Val Sharpe = −6.49.
Фаза 2 (эп. 8): flat collapse. Найдя, что активная торговля убыточна, модель уходит в противоположную крайность: flat fraction = 77.5%, turnover ≈ 0. Это безопасный, но торгово бесполезный режим.
Фаза 3 (эп. 12+): рабочий компромисс. Flat_target-регуляризация не даёт модели оставаться в кэше. Val Sharpe переходит в положительную зону и продолжает расти.

Рис. 3. Доля времени в flat (кэш) по эпохам. Хорошо виден путь через flat collapse (пик 77.5% на эп. 8) и возврат к рабочему режиму (13.2% к эп. 30).

Рис. 4. Validation Max Drawdown по эпохам. По мере роста активности Sharpe растёт, а так же вместе с ним умеренно растёт и просадка (до ~7% к концу обучения).

Рис. 5. Turnover/bar по эпохам. После начального скачка (0.0335 на эп. 2) стабилизируется в диапазоне 0.01-0.014 это торгово разумный уровень.
Важное наблюдение: лучший checkpoint сохранён на последней эпохе (30), и val Sharpe продолжал расти к концу run’а. Это согласуется с гипотезой о недосходимости и указывает на потенциал дополнительных эпох, но это вопрос, требующий отдельной абляции и дополнительных исследований.
8. Walk-forward оценка: test и backtest
Как training validation, так и финальная оценка используют единый непрерывный walk-forward протокол, тот же, что применялся бы при live-торговле:
for t in range(ctx_len, N): window = features[t − ctx : t] # только прошлые бары position = model(normalize(window)) # один forward pass pnl_t = prev_pos × ret_t − commission × |Δpos| # позиция переносится на следующий бар без сброса
Нет отдельной evaluation-логики. Нет эпизодных сбросов. Один и тот же WalkForwardEvaluator работает и при обучении (каждые val_freq эпох), и при финальной оценке.
Test: июль–сентябрь 2025 (out-of-sample, 3 месяца)

Рис. 6. Walk-forward оценка на test-периоде (фактическое окно: 2025-07-02 → 2025-09-29): кривая капитала (white line), daily PnL (bar chart), underwater equity, распределение позиций Long/Short и динамика gate-сигнала. Sharpe=+1.73, Return=+8.22%, MaxDD=6.10%.
Метрика | Значение |
|---|---|
Sharpe (ann.) | +1.735 |
Sortino (ann.) | +2.173 |
Calmar | 1.346 |
Total Return | +8.22% |
Max Drawdown | 6.10% |
Commission paid | 2.50% |
Rebalances | 79 |
Long / Short / Flat | 66.9% / 17.3% / 15.8% |
Mean |position| | 0.445 |
Direction accuracy | 50.65% |
Correct avg ret | +0.0656% |
Incorrect avg ret | −0.0613% |

Рис. 7. Анализ позиций на test-периоде: гистограмма весов (Long/Short/Flat), CDF (cumulative distribution function) |position| с exit threshold=0.05 и круговая диаграмма соотношения. Mean gate=0.125 сообщает о том, что модель работает с частичной экспозицией, а не просто полным рычагом.
Backtest: октябрь–декабрь 2025 (финальный hold-out)

Рис. 8. Walk-forward оценка на backtest-периоде (фактическое окно: 2025-10-02 → 2025-12-30). Sharpe=+1.15, Return=+6.91%, MaxDD=7.91%. Заметен сложный ноябрьский период с откатом до −3%, после которого стратегия восстановилась и завершила квартал в плюсе.
Метрика | Значение |
|---|---|
Sharpe (ann.) | +1.152 |
Sortino (ann.) | +1.250 |
Calmar | 0.874 |
Total Return | +6.91% |
Max Drawdown | 7.91% |
Commission paid | 2.60% |
Rebalances | 76 |
Long / Short / Flat | 53.3% / 20.9% / 25.8% |
Mean |position| | 0.357 |
Direction accuracy | 50.56% |
Correct avg ret | +0.0753% |
Incorrect avg ret | −0.0708% |

Рис. 9. Анализ позиций на backtest-периоде. Mean gate=0.123. Flat fraction вырос до 25.8% - модель стала осторожнее в менее определённом рыночном режиме, но сохранила ненулевую short-экспозицию (20.9%).
9. Что именно показывают результаты
9.1 Оба held-out периода: положительные
Первичный результат прост: и test (+1.73), и backtest (+1.15) показали положительный Sharpe и положительную доходность после полного учёта комиссий (2.50% и 2.60% соответственно).
Один положительный out-of-sample квартал может быть потенциальной случайностью. Два последовательных непересекающихся квартала это уже более содержательный сигнал. Не доказательство готовой стратегии, но достаточное основание для продолжения исследований.
9.2 Direction accuracy ≈ 50% и это не слабость
Direction accuracy на test 50.65%, на backtest 50.56%. Наивно это выглядит как “почти случайное угадывание”. Но точнее как правильно поставленная задача.
Ключевые числа:
Test | Backtest | |
|---|---|---|
Correct avg ret | +0.0656% | +0.0753% |
Incorrect avg ret | −0.0613% | −0.0708% |
Асимметрия | +0.0043% | +0.0045% |
Модель не предсказывает следующий бар. Она управляет экспозицией: открывается тогда, когда expected return превышает expected cost, и остаётся в кэше или берёт частичную позицию в остальное время. Gate-механизм фильтрует сделки с низкой уверенностью, улучшая signal-to-noise ratio исполненных позиций.
9.3 Осторожный режим во втором периоде
Между test и backtest прослеживается систематический сдвиг в сторону большей осторожности:
Показатель | Test | Backtest |
|---|---|---|
Flat fraction | 15.8% | 25.8% |
Mean |position| | 0.445 | 0.357 |
Active days | 92.2% | 84.4% |
Снижение активности совпадает с более сложным рыночным режимом (ноябрьский откат виден на equity curve). Важно: стратегия не компенсирует ухудшение условий увеличением риска. Наоборот gate-сигнал снижает экспозицию в неопределённых ситуациях.
9.4 Asymmetric learning работает
На обучающем периоде (бычий BTC 2024–2025) модель тем не менее выучила симметричное поведение: short-фракция 17-21% в оба evaluation-квартала. Без mirror augmentation в большинстве предыдущих экспериментах short_fraction стремился ожидаемо к нулю.
9.5 Gate остаётся низким по всей траектории
Mean gate ≈ 0.12-0.13 на обоих периодах. Модель никогда не работает с полной экспозицией. CDF |position| показывает, что большинство позиций частичные. Это соответствует консервативному профилю риска, заданному lambda_bias и flat_target регуляризацией.
10. Ограничения
Честное описание ограничений важнее, чем замалчивание.
Один инструмент. Все результаты получены только на BTCUSDT. Никаких выводов о переносимости на другие активы из этой статьи сделать пока нельзя.
Упрощённая модель издержек. Commission и slippage применяются равномерно. Для позиций, достаточных для движения рынка, необходим квадратичный market impact (параметр market_impact_eta в SimulatorConfig реализован.
Чувствительность к гиперпараметрам. Веса loss-функции, длина train-окна, состав признаков и параметры обучения взаимодействуют нелинейно. Это не plug-and-play рецепт, а исследовательская постановка, требующая систематической настройки.
Малая статистическая база. Два квартала достаточно для содержательного сигнала, но недостаточно для сильных заявлений о статистической значимости.
Нет live execution layer. Проект является исследовательским фреймворком, не production-ready системой. Подключение к брокерскому API требует инженерной работы за пределами текущего scope.
11. Архитектура проекта и дальнейшее развитие
DiffQuant изначально строился как открытая исследовательская лаборатория, а не как один удачный эксперимент. Ключевые свойства архитектуры кода:
diffquant/ ├── configs/ # MasterConfig - единый источник всех гиперпараметров ├── data/ # Кэшируемый пайплайн MD5-хешем, агрегация, признаки, сплиты ├── model/ # backbone/ (iTransformer, LSTM), policy_head, policy_network ├── simulator/ # DiffSimulator + loss-функции ├── training/ # DiffTrainer - episode rollout + walk-forward val ├── evaluation/ # Единый WalkForwardEvaluator (обучение и финальная оценка) ├── sanity/ # Gradient flow checks + trend bias checks ├── optimize.py # Optuna: поиск гиперпараметров ├── optimize_thresholds.py # Optuna: отбор порогов на val └── compare.py # Сравнительная таблица всех завершённых экспериментов
Перед запуском основного обучения доступна sanity-проверка:
python sanity_check.py --config configs/experiments/itransformer_hybrid.py # PASS gradient_flow all params receive gradient # PASS long_bias mean_position=+0.19 expected_sign=+ # PASS short_bias mean_position=-0.16 expected_sign=- # ALL PASSED
Приоритетные направления развития
Мультиактивный портфель. Текущая архитектура оптимизирует одну позицию. Расширение на портфель требует cross-asset attention и портфельного Sharpe с учётом корреляций. Дифференцируемый симулятор обобщается естественно: .
Более богатые objective-функции. Гибридный loss это первое приближение. Перспективны Calmar-ориентированные цели, conditional drawdown penalties и режимно-зависимое взвешивание -коэффициентов.
Дополнительные backbones. LSTM-энкодер реализован, но полноценного benchmark против iTransformer в идентичной постановке ещё нет. Запланированы PatchTST, Mamba и линейные варианты attention.
Online data pipeline. Scheduled сбор данных (Binance WebSocket → feature pipeline → model inference) для paper trading и live мониторинга.
Быстрый старт
git clone https://github.com/YuriyKolesnikov/diffquant cd diffquant pip install -r requirements.txt # Данные (1-min BTCUSDT 2021–2025) huggingface-cli download ResearchRL/diffquant-data \ --local-dir data_source/ --repo-type dataset # Sanity checks python sanity_check.py --config configs/experiments/itransformer_hybrid.py # Обучение python train.py --config configs/experiments/itransformer_hybrid.py --device cuda # Финальная оценка (test + backtest) python evaluate.py --config configs/experiments/itransformer_hybrid.py # Поиск гиперпараметров python optimize.py --config configs/experiments/itransformer_hybrid.py --trials 100 # Сравнение всех экспериментов python compare.py
Связанные работы
Buehler et al. (2019). Deep Hedging. Quantitative Finance. Фундаментальный фреймворк для обучения нейросетевых политик через дифференцируемую финансовую цель. DiffQuant адаптирует эту парадигму от хеджирования деривативов к направленной альфа-генерации.
Liu et al. (2024). iTransformer. ICLR 2024 Spotlight. Backbone основного эксперимента. Рассматривает каждый признаковый канал как токен, захватывая межканальные зависимости.
Moody & Saffell (2001). Learning to Trade via Direct Reinforcement. IEEE TNN. Оригинальная формулировка прямой оптимизации PnL как цели обучения, до эпохи deep learning. DiffQuant расширяет этот подход на полностью дифференцируемый end-to-end пайплайн.
Khubiev et al. (2026). Finance-Grounded Optimization For Algorithmic Trading. arXiv:2509.04541. Ближайшая параллельная работа: вводит Sharpe, PnL и MaxDD как loss-функции для задачи предсказания доходностей. DiffQuant отличается тем, что градиент проходит через саму торговую механику, а не только через голову предсказания.
Заключение
DiffQuant это попытка устранить структурный разрыв и перейти от прогнозирования цен к прямой оптимизации торговых решений квантовой ML-модель.
Вместо схемы «сначала предсказываем, потом отдельно торгуем» → единый дифференцируемый граф: признаки → позиция → симулятор → торговая метрика → градиент.
Текущий эксперимент демонстрирует несколько конкретных вещей:
End-to-end дифференцируемый торговый пайплайн технически реализуем на стандартном PyTorch;
Гибридный loss успешно выводит модель из двух типичных патологий: гиперактивности и flat collapse;
Симметричное long/short поведение восстанавливается mirror augmentation даже при полностью бычьем train-режиме;
Два последовательных held-out квартала дали положительный результат после учёта комиссий и проскальзываний.
Это не основание говорить о готовой торговой системе. Это основание утверждать, что сам подход заслуживает серьёзного дальнейшего исследования.
Именно в этом ценность проекта: не как «готовая кнопка», а как открытая воспроизводимая исследовательская платформа для честного изучения того, что происходит, когда trading objective наконец ставится внутрь самого градиента.
P.S. - для тех, кто дочитал до конца
Если вы ожидали увидеть здесь систему, которую достаточно склонировать, запустить и сразу использовать как готовый торговый инструмент, то важно сразу уточнить: эта статья не об этом.
DiffQuant находится на самой ранней стадии исследований. Это не продукт. Это не сигнал. Это не торговый робот. Это экспериментальная исследовательская платформа с конкретной постановкой проблемы: что происходит, если убрать proxy-цель из трейдингового ML-пайплайна и поставить торговую механику прямо внутрь градиента.
Я публикую это сейчас не потому что считаю задачу решённой, а именно потому что она не решена. Два положительных held-out квартала это сигнал, заслуживающий внимания, но не основание для сильных заявлений. Модель обучена на одном инструменте, на конкретном историческом окне, с конкретным набором гиперпараметров. Она чувствительна к ним. Она не обобщалась на другие активы. Статистической базы для выводов о стабильности пока недостаточно.
Всё это написано в разделе “Ограничения” и для меня это принципиально важная часть статьи, а не формальная оговорка.
Зачем тогда публиковать?
Потому что такие проекты становятся лучше именно тогда, когда их видит профессиональное сообщество. Если вы запустили эксперимент и получили другой результат, это ценно. Если вы нашли слабое место в архитектуре или в протоколе оценки, это ещё ценнее. Если вы взяли кодовую базу, добавили свой backbone или переписали loss, и это сработало лучше, я обязательно хочу об этом знать.
Код открыт. Данные открыты. Протокол воспроизводим.
Это приглашение к исследованию, а не обещание прибыли.
GitHub: github.com/YuriyKolesnikov/diffquant
Dataset: huggingface.co/datasets/ResearchRL/diffquant-data
@software{Kolesnikov2026diffquant, author = {Kolesnikov, Yuriy}, title = {{DiffQuant}: End-to-End Differentiable Trading Pipeline}, year = {2026}, url = {https://github.com/YuriyKolesnikov/diffquant}, version = {0.1.0} }
