Талиб, Питон и индикаторы. Всё просто

О чем пойдет речь

В этой статье мы мельком коснемся индикаторов, и, на примере биржи Полоникс, построим такие же, используя язык программирования Python и библиотеку TA-Lib.

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

Вступление. Индикаторы

Торговля была бы намного проще и приятнее, если бы вы знали будущее. Вы бы закупались в нужный момент, и продавали на самом пике.. Знакомая мысль?

Тысячи людей пытались найти закономерности рынка, выстроить математические модели для расчета падения и роста курса, кое-кто потратил на это почти всю жизнь, и многие более-менее приблизились к решению. Более-менее - это значит что они теперь знают о бирже немного больше других. Но, когда вопрос касается денег, даже 0.5% знания могут принести серьезные дивиденды... Если эти знания истинны, конечно.

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

Довольно воды - давайте рассмотрим на простых примерах, и подумаем, как мы можем это использовать в автоматизированной торговле.

Вот перед нами окно Полоникса – сейчас выбрана пара BTC-ETH, период 24 часа, свечи по 5 минут. Мы видим соответственно сами свечи (как они строятся, мы уже разбирали), за ними затененные столбики то ли серого, то ли светло-зеленого цвета – объемы торгов по паре (сколько было вбухано денег при том курсе), и кучу разноцветных полос тут и там. Так вот эти полосы как раз отображают посчитанные данные некоторых индикаторов, которые можно использовать при торговле.

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

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

MACD тоже неплохо разобран везде – и на вики, и на нашем сайте есть видео, тоже немного процитирую:

Чаще всего индикатор используют для выявления торговых сигналов при боковом движении цен — периоды стабилизации курса после повышения или понижения (консолидация).
Обычно сигналом «Покупать» считают, когда скользящая с меньшим периодом (на рисунке синяя линия) в нижней зоне пересекает снизу вверх скользящую с бо́льшим периодом (красная линия). Сигналом «Продавать» считают, когда скользящая с меньшим периодом в верхней зоне пересекает сверху вниз скользящую с бо́льшим периодом.
При росте гистограммы (предыдущий столбик гистограммы ниже следующего), независимо от положения гистограммы выше или ниже нуля усиливается сила быков (игроков на повышение), это сигнал для сделок на повышение. При падении гистограммы (предыдущий столбик гистограммы выше следующего), усиливается сила медведей (игроков на понижение), это сигнал для сделок на понижение.

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

Так же маленький хинт – на графике полоникса сверху слева есть шестеренка – вы можете нажать её и поиграться с настройкой индикаторов.

Пишем код

Подготовка

Для работы нам потребуется библиотека для научных расчетов numpy, библиотека TA-Lib и модуль requests. Так же понадобится пакет matplotlib, с его помощью мы будем рисовать графики. Ну и установленный Python, конечно. У меня установлен Python 3.5.2 разрядность 32.


Реклама:


  1. В командной строке пишем и выполняем команды
pip install numpy

pip install requests

pip install matplotlib
  1. Скачиваем и устанавливаем набор для TA-Lib (вот прямая ссылка на архив, вот ссылка на страницу, где можно скачать последнюю версию в разделе Windows). После скачивания архива нужно его распаковать на диск C в папку ta-lib. Должно получиться так – C:\ta-lib\, а в этой папке уже папки C, Excel, java и т.п.
  2. В командной строке выполнить pip install ta-lib

Подготовка окончена.

Для начала построим график

Полоникс предоставляет публичный API-метод для построения графика – дает цены открытия, закрытия, минимальной и максимальной цены за период, сгруппированный по указанным периодам. Метод returnChartData, пример можно посмотреть по ссылке. Мы будем использовать эти данные, что бы

  1. Построить график
  2. Сформировать индикаторы

График будем строить по паре BTC-ETH, за прошедшие 24 часа с группировкой по 5 минут. Для этого напишем небольшой скрипт. Если нужны данные по другим парам, меняйте в коде BTC_ETH на что вам угодно.

import numpy
import talib
import requests
import json
import time

from matplotlib.finance import candlestick2_ohlc
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import datetime as datetime

start_time = time.time() - 24*60*60
resource = requests.get("https://poloniex.com/public?command=returnChartData&currencyPair=BTC_ETH&start=%s&end=9999999999&period=300" % start_time)
data = json.loads(resource.text)

