Оптимизация параметров торговой стратегии

Проектируем и разрабатываем блокчейн-решения полного цикла: от архитектуры смарт-контрактов до запуска DeFi-протоколов, NFT-маркетплейсов и криптобирж. Аудит безопасности, токеномика, интеграция с существующей инфраструктурой.
Показано 1 из 1 услугВсе 1306 услуг
Оптимизация параметров торговой стратегии
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы
Направления блокчейн-разработки
Этапы блокчейн-разработки
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1221
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1163
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    855
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1062
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    828

Оптимизация параметров торговой стратегии

Написать стратегию — половина работы. Найти параметры, при которых она работает — другая половина. Оптимизация параметров это не магия: это поиск по пространству значений с корректной валидацией результатов. Главный враг здесь — overfitting.

Что такое overfitting и почему это критично

Стратегия с EMA(9, 21) даёт Sharpe 1.2 на истории. Оптимизатор перебирает все комбинации EMA(5–50) и находит EMA(13, 34) с Sharpe 2.8. Отличный результат? Нет — это overfitting. Параметры подогнаны под конкретный исторический период. На реальных данных стратегия покажет результат, близкий к случайному.

Правило: оптимизируй на train set, валидируй на hold-out (out-of-sample) test set. Если на test set результат сильно хуже — overfitting.

Walk-forward optimization

Самый надёжный метод для временных рядов:

def walk_forward_optimization(data: pd.DataFrame, 
                               strategy_class,
                               param_grid: dict,
                               train_periods: int = 180,  # дней
                               test_periods: int = 30) -> list:
    results = []
    start = 0
    
    while start + train_periods + test_periods <= len(data):
        train = data.iloc[start:start + train_periods]
        test = data.iloc[start + train_periods:start + train_periods + test_periods]
        
        # Оптимизация на train
        best_params = optimize_on_period(strategy_class, train, param_grid)
        
        # Валидация на test (OOS)
        oos_result = run_backtest(strategy_class, test, best_params)
        results.append({
            'period': test.index[0],
            'params': best_params,
            'oos_sharpe': oos_result.sharpe,
            'oos_return': oos_result.total_return,
        })
        
        start += test_periods  # сдвигаем окно
    
    return results

Walk-forward: оптимизируешь на 6 месяцах, тестируешь на следующем месяце, сдвигаешься на месяц вперёд, повторяешь. Финальный результат — медиана OOS Sharpe по всем окнам.

Методы поиска параметров

Grid Search

Полный перебор всех комбинаций. Прост, но экспоненциально дорог при большом числе параметров.

from itertools import product
import vectorbt as vbt

param_grid = {
    'rsi_period': range(7, 21),      # 14 значений
    'rsi_lower': range(20, 40, 5),   # 4 значения
    'rsi_upper': range(65, 80, 5),   # 3 значения
}
# Итого: 14 * 4 * 3 = 168 комбинаций — приемлемо

# Vectorbt — векторизованный backtesting, 168 комбинаций за секунды
RSI = vbt.IndicatorFactory.from_pandas_ta("rsi")
rsi = RSI.run(close, length=vbt.Param(param_grid['rsi_period']))

Bayesian Optimization

Умнее grid search: строит суррогатную модель функции качества и выбирает следующую точку для проверки на основе exploration/exploitation balansce. Требует меньше итераций для хорошего результата.

from optuna import create_study

def objective(trial):
    rsi_period = trial.suggest_int('rsi_period', 5, 30)
    rsi_lower = trial.suggest_int('rsi_lower', 20, 40)
    rsi_upper = trial.suggest_int('rsi_upper', 60, 85)
    
    result = backtest_strategy(data, rsi_period, rsi_lower, rsi_upper)
    return result.sharpe_ratio  # максимизируем

study = create_study(direction='maximize', sampler=optuna.samplers.TPESampler())
study.optimize(objective, n_trials=200, n_jobs=4)

print(f"Best params: {study.best_params}")
print(f"Best Sharpe: {study.best_value:.3f}")

Optuna — отличная библиотека для Bayesian optimization. Параллельный поиск, pruning (ранняя остановка плохих trials), визуализация importance параметров.

Метрики для оптимизации

Не оптимизируй под total return — это провоцирует высокий риск. Лучшие targets:

Метрика Формула Комментарий
Sharpe Ratio (Return - Rf) / Std Золотой стандарт
Calmar Ratio Annual Return / Max Drawdown Хорош для трендовых
Sortino Ratio Return / Downside Std Штрафует только убытки
Profit Factor Gross Profit / Gross Loss Простой, интуитивный

Комбинируй метрики: score = sharpe * 0.5 + calmar * 0.3 + win_rate * 0.2. Это снижает шанс выбрать стратегию, хорошую по одному параметру и плохую по другим.

Параметрическая робастность

Хорошая стратегия работает при небольших отклонениях параметров от оптимума. Проверка:

def check_robustness(best_params: dict, data: pd.DataFrame, delta_pct: float = 0.2):
    """Проверяем, работает ли стратегия при ±20% изменении параметров"""
    results = []
    for param, value in best_params.items():
        for multiplier in [0.8, 0.9, 1.0, 1.1, 1.2]:
            test_params = best_params.copy()
            test_params[param] = int(value * multiplier)
            result = backtest_strategy(data, **test_params)
            results.append({'param': param, 'multiplier': multiplier, 'sharpe': result.sharpe})
    
    return pd.DataFrame(results)

Если Sharpe резко падает при изменении RSI с 14 на 13 или 15 — это признак overfitting. Хорошая стратегия показывает плавную sensitivity кривую.

Процесс оптимизации

  1. Сбор данных: минимум 3–5 лет истории, разные рыночные режимы (бычий, медвежий, боковик)
  2. Разбивка: 70% train, 30% test (хронологически, не случайно)
  3. Optimization на train: grid/Bayesian, 100–500 итераций
  4. Валидация на test: если OOS Sharpe < 50% от IS Sharpe — вероятно overfitting
  5. Walk-forward check: дополнительная валидация устойчивости
  6. Sensitivity analysis: проверка робастности параметров

Оптимизация параметров занимает 2–4 недели: сбор и подготовка данных, реализация optimization framework, walk-forward тестирование и документирование результатов.