Торговая стратегия Aroon Up Down

Фото R M с сайта Unsplash
  • Создание автоматической торговой стратегии Aroon Up Down
  • Развертывание торговой стратегии Aroon Up Down на TQuant Lab

Создание автоматической торговой стратегии Aroon Up Down

Предисловие

Технический индикатор осциллятора — это технический индикатор, используемый в анализе финансовых рынков для оценки перекупленности/перепроданности данного актива в заданный период. Он может помочь инвесторам в определении трендов и потенциальных разворотов тренда.

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

Сегодня мы познакомим вас с техническим индикатором Oscillator — Aroon Up Down.

Знакомство

Индикатор Aroon, разработанный Тушаром Чанде в 1995 году, обычно используется для измерения рыночных тенденций. Он состоит из двух линий — Aroon Up и Aroon Down.

  • Aroon Up:((Кол-во периодов — Количество периодов с момента наивысшего максимума) / Количество периодов) * 100
    Этот индикатор измеряет периоды, прошедшие с момента достижения максимальной цены (максимума) в выбранном периоде.
  • Aroon Down:((Кол-во периодов — Количество периодов с самого низкого минимума) / Количество периодов) * 100
    Этот индикатор измеряет периоды, прошедшие с момента возникновения самой низкой цены (нижней точки) в выбранном периоде.

Индикатор Aroon Up измеряет силу и время, прошедшее с момента достижения максимальной цены в течение заданного периода (обычно 25 периодов). Напротив, индикатор Aroon Down измеряет силу и время с момента самой низкой цены за тот же период. Эти показатели выражаются в процентах и колеблются от 0% до 100%.

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

Среда программирования и требуемый модуль

В качестве редактора используется MacOS и Jupyter Notebookimport pandas as pd
import re
import numpy as np
import tejapi
import plotly.express as px
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from matplotlib.pyplot import MultipleLocator
from sklearn.linear_model import LinearRegression
import datetimetejapi.ApiConfig.api_key = «Your api key»
tejapi.ApiConfig.ignoretz = True

База данных

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

За период с 01.01.2018 по 31.12.2020 г. возьмем Hon Hai Precision Industry Co., Ltd.(2317), Compal Electronics, Inc.(2324), YAGEO Corporation(2327), Taiwan Semiconductor Manufacturing Co., Ltd.(2330), Synnex Technology International Corp.(2347), Acer(2353), Foxconn Technology Co., Ltd.(2354), ASUS(2357), Realtek Semiconductor Corp.(2379), Quanta Computer, Inc.(2382), Advantech Co., Ltd.(2395) в качестве примера, мы построим систему тестирования на истории с нескорректированными ценовыми данными и сравним производительность с индексом рыночной доходности (Y9997).stock_id = [«Y9997», «2317», «2324», «2327», «2330», «2347», «2353», «2354»,
«2357», «2379», «2382», «2395»]
gte, lte = ‘2018-01-01’, ‘2020-12-31’
stock = tejapi.get(‘TWN/APRCD’,
paginate = True,
coid = stock_id,
mdate = {‘gte’:gte, ‘lte’:lte},
opts = {
‘columns’:[ ‘mdate’, ‘coid’, ‘open_d’, ‘high_d’, ‘low_d’, ‘close_d’, ‘volume’]
}
)

Далее переносим таблицу в сводную таблицу по coid(company id) и исключаем рыночный индекс.

Торговая стратегия

Прежде всего, нам нужно объявить следующие аргументы:

  • Принципал: Первоначально инвестированный капитал.
  • Денежные средства: Денежная позиция, которую мы держим в настоящее время.
  • order_unit: Торговая единица каждой транзакции.

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

  • position: Позиция по акциям, которую мы держим в настоящее время.
  • invested_principal: Сумма основного долга, которую мы инвестировали.

Мы используем объект типа списка, aroon_record для записи «coid», «mdate», «Aroon-up», «Aroon-down».

Кроме того, чтобы измерить конечную эффективность нашего портфеля, мы создаем два объекта типа списка — daily_stock_value_record и daily_cash_value_record для хранения «позиции удержания», «стоимости акций» и «оставшейся денежной стоимости» каждого дня сделки.