quotes = {}
quotes['open']=numpy.asarray([item['open'] for item in data])
quotes['close']=numpy.asarray([item['close'] for item in data])
quotes['high']=numpy.asarray([item['high'] for item in data])
quotes['low']=numpy.asarray([item['low'] for item in data])

xdate=[datetime.datetime.fromtimestamp(item['date']) for item in data]

fig, ax = plt.subplots()

candlestick2_ohlc(ax,quotes['open'],quotes['high'],quotes['low'],quotes['close'],width=0.6)

ax.xaxis.set_major_locator(ticker.MaxNLocator(6))

def chart_date(x,pos):
    try:
        return xdate[int(x)]
    except IndexError:
        return ''

ax.xaxis.set_major_formatter(ticker.FuncFormatter(chart_date))

fig.autofmt_xdate()
fig.tight_layout()

plt.show()

При запуске он будет выдавать предупреждение MatplotlibDeprecationWarning: The finance module has been deprecated in mpl 2.0 and will be removed in mpl 2.2. Please use the module mpl_finance instead., но не обращайте на него внимание, он просто предупреждает, что в будущем код надо писать по другому. Но что бы писать прямо сейчас такой код, как он хочет, надо скачивать отдельные библиотеки, подключать их.. В общем, не берите в голову.

Итак, мы запустили код, и что мы видим? Хм, график! Совпадают данные с полониксом? Ага)

Добавим индикаторов

Но в самом графике смысла нет – его можно и так смотреть на полониксе. Давайте попробуем построить данные для индикатора?

На Полониксе в верхней части используются SMA и EMA – давайте начнем с чего-то одного. Значит так, SMA строится с интервалом в 50 минут? Оок. Немного меняем скрипт:

import numpy
import talib
import requests
import json
import time

from matplotlib.finance import candlestick2_ohlc
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import datetime as datetime

start_time = time.time() - 24*60*60
resource = requests.get("https://poloniex.com/public?command=returnChartData&currencyPair=BTC_ETH&start=%s&end=9999999999&period=300" % start_time)
data = json.loads(resource.text)

quotes = {}
quotes['open']=numpy.asarray([item['open'] for item in data])
quotes['close']=numpy.asarray([item['close'] for item in data])
quotes['high']=numpy.asarray([item['high'] for item in data])
quotes['low']=numpy.asarray([item['low'] for item in data])

xdate=[datetime.datetime.fromtimestamp(item['date']) for item in data]

fig, ax = plt.subplots()

candlestick2_ohlc(ax,quotes['open'],quotes['high'],quotes['low'],quotes['close'],width=0.6)

ax.xaxis.set_major_locator(ticker.MaxNLocator(6))

def chart_date(x,pos):
    try:
        return xdate[int(x)]
    except IndexError:
        return ''

ax.xaxis.set_major_formatter(ticker.FuncFormatter(chart_date))

fig.autofmt_xdate()
fig.tight_layout()

sma = talib.SMA(quotes['close'], timeperiod=50)
print(sma)
ax.plot(sma)

plt.show()

Работает… Так же обратили внимание, что в коде есть строка print(sma)? Я специально в отладочную консоль вывел посчитанные данные:

В «нормальной» жизни вам (наверное) не нужны графики – вам нужны именно эти цифры. Т.е. ваш бот может получать такой массив данных, и понимать – тренд растет, либо тренд падает, цена биржи пересекает тренд снизу вверх или сверху вниз и т.п… Но в этой статье мы рисуем графики для визуализации принципа, поэтому пока-что мы их анализировать не будем.. И print() писать тоже)

Так же график начинается не с начала, а с некоторым интервалом – но тут все просто. Мы берем данные за 24 часа, поэтому в начале работы скрипту нечего считать – мы же ведь за 50 минут строим? Это легко поправить, но я не хочу усложнять код и объяснять, почему и как усложнил, сути это не поменяет.

Теперь надо добавить EMA с периодом в 30 минут. Дополняем код:

import numpy
import talib
import requests
import json
import time

from matplotlib.finance import candlestick2_ohlc
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import datetime as datetime

start_time = time.time() - 24*60*60
resource = requests.get("https://poloniex.com/public?command=returnChartData&currencyPair=BTC_ETH&start=%s&end=9999999999&period=300" % start_time)
data = json.loads(resource.text)

