Разработка системы оптимизации гиперпараметров торговой AI-модели

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1 услугВсе 1566 услуг
Разработка системы оптимизации гиперпараметров торговой AI-модели
Средняя
~2-3 рабочих дня
Часто задаваемые вопросы
Направления AI-разработки
Этапы разработки AI-решения
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1240
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1167
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    867
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1084
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    563
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    829

Разработка системы оптимизации гиперпараметров торговой AI-модели

Торговая AI-модель гиперчувствительна к гиперпараметрам: пространство поиска огромно, а классический grid search неприемлем по времени. Специализированные методы оптимизации для финансовых задач учитывают временну́ю структуру данных и нестабильность рынков.

Специфика финансовых задач

Почему стандартный AutoML не работает для трейдинга:

  • Стандартная кросс-валидация нарушает временную причинность (data leakage)
  • Метрика accuracy бесполезна — нужен Sharpe Ratio, Calmar, Max Drawdown
  • Режим рынка меняется: параметры оптимальные для 2022 года могут убивать в 2024
  • Overfitting особенно опасен: в реальной торговле curve fitting = потеря капитала

Walk-Forward Validation — единственный честный метод:

import numpy as np
import pandas as pd
from typing import Callable

def walk_forward_optimization(
    price_data: pd.DataFrame,
    strategy_func: Callable,
    param_space: dict,
    in_sample_months: int = 12,
    out_sample_months: int = 3
) -> dict:
    """
    WFO: обучаем на IS периоде, тестируем на OOS — и так скользим вперёд.
    Метрика = агрегированный OOS Sharpe ratio по всем периодам.
    """
    results = []
    total_months = len(price_data) // 21  # ~21 торговый день в месяце

    for start_month in range(0, total_months - in_sample_months, out_sample_months):
        is_end = start_month + in_sample_months
        oos_end = is_end + out_sample_months

        if oos_end > total_months:
            break

        is_data = price_data.iloc[start_month * 21: is_end * 21]
        oos_data = price_data.iloc[is_end * 21: oos_end * 21]

        # Оптимизация на IS периоде
        best_params = optimize_on_period(strategy_func, is_data, param_space)

        # Тест на OOS
        oos_returns = strategy_func(oos_data, **best_params)
        oos_sharpe = calculate_sharpe(oos_returns, annualization=252)

        results.append({
            'period_start': is_end,
            'best_params': best_params,
            'oos_sharpe': oos_sharpe,
            'oos_returns': oos_returns
        })

    return {
        'wfo_results': results,
        'avg_oos_sharpe': np.mean([r['oos_sharpe'] for r in results]),
        'sharpe_stability': np.std([r['oos_sharpe'] for r in results]),
        'profitable_periods': sum(1 for r in results if r['oos_sharpe'] > 0) / len(results)
    }

Optuna для финансовых задач

Bayesian Optimization с кастомной метрикой:

import optuna

def optimize_trading_model(train_data: pd.DataFrame,
                             val_data: pd.DataFrame) -> dict:
    def objective(trial):
        params = {
            'n_estimators': trial.suggest_int('n_estimators', 100, 500),
            'max_depth': trial.suggest_int('max_depth', 3, 8),
            'learning_rate': trial.suggest_float('learning_rate', 1e-3, 0.1, log=True),
            'min_samples_leaf': trial.suggest_int('min_samples_leaf', 50, 500),
            'feature_fraction': trial.suggest_float('feature_fraction', 0.5, 1.0),

            # Специфичные для финансов параметры
            'lookback_window': trial.suggest_int('lookback_window', 5, 60),
            'prediction_horizon': trial.suggest_categorical('prediction_horizon', [1, 5, 10, 20]),
            'threshold_long': trial.suggest_float('threshold_long', 0.001, 0.01),
            'threshold_short': trial.suggest_float('threshold_short', -0.01, -0.001)
        }

        # Обучаем и тестируем
        model = train_model(train_data, params)
        signals = generate_signals(val_data, model, params)
        returns = backtest_signals(val_data, signals)

        # Составная метрика: Sharpe с штрафом за drawdown
        sharpe = calculate_sharpe(returns)
        max_dd = calculate_max_drawdown(returns)

        # Штраф за чрезмерную торговлю (транзакционные издержки)
        trade_count = signals.abs().sum()
        cost_penalty = trade_count * 0.0001  # 1 bp за сделку

        # Optuna максимизирует: sharpe - drawdown_penalty - cost_penalty
        return sharpe - abs(max_dd) * 0.5 - cost_penalty

    study = optuna.create_study(
        direction='maximize',
        sampler=optuna.samplers.TPESampler(seed=42),
        pruner=optuna.pruners.HyperbandPruner()
    )
    study.optimize(objective, n_trials=200, timeout=3600)

    return {
        'best_params': study.best_params,
        'best_value': study.best_value,
        'n_trials': len(study.trials)
    }

Адаптивная оптимизация к режиму рынка

Детекция режима и выбор параметров:

from hmmlearn import hmm

class RegimeAwareOptimizer:
    """
    Разные режимы рынка (тренд/флэт/волатильность) требуют разных гиперпараметров.
    HMM определяет режим → выбираем предварительно оптимизированный набор параметров.
    """
    def __init__(self, n_regimes=3):
        self.regime_model = hmm.GaussianHMM(n_components=n_regimes, covariance_type='full')
        self.regime_params = {}  # {режим: best_params}

    def fit_regimes(self, returns: np.ndarray):
        features = np.column_stack([
            returns,
            np.abs(returns),                         # волатильность
            pd.Series(returns).rolling(20).std().values  # rolling vol
        ])
        self.regime_model.fit(features[~np.isnan(features).any(axis=1)])

    def optimize_per_regime(self, price_data, strategy_func, param_space):
        """Для каждого режима — отдельная WFO оптимизация"""
        regimes = self.get_current_regime(price_data)

        for regime_id in range(self.regime_model.n_components):
            regime_data = price_data[regimes == regime_id]
            if len(regime_data) > 500:
                self.regime_params[regime_id] = optimize_trading_model(
                    regime_data[:len(regime_data)//2],
                    regime_data[len(regime_data)//2:]
                )['best_params']

    def get_current_regime(self, recent_data: pd.DataFrame) -> int:
        features = extract_regime_features(recent_data.tail(20))
        return self.regime_model.predict(features)[-1]

Сроки: Walk-forward validation + Optuna базовая оптимизация + backtest — 3-4 недели. Regime-aware optimization, адаптивная переоптимизация, multi-objective Pareto front — 6-8 недель.