Создание эффективного торгового скринера

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

Для этого мы будем использовать библиотеку «tradingview_ta», мощную библиотеку Python, которая предоставляет доступ к широкому спектру обновленных и популярных индикаторов, используемых трейдерами по всему миру. Это гарантирует, что мы остаемся впереди всех, включая последние рыночные данные в наш процесс отбора. Мы также будем использовать библиотеку yfinance, чтобы легко загружать исторические котировки для выбранных нами инструментов. Это дает нам прочную историческую базу данных для всестороннего анализа и тестирования.

В данной статье речь пойдет о практическом применении аргентинских АДР (американских депозитарных расписок). Однако важно отметить, что принципы и методы, которые мы исследуем, могут быть применены к широкому спектру инструментов, доступных на Tradingview. Независимо от того, интересуетесь ли вы акциями, фьючерсами, ETF, криптовалютами или любым другим торгуемым активом, этот скринер может адаптироваться к вашим потребностям.

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

1. Импорт библиотек

Мы импортируем основные библиотеки, такие как pandas, numpy, tradingview_ta, yfinance, mplfinance, datetime и matplotlib. Эти библиотеки позволят нам обрабатывать данные, выполнять скрининги, визуализировать результаты и создавать графики.

# import the libraries that we going to use for the analysis
import pandas as pd
import numpy as np
from tradingview_ta import TA_Handler, Interval, Exchange
import yfinance as yf
import mplfinance as mpf
from datetime import datetime, timedelta
import matplotlib.pyplot as plt

2. Определите список акций

В предоставленном фрагменте кода у нас есть список тикерных символов, представляющих различные аргентинские АДР (американские депозитарные расписки). АДР — это акции иностранных компаний, которые торгуются на биржах США, что позволяет инвесторам получать доступ к международным рынкам без необходимости напрямую покупать акции на иностранных биржах.

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

tickers = [ 'YPF',
'BBAR',
'GGAL',
'MELI',
'SUPV',
'BMA',
'DESP',
'LOMA',
'PAM',
'CEPU',
'TGS',
'TEO',
'BIOX',
'CRESY',
'IRS',
'EDN'
]

3. Получить данные

На этом шаге мы получаем данные для каждого тикерного символа в списке тикеров. Мы перебираем список и выполняем следующие действия для каждого тикера:

Мы создаем экземпляр класса TA_Handler из библиотеки tradingview_ta. Этот обработчик позволяет нам взаимодействовать с функциями технического анализа TradingView.

Кроме того, мы указываем параметры для TA_Handler экземпляра:

  • symbol: Тикерный символ, для которого мы хотим получить данные.
  • screener: регион или биржа, с которой мы хотим получить данные. В этом случае мы установили его на «Америка», чтобы сосредоточиться на американских акциях.
  • биржа: Конкретная фондовая биржа, на которой котируется тикер. Сначала мы ищем данные на NYSE (Нью-Йоркская фондовая биржа).
  • interval: Временной интервал данных, которые мы хотим получить. Здесь мы устанавливаем его на «1d» для ежедневных данных.

Мы используем метод get_analysis().summary, чтобы получить сводку технического анализа для указанного тикера. Эта сводка содержит различные индикаторы и метрики, рассчитанные на основе исторических данных о ценах. Затем мы добавляем полученные данные для тикера в список tickers_data.

Если в процессе поиска возникает исключение, указывающее на то, что данные по тикеру на NYSE не найдены, мы обрабатываем исключение и ищем данные на NASDAQ (фондовая биржа NASDAQ), которая является еще одной популярной фондовой биржей США.

Наконец, мы печатаем сообщение о том, что данные были успешно импортированы.

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

tickers_data = []

# Iterate through each ticker
for ticker in tickers:
try:
# Retrieve data for the ticker from NYSE
data = TA_Handler(
symbol=ticker,
screener="america",
exchange="NYSE",
interval="1d"
)
data = data.get_analysis().summary
tickers_data.append(data)

except Exception as e:
# If no data is found for the ticker in NYSE, search in NASDAQ
print(f"No data found for ticker {ticker} in NYSE. Searching in NASDAQ...")
data = TA_Handler(
symbol=ticker,
screener="america",
exchange="NASDAQ",
interval="1d"
)
data = data.get_analysis().summary
tickers_data.append(data)

print("Data successfully imported.")

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

4. Обработка данных

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

