Тепловая карта

  • Создание тепловой карты корреляции для торговли валютой
  • Создание тепловой карты фондового рынка на Python

Создание тепловой карты корреляции для торговли валютой

Корреляции между различными активами и рынками имеют решающее значение для определения любого направленного смещения и триггера для сделки. Если у нас есть сигнал на покупку по одному активу и сигнал на продажу по другому, но они почти идеально коррелируют, то мы знаем, что один из сигналов неверен, потому что эмпирически у нас есть информация о том, что они движутся вместе в одном направлении.

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

Я выпустил новую книгу после успеха моей предыдущей книги «Стратегии следования за трендом в Python». Он содержит расширенные противоположные индикаторы и стратегии со страницей GitHub, посвященной постоянно обновляемому коду. Если вы чувствуете, что это вас интересует, не стесняйтесь посетить приведенную ниже ссылку Amazon (которая содержит образец) или, если вы предпочитаете купить версию в формате PDF, вы можете проверить ссылку в конце статьи.

Понятие корреляции

Корреляция — это степень линейной зависимости между двумя или более переменными. Он ограничен между -1 и 1, где единица является совершенно положительной корреляцией, -1 — совершенно отрицательной корреляцией, а 0 — указанием на отсутствие линейной зависимости между переменными (они относительно идут в случайных направлениях). Мера не идеальна и может быть смещена выбросами и нелинейными зависимостями, однако она дает быстрый взгляд на статистические свойства. Существуют и широко используются два известных типа корреляции:

  • Корреляция Спирмена измеряет взаимосвязь между двумя непрерывными или порядковыми переменными. Переменные могут иметь тенденцию изменяться вместе, но не обязательно с постоянной скоростью. Он основан на рангах значений, а не на необработанных данных.
  • Корреляция Пирсона измеряет линейную зависимость между двумя непрерывными переменными. Зависимость можно считать линейной, когда изменение одного сопровождается пропорциональным изменением другого.

Мера не идеальна и может быть смещена выбросами и нелинейными зависимостями, однако она дает быстрый взгляд на статистические свойства.

Мы можем закодировать функцию корреляции между двумя переменными в Python, используя приведенную ниже команду. Обратите внимание, что это должен быть массив, а не кадр данных:

def rolling_correlation(Data, first_data, second_data, lookback, where):

for i in range(len(Data)):

try:
Data[i, where] = pearsonr(Data[i - lookback + 1:i + 1, first_data], Data[i - lookback + 1:i + 1, second_data])[0]


except ValueError:
pass

Data = jump(Data, lookback)

return Data

Импорт данных OHLC

Одной из самых известных торговых платформ в розничном сообществе является программное обеспечение MetaTrader5. Это мощный инструмент с собственным языком программирования и огромной поддержкой онлайн-сообщества. Самое главное, он предлагает возможность экспортировать свои исторические краткосрочные и долгосрочные валютные данные. Первое, что нам нужно сделать, это просто скачать его с официального сайта. Затем, после создания демо-счета, мы готовы импортировать библиотеку на Python, которая позволяет импортировать данные OHLC из MetaTrader5.

Библиотека — это группа структурированных функций, которые можно импортировать в наш интерпретатор Python, откуда мы можем вызывать и использовать те, которые нам нужны.

Самый простой способ установить библиотеку — перейти в подсказку Python на нашем компьютере и ввести:

pip install MetaTrader5

Это должно установить библиотеку в наш локальный Python. Теперь мы хотим импортировать его в интерпретатор Python (например, Pycharm или SPYDER), чтобы мы могли его использовать. Давайте на самом деле импортируем все библиотеки, которые мы будем использовать для этого:

import datetime                 # Date acquiring
import pytz # Time zone management
import pandas as pd # Mostly for Data frame manipulation
import MetaTrader5 as mt5 # Importing OHLC data
import matplotlib.pyplot as plt # Plotting charts
import numpy as np # Mostly for array manipulation

