100 строк Python-кода: Автоматизируем биржевую торговлю

Алгоритмическая торговля

Алгоритмическая торговля (алготрейдинг, algorithmic trading) – это автоматизированная с помощью компьютерных средств торговля финансовыми инструментами на основе определенного алгоритма или правила с незначительным участием или без участия человека. Торговать в автоматическом режиме можно почти любыми финансовыми инструментами: акциями, валютами, сырьем, кредитными продуктами или волатильностью. В некоторых сегментах рынка львиная доля сделок совершается именно алгори («The Quants») Скотта Паттерсона (Scott Patterson) и «More Money Than God» Себастиана Маллаби (Sebastian Mallaby) дают хорошее представление об алгоритмической торговле и личностях, стоявших у ее истоков.

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

  • • Программное обеспечение с открытым исходным кодом. Все инструменты, необходимые трейдеру, чтобы начать алгоритмическую торговлю, доступны под свободными лицензиями. В частности, Python и его экосистема приобрели статус стандарта в этой области.
  • • Открытые источники данных. Появляется все больше открытых источников ценных данных. Благодаря этому, трейдеры получают широкие возможности для проверки гипотез и тестирования торговых стратегий.
  • • Торговые онлайн-платформы. В настоящее время существует множество онлайн-платформ, которые предоставляют простой стандартизированный доступ к историческим данным (посредством RESTful API), данным реального времени (посредством socket API), а также обеспечивают широкий спектр средств для торговли и работы с портфелями (посредством программного API).

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

Рассмотрим основные составляющие проекта:

  • • Стратегия. Мы выбрали моментум-стратегию (momentum strategy), представленную в публикации Moskowitz et al. «Time Series Momentum», 2012. В рамках данной стратегии мы предполагаем, что финансовый инструмент, демонстрировавший в прошлом определенную (позитивную или негативную) тенденцию, в дальнейшем будет следовать этой же тенденции.
  • • Платформа. Мы остановили свой выбор на платформе Oanda. Данная платформа позволяет торговать различные контракты на разницу цен (contract for difference, CFD), что, по сути, позволяет оперировать широким спектром финансовых инструментов, таких как валюты, фондовые индексы, сырье и др.
  • • Данные. Все исторические данные и данные реального времени для нас обеспечит платформа Oanda.
  • • Программное обеспечение. Мы будем использовать Python, мощную аналитическую библиотеку Pandas, а также несколько дополнительных библиотек.

В дальнейшем мы предполагаем, что у вас установлен Python 3.5 и основные библиотеки, такие как NumPy и Pandas. Если у вас еще нет этих средств, вы можете установить все необходимое, используя, например, дистрибутив Anaconda.

Аккаунт Oanda

