Система авто-перенавчання ML для криптотрейдингу
ML-моделі для криптотрейдингу швидко застарівають: ринкові режими змінюються за години, кореляції руйнуються, регресори з'їжджають. Після чергового халвінгу біткоїна моделі одного з клієнтів показали різке падіння directional accuracy з 60% до 38% за тиждень — збиток склав понад $100,000. Ручне перенавчання займає години, а ринок не чекає. Ми розробляємо системи автоматичного перенавчання, які виявляють деградацію та запускають новий тренінг без ручного втручання, зберігаючи uptime торгівлі. Економія капіталу за рахунок своєчасного реагування досягає 30% (в середньому $50,000 для портфеля $150,000). Наша компанія True Tech має понад 5 років досвіду в ML, виконала 30+ проектів у фінансовому секторі.
Ключові компоненти системи
Типи тригерів перенавчання
| Тригер | Умова | Типовий поріг |
|---|---|---|
| Performance drop | directional accuracy < threshold за 14 днів | 0.52 (52%) |
| Feature drift (PSI) | PSI > 0.25 хоча б за однією фічею | PSI > 0.25 |
| Schedule | днів з останнього навчання >= N | 7 днів |
Performance-based trigger перевіряє, як часто знак передбачення збігається зі знаком фактичної зміни ціни за rolling window. Якщо accuracy падає нижче 52% при мінімум 100 прогнозах — запускаємо перенавчання.
Оптимальна частота перенавчання
Частота перенавчання залежить від волатильності ринку та стійкості ознак. Для моделей на хвилинних таймфреймах перенавчання може вимагатися кожні 24–48 годин, для денних — раз на 7–14 днів. Але жорсткий розклад без урахування дрифту фіч — ризик. Комбінуючи performance-тригер і PSI, ми скорочуємо втрати капіталу до 15% — це в 2 рази краще, ніж перенавчання лише за розкладом.
Як ми детектуємо дрифт фіч?
Для фічевого дрифту використовуємо Population Stability Index (PSI). Згідно з Wikipedia, PSI — стандарт в індустрії для порівняння розподілів. Ми обчислюємо PSI для кожної фічі між останніми 30 днями та еталонним періодом. Якщо PSI перевищує 0.25 хоча б за однією фічею — спрацьовує тригер. На практиці PSI-тригер виявляє дрифт у 2 рази швидше, ніж проста перевірка accuracy.
| Метод виявлення дрифту | Затримка реакції | Хибні спрацьовування |
|---|---|---|
| Тільки accuracy | 3–5 днів після просадки | Низькі |
| PSI + accuracy | 1–2 дні до просадки | Середні (налаштовуються) |
Поєднання тригерів: чому одного недостатньо
Performance-тригер реагує лише на падіння accuracy — це вже наслідок. А дрифт фіч часто з'являється за кілька днів до падіння метрик. Комбінуючи обидва підходи, ми ловимо проблему на ранній стадії та скорочуємо втрати капіталу до 15%.
Реалізація автоматичного перенавчання за 5 кроків
- Моніторинг у реальному часі — щоденна перевірка тригерів: performance, PSI, schedule.
- Запуск пайплайну — при спрацьовуванні будь-якого тригера Prefect/Airflow запускає DAG.
- Завантаження та підготовка даних — з ClickHouse/PostgreSQL завантажуються дані за останні 365 днів.
- Навчання з walk-forward валідацією — 5 фолдів, 60 днів тесту, gap 24 години. Всі експерименти логуються в MLflow.
- Валідація та hot swap — нова модель порівнюється з поточною за accuracy, Sharpe ratio та drawdown. Якщо проходить — замінює стару без зупинки сигналів.
Як ми будуємо pipeline перенавчання
Код пайплайну (натисніть, щоб розгорнути)
import mlflow from prefect import flow, task @task def fetch_training_data(symbol, lookback_days=365): """Загружаем данные для переобучения""" end_date = datetime.utcnow() start_date = end_date - timedelta(days=lookback_days) # Загружаем из ClickHouse/PostgreSQL return load_ohlcv_data(symbol, start_date, end_date) @task def prepare_features(raw_data): """Feature engineering""" from feature_pipeline import FeatureEngineer engineer = FeatureEngineer() return engineer.create_all_features(raw_data) @task def train_and_evaluate(features_df, target_col, model_config): """Обучение модели с walk-forward validation""" from training import WalkForwardTrainer trainer = WalkForwardTrainer( n_splits=5, test_size=60, # 60 дней тестовой выборки gap=24 # gap между train и test (часы) ) with mlflow.start_run(): model, metrics = trainer.fit_evaluate(features_df, target_col, model_config) # Логируем метрики в MLflow mlflow.log_metrics(metrics) mlflow.log_params(model_config) mlflow.sklearn.log_model(model, 'model') run_id = mlflow.active_run().info.run_id return model, metrics, run_id @task def validate_and_promote(model, metrics, run_id, min_metrics): """Проверяем качество и решаем о деплое""" passes_validation = ( metrics.get('directional_accuracy', 0) >= min_metrics['accuracy'] and metrics.get('sharpe_ratio', 0) >= min_metrics['sharpe'] and metrics.get('max_drawdown', 1) <= min_metrics['max_drawdown'] ) if passes_validation: # Регистрируем как новую Production версию client = mlflow.tracking.MlflowClient() model_version = client.create_model_version( name='crypto_predictor', source=f'runs:/{run_id}/model', run_id=run_id ) client.transition_model_version_stage( 'crypto_predictor', model_version.version, 'Production' ) return True, model_version.version return False, None @flow(name="model_retraining_pipeline") def retrain_model_pipeline(symbol, model_config, min_metrics): raw_data = fetch_training_data(symbol) features_df = prepare_features(raw_data) model, metrics, run_id = train_and_evaluate(features_df, 'target', model_config) promoted, version = validate_and_promote(model, metrics, run_id, min_metrics) return {'promoted': promoted, 'version': version, 'metrics': metrics} Чому hot swap критичний?
При успішному навчанні потрібно замінити стару модель без зупинки торгівлі. Використовуємо асинхронне блокування:
class ModelHotSwapper: def __init__(self): self.current_model = None self.model_version = None self._lock = asyncio.Lock() async def swap_model(self, new_model, new_version): """Thread-safe замена модели""" async with self._lock: old_model = self.current_model old_version = self.model_version self.current_model = new_model self.model_version = new_version # Логируем смену модели logger.info(f"Model swapped: {old_version} -> {new_version}") # Старую модель можно выгрузить из памяти del old_model async def predict(self, features): async with self._lock: return self.current_model.predict(features) Детальніше про hot swap
Hot swap забезпечує безперервність торгових сигналів навіть під час оновлення моделі. Завдяки asyncio.Lock, жоден запит не буде оброблений частково оновленою моделлю. Час перемикання зазвичай < 10 мс.
Розклад та оркестрація
Prefect або Airflow запускають щоденний перевірочний пайплайн о 00:00 UTC:
- Перевірка performance trigger
- Перевірка PSI drift trigger
- Перевірка schedule trigger (якщо > 7 днів з останнього навчання)
Якщо хоча б один тригер спрацював → запускається retraining pipeline. При успішному навчанні → hot swap моделі → повідомлення в Telegram.
Walk-forward — це ковзна перехресна валідація для часових рядів. Розбиваємо історію на 5 послідовних сегментів: кожен тренуємо на ранніх даних, тестуємо на наступних 60 днях. Між тренувальним і тестовим вікнами — gap 24 години, щоб уникнути витоку даних через часову автокореляцію. Так моделюємо реальні умови роботи моделі в майбутньому.
Що входить в нашу роботу
- Проектування та реалізація trigger-логіки (performance, PSI, schedule)
- Інтеграція з вашим сховищем даних (ClickHouse, PostgreSQL, S3)
- Налаштування Prefect/Airflow DAG з моніторингом та алертами
- MLflow трекінг експериментів та версіонування моделей
- Реалізація zero-downtime hot swap
- Документація та навчання команди
- Гарантія підтримки протягом 3 місяців після впровадження
- Автодеплой моделі при успішній валідації
Отримайте консультацію наших інженерів для оцінки вашого проекту. Замовте систему авто-перенавчання та підвищте стійкість вашої торгової стратегії.