Все, что идет после «как», является ярлыком. Ярлык plt предназначен для того, чтобы каждый раз, когда мы хотим вызвать функцию из этой библиотеки, нам не нужно вводить полную инструкцию matplotlib.pyplot.

Первое, что мы можем сделать, это выбрать, какой таймфрейм мы хотим импортировать. Предположим, что есть только два фрейма, 30-минутный и часовой бары. Таким образом, мы можем создать переменные, которые содержат оператор, чтобы сообщить библиотеке MetaTrader5, какой фрейм нам нужен.

# Choosing the 30-minute time frame
frame_M30 = mt5.TIMEFRAME_M30# Choosing the hourly time frame
frame_H1 = mt5.TIMEFRAME_H1

Затем, оставаясь в духе импорта переменных, мы можем определить переменную, которая указывает, какая сейчас дата. Это помогает алгоритму узнать дату остановки импорта. Мы можем сделать это с помощью простой строки кода ниже.

# Defining the variable now to give out the current date
now = datetime.datetime.now()

Обратите внимание, что эти фрагменты кода лучше использовать в хронологическом порядке, поэтому я призываю вас копировать их по порядку, а затем выполнять один за другим, чтобы вы понимали эволюцию того, что вы делаете. Ниже приведена функция, которая определяет, какие активы нам нужны. Как правило, я использую 10 или более, но для простоты давайте учтем, что существует только две валютные пары: EURUSD и USDCHF.

def asset_list(asset_set):

if asset_set == 1:
assets = ['EURUSD', 'USDCHF'] return assets

Теперь с ключевой функцией, которая дает нам данные OHLC. Ниже устанавливается соединение с MetaTrader5, применяется текущая дата и извлекаются необходимые данные. Обратите внимание на аргументы год, месяц и день. Они будут заполнены нами, чтобы выбрать, когда мы хотим, чтобы данные начались. Обратите внимание, что я ввел Европу / Париж в качестве своего часового пояса, вы должны использовать свой часовой пояс, чтобы получить более точные данные.

def get_quotes(time_frame, year = 2005, month = 1, day = 1, asset = "EURUSD"):

# Establish connection to MetaTrader 5
if not mt5.initialize():
print("initialize() failed, error code =", mt5.last_error())
quit()

timezone = pytz.timezone("Europe/Paris")

utc_from = datetime.datetime(year, month, day, tzinfo = timezone)
utc_to = datetime.datetime(now.year, now.month, now.day + 1, tzinfo = timezone)

rates = mt5.copy_rates_range(asset, time_frame, utc_from, utc_to)

rates_frame = pd.DataFrame(rates)
return rates_frame

И, наконец, последняя функция, которую мы будем использовать, — это та, которая использует приведенную ниже функцию get_quotes, а затем очищает результаты, чтобы у нас был красивый массив. Мы отобрали данные с января 2019 года, как показано ниже.

def mass_import(asset, horizon):

if horizon == 'M30':
data = get_quotes(frame_M30, 2019, 1, 1, asset = assets[asset])
data = data.iloc[:, 1:5].values
data = data.round(decimals = 5)
return data

Наконец, мы закончили создание блоков, необходимых для импорта данных. Чтобы импортировать исторические данные OHLC по EURUSD, мы просто используем следующую строку кода:

# Choosing the horizon
horizon = 'M30'
# Creating an array called EURUSD having M30 data since 2019
EURUSD = mass_import(0, horizon)

И вуаля, теперь у нас есть данные по EURUSD OHLC за 2019 год.

Создание тепловой карты корреляции

Тепловая карта будет создана с помощью библиотеки под названием seaborn. Он позаботится о сюжетной части. Часть подготовки и структурирования данных будет обрабатываться вручную с использованием следующих фрагментов кода. Все, что нам нужно, это функция импорта из предыдущего раздела. Во-первых, давайте убедимся, что у нас есть правильные импортированные библиотеки.

# Importing libraries
import pandas as pd
import numpy as np
import seaborn as sn

Следующим шагом является определение массива валютных пар, которые мы хотим охватить. В нашем примере мы выбрали 9 различных валютных пар, как показано ниже:

assets = ['EURUSD', 'USDCHF', 'GBPUSD', 'AUDUSD', 'NZDUSD', 'USDCAD', 'EURCAD', 'EURGBP', 'EURCHF']

Следующим шагом является импорт их в интерпретатор Python с помощью функции mass_import, которую мы видели ранее. Для каждой из следующих валютных пар мы будем делать три вещи:

  • Импорт исторических данных OHLC из MetaTrader5 с помощью функции mass_import.
  • Убрав все столбцы, кроме столбца цены закрытия, так как мы будем вычислять по нему меру корреляции.
  • Выберите последние 1000 данных, так как корреляция является динамической и вряд ли будет напоминать корреляцию несколько лет назад. С часовыми значениями мы выбрали последние 1000 данных (часовые бары).
# Mass imports 
EURUSD = mass_import(0, horizon)
EURUSD = EURUSD[:, 3:4]
EURUSD = EURUSD[-1000:, ]USDCHF = mass_import(1, horizon)
USDCHF = USDCHF[:, 3:4]
USDCHF = USDCHF[-1000:, ]GBPUSD = mass_import(2, horizon)
GBPUSD = GBPUSD[:, 3:4]
GBPUSD = GBPUSD[-1000:, ]AUDUSD = mass_import(3, horizon)
AUDUSD = AUDUSD[:, 3:4]
AUDUSD = AUDUSD[-1000:, ]NZDUSD = mass_import(4, horizon)
NZDUSD = NZDUSD[:, 3:4]
NZDUSD = NZDUSD[-1000:, ]USDCAD = mass_import(5, horizon)
USDCAD = USDCAD[:, 3:4]
USDCAD = USDCAD[-1000:, ]EURCAD = mass_import(6, horizon)
EURCAD = EURCAD[:, 3:4]
EURCAD = EURCAD[-1000:, ]EURGBP = mass_import(7, horizon)
EURGBP = EURGBP[:, 3:4]
EURGBP = EURGBP[-1000:, ]EURCHF = mass_import(8, horizon)
EURCHF = EURCHF[:, 3:4]
EURCHF = EURCHF[-1000:, ]

Следующим шагом является объединение (объединение) каждого столбца из каждой пары в один массив с помощью функции concatenate из numpy, как показано ниже.

Correlation_Matrix = np.concatenate((EURUSD, 
USDCHF,
GBPUSD,
AUDUSD,
NZDUSD,
USDCAD,
EURCAD ,
EURGBP,
EURCHF), axis = 1)

Затем мы хотим назвать столбцы, но это можно сделать только в кадрах данных. Поэтому мы просто преобразуем массив в кадр данных, а затем назовем столбцы, как показано во фрагменте кода ниже.

Correlation_Matrix = pd.DataFrame(Correlation_Matrix)Correlation_Matrix.columns = ['EURUSD', 
'USDCHF',
'GBPUSD',
'AUDUSD',
'NZDUSD',
'USDCAD',
'EURCAD',
'EURGBP',
'EURCHF']

Теперь у нас есть все, что нам нужно для тепловой карты. Все, что осталось сделать, это линия моря, чтобы нанести карту. Это можно легко сделать, следуя приведенному ниже синтаксису.

# Visual representation
sn.heatmap(Correlation_Matrix.corr(), cmap ="YlGnBu")

О чем говорит приведенная выше тепловая карта? Первое, на что мы должны обратить внимание, это шкала справа, которая говорит нам, как интерпретировать цвета (или тепло). Бежевый цвет относится к сильной отрицательной корреляции, а темно-синий цвет относится к сильному положительному цвету. Зеленовато-синий — это место, где корреляция близка к нулю, что означает, что два рынка движутся независимо друг от друга и на самом деле не связаны.

Взгляните на корреляцию EURUSD против GBPUSD, AUDUSD и NZDUSD. Мы можем заметить, что, поскольку они являются основными долларами США, движения доллара США были доминирующими, что заставляло их двигаться вместе и возглавлять доллар США.

Несвязанные пары, такие как NZDUSD и EURCHF, скорее всего, будут иметь нулевую корреляцию, что имеет место, если мы посмотрим на приведенную выше тепловую карту. Зеленый и синий цвета являются преобладающими, что подтверждает эту гипотезу.

Как и ожидалось, EURUSD и USDCHF имеют крайне высокую отрицательную корреляцию. Когда один движется вверх, другой, скорее всего, движется вниз. Швейцарский франк связан с еврозоной, и поэтому он, вероятно, будет иметь те же отношения с долларом США, что и евро с ним.

Прежде чем совершить вторую сделку или одновременные сделки, нам нужно сначала проверить корреляцию и посмотреть, увеличиваем или уменьшаем ли мы наш риск.

Если вы хотите увидеть, как самостоятельно создавать всевозможные алгоритмы, смело загляните в Lumiwealth. От алгоритмической торговли до блокчейна и машинного обучения — у них есть практические подробные курсы, которые я настоятельно рекомендую.

Заключение

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

Я рекомендую вам всегда следовать приведенным ниже шагам, когда вы сталкиваетесь с торговой техникой или стратегией:

  • Имейте критический настрой и избавьтесь от любых эмоций.
  • Протестируйте его на истории, используя моделирование и условия реальной жизни.
  • Если вы найдете потенциал, попробуйте оптимизировать его и запустить форвард-тест.
  • Всегда включайте транзакционные издержки и любую симуляцию проскальзывания в свои тесты.
  • Всегда включайте управление рисками и определение размера позиции в свои тесты.

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

Создание тепловой карты фондового рынка на Python

Изучите взаимосвязь между биржевыми тикерами в бычьей или медвежьей фазе и их эквивалентностью.

Эта статья поможет вам создать тепловую карту фондового рынка с помощью Python. Мы стремимся исследовать взаимосвязь между биржевыми тикерами в бычьей или медвежьей фазе и их соответствующей доходностью. Чтобы оценить настроение рынка, воспользуемся индикатором SMA50/SMA200. Бычье состояние указывается, когда SMA50 превосходит SMA200, в то время как противоположное сигнализирует о медвежьей позиции. Доходность определяется путем деления разницы между текущей и предыдущей ценой закрытия на более раннюю цену закрытия, а затем умножения в 100 раз.

Сбор и предварительная обработка наших данных

EODHD API предоставит необходимые исторические данные для нашего проекта. Итак, какие тикеры фондового рынка выбрать? Рассматривая индекс S&P 500, который включает в себя чуть более 500 компаний из-за того, что некоторые организации имеют несколько типов акций, мы находим ответ. Список этих компаний есть в Википедии. Используя Python, мы разработали скрипт для парсинга этой страницы, позволяющий извлекать коды компаний и компилировать их в список.

import requests
import pandas as pd
from io import StringIO

def get_sp500_tickers():
url = "https://en.wikipedia.org/wiki/List_of_S%26P_500_companies"
html = requests.get(url).text
data = StringIO(html)
df = pd.read_html(data, header=0)[0]
tickers = df["Symbol"].tolist()
return tickers

sp500_tickers = get_sp500_tickers()
print(sp500_tickers)

Вооружившись нашим списком кодов компаний из S&P 500, мы стремимся сопоставить его со списком рынков США, доступных в EODHD API, чтобы обеспечить охват всех необходимых рынков. Наша цель состоит в том, чтобы получить результат в виде списка Python. В следующем фрагменте кода мы импортируем наши API_KEY из config.py.

import config as cfg
from eodhd import APIClient

api = APIClient(cfg.API_KEY)

df_symbols = api.get_exchange_symbols("US")
eodhd_tickers = df_symbols["Code"].tolist()
print(eodhd_tickers)

Теперь, когда у нас есть два списка, мы хотим сделать быструю проверку, чтобы убедиться, что все выглядит хорошо.

for sp500_ticker in sp500_tickers:
if sp500_ticker not in eodhd_tickers:
print("Missing: ", sp500_ticker)
else:
print("Found: ", sp500_ticker)

Вы можете заметить, что несколько тикеров отсутствуют; однако это несущественно, поскольку они в первую очередь относятся к акциям категории «B» компаний, котирующихся в индексе S&P 500 более одного раза. Ими можно пренебречь. Решающим результатом является попадание в наш список из 500 компаний, которого мы успешно достигли.

Следующий шаг включает в себя расширение кода, чтобы включить в него «найденные» компании, получая их исторические данные, ограниченные последними 200 дневными свечами. Мы применим SMA50/SMA200 к этим данным, чтобы определить бычье или медвежье состояние и рассчитать доходность, как было описано изначально. Для каждой обрабатываемой компании мы добавим данные в файл с именем «sp500.csv». Начните с того, что создайте этот файл пустым и вручную добавьте заголовок: «Биржевой символ,Дата,Цена закрытия,Состояние рынка,Доходность».

def calculate_technical_indicators(df):
df_ta = df.copy()
df_ta["sma50"] = df_ta["close"].rolling(50, min_periods=0).mean()
df_ta["sma200"] = df_ta["close"].rolling(200, min_periods=0).mean()
df_ta["bull"] = df_ta.sma50 > df_ta.sma200
return df_ta

for sp500_ticker in sp500_tickers:
if sp500_ticker not in eodhd_tickers:
print("Missing: ", sp500_ticker)
else:
print("Found: ", sp500_ticker)

df_ticker_history = api.get_historical_data(
f"{sp500_ticker}.US", "d", results=200
)
df_ticker_history_ta = calculate_technical_indicators(df_ticker_history)
df_ticker_history_ta["date"] = df_ticker_history_ta.index

df_result = df_ticker_history_ta[["symbol", "date", "close", "bull"]].copy()
df_result.columns = ["Stock Symbol", "Date", "Closing Price", "Market State"]

df_result.loc[:, "Return"] = (
(df_result["Closing Price"] - df_result["Closing Price"].shift(1))
/ df_result["Closing Price"].shift(1)
) * 100

df_result.loc[:, "Market State"] = df_result["Market State"].apply(
lambda x: "Bullish" if x else "Bearish"
)

df_result.loc[:, "Return"] = df_result["Return"].fillna(0)
df_result.loc[:, "Stock Symbol"] = df_result["Stock Symbol"].str.replace(".US", "")

print(df_result.to_csv("sp500.csv", mode="a", index=False, header=False))

По завершении у нас будет файл «sp500.csv», отформатированный следующим образом…

Stock Symbol,Date,Closing Price, Market State, Return
MMM,2023-06-02,102.53,Bearish,0.0
MMM,2023-06-05,97.98,Bearish,-4.437725543743292
MMM,2023-06-06,98.29,Bearish,0.3163911002245379
MMM,2023-06-07,101.0,Bearish,2.7571472174178386
...

Наш файл содержит 68 558 строк, включая заголовок.

Корреляционная матрица

Чтобы создать тепловую карту фондового рынка, мы сначала импортируем данные в Pandas DataFrame и создадим сводную таблицу. Эта таблица послужит основой для нашей корреляционной матрицы.

df = pd.read_csv("sp500.csv")
print(df)

pivoted_df = df.pivot(index="Date", columns="Stock Symbol", values="Closing Price")
print(pivoted_df)

corr_matrix = pivoted_df.corr()

Тепловые карты фондового рынка

Прежде чем продолжить, предостережение: создание корреляционной матрицы такой величины приведет к довольно громоздкому результату. Прямо «из коробки», это, скорее всего, будет сложно интерпретировать. Тем не менее, он будет служить нашей отправной точкой. Я помогу вам создать фундаментальную тепловую карту фондового рынка. Убедитесь, что вы заранее установили библиотеку Python «seaborn«, если ее еще нет в вашем наборе инструментов.

import seaborn as sns

plt.figure(figsize=(16, 16))
sns.heatmap(corr_matrix, annot=True, cmap="coolwarm")
plt.title("Heatmap of Stock Price Correlations")
plt.savefig("heatmap-full.png")
plt.tight_layout()
plt.show()

