Кластеризация рынка с помощью многомерного машинного обучения
TL; DR:
Возможность характеризовать дневную торговлю на рынке с помощью TML позволяет адаптировать стратегии к определенным рыночным «личностям». Эти «личности» делают практически невозможным прибыльную торговлю примерно в 40% торговых дней!
Справочная публикация: Новая золотая лихорадка искусственного интеллекта - межпространственное машинное обучение (предоставлена панорама!)
Записная книжка Jupyter предоставляется вместе с кодом в репозитории GitHub ЗДЕСЬ.
Пример:
- Для данного базового инструмента 10-минутные свечи OHLC были созданы на основе тиковых данных, охватывающих приблизительно 10-летний период.
- Бэктестирование проводилось на данных свечей с использованием базового индикатора «Покупка / Продажа» для (9) случаев на каждый день с фиксированным стоп-лоссом / стоп-лоссом на основе ATR / без стоп-лосса.
- Каждый случай был оптимизирован для гиперпараметра базового индикатора, асимметрично как для ДЛИННЫХ, так и для КОРОТКИХ позиций, как для ЛУЧШЕГО, так и для НАИЛУЧШЕГО дневных прибылей и убытков, записи максимальных и минимальных дневных торговых прибылей и убытков, количества сделок и соответствующего оптимального значения гиперпараметра.
- Для каждого дня результаты для каждого (9) случаев усреднялись, чтобы сформировать вектор «сырых данных» для каждого дня.
- Предварительное исследование данных было выполнено с использованием TML, установив, что вероятное количество нижележащих кластеров должно быть приблизительно (9).
- «Функция пригодности» была изменена, чтобы помочь сосредоточить внимание на (9) кластерных решениях в процессе эволюции гибридного NEAT.
Итоговые "типичные" личности "дневного рынка" по относительному размеру:
«ПЕРЕД» применением TML (12-D в 2-D через tSNE):
time_start = time.time() tsne = TSNE(n_components=2, verbose=1, perplexity=100, n_iter=1000) tsne_results_orig = tsne.fit_transform( data_orig ) print('t-SNE done! Time elapsed: {} seconds'.format(time.time()-time_start)) df_subset['tsne-2d-one'] = tsne_results_orig[:,0] df_subset['tsne-2d-two'] = tsne_results_orig[:,1] plt.figure(figsize=(16,10)) sns.scatterplot( x="tsne-2d-one", y="tsne-2d-two", hue="y", palette=['purple','red','darkcyan','brown','blue', 'dodgerblue','green','lightgreen', 'black'], data=df_subset, legend="full", alpha=0.3 )
Применение TML (от 12 до 1000 через TML):
... metric = "jaccard" n_neighbors_max = 100 n_neighbors_min = 2 min_dist_max = 0.99 min_dist_min = 0.0 n_components_max = 1000 n_components_min = 1 min_samples_max = 1000 min_samples_min = 2 min_cluster_size_max = 2 min_cluster_size_min = 2 ... if ( num_clusters_found == 9 ): genome.fitness = 10000.0 / abs( clustered_COMB_sum_SE + 1) elif ( num_clusters_found == 0 ): genome.fitness = -99999.0 else: genome.fitness = 10000.0 / abs( clustered_COMB_sum_SE + 1) — ( abs( num_clusters_found — 9 ) * 1000.0 ) ... $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ New best_fitness_so_far = -2984.7710672587614 1 New best: metric = jaccard New best: n_neighbors = 98 New best: min_dist = 0.06658783809866256 New best: n_components = 1000 New best: min_samples = 3 New best: min_cluster_size = 2 New best: cluster_selection_epsilon = 0.6658783809866257 OUT: num_clusters_found = 12 OUT: ratio_clustered = 1.0 OUT: clusterer_probabilities_sum = 0.9558447965277097 OUT: clusterer_probabilities_sum_SE = 184.0931575208609 OUT: clusterer_outlier_scores_sum = 0.13366803680011266 OUT: clusterer_outlier_scores_sum_SE = 471.55167569985406 OUT: clustered_COMB_sum_SE = 655.644833220715 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ … $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ New best_fitness_so_far = 182.75239956493343 104 New best: metric = jaccard New best: n_neighbors = 100 New best: min_dist = 0.9899882983797373 New best: n_components = 1000 New best: min_samples = 2 New best: min_cluster_size = 2 New best: cluster_selection_epsilon = 9.899882983797372 OUT: num_clusters_found = 9 OUT: ratio_clustered = 1.0 OUT: clusterer_probabilities_sum = 0.9978606463926271 OUT: clusterer_probabilities_sum_SE = 1.649803561162849 OUT: clusterer_outlier_scores_sum = 0.03316588079964379 OUT: clusterer_outlier_scores_sum_SE = 52.31724504377773 OUT: clustered_COMB_sum_SE = 53.96704860494058 $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
«ПОСЛЕ» применения TML (от 1000-D до 2-D через tSNE):
time_start = time.time() raw_data = fit_HDBSCAN._raw_data tsne = TSNE(n_components=2, verbose=1, perplexity=100, n_iter=1000) tsne_results_1 = tsne.fit_transform( raw_data ) print('t-SNE done! Time elapsed: {} seconds'.format(time.time()-time_start)) df_subset['tsne-2d-one'] = tsne_results_1[:,0] df_subset['tsne-2d-two'] = tsne_results_1[:,1] plt.figure(figsize=(16,10)) sns.scatterplot( x="tsne-2d-one", y="tsne-2d-two", hue="y", palette=['purple','red','darkcyan','brown','blue', 'dodgerblue','green','lightgreen', 'black'], data=df_subset, legend="full", alpha=0.3 )
... unique_elements, counts_elements = np.unique(fit_HDBSCAN.labels_, return_counts=True) print(“Frequency of unique values of the said array:”) print(np.asarray((unique_elements, counts_elements))) # Frequency of unique values of the said array: # [[ 0 1 2 3 4 5 6 7 8] # [638 893 269 19 41 23 486 159 225]] threshold = pd.Series(fit_HDBSCAN.outlier_scores_).quantile(0.9) # threshold = 0.09822259079456185 outliers = np.where(fit_HDBSCAN.outlier_scores_ > threshold)[0] sns.distplot(fit_HDBSCAN.outlier_scores_[np.isfinite(fit_HDBSCAN.outlier_scores_)], rug=True) ...
Характеристики ДЛИННЫХ сделок, избегание ДЛИННЫХ сделок 38,5% торговых дней, связанных с идентификаторами кластера 6, 7, 8 и 9
КОРОТКИЕ торговые характеристики, избегание КОРОТКИХ сделок 40,3% торговых дней, связанных с идентификаторами кластера 0, 2, 5 и 8.
Резюме:
- Избегайте торговли ДОЛГО 38 процентов торговых дней, связанных с идентификаторами кластера 6, 7, 8 и 9.
- Избегайте КОРОТКОЙ торговли 40% торговых дней, связанных с идентификаторами кластера 0, 2, 5 и 8.
- У рынка множество «личностей», поэтому одна универсальная стратегия неадекватна!
- Способность определять индивидуальные особенности рынка позволяет адаптировать стратегии к конкретному «персонажу» с целью повышения прибыльности.
- Управление рисками требует знания «Как играть», но, что более важно, знания «Когда не играть»!
- Вектор необработанных данных с 12 измерениями был преобразован в вектор с размерностями 1000 для достижения разделения кластеров с помощью TML, а затем преобразован обратно в вектор 2D с использованием tSNE для целей визуализации.
- Межпространственное машинное обучение (TML) можно определить как целостные данные просмотра в перспективе приложения, выбор / создание показателей, отображение коллектора, выбор инструментов AI / ML / DL и определение фитнес-функции, управляемое только в зависимости от особенностей предполагаемого варианта использования и, что более важно, независимо от размерности исходных необработанных данных и размерности отображения множества.
Вдохновение:
- UMAP, Лиланд Макиннес
- HDBSCAN, Лиланд Макиннес, Джон Хили, Стив Астелс
- NEAT, Кеннет Стэнли
- Как настроить гиперпараметры tSNE, Николай Осколков
Об Эндрю (Энди) Карле:
Активный разработчик инструментов повышения производительности НЛП «GitHub AI Brain-of-Brains» и «GITHUB2VEC». Увлеченный многопрофильный инженер-аэрокосмический механик с обширным опытом интеграции искусственного интеллекта, гибридного обучения с подкреплением (Hybrid-NEAT), науки о данных и многопрофильного моделирования в оптимизации на основе гибридного обучения с подкреплением ( Hybrid-NEAT), проектирование и анализ сложных систем воздушного, космического и наземного базирования, разработка инженерных инструментов.