CatBoost для Классификации Ложных Пробоев в Торговом Боте на Python

CatBoost для Классификации Ложных Пробоев в Торговом Боте на Python Python & API
Подробное руководство по интеграции ML-модели CatBoost в торгового бота на Python для эффективной классификации ложных пробоев уровней поддержки и повышения точности торговых решений.
Суть: Интеграция ML-модели CatBoost для классификации ложных пробоев уровней поддержки в торговом боте на Python включает подготовку исторических данных с признаками пробоя, обучение модели CatBoost на этих данных и использование обученной модели для предсказания вероятности ложного пробоя в реальном времени перед открытием сделки. Это позволяет фильтровать неэффективные сигналы и повышать прибыльность стратегии.

Исходный код

Ложные пробои уровней поддержки (или сопротивления) являются одной из самых коварных ловушек для трейдеров. Они выглядят как сильный сигнал к открытию позиции, но быстро разворачиваются, приводя к убыткам. Эффективное распознавание таких паттернов может значительно улучшить результаты торговой стратегии. В этом руководстве мы покажем, как интегрировать мощную градиентную бустинговую библиотеку CatBoost в ваш торговый бот на Python для классификации ложных пробоев.

CatBoost, разработанный Яндексом, отличается высокой производительностью, отличной обработкой категориальных признаков и устойчивостью к переобучению, что делает его идеальным выбором для финансовых временных рядов. Мы создадим упрощенный пример, который включает генерацию данных, обучение модели и ее применение в симулированном торговом цикле.

Для реальной работы вам потребуется подключение к биржевым API (например, через CCXT для OKX) для получения исторических и текущих данных, а также, возможно, дополнительные данные, такие как исторические ликвидации с Coinglass API для обогащения признаков.


import pandas as pd
import numpy as np
from catboost import CatBoostClassifier, Pool
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import random

# 1. Генерация фиктивных данных для демонстрации
def generate_dummy_data(num_samples=1000):
    data = {
        'price': np.cumsum(np.random.randn(num_samples) * 0.1 + 0.05) + 100, # Симулируем цену
        'volume': np.random.rand(num_samples) * 1000 + 100,
        'rsi': np.random.rand(num_samples) * 70 + 15,
        'macd_hist': np.random.randn(num_samples) * 2,
        'volatility': np.random.rand(num_samples) * 2 + 0.5
    }
    df = pd.DataFrame(data)

    # Симулируем ложные пробои (1) и истинные пробои/отскоки (0)
    # Это очень упрощенная логика, в реальной жизни требуется сложный анализ
    df['is_false_breakout'] = 0
    for i in range(50, num_samples - 50):
        # Упрощенное определение поддержки: локальный минимум
        if df['price'].iloc[i] < df['price'].iloc[i-5:i].min() and \
           df['price'].iloc[i] < df['price'].iloc[i+1:i+6].min():
            # Если цена быстро восстанавливается после пробоя
            if df['price'].iloc[i+10] > df['price'].iloc[i] * 1.005:
                df.loc[i, 'is_false_breakout'] = 1 # Ложный пробой
            elif df['price'].iloc[i+10] < df['price'].iloc[i] * 0.995:
                df.loc[i, 'is_false_breakout'] = 0 # Истинный пробой (или продолжение падения)
    return df

# 2. Извлечение признаков для классификации пробоя
def extract_features(df, index):
    if index < 20:
        return None # Недостаточно данных для признаков

    features = {
        'price_change_1h': (df['price'].iloc[index] - df['price'].iloc[index-5]) / df['price'].iloc[index-5], # 5 баров = 1 час
        'price_change_4h': (df['price'].iloc[index] - df['price'].iloc[index-20]) / df['price'].iloc[index-20], # 20 баров = 4 часа
        'volume_avg_5h': df['volume'].iloc[index-20:index].mean(),
        'rsi_current': df['rsi'].iloc[index],
        'rsi_prev_5h_avg': df['rsi'].iloc[index-20:index].mean(),
        'macd_hist_current': df['macd_hist'].iloc[index],
        'volatility_5h': df['volatility'].iloc[index-20:index].std(),
        'is_support_level': 1 if df['price'].iloc[index] < df['price'].iloc[index-10:index].min() else 0 # Упрощенный детектор поддержки
    }
    return pd.Series(features)