Затем мы создаем словарь под названием data, чтобы упорядочить извлеченную информацию, связав ее с соответствующим тикерным символом. Этот словарь используется для создания кадра данных Pandas с именем df, где каждый столбец представляет определенную часть информации: тикер, рекомендации, покупки, продажи и нейтральные позиции.

recommendations = []
buys = []
sells = []
neutrals = []

# Iterate through each data in tickers_data
for data in tickers_data:
recommendation = data.get('RECOMMENDATION')
buy = data.get('BUY')
sell = data.get('SELL')
neutral = data.get('NEUTRAL')

recommendations.append(recommendation)
buys.append(buy)
sells.append(sell)
neutrals.append(neutral)

data = {
'Ticker': tickers,
'Recommendations': recommendations,
'Buys': buys,
'Sells': sells,
'Neutrals': neutrals
}

df = pd.DataFrame(data)

Чтобы установить порядок рекомендаций, мы определяем словарь под названием order_categories, который присваивает числовые значения каждой категории. Столбец «Порядок» создается в DataFrame путем сопоставления значений из столбца «Рекомендации» с соответствующими категориями в словаре order_categories. Затем DataFrame сортируется на основе столбца Order в порядке возрастания, обеспечивая логический порядок рекомендаций.

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

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

# Define the order of categories
order_categories = {
'STRONG_BUY': 5,
'BUY': 4,
'NEUTRAL': 3,
'SELL': 2,
'STRONG_SELL': 1
}

# Assign a numerical value to each category in a new column "Order"
df['Order'] = df['Recommendations'].map(order_categories)
df = df.sort_values('Order', ascending=True).reset_index(drop=True)

# Drop the "Order" column if not needed in the final output
df = df.drop('Order', axis=1)

# Display the sorted dataframe
df

5. Построение графика данных

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

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

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

# Create the figure and axes
fig, ax = plt.subplots(figsize=(10, 6))
fig.set_facecolor('#111111')
ax.set_facecolor('#111111')

# Add the horizontal bars for buys, neutrals, and sells
ax.barh(df.index, df["Buys"], height=0.25, color='#00BFFF', label='Indicators signaling buy')
ax.barh(df.index, df["Neutrals"], height=0.25, color='#808080', label='Neutral indicators', left=df["Buys"])
ax.barh(df.index, df["Sells"], height=0.25, color='#FFA500', label='Indicators signaling sell', left=df["Buys"] + df["Neutrals"])

# Set the axes labels
ax.set_yticks(df.index)
ax.set_yticklabels(df["Ticker"], fontsize=8, color='white')
ax.set_xlabel('Number of indicators', fontsize=10, color='white')

# Add title with larger font size and additional spacing
ax.set_title('Indicators with buy, sell, and neutral recommendations by ticker', fontsize=14, color='white', pad=20)

# Add the annotations
for i, recommendation in enumerate(df["Recommendations"]):
ax.annotate(recommendation, xy=(25, i), xytext=(26.5, i),
color='white', fontsize=8, va='center', ha='left')

# Remove the horizontal grid lines
ax.yaxis.grid(False)

# Configure the tick and axis styles
ax.tick_params(axis='x', colors='white')
ax.tick_params(axis='y', colors='white')
ax.spines['left'].set_color('white')
ax.spines['bottom'].set_color('white')
ax.spines['left'].set_linewidth(0.5)
ax.spines['bottom'].set_linewidth(0.5)
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)

# Adjust the spacing
plt.tight_layout()

# Set the text color of the legend to white
legend = ax.legend(loc='lower center', bbox_to_anchor=(0.5, -0.175), ncol=3, fontsize=8)
for text in legend.get_texts():
text.set_color('#111111')

# Display the plot
plt.show()

Раздел 2: Раскрытие торговых возможностей с помощью фильтрации индикаторов

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

На первом этапе мы импортируем данные технических индикаторов для списка биржевых тикеров с биржи NYSE или NASDAQ и сохраняем их в кадре данных pandas под названием df_adrs_indicators. Код перебирает каждый тикер, пытается получить данные индикатора с NYSE и, если это не удается, ищет данные в NASDAQ. Затем полученные данные объединяются с существующим DataFrame. Наконец, имена столбцов преобразуются в строки, и выводится сообщение об успешном завершении. Этот процесс позволяет консолидировать данные технических индикаторов для нескольких акций, что позволяет проводить дальнейший анализ и выявлять торговые возможности.

df_adrs_indicators = pd.DataFrame()

for ticker in tickers:
try:
data = TA_Handler(
symbol=ticker,
screener="america",
exchange="NYSE",
interval="1d"
)
data = data.get_analysis().indicators

except Exception as e:
print(f"No data found for ticker {ticker} in NYSE. Searching in NASDAQ...")
data = TA_Handler(
symbol=ticker,
screener="america",
exchange="NASDAQ",
interval="1d"
)
data = data.get_analysis().indicators

df_temp = pd.DataFrame(data, index=[ticker])
df_adrs_indicators = pd.concat([df_adrs_indicators, df_temp])

df_adrs_indicators.columns = df_adrs_indicators.columns.astype(str)
print("Data successfully imported.")

В результате мы получаем df_adrs_indicators кадра данных. Он имеет 91 столбец с информацией о многих технических индикаторах, чрезвычайно полезную информацию для фильтрации активов по критериям, которые мы считаем актуальными.

Например, после того, как мы импортировали данные технического индикатора в df_adrs_indicators DataFrame, мы можем приступить к фильтрации акций по определенным критериям. В этом фрагменте кода мы применяем несколько фильтров для определения акций, отвечающих определенным условиям.

Во-первых, мы фильтруем акции, у которых 10-дневная стоимость экспоненциальной скользящей средней (EMA) пересекается выше 20-дневного значения EMA. Это делается путем создания нового DataFrame с именем df_filtered с использованием условия df_adrs_indicators[‘EMA10’] > df_adrs_indicators[‘EMA20’].

Затем мы еще больше сужаем выбор, фильтруя акции со значением индекса относительной силы (RSI) выше 75. Кадр df_filtered DataFrame обновляется с таким условием: df_filtered[df_filtered[‘RSI’] > 75.

Затем мы применяем фильтр для акций с положительной конвергенцией-расхождением скользящих средних (MACD), особенно когда линия MACD пересекает сигнальную линию. Кадр df_filtered DataFrame снова обновляется с условием: df_filtered[df_filtered[‘MACD.macd’] > df_filtered[‘MACD.signal’].

Наконец, мы фильтруем акции со средним индексом направления (ADX) выше 30, что указывает на сильный тренд. Кадр df_filtered DataFrame обновляется с окончательным условием: df_filtered[df_filtered[‘ADX’] > 30.

# Filter stocks with EMA crossing SMA
df_filtered = df_adrs_indicators[df_adrs_indicators['EMA10'] > df_adrs_indicators['EMA20']]

# Filter stocks with RSI above 70 (overbought)
df_filtered = df_filtered[df_filtered['RSI'] > 75]

# Filter stocks with positive MACD (signal line crossover)
df_filtered = df_filtered[df_filtered['MACD.macd'] > df_filtered['MACD.signal']]

# Filter stocks with ADX above a certain threshold (indicating a strong trend)
df_filtered = df_filtered[df_filtered['ADX'] > 30]

# Print the stocks that meet the criteria
filtered_shares = df_filtered.index.to_list()

print('Shares filtered:', filtered_shares)

Акции отфильтрованы: [‘YPF’, ‘BMA’, ‘CRESY’, ‘EDN’]

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

# Get the current date
end_date = datetime.now().strftime("%Y-%m-%d")

# Calculate the start date (3 months ago from today)
start_date = (datetime.now() - timedelta(days=3 * 30)).strftime("%Y-%m-%d")

# Calculate the number of rows and columns based on the desired layout
num_rows = (len(filtered_shares) + 1) // 2
num_cols = 2

# Create a figure with subplots
fig, axes = plt.subplots(nrows=num_rows, ncols=num_cols, figsize=(12, 8))
fig.suptitle("Daily Candlestick Charts", fontsize=14)

# Iterate over each stock and add a subplot for each one
for i, symbol in enumerate(filtered_shares):
# Calculate the row and column index for the current subplot
row = i // num_cols
col = i % num_cols

# Get historical data from Yahoo Finance
data = yf.download(symbol, start=start_date, end=end_date)

# Plot the candlestick chart in the subplot
mpf.plot(data, type='candle', ax=axes[row, col], volume=False, show_nontrading=False)

# Set the title of the subplot
axes[row, col].set_title(symbol)

# Adjust the spacing between subplots
plt.tight_layout()

# Show the plot
plt.show()

Полный код можно посмотреть в моем профиле GitHub

Источник