Теперь пришло время разработать наши торговые сигналы.

Когда Aroon Up больше 80, а Aroon Down меньше 45, что представляет собой бычий тренд. Мы считаем это сигналом на покупку и приобретем одну единицу по цене завтрашнего открытия.

Когда Aroon Up меньше 45, Aroon Down больше 55, а разрыв двух индикаторов больше 15, мы расцениваем это как сигнал на продажу и продаем удерживающую позицию по завтрашней цене открытия.

Когда Aroon Up больше 55, Aroon Down меньше 45, разрыв между двумя показателями больше 15, наша инвестированная сумма не превышает 20% от основной суммы, и у нас все еще много денежных средств. Мы приобретем еще одну единицу по цене открытия завтрашнего дня.

def Aroon_strategy_multi(data_pivot, principal, cash, order_unit, n):
trade_book = pd.DataFrame()
aroon = pd.DataFrame(columns=[«coid», «mdate», «AroonUp», «AroonDown»])

daily_stock_value_record = []
daily_cash_value_record = []

coid_dict = {}
for i in list(data_pivot.high_d.columns):
coid_dict.update({i:{«position»:0, «invested_principal»:0}})

for ind in range(len(data_pivot.index) — n -1):
for col in data_pivot.high_d.columns:
high_period = data_pivot.high_d[col].iloc[ ind : ind+n].reset_index()
AroonUp = round((high_period.idxmax()[1] + 1)/n*100)

low_period = data_pivot.low_d[col].iloc[ ind : ind+n].reset_index()
AroonDown = round(((low_period.idxmin()[1] + 1)/n*100))


aroon = aroon.append({
«coid»:col,
«mdate»:data_pivot.index[ind+n],
«AroonUp»:AroonUp,
«AroonDown»:AroonDown,
}, ignore_index=True)

n_time = data_pivot.index[ind+n+1]
n_open = data_pivot.open_d[col].iloc[ind+n+1]

if coid_dict.get(col).get(«position») == 0: #進場條件
if (AroonDown < 45) and (AroonUp > 80):
position = coid_dict.get(col).get(«position»)

order_time = n_time
order_price = n_open
order_unit = 1
friction_cost = (20 if order_price*1000*0.001425 < 20 else order_price*1000*0.001425)
total_cost = -1 * order_price * 1000 — friction_cost
cash += total_cost

coid_dict.update({col:{«position»:position+1, «invested_principal»:order_price * 1000,}})

trade_book = pd.concat([trade_book,
pd.DataFrame([col, ‘Buy’, order_time, 0, total_cost, order_unit, coid_dict.get(col).get(«position»), cash, order_price])],
ignore_index = True, axis=1)

elif coid_dict.get(col).get(«position») > 0:
if (AroonDown — AroonUp) > 15 and AroonDown > 55 and AroonUp < 45: # 出場條件
order_unit = coid_dict.get(col).get(«position»)
cover_time = n_time
cover_price = n_open
friction_cost = (20 if cover_price*order_unit*1000*0.001425 < 20 else cover_price*order_unit*1000*0.001425) + cover_price*order_unit*1000*0.003
total_cost = cover_price*order_unit*1000-friction_cost
cash += total_cost

coid_dict.update({col:{«position»:0, «invested_principal»:0}})

trade_book = pd.concat([trade_book,
pd.DataFrame([col, ‘Sell’, 0, cover_time, total_cost, -1*order_unit, coid_dict.get(col).get(«position»), cash, cover_price])],
ignore_index = True, axis=1)

elif (AroonUp — AroonDown) > 15 and (AroonDown < 45) and AroonUp > 55 and (cash >= n_open*1000) and (coid_dict.get(col).get(«invested_principal») <= 0.2 * principal): #加碼條件
order_unit = 1
order_time = n_time
order_price = n_open

position = coid_dict.get(col).get(«position»)

friction_cost = (20 if order_price*1000*0.001425 < 20 else order_price*1000*0.001425)
total_cost = -1 * order_price * 1000 — friction_cost
cash += total_cost

invested_principal = coid_dict.get(col).get(«invested_principal»)
coid_dict.update({col:{«position»:position+1, «invested_principal»: invested_principal + order_price*1000}})