# 3. Обучение модели CatBoost
def train_catboost_model(X, y):
    X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)

    model = CatBoostClassifier(
        iterations=100, # Количество деревьев
        learning_rate=0.1, # Скорость обучения
        depth=6, # Глубина деревьев
        loss_function='Logloss', # Функция потерь для бинарной классификации
        eval_metric='Accuracy', # Метрика для оценки
        random_seed=42,
        verbose=False, # Отключение подробного вывода
        early_stopping_rounds=10 # Ранняя остановка для предотвращения переобучения
    )

    model.fit(X_train, y_train, eval_set=(X_test, y_test))

    y_pred = model.predict(X_test)
    accuracy = accuracy_score(y_test, y_pred)
    print(f"Точность модели на тестовой выборке: {accuracy:.4f}")

    return model

# 4. Функция для предсказания ложного пробоя в реальном времени
def predict_false_breakout(model, current_features):
    # CatBoost ожидает 2D массив, даже для одной выборки
    features_df = pd.DataFrame([current_features])
    prediction_proba = model.predict_proba(features_df)[0][1] # Вероятность класса 1 (ложный пробой)
    return prediction_proba

# 5. Симуляция торгового бота
def main_trading_bot_loop(model, historical_data, threshold=0.7):
    print("\n--- Запуск симуляции торгового бота ---")
    trade_signals = []
    for i in range(len(historical_data)):
        current_price = historical_data['price'].iloc[i]
        
        # В реальном боте здесь были бы получение новых данных с биржи
        # Например, через CCXT: exchange.fetch_ohlcv('BTC/USDT', '1h', limit=20)

        features = extract_features(historical_data, i)
        if features is None:
            continue

        # Если текущий бар является потенциальным пробоем поддержки
        if features['is_support_level'] == 1:
            proba_false_breakout = predict_false_breakout(model, features)
            print(f"Время: {i}, Цена: {current_price:.2f}, Вероятность ложного пробоя: {proba_false_breakout:.2f}")

            if proba_false_breakout > threshold: # Если высокая вероятность ложного пробоя
                signal = {'time': i, 'price': current_price, 'type': 'BUY_ON_FALSE_BREAKOUT', 'proba': proba_false_breakout}
                trade_signals.append(signal)
                print(f"  -> СИГНАЛ: Покупка на ожидаемом ложном пробое! Вероятность: {proba_false_breakout:.2f}")
            else:
                print(f"  -> Пробой поддержки, но не классифицирован как ложный. Вероятность: {proba_false_breakout:.2f}")

    print("\n--- Результаты симуляции ---")
    for signal in trade_signals:
        print(f"Сигнал: {signal['type']} по цене {signal['price']:.2f} в момент {signal['time']} (proba: {signal['proba']:.2f})")


if __name__ == "__main__":
    # 1. Генерация или загрузка данных
    print("Генерация фиктивных данных...")
    df_historical = generate_dummy_data(num_samples=2000)

    # 2. Извлечение признаков и меток
    print("Извлечение признаков...")
    features_list = []
    labels_list = []
    for i in range(len(df_historical)):
        features = extract_features(df_historical, i)
        if features is not None:
            features_list.append(features)
            labels_list.append(df_historical['is_false_breakout'].iloc[i])

    X = pd.DataFrame(features_list)
    y = pd.Series(labels_list)

    # Удаляем строки с NaN, которые могли появиться из-за std() на малом окне
    X.dropna(inplace=True)
    y = y[X.index] # Синхронизируем метки

    # Убедимся, что есть оба класса для обучения
    if len(y.unique()) < 2:
        print("Недостаточно классов для обучения. Сгенерируйте больше данных или проверьте логику.")
    else:
        # 3. Обучение модели
        print("Обучение модели CatBoost...")
        catboost_model = train_catboost_model(X, y)

        # 4. Запуск симуляции торгового бота
        main_trading_bot_loop(catboost_model, df_historical, threshold=0.6)

Разбор параметров

В представленном коде используются различные параметры для настройки модели CatBoost и логики торгового бота. Понимание этих параметров критически важно для адаптации решения к вашим потребностям.

  • num_samplesgenerate_dummy_data): Количество генерируемых точек данных. В реальном сценарии это будет объем исторических данных, которые вы загружаете.
  • iterationsCatBoostClassifier): Максимальное количество деревьев решений, которые будут построены. Большее количество итераций может улучшить точность, но увеличивает время обучения и риск переобучения.
  • learning_rateCatBoostClassifier): Скорость, с которой каждый новый ансамбль деревьев корректирует ошибки предыдущих. Меньшее значение требует больше итераций, но может привести к лучшей обобщающей способности.
  • depthCatBoostClassifier): Максимальная глубина каждого дерева решений. Более глубокие деревья могут улавливать более сложные зависимости, но также увеличивают риск переобучения.
  • loss_functionCatBoostClassifier): Функция потерь, используемая для оптимизации модели. Для бинарной классификации обычно используется 'Logloss'.
  • eval_metricCatBoostClassifier): Метрика, используемая для оценки качества модели на валидационном наборе во время обучения. 'Accuracy' (точность) подходит для сбалансированных классов.
  • random_seedCatBoostClassifier): Зерно для генератора случайных чисел, обеспечивающее воспроизводимость результатов обучения.
  • verboseCatBoostClassifier): Если True, CatBoost будет выводить информацию о процессе обучения. Установлено в False для краткости.
  • early_stopping_roundsCatBoostClassifier): Количество итераций без улучшения на валидационном наборе, после которых обучение будет остановлено. Помогает предотвратить переобучение.
  • thresholdmain_trading_bot_loop): Порог вероятности, выше которого модель классифицирует событие как ложный пробой. Настройка этого параметра критична для баланса между точностью и количеством торговых сигналов.
  • price_change_1h, price_change_4h и другие (в extract_features): Признаки, извлекаемые из ценовых данных и индикаторов. Их выбор и расчет должны быть тщательно продуманы на основе вашей торговой стратегии и анализа рынка.

Как запустить

Чтобы запустить и адаптировать этот код для вашей торговой стратегии, выполните следующие шаги:

  1. Установка зависимостей: Убедитесь, что у вас установлены все необходимые библиотеки. Вы можете установить их с помощью pip:

    
    pip install pandas numpy scikit-learn catboost
    
  2. Подготовка исторических данных: Замените функцию generate_dummy_data на реальную загрузку исторических данных с биржи. Вам понадобятся OHLCV (Open, High, Low, Close, Volume) данные, а также, возможно, данные по индикаторам (RSI, MACD), объему, волатильности и даже данные по ликвидациям (например, используя Coinglass API) или данные из стакана заявок. Важно, чтобы ваши данные были размечены: для каждого потенциального пробоя вы должны знать, был ли он ложным или истинным. Это самая трудоемкая часть.

  3. Разработка признаков (Feature Engineering): Функция extract_features содержит примеры признаков. Вам необходимо разработать более сложные и релевантные признаки, которые действительно помогут модели отличить ложный пробой от истинного. Это могут быть: скорость изменения цены, объем на пробое, отклонение от скользящих средних, паттерны свечей, данные из книги ордеров, а также агрегированные данные по ликвидациям.

  4. Обучение и валидация модели: Обучите модель CatBoost на ваших подготовленных данных. Используйте кросс-валидацию и тщательно оцените производительность модели на отложенных данных. Экспериментируйте с гиперпараметрами CatBoost (как описано в разделе «Разбор параметров») для достижения оптимальной точности и устойчивости.

  5. Интеграция в торговый бот: Замените симуляцию в main_trading_bot_loop на реальное подключение к биржевому API. Используйте библиотеки вроде CCXT для получения потоковых данных и отправки ордеров. При получении нового бара или тика, извлекайте признаки, подавайте их в обученную модель и используйте предсказание для принятия торгового решения.

  6. Бэктестинг и бумажная торговля: Перед развертыванием бота на реальных деньгах, проведите тщательный бэктестинг на исторических данных, а затем запустите его в режиме бумажной торговли (paper trading) на реальном рынке. Это позволит выявить потенциальные проблемы и настроить параметры без финансового риска.

  7. Управление рисками и этика: Всегда внедряйте строгие механизмы управления рисками. Устанавливайте стоп-лоссы, тейк-профиты и контролируйте размер позиции. Также важно помнить о этических аспектах и избегать практик, таких как wash trading, которые могут быть вредны для рынка и привести к блокировке аккаунта.

Интеграция ML-моделей, таких как CatBoost, в торговые боты открывает новые возможности для создания более интеллектуальных и адаптивных стратегий. Однако это требует глубокого понимания как машинного обучения, так и динамики рынка.

Оцените статью
FinFluct