- PVSM.RU - https://www.pvsm.ru -
Обычно в статьях про финтех пишут о том, как работают биржи, которые обрабатывают огромные объемы данных на огромных скоростях, о том, как гениальные трейдеры и кванты используют отточенные алгоритмы, чтобы зарабатывать (или терять, бывает всякое) миллиарды долларов, или о работе блокчейна, обеспеченной сложными математическими выкладками. Все это создает впечатление, будто уровень входа в финтех-разработку запредельно высок. И отчасти оно правдиво — требования к разработчикам высоконагруженных финансовых приложений строги и специфичны.
Но все начинали с малого, и мы считаем, что любой заинтересованный человек способен создать приложение в финансовой сфере. Попробуем разработать собственное небольшое приложение, которое станет полезным для пользователей уже через полчаса.
Из обзоров современных технологий [1] взаимодействия с пользователями видно, как быстро набирают популярность всевозможные боты и помощники, понимающие запросы на естественном языке. Поддержим этот тренд и создадим простого Telegram-бота, который сможет что-то рассказать пользователю о рынке по запросу.
Начнем с простой ситуации: приложение будет использовать текущие и исторические данные о торгах, а не отправлять на биржу собственные заявки. Эти данные (т. н. market data [2], или биржевую информацию) можно получать у ряда компаний за относительно небольшую плату или вообще бесплатно. С отправкой заявок все заметно сложнее (как минимум — дороже), и мы рассмотрим этот процесс подробнее в следующих статьях.
Какие существуют технологии для получения биржевых данных? Список их не слишком велик: это FIX-протокол [3] (реализации могут немного различаться от поставщика к поставщику), FAST [4], ITCH и несколько вариантов бинарных и HTTP API (к примеру, CQG, EXANTE или MOEX). Впрочем, универсализация здесь не так принципиальна: набор предоставляемых данных может сильно различаться, и в любом случае при интеграции придется разобраться с особенностями конкретного поставщика.
Мы будем использовать недавно появившийся EXANTE Market Data API [5]: начать разработку с ним можно просто и быстро, регистрация в системе не требует дополнительных подтверждений, а доступ к данным бесплатен. Пока API работает в режиме Tech Preview, но доступ открыт для всех желающих.
Определив спектр возможностей, нужно решить, что именно будет делать наш чат-бот. Существует масса вариантов: от отображения курсов валют до аналитики торговых стратегий по запросу на конкретный биржевой инструмент. Пока что не станем углубляться в детали финансовых алгоритмов и попробуем сделать что-то полезное, но при этом достаточно простое.
Один из самых понятных финансовых инструментов — это акции компаний, торгующиеся на фондовых биржах. С ними и будем работать, выбрав для простоты фондовый рынок США, т. к. по нему легче всего получить фундаментальные данные, и торги там наиболее активны.
Что интересует начинающего инвестора? Конечно же, выбор портфеля акций, вложив средства в которые, он сможет получить прибыль. Существует много способов выбирать акции: можно читать обзоры [6], можно ориентироваться на портфели лучших инвесторов, вроде Уоррена Баффетта [7] или Билла Экмана [8], а можно пользоваться аналитическими методами. Один из общепринятых и самых распространенных методов — это оценка компании по метрике P/E (коэффициент цена/прибыль [9]). P/E рассчитывается как отношение нынешней цены акции компании к показателю Earning Per Share (EPS, прибыль на акцию).
Таким образом, наш чат-бот будет помогать инвестору решить, включать ли акции определенной компании фондового рынка США в свой портфель, исходя из текущей оценки коэффициента цена/прибыль. Высокий P/E относительно других компаний этой отрасли покажет, что у акций есть потенциал роста. Низкий же, напротив, даст понять, что в будущем компания может столкнуться с проблемами.
Итак, в качестве основного источника биржевой информации выберем EXANTE Market Data API (MD API). Для получения фундаментальной информации — информации об общем состоянии финансов компании — будем использовать открытый источник данных datatables.org [10], с которым можно работать через YQL (Yahoo! Query Language).
Для реализации самого бота возьмем Python 3, а чтобы запустить его максимально быстро, применим фреймворк, поддерживающий все необходимые методы Telegram: python-telegram-bot [11].
Для работы с Telegram будем использовать поллинг новых сообщений с сервера, т. к. в прототипе мы не рассчитываем на большой объем трафика.
Заранее подумаем о том, чтобы приложение могло работать не только с одним клиентом. Для этого будем обрабатывать запросы в отдельных потоках. Для синхронизации и запуска потоков используем встроенные возможности фреймворка python-telegram-bot и примитивы синхронизации, доступные в Python.
Все выбранные внешние сервисы доступны по HTTP, так что для работы с ними будем использовать известный модуль Requests [12].
Наверняка многие инвесторы будут интересоваться одними и теми же акциями, которые на слуху, так что добавим слой кэширования, чтобы эффективнее использовать ресурсы.
MD API требует авторизации запросов с помощью JSON Web Token [13], для генерации токенов возьмем библиотеку PyJWT [14].
Для начала работы с MD API нужно зарегистрироваться на сайте EXANTE для разработчиков [15].
После регистрации на портале становится доступным дэшборд с данными для доступа и управлением приложениями. Создадим там приложение для нашего бота:
Самого бота заведем так, как описано в документации к Telegram, через переписку с роботом BotFather [16]:
Начнем с того, что научим бота обрабатывать полученные запросы. Из каждого сообщения будем пытаться выделить тикеры акций и выдавать по ним информацию, чтобы диалог мог выглядеть так:
— Привет, робот, сегодня в новостях слышал об AAPL, кажется, это какая-то фруктовая компания, думаю вложить туда деньги, что скажешь?
— Акции AAPL (Apple Inc, биржа NASDAQ) имеют текущую оценку P/E 14, цена акции $117,06
— Спасибо, а что насчет NVDA и GOOG?
— NVDA (Nvidia Corp., NASDAQ): P/E 69, цена $105.7
GOOG (Alphabet Inc., NASDAQ): P/E 29, цена $796.42
Инициализируем бота и создаем обработчики сообщений:
# -*- coding:utf-8 -*-
import re
from sys import path
from configparser import ConfigParser
from telegram import ParseMode, Emoji
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters
config = ConfigParser()
config.read_file(open('config.ini'))
# Create telegram poller with token from settings
up = Updater(token=config[‘Api’]['token'])
dispatcher = up.dispatcher
# Welcome message
def start(bot, update):
msg = "Hello {user_name}! I'm {bot_name}. Ask me about stocks!"
# Send the message
bot.send_message(chat_id=update.message.chat_id,
text=msg.format(
user_name=update.message.from_user.first_name,
bot_name=bot.name))
def process(bot, update):
msg = "I will try to show info on {tickers}"
tickers = re.findall(r'[A-Z]{1,4}', update.message.text)
bot.send_message(chat_id=update.message.chat_id,
text=msg.format(tickers=", ".join(tickers)))
def main():
# Add handlers to dispatcher
dispatcher.add_handler(CommandHandler("start", start))
dispatcher.add_handler(MessageHandler(Filters.text, process))
# Start the program
up.start_polling()
up.idle()
if __name__ == '__main__':
main()
Сейчас наш бот уже умеет выделять тикеры акций, но ничего больше с ними сделать не может.
Напишем интерфейс для работы с Market Data API и генерации токенов. Используем документацию [5] и руководство по авторизации [17].
import jwt
# token expiration time in seconds
EXPIRATION = 3600
class MDApiConnector():
token = (None, None)
algo = "HS256"
def __init__(self, client_id, app_id, key):
self.client_id = client_id
self.app_id = app_id
self.key = key
def __get_token(self):
now = datetime.now()
# if there is token and it's not expired yet
if self.token[0] and (now - self.token[1]).total_seconds() < EXPIRATION:
return self.token[0]
claims = {
"iss": self.client_id,
"sub": self.app_id,
"aud": ["symbols", "ohlc"], # NB: only allowed scopes can be accessed
"iat": int(now.timestamp()),
"exp": int(now.timestamp()) + EXPIRATION
}
new_token = str(jwt.encode(claims, self.key, self.algo), ‘utf-8’)
self.token = (new_token, now)
return new_token
Полный код всех модулей доступен в репозитории: github.com/exante/telegram-bot-with-md-api [18]
Добавим отдельный поток, который будет периодически запрашивать объемные данные по акциям:
class DataStorage(Thread):
def __init__(self, connector):
super().__init__()
self.connector = connector
self.stocks = {}
def run(self):
while True:
timeout = 15 * 60 # 15 minutes
try:
self.stocks = connector.get_stocks()
except Exception as e:
logger.error(e)
timeout = 30 # re-read in case of exception
time.sleep(timeout)
Метод работы с API для получения списка акций США может выглядеть так:
def get_stocks(self):
stocks = self.__request("/types/STOCK")
return {x['ticker']: {"id": x["id"],
"exchange": x["exchange"],
"description": x["description"]}
for x in stocks if x.get("country") == "US"}
После запуска этого потока и обращения к нему из обработчика сообщения, бот сможет вывести больше полезных данных (P/E здесь пока еще заглушка):
Добавим запрос Earning Per Share, для этого сделаем небольшую обертку над YQL с кэшированием (в скором будущем мы сможем заменить этот вызов на аналогичный из MD API), которая запросит значение «EarningsShare» для выбранной акции.
Теперь мы можем вывести полученный показатель EPS:
Осталось последнее: получить текущую цену акции. Для большей производительности нам следовало бы подписаться на поток обновлений с ценами, но для прототипа можно выбрать более простой способ: запрашивать последнюю дневную «свечу» — так называют элемент графика цен [19], популярного среди трейдеров.
Пример свечного графика соотношения индекса DJI и цены на золото по годам
«Свеча» строится для определенного периода (например, дня или часа) и на одном рисунке объединяет четыре цифры: цену на начало периода, максимальную и минимальную цену за период и цену на момент окончания периода. Сокращение OHLC, обозначающее такую свечу, как раз и расшифровывается как Open-High-Low-Close. Цена Close самой последней свечи будет соответствовать текущей цене акции.
Метод получения последней свечи может выглядеть так:
def get_last_ohlc_bar(self, symbolId):
# NB: we use internal symbolId, not ticker
# 86400 (sec) - day duration
ohlc = self.__request("/ohlc/%s/86400" % symbolId, {"size": 1})
return ohlc[0]
Собрав вместе все вызовы, мы получим такой код обработки одного тикера:
stock = storage.stocks.get(ticker)
eps = fundamendal_api.request(ticker).get('EarningsShare')
price = api.get_last_ohlc_bar(stock['id'])
ratio = Decimal("%.4f" % price['close']) / Decimal(eps)
msg = "{ticker} ({name}, {exchange}): EPS {eps}, P/E {ratio}, цена ${price} n".format(
ticker = ticker,
name = stock['description'],
exchange = stock['exchange'],
ratio = "%.2f" % ratio,
price = price['close'],
eps = eps
)
И теперь наш бот стал действительно полезен! Он может рассказать о текущем положении дел на рынке акций и даже кое-что посоветовать:
Текущий проект можно найти по адресу github.com/exante/telegram-bot-with-md-api [18]
Дальнейшее развитие возможно по многим направлениям. К примеру, можно воспользоваться потоком данных о нынешней цене акции из MD API (/md/1.0/feed
) и не запрашивать цену каждый раз из «свечек», а просто брать ее из внутреннего кэша, куда та будет попадать при обновлении потока.
Можно добавить боту мониторинг и аналитику (например через botan.io [20]), а также развернуть его на каком-нибудь облачном
Бота можно сделать более «живым», добавив больше вариантов ответов, а также научить его отображать графики изменения цен, чтобы дать инвестору еще больше информации для анализа. Можно добавить любые другие метрики для оценки акций, сохранять портфель в данных робота, чтобы держать инвестора в курсе всех изменений, и расширить функциональность — например, на российский рынок акций.
Подключив EXANTE Market Data API и воспользовавшись открытой фундаментальной информацией, за короткий срок мы разработали функционального робота, который поможет пользователю быстро оценить ситуацию на рынке. В процессе работы мы узнали о некоторых способах оценки акций на рынке и о терминологии, используемой в биржевой торговле.
Кроме того, мы рассмотрели возможности развития, и даже у такого небольшого робота их немало. Есть еще много способов применения market data — и много пользователей, которые заинтересуются вашими финансовыми приложениями.
В феврале EXANTE проведет хакатон, посвященный работе с рыночными данными с помощью EXANTE Market Data API. Авторы лучших чат-ботов и приложений получат призы, и сейчас как раз есть время подготовиться :) Подробнее о мероприятии напишем чуть позже.
А какие API используете вы? Что бы вы хотели делать с рыночными данными?
Автор: EXANTE
Источник [22]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/224602
Ссылки в тексте:
[1] обзоров современных технологий: https://habrahabr.ru/company/exante/blog/316584/
[2] market data: https://en.wikipedia.org/wiki/Market_data
[3] FIX-протокол: https://ru.wikipedia.org/wiki/Financial_Information_eXchange
[4] FAST: https://en.wikipedia.org/wiki/FAST_protocol
[5] EXANTE Market Data API: https://developers.exante.eu/api/
[6] обзоры: https://ru.insider.pro/investment/2016-12-12/akcii-kotorye-sdelayut-vas-bogatym-v-2017-godu/
[7] Уоррена Баффетта: https://ru.insider.pro/investment/2016-11-23/7-luchshih-akcij-v-portfele-uorrena-baffetta/
[8] Билла Экмана: https://ru.insider.pro/investment/2016-11-18/sobiraem-portfel-kak-u-billa-ekmana/
[9] коэффициент цена/прибыль: https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D1%8D%D1%84%D1%84%D0%B8%D1%86%D0%B8%D0%B5%D0%BD%D1%82_%D1%86%D0%B5%D0%BD%D0%B0/%D0%BF%D1%80%D0%B8%D0%B1%D1%8B%D0%BB%D1%8C
[10] datatables.org: https://datatables.org/
[11] python-telegram-bot: https://github.com/python-telegram-bot/python-telegram-bot
[12] Requests: http://docs.python-requests.org/en/master/
[13] с помощью JSON Web Token: https://developers.exante.eu/tutorials/auth-basics/
[14] PyJWT: https://github.com/jpadilla/pyjwt
[15] EXANTE для разработчиков: https://developers.exante.eu/
[16] переписку с роботом BotFather: https://tlgrm.ru/docs/bots
[17] руководство по авторизации: http://developers.exante.eu/tutorials/auth-basics/
[18] github.com/exante/telegram-bot-with-md-api: https://github.com/exante/telegram-bot-with-md-api
[19] графика цен: https://ru.wikipedia.org/wiki/%D0%AF%D0%BF%D0%BE%D0%BD%D1%81%D0%BA%D0%B8%D0%B5_%D1%81%D0%B2%D0%B5%D1%87%D0%B8
[20] botan.io: http://botan.io/
[21] хостинге: https://www.reg.ru/?rlink=reflink-717
[22] Источник: https://habrahabr.ru/post/318272/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.