trade_book = pd.concat([trade_book,
pd.DataFrame([col, ‘Buy’, order_time, 0, total_cost, order_unit, coid_dict.get(col).get(«position»), cash, order_price])],
ignore_index = True, axis=1)

daily_stock_value_record.append({
«mdate»: n_time,
«coid»:col,
«position»:coid_dict.get(col).get(«position»),
«stock_value»:coid_dict.get(col).get(«position») * data_pivot.close_d[col].iloc[ind+n+1] * 1000,
})
daily_cash_value_record.append(cash)

for col in data_pivot.high_d.columns:# 最後一天平倉

if coid_dict.get(col).get(«position») > 0:

high_period = data_pivot.high_d[col].iloc[ -n : -1].reset_index()
AroonUp = round((high_period.idxmax()[1] + 1)/n*100)
low_period = data_pivot.low_d[col].iloc[ -n : -1].reset_index()
AroonDown = round(((low_period.idxmin()[1] + 1)/n*100))

order_unit = coid_dict.get(col).get(«position»)
cover_price = data_pivot.open_d[col].iloc[-1]
cover_time = data_pivot.index[-1]
friction_cost = (20 if cover_price*order_unit*1000*0.001425 < 20 else cover_price*order_unit*1000*0.001425) + cover_price*order_unit*1000*0.003
cash += cover_price*order_unit*1000-friction_cost

coid_dict.update({col:{«position»:0, «invested_principal»: 0,}})

trade_book = pd.concat([trade_book,
pd.DataFrame([col, ‘Sell’,0, cover_time, cover_price*order_unit*1000-friction_cost, -1*order_unit, 0, cash, cover_price])],
ignore_index=True, axis=1)

daily_stock_value_record.append({
«mdate»: data_pivot.index[-1]+datetime.timedelta(days = 1),
«coid»:col,
«position»:coid_dict.get(col).get(«position»),
«stock_value»:0,
})

daily_cash_value_record.append(cash)
value_book = pd.DataFrame(daily_stock_value_record).set_index(«mdate»)
value_book = pd.pivot_table(value_book, columns = «coid», index = «mdate»)
value_book[«cash_value»] = daily_cash_value_record

trade_book = trade_book.T
trade_book.columns = [‘coid’, ‘BuyOrSell’, ‘BuyTime’, ‘SellTime’, ‘CashFlow’,’TradeUnit’, ‘HoldingPosition’, ‘CashValue’, ‘DealPrice’]
trade_book[‘mdate’] = [trade_book.BuyTime[i] if trade_book.BuyTime[i] != 0 else trade_book.SellTime[i] for i in trade_book.index]
trade_book = trade_book.loc[:, [‘coid’, ‘BuyOrSell’, ‘DealPrice’, ‘CashFlow’, ‘TradeUnit’, ‘HoldingPosition’, ‘CashValue’ ,’mdate’]]

return trade_book, aroon, value_book, order_unit, n)

После подтверждения торговых сигналов и установки входных и выходных данных функции, мы можем передать параметры в Aroon_strategy_multi() и выполнить его.principal = 10e6
cash = principal
order_unit = 0
n = 25

df, aroon, value = Aroon_strategy_multi(data_pivot, principal, cash, order_unit, n)

Записи о транзакциях

Aroon_strategy_multi() выведет три листа:

  • Лист транзакций: записывает сведения о каждой транзакции, включая поведение транзакции, цену сделки, единицу сделки и т. д.
  • Лист индикаторов Aroon: Записывает ежедневные Aroon-up и Aroon-down каждой цели.
  • Лист стоимости портфеля: записывает ежедневную позицию удержания каждой цели, ежедневную стоимость акций и оставшуюся денежную стоимость портфеля.
Лист транзакций
Лист индикаторов Aroon
Лист стоимости портфеля

Оценка эффективности

Сегодняшняя демонстрация будет проходить через движущиеся альфа- и бета-версии портфеля для оценки эффективности портфеля. Чтобы материализовать его, сначала нужно рассчитать дневную доходность портфеля и рынка, а затем, соответственно, сохранить их в новых столбцах Листа стоимости портфеля.value[«total_value»] = value.apply(lambda x : x.sum(), axis = 1)
value[«daily_return»] = value[«total_value»].pct_change(periods=1)
value[«market_return»] = list(stock[stock.coid == «Y9997»][«close_d»].pct_change(periods = 1)[25:])
value