Существует несколько стратегий для повышения читабельности тепловой карты. Основной подход включает в себя установку порога корреляции, например, 0,8, хотя для нахождения оптимального баланса может потребоваться экспериментирование.

threshold = 0.8
high_corr = corr_matrix[(corr_matrix >= threshold) & (corr_matrix < 1)]

plt.figure(figsize=(16, 16))
sns.heatmap(high_corr, annot=True, cmap="coolwarm")
plt.title("Heatmap of Stock Price Correlations")
plt.savefig("heatmap-0.8.png")
plt.tight_layout()
plt.show()

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

Карта кластеров

Карта кластеров предлагает альтернативу тепловой карте и визуально выглядит гораздо более привлекательной.

plt.figure(figsize=(16, 16))
sns.clustermap(corr_matrix, cmap="coolwarm")
plt.title("Cluster Map of Stock Price Correlations")
plt.savefig("clustermap.png")
plt.tight_layout()
plt.show()

При этом рынки с высокой корреляцией отображаются в теплых красных тонах, а рынки с более низкой корреляцией — в более холодных синих оттенках.

Тепловая карта Top n фондовых рынков

Альтернативный подход к тепловой карте включает в себя построение топ-50.

def get_top_n_correlations(corr_matrix, n):
c = corr_matrix.abs().stack()
return c[c < 1].sort_values(ascending=False).drop_duplicates().head(n)

top_n = get_top_n_correlations(corr_matrix, 50)

top_pairs = pd.DataFrame(list(top_n.index), columns=["Stock 1", "Stock 2"])
top_pairs["Correlation"] = top_n.values

top_pairs_pivot = top_pairs.pivot(
index="Stock 1", columns="Stock 2", values="Correlation"
)

plt.figure(figsize=(16, 16))
sns.heatmap(top_pairs_pivot, annot=True, cmap="coolwarm")
plt.title("Cluster Map of Stock Price Correlations")
plt.savefig("top_n_heatmap.png")
plt.tight_layout()
plt.show()

Это представление оказывается наиболее простым для чтения и интерпретации.

Тепловая карта фондового рынка по отраслям

Когда мы углубляемся в выявление корреляций между многочисленными тикерами фондового рынка, процесс может быстро стать ошеломляющим. Наша излюбленная стратегия включает в себя организацию рынков по секторам для более эффективного анализа корреляций внутри каждого сектора.

На странице Википедии, о которой мы упоминали ранее, мы использовали «Символ» для составления списка тикеров фондового рынка в S&P 500. Возможно, вы заметили две дополнительные колонки: «Сектор GICS» и «Подотрасль GICS». Приведенный ниже код Python сгенерирует словарь сопоставления, чтобы связать «Symbol» с его «Sector«.

def sp500_sector_mapping():
url = "https://en.wikipedia.org/wiki/List_of_S%26P_500_companies"
html = requests.get(url).text
data = StringIO(html)
df = pd.read_html(data, header=0)[0]
ticker_meta = df[[
"Symbol",
"GICS Sector"
# "GICS Sub-Industry"
]].to_dict(orient='records')

mapping_dict = {}
for ticker in ticker_meta:
mapping_dict[ticker["Symbol"]] = ticker["GICS Sector"]

return mapping_dict

sector_mapping = sp500_sector_mapping()

Используя этот код, мы затем отобразим корреляцию между секторами, представленную в виде тепловой карты фондового рынка.

mapped_sectors = corr_matrix.columns.map(sector_mapping)
mean_corr_by_sector = (
corr_matrix.groupby(mapped_sectors).mean().groupby(mapped_sectors, axis=1).mean()
)

plt.figure(figsize=(16, 16))
sns.heatmap(mean_corr_by_sector, annot=True, cmap="coolwarm")
plt.title("Heatmap of Stock Price Sector Correlations")
plt.savefig("heatmap_sector.png")
plt.tight_layout()
plt.show()

Заключение

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

Источник

Источник