На платформе Oanda (https://oanda.com) любой желающий может бесплатно зарегистрировать демо аккаунт, обеспечивающий доступ к имитации торгового процесса. После того, как аккаунт зарегистрирован, чтобы получить программный доступ к Oanda API, необходимо установить соответствующую Python-библиотеку:

pip install oandapy

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

[oanda] account_id = YOUR_ACCOUNT_ID access_token = YOUR_ACCESS_TOKEN

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

Выполнив следующий код, мы получаем основной объект для программного взаимодействия с платформой:

In [1]: import configparser # 1 import oandapy as opy # 2 config = configparser.ConfigParser() # 3 config.read(‘oanda.cfg’) # 4 oanda = opy.API(environment=’practice’, access_token=config[‘oanda’][‘access_token’]) # 5

У нас уже есть все необходимое, чтобы начать тестирование моментум-стратегии. В частности, мы можем получить исторические данные, предоставляемые платформой. Мы будем использовать инструмент EUR_USD, основанный на обменном курсе EUR/USD.

Первым делом мы загружаем набор исторических данных и преобразуем его в DataFrame. Мы получаем дынные за два дня: 8 и 9 декабря 2016 года. Дискретность данных составляет 1 минуту. Выполним следующий код:

In [2]: import pandas as pd # 6 data = oanda.get_history(instrument=’EUR_USD’, # our instrument start=’2016-12-08′, # start data end=’2016-12-10′, # end date granularity=’M1′) # minute bars # 7 df = pd.DataFrame(data[‘candles’]).set_index(‘time’) # 8 df.index = pd.DatetimeIndex(df.index) # 9 df.info() # 10

В результате получим подробную характеристику набора данных:

DatetimeIndex: 2658 entries, 2016-12-08 00:00:00 to 2016-12-09 21:59:00 Data columns (total 10 columns): closeAsk 2658 non-NULL float64 closeBid 2658 non-NULL float64 complete 2658 non-NULL bool highAsk 2658 non-NULL float64 highBid 2658 non-NULL float64 lowAsk 2658 non-NULL float64 lowBid 2658 non-NULL float64 openAsk 2658 non-NULL float64 openBid 2658 non-NULL float64 volume 2658 non-NULL int64 dtypes: bool(1), float64(8), int64(1) memory usage: 210.3 KB

Далее мы формализуем моментум-стратегию, вычисляя для каждого момента времени среднее логарифма доходности (mean log return) за последние 15, 30, 60 и 120 минут. Например, среднее логарифма доходности за последние 15 минут – это среднее 15 последних значений логарифма доходности. Если эта величина положительна, мы играем на повышение (go/stay long), если отрицательна – на понижение (go/stay short). Чтобы не усложнять код, мы полагаемся лишь на значение столбца closeAsk.

In [3]: import numpy as np # 11 df[‘returns’] = np.log(df[‘closeAsk’] / df[‘closeAsk’].shift(1)) # 12 cols = [] # 13 for momentum in [15, 30, 60, 120]: # 14 col = ‘position_%s’ % momentum # 15 df[col] = np.sign(df[‘returns’].rolling(momentum).mean()) # 16 cols.append(col) # 17

Затем, чтобы вычислить абсолютную результативность моментум-стратегий, основанных на различных временных интервалах, необходимо умножить доходность на величины, полученные выше (предварительно выполнив сдвиг). Вот как мы это сделаем:

In [4]: %matplotlib inline import seaborn as sns; sns.set() # 18 strats = [‘returns’] # 19 for col in cols: # 20 strat = ‘strategy_%s’ % col.split(‘_’)[1] # 21 df[strat] = df[col].shift(1) * df[‘returns’] # 22 strats.append(strat) # 23 df[strats].dropna().cumsum().apply(np.exp).plot() # 24

Получим следующую диаграмму:

Проанализировав диаграмму, мы видим, что в течение рассматриваемого периода, сам инструмент имеет отрицательную доходность около -2%. Моментум-стратегия, основанная на 120-минутных интервалах, показывает наилучший результат, демонстрируя положительную доходность около 1.5% (без учета разницы между спросом и предложением (bid/ask spread)). По сути, данная стратегия показывает «реальную альфу»: она обеспечивает положительную доходность даже тогда, когда сам инструмент имеет отрицательную доходность.

Этап 1.1. Изучение основ Python для торгового робота

Обучение по приложению от SoloLearn.

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

Прохождение курса на Stepik.org «Программирование на Python»

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

Совет: Некоторые условия задач описаны очень непонятно, в связи с этим сразу смотрите в комментарии, там найдете разъяснение задачи.

В день рекомендую уделять этому ресурсу 1 час.

Ссылка на курс: https://stepik.org/course/67/syllabus

Решение задач в Pythontutor.ru

Для закрепления знаний полезным будет ресурс Pythontutor. Это интерактивный учебник по Python, с большим количеством примеров и хорошими задачами. Интересная особенность в том, что после решения задачи можно посмотреть варианты решений от разработчиков и других участников.

Ежедневно рекомендую решать хотя бы по одной задаче.

Ссылка на учебник: https://pythontutor.ru/

Книги: Swaroop — «A Byte of Python»(Укус питона)

«Укус питона» это бесплатная книга по Python, отличается минимальным количеством «воды» и большим количеством примеров. Содержит всего 150 страниц, при этом отлично показывает возможности языка.

Популярные торговые роботы, боты для торговли на бирже криптовалюте

Совет: При чтении книг по программированию необходимо запускать пример кода у себя в IDE для лучшего усвоения материала.

В день достаточно читать по 5-10 страниц. В качестве IDE рекомендую бесплатный PyCharm Community.

По желанию: Видео курсы по Python на YouTube

Серия видеоуроков средней продолжительностью в 10 минут, состоящая из 21 эпизода поможет заполнить пробелы в полученных ранее знаниях.

Для знающих английский очень хорошо будет просмотеть курс Learn Python — Full Course for Beginners. В общей сложности материал состоит из четырех с половиной часов обучающего видео.

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

В интернете множество методик и материалов для изучения английского, каждый сможет подобрать подходящее для себя, но не откажусь порекомендовать книгу по грамматике Раймонда Мерфи — Essential Grammar in Use. Написана полностью на английском, но предельно простым языком и со множеством иллюстраций.

Автоматическая торговля

Выбрав торговую стратегию, мы можем полностью автоматизировать торговые операции. Чтобы ускорить процесс, мы используем данные с дискретностью 5 секунд, вместо 1 минуты, как было при тестировании. Автоматизировать торговлю можно с помощью одного достаточно компактного класса:

In [5]: class MomentumTrader(opy.Streamer): # 25 def __init__(self, momentum, *args, **kwargs): # 26 opy.Streamer.__init__(self, *args, **kwargs) # 27 self.ticks = 0 # 28 self.position = 0 # 29 self.df = pd.DataFrame() # 30 self.momentum = momentum # 31 self.units = 100000 # 32 def create_order(self, side, units): # 33 order = oanda.create_order(config[‘oanda’][‘account_id’], instrument=’EUR_USD’, units=units, side=side, ENGINE=’market’) # 34 print(‘\n’, order) # 35 def on_success(self, data): # 36 self.ticks += 1 # 37 # print(self.ticks, end=’, ‘) # appends the new tick data to the DataFrame object self.df = self.df.append(pd.DataFrame(data[‘tick’], index=[data[‘tick’][‘time’]])) # 38 # transforms the time information to a DatetimeIndex object self.df.index = pd.DatetimeIndex(self.df[‘time’]) # 39 # resamples the data set to a new, homogeneous interval dfr = self.df.resample(‘5s’).last() # 40 # calculates the log returns dfr[‘returns’] = np.log(dfr[‘ask’] / dfr[‘ask’].shift(1)) # 41 # derives the positioning according to the momentum strategy dfr[‘position’] = np.sign(dfr[‘returns’].rolling( self.momentum).mean()) # 42 if dfr[‘position’].ix[-1] == 1: # 43 # go long if self.position == 0: # 44 self.create_order(‘buy’, self.units) # 45 elif self.position == -1: # 46 self.create_order(‘buy’, self.units * 2) # 47 self.position = 1 # 48 elif dfr[‘position’].ix[-1] == -1: # 49 # go short if self.position == 0: # 50 self.create_order(‘sell’, self.units) # 51 elif self.position == 1: # 52 self.create_order(‘sell’, self.units * 2) # 53 self.position = -1 # 54 if self.ticks == 250: # 55 # close out the position if self.position == 1: # 56 self.create_order(‘sell’, self.units) # 57 elif self.position == -1: # 58 self.create_order(‘buy’, self.units) # 59 self.disconnect() # 60

Следующий фрагмент кода запускает класс MomentumTrader на выполнение. Расчет моментум-стратегии выполняется на основе интервалов по 12 наблюдений. Класс автоматически прекращает торговлю после получения 250 блоков данных. Это значение выбрано произвольно, чтобы быстро продемонстрировать работу класса MomentumTrader.

In [6]: mt = MomentumTrader(momentum=12, environment=’practice’, access_token=config[‘oanda’][‘access_token’]) mt.rates(account_id=config[‘oanda’][‘account_id’], instruments=[‘DE30_EUR’], ignore_heartbeat=True)

Вывод, представленный ниже, показывает отдельные торговые операции, выполняемые классом MomentumTrader, в процессе демонстрации:

{‘price’: 1.04858, ‘time’: ‘2016-12-15T10:29:31.000000Z’, ‘tradeReduced’: {}, ‘tradesClosed’: [], ‘tradeOpened’: {‘takeProfit’: 0, ‘id’: 10564874832, ‘trailingStop’: 0, ‘side’: ‘buy’, ‘stopLoss’: 0, ‘units’: 100000}, ‘instrument’: ‘EUR_USD’} {‘price’: 1.04805, ‘time’: ‘2016-12-15T10:29:46.000000Z’, ‘tradeReduced’: {}, ‘tradesClosed’: [{‘side’: ‘buy’, ‘id’: 10564874832, ‘units’: 100000}], ‘tradeOpened’: {‘takeProfit’: 0, ‘id’: 10564875194, ‘trailingStop’: 0, ‘side’: ‘sell’, ‘stopLoss’: 0, ‘units’: 100000}, ‘instrument’: ‘EUR_USD’} {‘price’: 1.04827, ‘time’: ‘2016-12-15T10:29:46.000000Z’, ‘tradeReduced’: {}, ‘tradesClosed’: [{‘side’: ‘sell’, ‘id’: 10564875194, ‘units’: 100000}], ‘tradeOpened’: {‘takeProfit’: 0, ‘id’: 10564875229, ‘trailingStop’: 0, ‘side’: ‘buy’, ‘stopLoss’: 0, ‘units’: 100000}, ‘instrument’: ‘EUR_USD’} {‘price’: 1.04806, ‘time’: ‘2016-12-15T10:30:08.000000Z’, ‘tradeReduced’: {}, ‘tradesClosed’: [{‘side’: ‘buy’, ‘id’: 10564875229, ‘units’: 100000}], ‘tradeOpened’: {‘takeProfit’: 0, ‘id’: 10564876308, ‘trailingStop’: 0, ‘side’: ‘sell’, ‘stopLoss’: 0, ‘units’: 100000}, ‘instrument’: ‘EUR_USD’} {‘price’: 1.04823, ‘time’: ‘2016-12-15T10:30:10.000000Z’, ‘tradeReduced’: {}, ‘tradesClosed’: [{‘side’: ‘sell’, ‘id’: 10564876308, ‘units’: 100000}], ‘tradeOpened’: {‘takeProfit’: 0, ‘id’: 10564876466, ‘trailingStop’: 0, ‘side’: ‘buy’, ‘stopLoss’: 0, ‘units’: 100000}, ‘instrument’: ‘EUR_USD’} {‘price’: 1.04809, ‘time’: ‘2016-12-15T10:32:27.000000Z’, ‘tradeReduced’: {}, ‘tradesClosed’: [{‘side’: ‘buy’, ‘id’: 10564876466, ‘units’: 100000}], ‘tradeOpened’: {}, ‘instrument’: ‘EUR_USD’}

На рисунке ниже показано приложение Oanda fxTrade Practice, где мы видим класс MomentumTrader в действии.

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

Зачем нужно Open API Тинькофф Инвестиции

Возможностей много.

  • Можно заниматься алготрейдингом. Можно через вебхуки связать Тинькофф Инвестиции с TradingView и торговать используя стратегии тамошних пользователей.
  • Можно анализировать свои сделки выгружая их в нужный формат. Например в Google Sheets (как делаю я).
  • Можно настроить алерты в мессенжер. Например в Телеграм (как делаю я).
  • Можно тестировать свои стратегии в бесплатной песочнице.
  • Можно разрабатывать торговых роботов на заказ (чем я бы хотел попробовать позаниматься в перспективе)
  • … и это только то что я знаю или смог придумать
Рейтинг
( 1 оценка, среднее 4 из 5 )
Понравилась статья? Поделиться с друзьями: