Исходный код
Представленный ниже скрипт демонстрирует полный цикл выявления аномалий в торговых объемах. Он включает генерацию синтетических данных, применение модели IsolationForest и визуализацию результатов, где аномальные точки четко выделены. Для реального использования вы можете заменить блок генерации данных на загрузку ваших исторических торговых объемов.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import IsolationForest
from datetime import datetime, timedelta
# 1. Генерация синтетических данных торговых объемов
# В реальном сценарии здесь будет загрузка данных из файла или API
np.random.seed(42)
start_date = datetime(2023, 1, 1)
dates = [start_date + timedelta(days=i) for i in range(365)]
# Базовый объем с нормальным распределением
base_volume = np.random.normal(loc=100000, scale=20000, size=365)
# Добавляем небольшой сезонный компонент и шум
volume = np.maximum(5000, base_volume + np.sin(np.arange(365) / 30 * 2 * np.pi) * 10000)
# Добавляем искусственные аномалии: резкие всплески объемов
anomaly_indices = [50, 120, 200, 300, 350]
volume[anomaly_indices[0]] *= 5.5 # Очень большой всплеск
volume[anomaly_indices[1]] *= 3.0
volume[anomaly_indices[2]] *= 4.2
volume[anomaly_indices[3]] *= 6.0
volume[anomaly_indices[4]] *= 2.5 # Менее выраженная аномалия
df = pd.DataFrame({'Date': dates, 'Volume': volume})
df.set_index('Date', inplace=True)
# 2. Подготовка данных для Isolation Forest
# Isolation Forest ожидает 2D массив, поэтому преобразуем Series в DataFrame
X = df[['Volume']]
# 3. Инициализация и обучение Isolation Forest
# contamination - ожидаемая доля аномалий в данных (0.01 = 1%)
# random_state для воспроизводимости результатов
model = IsolationForest(n_estimators=100, contamination=0.02, random_state=42, max_features=1.0, max_samples='auto')
model.fit(X)
# 4. Прогнозирование аномалий
# Метод predict() возвращает -1 для аномалий и 1 для нормальных точек
df['anomaly'] = model.predict(X)
# 5. Визуализация результатов
plt.figure(figsize=(18, 9))
plt.plot(df.index, df['Volume'], label='Торговый Объем', color='blue', alpha=0.7, linewidth=1.5)
# Выделяем аномалии красными точками
anomalies = df[df['anomaly'] == -1]
plt.scatter(anomalies.index, anomalies['Volume'], color='red', label='Выявленная Аномалия', s=70, zorder=5, edgecolor='black', linewidth=0.8)
plt.title('Выявление Аномалий в Торговых Объемах с помощью Isolation Forest', fontsize=16)
plt.xlabel('Дата', fontsize=12)
plt.ylabel('Объем', fontsize=12)
plt.legend(fontsize=10)
plt.grid(True, linestyle='--', alpha=0.6)
plt.tight_layout()
plt.show()
# Вывод аномальных дат и объемов
print("\nВыявленные аномалии (Дата и Объем):")
print(anomalies[['Volume']])
Разбор параметров
Алгоритм IsolationForest является мощным инструментом для выявления аномалий. Его эффективность во многом зависит от правильной настройки параметров:
n_estimators: Количество деревьев в ансамбле. Чем больше деревьев, тем более стабильными и точными будут результаты, но увеличивается время обучения. Типичное значение — 100.contamination: Ожидаемая доля аномалий в наборе данных. Это критически важный параметр, который определяет порог для классификации точек как аномалий. Если вы знаете примерный процент аномалий в ваших данных (например, 1% или 2%), установите это значение. Если нет, можно начать с небольших значений (например, 0.01) и экспериментировать.max_features: Количество признаков, используемых для обучения каждого базового оценщика (дерева). По умолчанию 1.0, что означает использование всех признаков. В нашем случае, когда у нас только один признак (‘Volume’), этот параметр не оказывает существенного влияния.max_samples: Количество выборок, извлекаемых для обучения каждого базового оценщика. Если установлено ‘auto’ (по умолчанию), тоmax_samples = min(256, n_samples). Это позволяет алгоритму работать эффективно даже с очень большими наборами данных, так как аномалии обычно легче изолировать на небольших подвыборках.random_state: Целочисленное значение для инициализации генератора случайных чисел. Использование фиксированногоrandom_stateгарантирует воспроизводимость результатов при каждом запуске скрипта.
Как запустить
Для запуска скрипта и выявления аномалий в торговых объемах выполните следующие шаги:
-
Установите необходимые библиотеки: Если у вас еще не установлены
pandas,numpy,matplotlibиscikit-learn, установите их с помощьюpip:pip install pandas numpy matplotlib scikit-learn -
Сохраните код: Скопируйте представленный выше Python-код и сохраните его в файл с расширением
.py, например,anomaly_detection.py. -
Подготовьте данные (для реального использования): Если вы хотите анализировать свои собственные данные, замените блок генерации синтетических данных (начиная с
# 1. Генерация синтетических данных торговых объемов) на код для загрузки ваших данных. Убедитесь, что ваш DataFrame имеет столбец с именем'Volume'и индекс типаdatetime. Например:# Пример загрузки данных из CSV df = pd.read_csv('your_trading_data.csv', parse_dates=['Date'], index_col='Date') # Убедитесь, что столбец с объемами называется 'Volume' # Если у вас другой столбец, например 'TradeVolume', переименуйте его: # df.rename(columns={'TradeVolume': 'Volume'}, inplace=True)Для более глубокого понимания методов анализа данных в финансовой сфере, рекомендуем ознакомиться с нашей статьей о бэктесте опционных стратегий Iron Condor на Python.
-
Запустите скрипт: Откройте терминал или командную строку, перейдите в директорию, где вы сохранили файл, и выполните команду:
python anomaly_detection.py -
Проанализируйте результаты: Скрипт отобразит график торговых объемов, на котором красными точками будут выделены выявленные аномалии. В консоль также будет выведен список дат и объемов для этих аномальных точек. Подобные методы уменьшения размерности, как в нашей статье PCA для портфеля альткоинов, могут быть полезны при работе с многомерными финансовыми данными, если вы решите добавить больше признаков для анализа аномалий. Анализ неструктурированных данных, например, как в парсинге Twitter API и сентимент-анализе, также может дополнить выявление аномалий, предоставляя контекст для необычных движений рынка.