Расчет ежедневной доходности

На следующем шаге мы будем использовать «daily_return» и «market_return» в качестве входных переменных, чтобы подогнать модель линейной регрессии для получения альфа и бета.X = np.array(value[«daily_return»].iloc[1:]).reshape(-1, 1)
y = np.array(value[«market_return»].iloc[1:])
regressor = LinearRegression()
regressor.fit(X, y)
w_0 = regressor.intercept_
w_1 = regressor.coef_

print(‘alpha : ‘, w_0)
print(‘beta : ‘, w_1)

Альфа- и бета-версии портфеля

Установим наше окно равным 60 дням, рассчитаем скользящие Альфа и Бета и визуализируем результат.window = 60
alpha = []
beta = []
mdate = []
for i in range(len(value) — window — 1):
X = np.array(value[«daily_return»].iloc[i+1 : i+1+window]).reshape(-1, 1)
y = np.array(value[«market_return»].iloc[i+1 : i+1+window])
regressor = LinearRegression()
regressor.fit(X, y)
w_0 = regressor.intercept_
w_1 = regressor.coef_
alpha.append(round(w_0, 5))
beta.append(w_1)
mdate.append(value.index[i+1+window])fig, ax1 = plt.subplots(figsize=[16, 9], constrained_layout=True)
ax1.plot(mdate, alpha, label = «Alpha»)
ax1_2 = ax1.twinx()
ax1_2.plot(mdate, beta, label = «Beta», color = «orange»)

Alpha_lines, Alpha_labels = ax1.get_legend_handles_labels()
Beta_lines, Beta_labels = ax1_2.get_legend_handles_labels()
ax1.legend(Alpha_lines + Beta_lines,
Alpha_labels + Beta_labels, loc=’upper right’)

ax1.set_xlabel(‘mdate’)
ax1.set_ylabel(‘Alpha’)
ax1_2.set_ylabel(‘Beta’)

Переезд Альфы и Бейта

Для более глубокого анализа мы рисуем два линейных графика, чтобы сравнить разницу между трендами каждой цели и рынка, а также вариацию индикаторов Aroon в период тестирования на истории.def make_plot(stock_df, aroon_dict, record_df, coid):
mdate = stock[stock.coid == «Y9997»].mdate

benchmark = stock[stock.coid == «Y9997»].close_d

AroonUp = aroon[aroon.coid == coid].AroonUp
AroonDown = aroon[aroon.coid == coid].AroonDown
aroon_date = aroon[aroon.coid == coid].mdate

fig, axes = plt.subplots(2,1, figsize=[16, 9], constrained_layout=True)

ax1 = axes[0]
stock[stock.coid == «Y9997»].set_index(«mdate»).close_d.plot(ax = ax1, label = «market return»)
ax1_2 = ax1.twinx()
stock[stock.coid == coid].set_index(«mdate»).close_d.plot(ax = ax1_2, label=f'{coid}_close’, color = «lime»)
stock[stock.coid == coid].set_index(«mdate»).open_d.plot(ax = ax1_2, label=f'{coid}_open’, color = «deeppink», alpha = 0.5)
ax1_2.scatter(df[df.coid == coid].mdate, df[df.coid == coid].DealPrice, label = «BuyOrSell», color = [«orange» if i == «Buy» else «purple» for i in df[df.coid == coid].BuyOrSell])

benchmark_lines, benchmark_labels = ax1.get_legend_handles_labels()
target_lines, target_labels = ax1_2.get_legend_handles_labels()

ax1.legend(benchmark_lines + target_lines,
benchmark_labels + target_labels, loc=’upper right’)
ax1.set_xlabel(‘mdate’)
ax1.set_ylabel(‘index’)
ax1_2.set_ylabel(f’price’)
ax1.set_title(f»{coid}_Aroon»)

ax2 = axes[1]
aroon[aroon.coid == coid].set_index(«mdate»).AroonUp.plot(ax = ax2, label = «AroonUp», color = «red»)
ax2_2 = ax2.twinx()
aroon[aroon.coid == coid].set_index(«mdate»).AroonDown.plot(ax = ax2_2, label = «AroonDown», color = «green»)

up_lines, up_labels = ax2.get_legend_handles_labels()
down_lines, down_labels = ax2_2.get_legend_handles_labels()

ax2.legend(down_lines + down_lines,
up_labels + down_labels, loc=’upper right’)
ax2.set_xlabel(‘mdate’)
ax2.set_ylabel(‘Aroon_indicator’)

fig.tight_layout()

plt.show()

Мы можем легко сгенерировать графики каждой цели, используя цикл for.
Обратите внимание, что, поскольку последним элементом stock.coid.unique() является идентификатор рынка «Y9997», наш диапазон цикла for не будет содержать последний элемент.for coid in stock.coid.unique()[:-1]:
make_plot(stock, aroon, value, coid)

2330 графиков

На первом графике синяя линия – это рыночный индекс, зеленая линия – цена закрытия цели, а розовая линия – цена открытия. Желтые точки – это точки покупки, а фиолетовые – точки продажи.
На втором графике красная линия – это индикатор Aroon-up, а зеленая линия – индикатор Aroon-down.

Сравните показатели портфеля с рыночными показателями

При расчете доходности портфеля и рыночных показателей мы обнаруживаем, что доходность первого превышает доходность второго примерно на 17 процентов.print(f’大盤總績效:{stock[stock.coid == «Y9997»].close_d.iloc[-1]/stock[stock.coid == «Y9997»].close_d.iloc[0] -1}’)
print(f’投資組合總績效:{value[«total_value»].iloc[-1]/value[«total_value»].iloc[0] -1}’)

Сравните показатели портфеля с рыночными показателями

Заключение

Изучив график Moving Alpha & Beta, мы можем сделать вывод, что наша стратегия, возможно, консервативна. Колебания Альфы и Беты умеренны; С другой стороны, собственные точки покупки и продажи каждой цели четко видны на первом графике каждой цели. Таким образом, мы можем проанализировать, какая цель в портфеле является основой прибыли. Кроме того, инвесторы могут свободно настраивать или настраивать торговую стратегию индикаторов Aroon в соответствии со своей собственной стратегией выбора акций, чтобы реализовать универсальную систему от выбора акций и автоматической торговли до оценки производительности.

И последнее, но не менее важное: обратите внимание, что «Акции, упомянутые в этой статье, предназначены только для обсуждения, пожалуйста, не считайте это какими-либо рекомендациями или предложениями по инвестициям или продуктам». Следовательно, если вас интересуют такие вопросы, как создание торговой стратегии, тестирование производительности, научно обоснованные исследования, добро пожаловать на покупку планов, предлагаемых в TEJ E Shop, и использовать полную базу данных для создания собственной оптимальной торговой стратегии.

Исходный код

https://medium.com/media/d5fb77be81d2e86d701a0a8d6b186506

Расширенное чтение

Ссылки по теме

Развертывание торговой стратегии Aroon Up Down на TQuant Lab

Индикатор Aroon, разработанный Тушаром Чанде в 1995 году, обычно используется для измерения рыночных тенденций. Он состоит из двух линий — Aroon Up и Aroon Down.

  • Aroon Up:((Кол-во периодов — Количество периодов с момента наивысшего максимума) / Количество периодов) * 100
    Этот индикатор измеряет периоды, прошедшие с момента достижения максимальной цены (максимума) в выбранном периоде.
  • Aroon Down:((Кол-во периодов — Количество периодов с самого низкого минимума) / Количество периодов) * 100
    Этот индикатор измеряет периоды, прошедшие с момента возникновения самой низкой цены (нижней точки) в выбранном периоде.

Индикатор Aroon Up измеряет силу и время, прошедшее с момента достижения максимальной цены в течение заданного периода (обычно 25 периодов). Напротив, индикатор Aroon Down измеряет силу и время с момента самой низкой цены за тот же период. Эти показатели выражаются в процентах и колеблются от 0% до 100%.

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

Торговая стратегия Aroon Up Down

Когда Aroon Up больше 80, а Aroon Down меньше 45, что представляет собой бычий тренд. Мы считаем это сигналом на покупку и приобретем одну единицу по цене завтрашнего открытия.

Когда Aroon Up меньше 45, Aroon Down больше 55, а разрыв двух индикаторов больше 15, мы расцениваем это как сигнал на продажу и продаем удерживающую позицию по завтрашней цене открытия.

Когда Aroon Up больше 55, Aroon Down меньше 45, разрыв между двумя показателями больше 15, наша инвестированная сумма не превышает 20% от основной суммы, и у нас все еще много денежных средств. Мы приобретем еще одну единицу по цене открытия завтрашнего дня.

Среда программирования и требуемый модуль

В качестве редактора используется MacOS и Jupyter Notebook

Импорт данных и модулей

Период тестирования на истории составляет период с 2018/01/01 по 2020/12/31, и мы берем Hon Hai Precision Industry (2317), Compal Electronics (2324), Yageo Corporation (2327), TSMC (2330), Synnex (2347), Acer (2353), FTC (2354), ASUS (2357), Realtek (2379), Quanta (2382) и Advantech (2395) для создания портфеля и сравнения производительности портфеля с бенчмарком — Total. Индекс возврата(IR0001), .import os
import pandas as pd
import numpy as np
import tejapios.environ[‘TEJAPI_KEY’] = ‘Your key’
os.environ[‘mdate’] = ‘20180101 20201231’
os.environ[‘ticker’] = ‘IR0001 2317 2324 2327 2330 2347 2353 2354 2357 2379 2382 2395’!zipline ingest -b tquantfrom zipline.api import set_slippage, set_commission, set_benchmark, attach_pipeline, order, order_target, symbol, pipeline_output, record
from zipline.finance import commission, slippage
from zipline.data import bundles
from zipline import run_algorithm
from zipline.pipeline import Pipeline, CustomFactor
from zipline.pipeline.filters import StaticAssets, StaticSids
from zipline.pipeline.factors import BollingerBands, Aroon
from zipline.pipeline.data import EquityPricing
from zipline.pipeline.mixins import LatestMixin
from zipline.master import run_pipeline

Установка бенчмарка

Во-первых, мы загружаем пакет, который мы только что приняли выше, и устанавливаем индекс возврата (coid : IR0001) в качестве эталона.bundle = bundles.load(‘tquant’)
ir0001_asset = bundle.asset_finder.lookup_symbol(‘IR0001’,as_of_date = None)

Создание функции конвейера

Pipeline() позволяет пользователям быстро обрабатывать данные, связанные с торговлей несколькими активами. В сегодняшней статье мы используем его для обработки:

  • Расчет Aroon-up, Aroon-down (встроенный коэффициент:Aroon)

def make_pipeline():
curr_price = EquityPricing.close.latest

alroon = Aroon(inputs = [EquityPricing.low, EquityPricing.high], window_length=25, mask = curr_price < 5000)
up, down = alroon.up, alroon.downreturn Pipeline(
columns = {
‘up’: up,
‘down’: down,
‘curr_price’: curr_price,},
screen = ~StaticAssets([ir0001_asset])
)

Создание функции инициализации

inintialize позволяет пользователям настраивать торговую среду в начале периода тестирования на истории. В этой статье мы настроим:

  • Проскальзывание
  • Комиссия
  • Установите индекс доходности в качестве эталона.
  • Прикрепите функцию Pipline() к тестированию на истории.

def initialize(context):
set_slippage(slippage.VolumeShareSlippage())
set_commission(commission.PerShare(cost=0.00285))
set_benchmark(symbol(‘IR0001’))
attach_pipeline(make_pipeline(), ‘mystrategy’)

Создание функции handle_date

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

По умолчанию торговые сигналы buysellимеют значение False

  • buy: Когда сегодняшние индикаторы соответствуют условию бай-ина, генерирует сигнал на покупку и переключает логическое значение на True
  • sell: Когда сегодняшние индикаторы соответствуют условию распродажи, генерирует сигнал на продажу и переключает логическое значение на True

def handle_data(context, data):
out_dir = pipeline_output(‘mystrategy’)
for i in out_dir.index:
sym = i.symbol # 標的代碼
up = out_dir.loc[i, ‘up’]
down = out_dir.loc[i, ‘down’]
curr_price = out_dir.loc[i, ‘curr_price’]cash_position = context.portfolio.cash
stock_position = context.portfolio.positions[i].amount
buy, sell = False, False
record(
**{
f’price_{sym}’:curr_price,
f’up_{sym}’:up,
f’down_{sym}’:down,
f’buy_{sym}’:buy,
f’sell_{sym}’:sell
}
)
if stock_position == 0:
if down < 45 and up > 80:
order(i, 1000)
context.last_signal_price = curr_price
buy = True
record(
**{
f’buy_{sym}’:buy
}
)
elif stock_position > 0:
if (up — down) > 15 and (down < 45) and (up > 55) and (cash_position >= curr_price * 1000):
order(i, 1000)
context.last_signal_price = curr_price
buy = True
record(
#globals()[f’buy_{sym}’] = buy
**{
f’buy_{sym}’:buy
}
)
elif (down — up > 15) and (down > 55) and (up < 45):
order_target(i, 0)
context.last_signal_price = 0
sell = True
record(
**{
f’sell_{sym}’:sell
}
)
else:
pass
else:
pass

Создание функции анализа

analyzeв основном используется для визуализации результата тестирования на истории. Поскольку в сегодняшней практике для визуализации будет использоваться pyfolio, мы просто оставим его пустым.def analyze(context, perf):
pass

Алгоритмы запуска

Мы используем run_algorithm() для реализации нашей стратегии. Период тестирования на истории установлен в период с 01.01.2018 по 31.12.2020. Мы используем пакет данных tquant. Мы предполагаем, что начальная база капитала составляет 1 000 000. Вывод run_algorithm(), который является результатомs, содержит информацию о ежедневных показателях и торговых поступлениях.results = run_algorithm(
start = pd.Timestamp(‘2018-01-01′, tz=’UTC’),
end = pd.Timestamp(‘2020-12-31′, tz =’UTC’),
initialize=initialize,
bundle=’tquant’,
analyze=analyze,
capital_base=10e6,
handle_data = handle_data
)
results

Запись транзакций

Визуализация

Перед визуализацией процесса необходимо разделить данные results на три части:

  • Возвращает
  • Позиции
  • Операций

from pyfolio.utils import extract_rets_pos_txn_from_zipline
returns, positions, transactions = extract_rets_pos_txn_from_zipline(results)# 時區標準化
returns.index = returns.index.tz_localize(None).tz_localize(‘UTC’)
positions.index = positions.index.tz_localize(None).tz_localize(‘UTC’)
transactions.index = transactions.index.tz_localize(None).tz_localize(‘UTC’)
benchmark_rets.index = benchmark_rets.index.tz_localize(None).tz_localize(‘UTC’)

Наконец, pyfolio.tears.create_full_tear_sheet можете создать несколько таблиц и диаграмм, которые помогут вам оценить эффективность портфеля.pyfolio.tears.create_full_tear_sheet(returns=returns,
positions=positions,
transactions=transactions,
benchmark_rets=benchmark_rets)

Исходный код

https://medium.com/media/3197b051f1e9aefa16240e58c2c311d1

Заключение

Сегодняшняя практика использует TQuant Lab для развертывания торговой стратегии Aroon Up Down. С привлечением TQuant Lab сложность и сложность программы значительно снизились. TQuant Lab предоставляет пользователям более подробные параметры и индикаторы для создания тщательно продуманной торговой стратегии.

И последнее, но не менее важное: обратите внимание, что «Акции, упомянутые в этой статье, предназначены только для обсуждения, пожалуйста, не считайте это какими-либо рекомендациями или предложениями по инвестициям или продуктам». /b10> Следовательно, если вы заинтересованы в таких вопросах, как создание торговой стратегии, тестирование производительности, научно обоснованные исследования, добро пожаловать на покупку планов, предлагаемых в TEJ E Shop и используйте полную базу данных для создания собственной оптимальной торговой стратегии.

Расширенное чтение

Ссылки по теме

Источник

Источник