Разработка системы grid search для оптимизации параметров стратегии

Вы разработали стратегию на основе скользящих средних. Периоды 5/15 дают одну доходность, 7/21 — другую. Какие выбрать? Перебор вручную — 50 вариантов, каждый бэктест по минуте — больше часа. А если параметров пять? 10^5 комбинаций — год работы. Мы решаем это grid search за 10 минут. Наше решение га

Направления блокчейн-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1453
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1312
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    1010
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1272
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    722
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1015

Вы разработали стратегию на основе скользящих средних. Периоды 5/15 дают одну доходность, 7/21 — другую. Какие выбрать? Перебор вручную — 50 вариантов, каждый бэктест по минуте — больше часа. А если параметров пять? 10^5 комбинаций — год работы. Мы решаем это grid search за 10 минут. Наше решение гарантированно находит глобальный оптимум в заданном пространстве параметров, экономя до 80% времени по сравнению с ручным подбором. Экономия на ручном подборе параметров может достигать $1.8k–2.6k в год.

Как grid search решает проблему выбора параметров?

Система перебирает все комбинации параметров из указанных вами диапазонов. Для каждой запускается бэктест, и результаты ранжируются по выбранной метрике — например, Sharpe ratio или годовая доходность. Вы получаете не только лучшие параметры, но и полную таблицу всех комбинаций для дальнейшего анализа. Это позволяет понять, насколько стабильны результаты, и избежать overfitting.

Базовая реализация и пример использования

import itertools from multiprocessing import Pool import pandas as pd from typing import Callable, Any def grid_search( backtest_fn: Callable[[dict], dict], param_grid: dict[str, list], n_jobs: int = -1, metric: str = 'sharpe_ratio', ) -> pd.DataFrame: param_names = list(param_grid.keys()) param_values = list(param_grid.values()) all_combinations = list(itertools.product(*param_values)) print(f"Total combinations: {len(all_combinations)}") print(f"Estimated time: ~{len(all_combinations) * 0.5:.0f} seconds") def run_single(params_tuple) -> dict: params = dict(zip(param_names, params_tuple)) try: metrics = backtest_fn(params) return {**params, **metrics} except Exception as e: return {**params, 'error': str(e), metric: float('-inf')} if n_jobs == 1: results = [run_single(combo) for combo in all_combinations] else: with Pool(processes=n_jobs if n_jobs > 0 else None) as pool: results = pool.map(run_single, all_combinations) df = pd.DataFrame(results) df = df[df.get('error').isna()] if 'error' in df.columns else df return df.sort_values(metric, ascending=False) 
import pandas as pd from functools import partial ohlcv = load_historical_data('BTC/USDT', '2023-01-01', '2024-01-01') def backtest_ema_crossover(params: dict) -> dict: backtester = Backtester(commission=0.001, slippage=0.0005) result = backtester.run( strategy_class=EMACrossoverStrategy, params=params, data=ohlcv, initial_cash=100_000, ) return { 'sharpe_ratio': result.metrics.sharpe_ratio, 'annual_return': result.metrics.annual_return_pct, 'max_drawdown': result.metrics.max_drawdown_pct, 'win_rate': result.metrics.win_rate, 'total_trades': result.metrics.total_trades, } param_grid = { 'fast_period': [5, 7, 9, 12], 'slow_period': [15, 21, 30, 50], 'rsi_threshold': [25, 30, 35, 40], 'stop_loss_pct': [0.02, 0.03, 0.05], } results = grid_search(backtest_ema_crossover, param_grid, n_jobs=8, metric='sharpe_ratio') print(results.head(10)[['fast_period', 'slow_period', 'rsi_threshold', 'stop_loss_pct', 'sharpe_ratio', 'annual_return']]) 

Анализ результатов и визуализация

Результаты grid search можно анализировать с помощью тепловых карт. Ниже — пример функции для визуализации зависимости метрики от двух параметров.

import matplotlib.pyplot as plt import seaborn as sns def plot_parameter_heatmap(results: pd.DataFrame, param1: str, param2: str, metric: str): pivot = results.pivot_table( values=metric, index=param1, columns=param2, aggfunc='max', ) plt.figure(figsize=(10, 8)) sns.heatmap(pivot, annot=True, fmt='.2f', cmap='RdYlGn', center=0) plt.title(f'{metric} by {param1} and {param2}') plt.tight_layout() plt.savefig(f'heatmap_{param1}_{param2}.png', dpi=150) 

Подробнее о визуализации: тепловые карты помогают быстро выявить зоны оптимальных значений. Например, если высокий Sharpe ratio наблюдается только в узкой области параметров, это сигнал возможного overfitting. Рекомендуется смотреть на топ-5 комбинаций и проверять их стабильность на отложенной выборке.

Что входит в работу по разработке системы grid search?

Этап Результат
Анализ стратегии Определение параметров, диапазонов и целевой метрики. Выявление гиперпараметров, требующих настройки.
Архитектура решения Проектирование системы с учётом вашего бэктестера и стека (Python, NumPy, Foundry и т.д.).
Разработка Написание кода с параллельными вычислениями, логированием, визуализацией. Интеграция стандартных защит от overfitting.
Тестирование Проверка на исторических данных, сравнение с baseline, стресс-тесты.
Документация и обучение Передача исходного кода, инструкции по настройке, 2-часовая сессия для команды. Поддержка в течение 2 недель.

Защита от overfitting при grid search

Overfitting — главная опасность при оптимизации параметров. Мы применяем несколько техник:

  • Разделение данных: 70% train для оптимизации, 15% validation для проверки топ-5 комбинаций, 15% test для финального подтверждения.
  • Минимальное число сделок: отсеиваем комбинации с менее чем 30 сделками — статистическая незначимость.
  • Stability check: проверяем, что небольшое изменение параметров (например, fast_period с 9 на 10) не приводит к резкому ухудшению метрик.
def split_data_temporal(data: pd.DataFrame, train_pct=0.7, val_pct=0.15): n = len(data) train_end = int(n * train_pct) val_end = int(n * (train_pct + val_pct)) return data[:train_end], data[train_end:val_end], data[val_end:] train, validation, test = split_data_temporal(ohlcv) results = grid_search(lambda p: backtest_fn(p, train), param_grid) # Топ-5 параметров тестируем на validation top_params = results.head(5) for _, row in top_params.iterrows(): val_result = backtest_fn(row.to_dict(), validation) print(f"Params: {row.to_dict()}, Val Sharpe: {val_result['sharpe_ratio']:.2f}") # Финальный тест на test set — один раз, выбранными параметрами 

Почему grid search, а не другие методы?

Метод Гарантия глобального оптимума Скорость при 3–4 параметрах Скорость при 5+ параметрах Простота реализации
Grid search Да (в заданной сетке) Высокая Низкая Высокая
Bayesian optimization Нет Средняя Высокая Средняя
Genetic algorithm Нет Средняя Высокая Низкая

Grid search проще и надёжнее Bayesian optimization при числе параметров до 4. Для стратегий с 2–4 параметрами это оптимальный выбор. При 5+ параметрах лучше перейти на байесовскую оптимизацию. Как утверждает Wikipedia, grid search — исчерпывающий метод, гарантирующий нахождение лучшей комбинации в заданной сетке.

Также мы включаем кросс-валидацию (cross validation) для оценки стабильности: разбиваем историю на несколько периодов и проверяем, что оптимальные параметры работают в разных рыночных условиях. Это снижает риск неожиданного падения результатов после запуска в live.

Процесс работы, сроки и стоимость

  1. Аналитика — изучаем вашу стратегию, определяем параметры, диапазоны и метрику оптимизации. Выявляем гиперпараметры, которые требуют настройки.
  2. Проектирование — разрабатываем архитектуру grid search, оптимизируем под ваш бэктестер и стек (Python, Foundry и т.д.).
  3. Реализация — пишем код с параллельными вычислениями, логированием, визуализацией.
  4. Тестирование — проверяем на исторических данных, сравниваем с baseline, применяем защиту от overfitting.
  5. Деплой — передаём систему, документацию, проводим обучение команды (1–2 часа).

Сроки: от 3 до 10 дней в зависимости от сложности стратегии и числа параметров. Стоимость рассчитывается индивидуально — точная сумма определяется после анализа вашей задачи. Закажите разработку системы grid search под ключ — мы реализуем её с учётом специфики вашей стратегии. Получите консультацию: свяжитесь с нами для оценки вашей задачи.