Розробка системи 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% часу порівняно з ручним підбором. Економія на ручному підборі параметрів може сягати 200 000 грн на рік.

Як 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 під ключ — ми реалізуємо її з урахуванням специфіки вашої стратегії. Отримайте консультацію: зв'яжіться з нами для оцінки вашого завдання.