quotes = {}
quotes['open']=numpy.asarray([item['open'] for item in data])
quotes['close']=numpy.asarray([item['close'] for item in data])
quotes['high']=numpy.asarray([item['high'] for item in data])
quotes['low']=numpy.asarray([item['low'] for item in data])

xdate=[datetime.datetime.fromtimestamp(item['date']) for item in data]

fig, ax = plt.subplots()

candlestick2_ohlc(ax,quotes['open'],quotes['high'],quotes['low'],quotes['close'],width=0.6)

ax.xaxis.set_major_locator(ticker.MaxNLocator(6))

def chart_date(x,pos):
    try:
        return xdate[int(x)]
    except IndexError:
        return ''

ax.xaxis.set_major_formatter(ticker.FuncFormatter(chart_date))

fig.autofmt_xdate()
fig.tight_layout()

sma = talib.SMA(quotes['close'], timeperiod=50)
ax.plot(sma)

ema = talib.EMA(quotes['close'], timeperiod=20)
ax.plot(ema)

plt.show()

Мне, в целом, нравится. Но надо больше графиков!

Разделяем графики

Теперь я хочу добавить MACD, но он на этот график не ложится – там совсем другие значения, слишком маленькие. Все просто, сейчас мы будем рисовать сразу ТРИ графика с одной и той-же осью X. На первом графике мы оставим всё как есть, на второй вынесем линию MACD и сигнальную, а на третью – гистограмму MACD. Конечно, можно уместить все в двух графиках, как на Полониксе, но так просто нагляднее.

Меняем код:

import numpy
import talib
import requests
import json
import time

from matplotlib.finance import candlestick2_ohlc
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import datetime as datetime

start_time = time.time() - 24*60*60
resource = requests.get("https://poloniex.com/public?command=returnChartData&currencyPair=BTC_ETH&start=%s&end=9999999999&period=300" % start_time)
data = json.loads(resource.text)

quotes = {}
quotes['open']=numpy.asarray([item['open'] for item in data])
quotes['close']=numpy.asarray([item['close'] for item in data])
quotes['high']=numpy.asarray([item['high'] for item in data])
quotes['low']=numpy.asarray([item['low'] for item in data])

xdate=[datetime.datetime.fromtimestamp(item['date']) for item in data]

fig, ax = plt.subplots(3, sharex=True)

candlestick2_ohlc(ax[0], quotes['open'],quotes['high'],quotes['low'],quotes['close'],width=0.6)

ax[0].xaxis.set_major_locator(ticker.MaxNLocator(6))

def chart_date(x,pos):
    try:
        return xdate[int(x)]
    except IndexError:
        return ''

ax[0].xaxis.set_major_formatter(ticker.FuncFormatter(chart_date))

fig.autofmt_xdate()
fig.tight_layout()

sma = talib.SMA(quotes['close'], timeperiod=50)
ax[0].plot(sma)

ema = talib.EMA(quotes['close'], timeperiod=20)
ax[0].plot(ema)

macd, macdsignal, macdhist = talib.MACD(quotes['close'], fastperiod=12, slowperiod=26, signalperiod=9)
ax[1].plot(macd, color="y")
ax[1].plot(macdsignal)

hist_data = []
for elem in macdhist:
    if not numpy.isnan(elem):
        v = 0 if numpy.isnan(elem) else elem
        hist_data.append(v*100)
ax[2].fill_between([x for x in range(len(macdhist))], 0,macdhist)

plt.show()

Ну что ж, теперь на втором графике рисуются линии MACD, на третьем – гистограмма.. Если хотите гистограмму отправить на второй график, поменяйте ax[2].fill_between на ax[1] .fill_between и т.п.

Заключение

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

Если разберетесь с этим, сможете строить и комбинировать свои индикаторы в тех комбинациях, в которых сочтете нужными. Полный список индикаторов, поддерживаемых библиотекой, вы можете найти тут. Обратите внимание, что в разные функции нужно передавать разные параметры, а так же некоторые возвращают один набор данных (EMA, например), а некоторые - несколько (MACD, например, возвращает сразу три)

А я желаю вам удачи и процветания, и не стесняйтесь задавать вопросы в комментариях ;)

Тэги: