Как написать торгового робота на python

Время на прочтение
4 мин

Количество просмотров 110K

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

Покроем следующие моменты:

  • Суть биржевой игры;
  • Брокеры;
  • API для торговли/Пример робота;
  • Деплоймент онлайн;
  • Заключительные мысли.

Суть биржевой игры

Есть много теорий и объяснений. Но мы подойдем к вопросу с точки зрения софтверщика и понятия об уровнях абстракции. Очень просто (но вместе с тем правдиво) суть игры в следующем: есть график некоей (псевдо?) случайной величины (цены). Известна её история за довольно большой период. Стоит задача предсказания движения (вверх или вниз). Всё. Реально. То, что делают трейдеры — предсказывают, пойдет цена вверх или вниз и делают на это ставки (оpen trades): покупают (buy/long) какое-то количество «продукта» (instrument) в надежде на поход вверх, или продают (sell/short) в надежде, что пойдет вниз.
После какого-то времени (если цена изменилась значительно) open trades закрывают и получают в результате прибыть (угадали с движением) или убыток (не угадали).

Сделку можно закрыть руками, а можно автоматичеки (order): можно заранее задекларировать — если цена достигнет такого-то уровня, то закрыть trade.

Доступ к рынку для совершения сделок предоставляет брокер. И за это он взимают плату за каждую сделку.

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

Всё верно, так всё и есть. Игра началась.

Брокеры

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

Я не буду давать сравнительный анализ. Сразу дам лучшего — Oanda. Почему Oanda:

  • Репутация;
  • Возможность открыть сделку в 1 доллар и нет требований к размеру trade (некоторые брокеры обязывают делать его кратным большим величинам);
  • Низкая цена за сделки (узкий spread);
  • Огромное количество инструментов: валюты, драг металлы и нефть, индексы;
  • Возможность торговать через API;
  • Ввод вывод денег возможен через PayPal.

Для того, чтобы торговать, надо создать учетную запись на Oanda. Для начала — тренировочную (fxtrade practice). В меню «Manage API Access» нужно указать, что на вашем счету возможна торговля через API. После этого вам сгенерят секретный токен для использования в RESTful вызовах.

API для торговли

image

developer.oanda.com/docs — RESTful
Примеры: developer.oanda.com/docs/v1/code-samples

Я буду использовать Python 2.7 и библиотеку requests.

Для того, чтобы торговать, нам нужно:

Получать информацию о цене. Робот должен знать, что происходит

def connect_to_stream():
    try:
        s = requests.Session()
        url = "https://stream-fxpractice.oanda.com/v1/prices"
        headers = {'Authorization' : 'Bearer ' + "YOUR TOKEN",
                   #'X-Accept-Datetime-Format' : 'unix'
                  }
        params = {'instruments' : "EUR_USD,AUD_JPY", 'accountId' : "YOUR ACC ID"}
        req = requests.Request('GET', url, headers = headers, params = params)
        pre = req.prepare()
        resp = s.send(pre, stream = True, verify = False, timeout=20)
        return resp
    except Exception as e:
        s.close()
        print "Caught exception when connecting to streamn" + str(e) 

Эта функция позволит соединиться к потоку цен на EUR/USD и AUD/JPY.

Теперь мы можем их считывать:

 try: #infinite loop on receiving events about price. on each tick Strategy function is called
         for line in response.iter_lines(1):
             if line:
                 msg = json.loads(line)         
                 if msg.has_key("instrument") or msg.has_key("tick"): 
                       strategy(msg['tick']['instrument'], msg['tick']['time'], msg['tick']['ask'])
    except Exception as e:
         print "something gone bad " +str(e)
         return

Теперь нам нужен мозг. Принятие решений

image

Как видно, в функцию стратегии передается информация о названии инструмента, цена и время.
Мы можем решать в функции strategy: а что нам делать с этой новой инфой? Проигнорировать? Или, может, открыть новую сделку?

Вот здесь пригодится, что вы — программист. Изобретайте! Есть числовой ряд — ищете закономерности, анализируйте, да всё, что угодно.

Допустим, робот подумал и сказал: точно цена пойдет вверх! Чувствую своей shiny metal ass!

Тогда нам нужна возможность заключить сделку

def order(instr, take_profit, stop_loss):
    try:
         url = "https://" + "api-fxpractice.oanda.com" + "/v1/accounts/"+"YOUR ACC"+"/orders"
        
         headers = {'Authorization' : 'Bearer ' + "YOUR TOKEN",
                    #'X-Accept-Datetime-Format' : 'unix'
                    "Content-Type" : "application/x-www-form-urlencoded"
                  }
    
         params = urllib.urlencode({
                                    "instrument" : instr,           # инструмент, по которому открывает сделку
                                    "units" : 10,                       # сколько единиц покупаем
                                    "type" : 'market',                # прям сейчас исполнить!
                                    "side" : "buy",                     #  считаем, что цена пойдет вверх ("sell"  если думаем что вниз)
                                    "takeProfit" : take_profit     #   насколько цена должна пройти вверх, чтобы наша жадность удовлетворилась, и мы закрыли бы сделку. и считали профит
                                    "stopLoss" : stop_loss       # насколько цена может опуститься, прежде чем наш страх скажет "ты чё?!! дальше только хуже будет. закрывай немедля. фиг с ними с потерями"
                                    	})
                                	
         req =requests.post(url, data=params, headers=headers)
         for line in req.iter_lines(1):
          print "order responce: ", line
    except Exception as e:
         print "Caught exception when connecting to ordersn" + str(e) 

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

Деплоймент онлайн

Открыл для себя наличие vps по бросовым ценам. Например, ftpit.com. Взял тот, что за 2 доллара в месяц.
Этот хостиг без проблем держит на себе 3-х моих роботов, которые день и ночь пытаются одолеть толстосумов с Wall Street. Плюс к этому есть свой SMTP server и небольшой сайт.

Заключительные мысли

Торговля на финансовых рынках может стать замечательным хобби, которое не только дает возможность программировать, но и приобщиться к огромной онлайн игре, в которой каждый день много новостей, мнений, событий, страха, жадности и надежды!

Если у вас есть вопросы — отвечу с радостью и в меру сил.

image

UPDATE

Очень рекомендую оставаться на practice account хотя бы 1 год
не торопитесь вводить настоящие деньги
если Вы будете видеть, что у вас прям «прёт» и все получается, то просто замониторьте счет вот здесь — forexfactory.com
если будет стабильный результат даже на демо счете — инвесторы сами вас будут искать и предлагать деньги в управление

UPDATE 2

Вспомнил кто еще любил сыграть на финасовых рынках — сэр Исаак Ньютон (тот самый :))

Привет! На связи команда Тинькофф Инвестиций. В этой статье рассказываем про Tinkoff Invest API, объясняем, как написать робота на Python, и разбираем плюсы этого языка в сравнении с другими. А вместо заключения ловите гайд по созданию робота на примере работы победителя нашего конкурса Tinkoff Invest Robot Contest.

Почему Python

Когда хочется попробовать алготрейдинг, но нет глубоких знаний языков программирования, Python станет хорошим стартом. Этот язык самый популярный: через него исполняется более 8 миллионов запросов в сутки. Вдвое больше, чем у SDK на Java — второго по популярности.

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

  • Часть брокеров позволяет клиентам подключаться через протоколы FIX/FAST, но для этого робот должен поддерживать этот протокол. В open source есть ряд библиотек, разработанных энтузиаcтами, и многие из них поддерживаются авторами.

  • Некоторые брокеры предоставляют современные открытые API, не требующие дополнительных библиотек или ПО.

Tinkoff Invest API — это интерфейс для взаимодействия с торговой платформой Тинькофф Инвестиций

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

В Tinkoff Invest API можно не только торговать, но и собирать данные для анализа. А еще есть песочница для регулировки и отладки стратегий на реальных котировках. Но обо всем по порядку.

Протокол и типы данных

Понять принципы структур и взаимодействие с ними помогает изучение протоколов и типов данных, используемых в API. Мы стараемся следовать рекомендациям Google и используем протоколы и типы данных, о которых расскажем ниже. Tinkoff Invest API поддерживает три протокола — gRPC, gRPC web и REST. Подробно об этом мы рассказывали в прошлой статье:

API для Инвестиций, или Как написать торгового робота

На связи команда Тинькофф Инвестиций. В этой статье разберем, как клиенты с минимальными навыками пр…

habr.com

Через Tinkoff Invest API можно получить набор типов данных:

  • Текущие режимы торгов на бирже.

  • Список поручений других клиентов биржи на покупку и продажу — биржевой стакан.

  • Ленту сделок в режиме реального времени.

  • Биржевые свечи — исторические и текущие, в режиме реального времени. Свеча показывает, как менялась цена актива за определенный период. Это визуальное отображение цены открытия, закрытия, максимума и минимума и объема торгов за определенный промежуток, от минуты до суток.

  • Информацию по торговым инструментам — акциям, облигациям, фьючерсам, опционам, ETF и другим.

  • Данные о своих позициях, портфеле, списке операций, брокерском отчете и многое другое.

TINKOFF INVEST API позволяет выставить разные типы заявок. Мы собрали в документации описание зависимости рыночных или лимитных заявок от статуса торгов. Каждый тип заявки описали на сайте и дополнили примерами. Вот короткая справка.

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

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

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

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

Лимитная заявка — указание брокеру, какую бумагу или валюту, сколько лотов и по какой цене нужно купить или продать.

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

Заявка «Лучшая цена» — заявка на покупку или продажу активов по цене, которая есть на бирже в данный момент, но с защитным механизмом. Цена на бирже меняется ежесекундно, и, чтобы не отменять сделку при каждом таком изменении, брокер дополнительно блокирует на счете примерно 0,3% от суммы заявки. Если цена изменится в худшую сторону, заявка автоматически отменится, а деньги вернутся на счет.

Еще в Tinkoff Invest API мы используем нестандартные типы данных по рекомендации Google. Расскажем подробнее про каждый.

Timestamp — основной тип для передачи времени в формате protoсol-buffers. Это значение в диапазоне интервала дат от 0001-01-01T00:00:00Z до 9999-12-31T23:59:59.999999999Z. Timestamp всегда работает в формате UTC с нулевым смещением и состоит из двух полей целого типа: seconds и nanos.

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

  • currency — строковый ISO-код валюты, например RUB или USD;

  • units — целая часть суммы;

  • nano — дробная часть суммы, миллиардные доли единицы.

Quotation — тип, аналогичный MoneyValue, но без информации о валюте. Параметры типа — units и nano. Для корректной работы с ним требуется конвертация в стандартные типы языка программирования, который используется для написания торгового робота. Для Python это преобразование описано в utils. 

Как сделать робота

Если вы планируете создать робота самостоятельно, план прост:

  1. Станьте нашим клиентом и создайте токен доступа.

  2. Протестируйте взаимодействие с Tinkoff Invest API через gRPC-клиенты или наш swagger.

  3. Скачайте исторические рыночные данные по инструментам в виде архива. Для загрузки истории котировок можно воспользоваться специальным методом или подготовленными скриптом и справочником figi.

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

  5. Переведите робота на боевой контур.

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

Tinkoff Trading Bot — реализована простая интервальная стратегия. Несложный код поможет начинающим разработчикам быстро запустить, проверить и доработать торговую стратегию под свои цели. Простое ведение статистики через sqllite. Любой желающий может дописывать свои стратегии. Интерфейс простой — только init и start. Фабрика на старте использует стратегии, опираясь на файл конфигурации. Параллельно может работать несколько стратегий для разных figi. Автор робота — @qwertyo

InvestRobot — понятный для запуска робот. В качестве демонстрации представлена одна торговая стратегия, основанная на индикаторе двух скользящих средних. Автор робота — @karpp

Робот на основе объемного анализа для Тинькофф Инвестиций — кластерный анализ и профиль рынка позволяет определить действительную заинтересованность участников рынка, реализован один из методов работы с профилем рынка — реакция на максимальный горизонтальный объем внутри дня за выбранный период. Автор робота — @rteslenko

Вместо заключения — план создания робота на примере работы победителя

  1. Переходим на Tinkoff Trading Bot.

  2. Клонируем ссылку на репозиторий.

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

  4. Вставляем и выполняем команду:

git clone </span><a href="https://github.com/qwertyo1/tinkoff-trading-bot.git" style="text-decoration:none;"><span style="font-size:11pt;font-family:Arial;color:#1155cc;background-color:transparent;font-weight:400;font-style:italic;font-variant:normal;text-decoration:underline;-webkit-text-decoration-skip:none;text-decoration-skip-ink:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">https://github.com/qwertyo1/tinkoff-trading-bot.git</span></a><span style="font-size:11pt;font-family:Arial;color:#000000;background-color:transparent;font-weight:400;font-style:italic;font-variant:normal;text-decoration:none;vertical-align:baseline;white-space:pre;white-space:pre-wrap;">
  1. Следуем инструкции из репозитория:

Hidden text

  • Generate token for your account at the settings #Создаем токен для своего аккаунта в настройках.

  • Create a file .env with required env variables. You can find an example in .env.example #из файла .env.example делаем файл .env и придаем заданным переменным свои значения.

    • Create a file instuments_config.json with configurations. You can find an example in instruments_config.json.example #из файла instruments_config.json. делаем файл instuments_config.json. Для легкого старта советуем изменить значение параметра figi на BBG333333333 — «Тинькофф iMOEX».

  • Далее выполняем следующие команды для создания и запуска виртуального окружения:

    pip install virtualenv
    virtualenv --python=python3.9 venv
    source venv/bin/activate
  • Устанавливаем зависимости

    pip install -r requirements.txt

  • Робот запрашивает свечи за последние 10 дней и высчитывает коридор с низшей и высшей ценой. И в случае пересечения границы коридора робот выставляет заявки на покупку или продаж.

  • Ждем профит!

Earlier this week, we explored how code has drastically changed financial markets through the use of autonomous trading algorithms. Surprisingly, building your own trading bot is actually not that difficult! 

In this tutorial, we’re going to be using Python to build our own trading bot.

Keep in mind that this tutorial is not about how to make billions off of your trading bot. If I had an algorithm that sophisticated I probably wouldn’t be giving it away. Rather, I’m going to show you how you can read market data, buy and sell stocks, and program the logic of your trading algorithm, all with some relatively simple Python code.

And of course:
This article is for information purposes only. It is not intended to be investment advice. Seek a duly licensed professional for investment advice.

You can open up a quick demo of the project on Codesphere here:

https://codesphere.com/#https://github.com/LiorB-D/TradingBot

However, you will need an API key before you can actually start trading with our bot - More on that later.


Some Helpful Terms

Before we get started, it’ll be helpful to define a couple of terms:

  • Paper Trading: The trading of securities with fake money for educational or testing purposes.
  • Backtesting: Testing a trading algorithm against past market data in order to evaluate its effectiveness.
  • Moving Average: The average of a certain amount of recent entries in a set of data.
  • S&P 500: A stock market index composed of the 500 largest companies listed on US stock exchanges
  • Closing Price: The final price of a security during a unit of time
  • Good ‘Til Cancel (GTC): When you place a trade, it may not be met right away. A broker will continue to try and execute a GTC trade until you cancel it.

Setup

The trading API we’re going to be using is called Alpaca and is by far one of the most intuitive trading APIs I’ve found.

https://alpaca.markets/

In its free tier, Alpaca includes both Paper and Real Trading and both Historical and Live market data. It also has an incredibly clean user interface and Python library.

In addition, unless you’re willing to leave your python script running on your computer, you’re going to need to deploy your trading bot in the cloud. For this, we’re going to use Codesphere:

https://codesphere.com

Since Codesphere’s front-end is an IDE, we can develop our bot directly on the platform. If you wish to do the coding on your local machine, however, you can connect your GitHub repo to Codesphere and deploy afterward.

The only environment setup we really need before we can start coding is to create our pip environment:

pipenv shell

And then install the Alpaca API

pipenv install alpaca_trade_api

We are also going to need to make a free Alpaca account and then navigate to our Paper Trading Account.

Alt Text

Notice your API Key on the right-hand side. When you first open your account, you will be prompted to generate a key and both public and private key will be shown to you. We’re going to need those for later.

Buying and Selling Stocks

We can then set up our Alpaca Trading library and buy and sell stocks in Python like so:

Our Strategy

The strategy we’re going to use is to buy and sell whenever the 5 minute moving average crosses our price. Now, this is FAR from a good trading strategy, but the logic is relatively simple and will allow us to focus on the general structure of a trading bot.

Alt Text

In the above example, the red line is the stock price and the blue line is the moving average. When the moving average crosses under our price, we are going to buy a share of our stock. We are then going to hold the stock until the moving average crosses again and goes above the price. When that happens we are going to sell our share, and then wait for the next buying signal.

In this article, we’ll be trading SPY, which is an index that tracks the S&P 500, and we will only be trading one stock at a time.

Keep in mind that if you were to make these trades with real money, you would have to comply with day trading regulations and brokerage fees, which would likely offset your gains.

Reading Market Data

Now let’s go over how to read market data using the Alpaca API in Python:

If you’re looking for more in-depth information for when you build your strategy, check out Alpaca’s documentation:
https://alpaca.markets/docs/api-documentation/api-v2/market-data/alpaca-data-api-v2/

Executing Our Strategy

Now let’s finally put all of this together for our complete trading algorithm:

And there we have it! We just built a trading bot in 54 lines of code! Now if we leave this running on Codesphere throughout the day, we should see our Alpaca dashboard update throughout the day:

Alt Text

Backtesting a Strategy

Now if you don’t want to wait around to see if your algorithm is any good, we can use Alpaca’s market data API to backtest our Python algorithm against historical data:

Next Steps

So there you have it, we just created a rudimentary trading bot with some fairly simple Python!

Here is the full repo:
https://github.com/LiorB-D/TradingBot

While I highly encourage you guys to play around with the Alpaca API for educational purposes, be extremely careful if you are going to trade real securities. One bug in your code could have disastrous effects on your bank account.
On a lighter note, this is a great opportunity to put those statistics classes you took to work.


Comment down below if you’re going to build your own trading algorithm!

Happy Coding from your folks at Codesphere, the next generation cloud provider

Шаг 1. Установка необходимых библиотек

Нам потребуется набор библиотек и инструментов для приложений. Для этого мы будем использовать такие библиотеки как NumPy, Pandas и Scikit-learn. Чтобы установить их, можно использовать команду pip:

pip install numpy pandas scikit-learn

Шаг 2. Настройка веб-фреймворков

Для создания веб-интерфейса для вашего бота мы будем использовать фреймворки Flask и Django. Чтобы установить их, можно использовать команду pip:

pip install flask django

Шаг 3. Создание алгоритма торговли

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

Шаг 4. Подключение бота к торговой платформе

Чтобы подключить бота к торговой платформе, мы можем использовать API-интерфейсы для подключения бота к различным криптовалютным биржам, таким как Coinbase, Binance или Kraken.

Шаг 5. Запуск бота

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

Второй алгоритм

  • Начните с установки установки библиотек Python: NumPy, Pandas и Scikit-learn, которые помогут преобразовывать данные и использовать алгоритмы машинного обучения.
  • Далее установите фреймворки для разработки приложений, такие как Flask и Django, чтобы создать веб-интерфейс для вашего бота.
  • Следующим шагом будет проектирование алгоритма для торговли. Для этого установите параметры и выберите алгоритм машинного обучения для идентификации точки входа и выхода из торговой пары.
  • Для отслеживания активности торговли и просмотра динамики цен установите аналитические платформы, такие как Plotly или Bokeh, чтобы визуализировать данные и определить, как конкретные параметры влияют на торговые решения.
  • Затем подключите бота к торговой платформе с помощью API-интерфейсов, таких как Coinbase, Binance или Kraken.
  • После этого вы можете протестировать алгоритм торговли и проверить точность предсказания с помощью различных аналитических платформ.
  • Наконец, запустите бота на торговой платформе и начните торговать. Отслеживайте ситуацию и делайте регулярные изменения в настройках бота, чтобы он мог адаптироваться к изменениям на рынке.

1 Шаг: Установить библиотеки и инструменты для приложения, такие как NumPy, Pandas и Scikit-learn. Эти библиотеки предоставят инструменты для анализа и аналитики, которые будут необходимы для создания торгового бота. Настройте интерпретатор Python, чтобы вы могли использовать инструменты и библиотеки, необходимые для разработки приложения.

2 Шаг: Выбрать фреймворк для разработки приложений, например, Flask или Django. Эти фреймворки предоставят идеальные инструменты для разработки веб-решений и интерфейсов. Сконфигурируйте фреймворк и интерпретатор Python, чтобы они могли работать вместе для разработки приложения.

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

4 Шаг: Используйте аналитические платформы, такие как Plotly или Bokeh, чтобы визуализировать данные и понять, как влияют конкретные параметры на решения по торговле. Настройте аналитические платформы, чтобы они могли отображать данные так, как вы хотите.

5 Шаг: Подключите бота к торговой платформе используя API-интерфейсы, доступные для бирж криптовалют, таких как Coinbase, Binance или Kraken. Настройте API-интерфейсы, чтобы бот мог получать данные о рынке и выполнять торговые операции на вашей платформе. Вы можете также создать интерфейс для отслеживания производительности бота и просмотра торговых историй.

6 Шаг: Проверьте работу бота, чтобы убедиться, что он правильно использует данные и правильно использует алгоритмы, которые вы проектировали. Если вы недовольны работой бота, вы можете изменить алгоритмы и проверить работу бота заново. Также проверьте, что бот правильно отвечает на данные биржи и не делает неправильные торговые действия.

7 Шаг: Проведите тестирование бота для проверки его надежности и стабильности. Проверьте производительность бота на различных платформах и проверьте его способность корректно обрабатывать данные. Также проверьте скорость бота и его способность адаптироваться к изменениям рынка. Если бот не удовлетворяет вашим требованиям, продолжайте править алгоритмы и тестировать бота, пока он не будет работать как надо.

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

Создание торгового бота на Python: шаг первый — установка необходимых библиотек

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

Установка Python

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

Установка библиотек

Для работы с торговым ботом нам потребуются следующие библиотеки:

  • Pandas — это библиотека для анализа и обработки данных. Она позволяет работать с различными типами данных, включая таблицы, матрицы и даже временные ряды.
  • Numpy — это библиотека для работы с массивами и матрицами. Она позволяет выполнять различные математические операции и предоставляет инструменты для анализа данных.
  • Matplotlib — это библиотека для визуализации данных. Она позволяет создавать различные графики и диаграммы, которые могут быть использованы для анализа данных.
  • Scikit-learn — это библиотека для машинного обучения. Она предоставляет инструменты для обучения моделей машинного обучения и применения их для анализа данных.
  • TensorFlow — это библиотека для глубокого обучения. Она предоставляет инструменты для обучения нейронных сетей и применения их для анализа данных.

Для установки библиотек можно воспользоваться пакетным менеджером pip. Для этого необходимо открыть командную строку и выполнить следующую команду:

pip install pandas numpy matplotlib scikit-learn tensorflow

Эта команда установит все необходимые библиотеки.

Установка дополнительных инструментов

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

Для установки этих инструментов можно воспользоваться пакетным менеджером pip. Для этого необходимо открыть командную строку и выполнить следующую команду:

pip install <имя инструмента>

Например, для установки инструмента для автоматической сборки кода необходимо выполнить следующую команду:

pip install make

Заключение

На первом этапе процесса создания торгового бота на Python мы установили необходимые библиотеки и инструменты. Теперь мы можем перейти к следующему этапу — подготовке данных.

Если вы знакомы с финансовым рынком и владеете 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 (http://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)). По сути, данная стратегия показывает «реальную альфу»: она обеспечивает положительную доходность даже тогда, когда сам инструмент имеет отрицательную доходность.

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

Выбрав торговую стратегию, мы можем полностью автоматизировать торговые операции. Чтобы ускорить процесс, мы используем данные с дискретностью 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, внести необходимые средства, и изменить параметры аккаунта в коде. Сам код изменять не нужно.

Заключение

В данной статье мы рассмотрели быстрый старт в алгоритмической торговле, для которого требуется менее 100 строк Python-кода. Мы обсудили все основные этапы реализации подобных проектов: получение исторических данных для тестирования, тестирование стратегии, автоматизация торговых операций на основе выбранной стратегии. Представленный код является отправной точкой, откуда можно двигаться в различных направлениях. Например, можно использовать различные стратегии, задействовать различные инструменты или работать с несколькими инструментами одновременно.

О популярности алгоритмической торговли свидетельствует появление различных типов торговых платформ. Например, создатели Quantopian – онлайн-платформы для тестирования стратегий алгоритмической торговли – сообщили в конце 2016 года о привлечении более 100000 пользователей. Торговые онлайн-платформы, подобные Oanda, а также специализирующиеся на криптовалюте, такие как Gemini, позволяют очень быстро начать торговлю на реальном рынке, присоединившись к тысячам трейдеров, живущих во всех точках земного шара.

Можно ли с помощью ИИ автоматизировать набор правил, по которым действуют на бирже профессиональные трейдеры? Команда VK Cloud Solutions перевела статью о том, как это удалось реализовать и что вышло из такой затеи.

Как появилась идея автоматизации

Пару недель назад я болтал с приятелем. Он рассказывал мне, что пытался устроить детокс от брокерского приложения на смартфоне. Я забеспокоился, не разорился ли он, и уточнил значение слова «детокс» в этом контексте. 

Он ответил, что занимается трейдингом. «Если какая-то ценная бумага растет на протяжении часа и я уже заработал более 1%, я ее продаю, — объяснил он. — Это одно из моих персональных правил». Не обращая внимания на псевдонаучный аспект этих правил, я понял, что он имел в виду под детоксом. Чтобы соблюдать такие правила, нужно постоянно заглядывать в смартфон.

И я задумался, можно ли автоматизировать набор правил, по которым действовал мой приятель? Чтобы система занималась трейдингом вместо меня? Вы наверняка уже догадались, что ответ на этот вопрос — «да». Что ж, давайте порассуждаем. 

Но для начала: время — деньги, и я не хочу никого разводить на деньги. Вот что мы сделаем:

  1. Возьмем детализированные данные о ценах на акции в реальном времени, в идеале с интервалом в одну минуту. Чем их больше, тем лучше. Используем для этого Yahoo! Finance, подробнее объясню ниже.

  2. Вместо персонального набора правил добавим в систему ИИ. Раскрою все карты. Я, мягко говоря, не эксперт по анализу временных рядов. Сейчас есть немало руководств по обучению нейронных сетей трейдингу, и мне совершенно не хочется усложнять игрушечную систему вроде этой. Так что давайте стремиться к простоте: пока нам хватит самой базовой модели ARIMA.

  3. У нас есть данные и прогноз, который мы получаем от алгоритма. С его помощью нужно решать, что делать с акциями: покупать, продавать или сохранять. А еще нужно подключиться к брокеру, чтобы выполнять нужные действия. Мы будем использовать RobinHood и Alpaca.

  4. Вот, собственно, и все — система готова. Осталось только где-то деплоить и отслеживать ее работу. Я решил, что система будет отправлять сообщение в телеграм-чат при выполнении какого-либо действия.

Что нам понадобится?

  • Python 3.6 с несколькими библиотеками;

  • учетная запись в облаке с правами администратора для хранения и деплоймента;

  • Node.js, чтобы установить Serverless Framework для деплоймента;

  • аккаунт в телеграме для мониторинга.

Весь написанный код — здесь. Без лишних церемоний перейдем к первой части — сбору данных.

Сбор данных

Собрать данные — дело непростое. Еще несколько лет назад были доступны официальный Yahoo! Finance API и его альтернатива Google Finance. К сожалению, оба сервиса закрылись несколько лет назад. Но остались альтернативы. Я сформулировал следующие требования:

  • Бесплатно. Для рабочей системы я бы, конечно, поменял это требование на «недорого», но для игрушечной системы данные мне нужны бесплатно.

  • Высокая скорость. Желательно вообще без ограничений, но производительности свыше 500 запросов в минуту более чем достаточно.

  • Данные в реальном времени. Некоторые API выдают данные с небольшой задержкой, скажем, в 15 минут. Мне нужны цены на акции, максимально приближенные к текущим.

  • Простота использования. Это проверка идеи, так что мне нужно самое простое решение.

С учетом своих требований я решил присмотреться к yfinance — неофициальной альтернативе старого доброго Yahoo Finance API. Для рабочей системы я бы выбрал Alpha Vantage API, опираясь на замечательный список Патрика Коллинза. Но пока давайте не усложнять. 

Ран Арусси разработал библиотеку yfinance для доступа к данным Yahoo! Finance, когда официальный API перестал работать. Приведу цитату с GitHub:

«С тех пор как Yahoo! Finance закрыли свой API исторических данных, многие программы, которые использовали этот интерфейс, прекратили работу. yfinance призвана решить проблему — это надежное решение на Python для загрузки исторических данных по рынку из Yahoo! Finance».

Мило, мне подходит. Как это работает? Для начала библиотеку нужно установить:

$ pip install yfinance --user

А потом можно получить доступ к данным через объект Ticker:

import yfinance as yf

google = yf.Ticker(“GOOG”)

Это достаточно быстрый метод (в среднем исполняется чуть дольше 0,005 секунды), который возвращает МАССУ информации об акциях. Например, google.info содержит 123 поля, в том числе:

52WeekChange: 0.3531152
SandP52WeekChange: 0.17859101
address1: 1600 Amphitheatre Parkway
algorithm: None
annualHoldingsTurnover: None
annualReportExpenseRatio: None
ask: 1815
askSize: 1100
…
twoHundredDayAverage: 1553.0764
volume: 1320946
volume24Hr: None
volumeAllCurrencies: None
website: http://www.abc.xyz
yield: None
ytdReturn: None
zip: 94043

 Еще больше данных можно получить с помощью методов dividends, splits, balance_sheet, earnings и других. Большинство из них возвращают данные в виде объекта pandas DataFrame, так что придется немного повозиться, чтобы получить все, что нам нужно. 

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

Обратите внимание, что информация с разбивкой по времени внутри дня доступна, если вы указали период менее 60 дней, и что за один запрос можно получить данные с детализацией до минуты только за семь дней. Транспонированные данные последней записи с интервалом в одну минуту:

df = google.history(period='1d', interval="1m")print(df.head())

DataFrame — динамика цен на акции Google

DataFrame — динамика цен на акции Google

Видно, как они индексируются по дате и времени. При этом у каждой записи семь характеристик: четыре значения цены на акцию за эту минуту (открытие, максимальная, минимальная, закрытие) а также объем, дивиденды и сплит акций. Я буду использовать только характеристику «минимальная». Соберем необходимые данные:

df = google.history(period='1d', interval="1m")
df = df[['Low']]
df.head()

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

df['date'] = pd.to_datetime(df.index).time
df.set_index('date', inplace=True)
df.head()

Хорошо выглядит! Мы уже знаем, как найти последние данные в yfinance. Чуть позже передадим их в наш алгоритм. Но для начала нужно с ним определиться, так что переходим к следующему этапу.

Добавляем ИИ

Не пытайтесь повторять это в домашних условиях. Я подобрал ОЧЕНЬ простую модель ARIMA для прогнозирования следующей цены на акцию, поэтому относитесь к ней как к учебной. Чтобы использовать эти наработки для настоящего трейдинга, советую поискать модель получше и помощнее. Но не теряйте бдительности: если бы это было просто, такие модели были бы у всех.

Для начала давайте разделим DataFrame на данные для обучения и для тестирования, чтобы можно было использовать тестовый набор для проверки результатов учебной модели. В качестве тестового набора я собираюсь использовать последние 10% данных.

X = df.index.values
y = df['Low'].values
# The split point is the 10% of the dataframe length
offset = int(0.10*len(df))
X_train = X[:-offset]
y_train = y[:-offset]
X_test  = X[-offset:]
y_test  = y[-offset:]

Построим график:

plt.plot(range(0,len(y_train)),y_train, label='Train')
plt.plot(range(len(y_train),len(y)),y_test,label='Test')
plt.legend()
plt.show()

Теперь добавим в модель данные для обучения и получим прогноз. Обратите внимание, что здесь гиперпараметры модели фиксированы, а в реальной жизни для получения оптимальных параметров нужно использовать кросс-валидацию. К вашим услугам замечательное руководство о том, как подбирать гиперпараметры ARIMA по сетке на Python. Я использую конфигурацию 5, 0, 1 и получаю прогноз на момент, который наступает сразу после данных для обучения.

from statsmodels.tsa.arima.model import ARIMAmodel = ARIMA(y_train, order=(5,0,1)).fit()
forecast = model.forecast(steps=1)[0]

Давайте посмотрим, хорошо ли сработала наша учебная модель:

print(f'Real data for time 0: {y_train[len(y_train)-1]}')
print(f'Real data for time 1: {y_test[0]}')
print(f'Pred data for time 1: {forecast}')
—
Real data for time 0: 1776.3199462890625
Real data for time 1: 1776.4000244140625
Pred data for time 1: 1776,392609828666

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

Подключение к брокеру

Как вы, наверное, догадались, многое зависит от выбранного брокера. Я расскажу о подключении к RobinHood и Alpaca. Почему я выбрал именно их?

  • Есть публичный API.

  • Они не берут комиссию за трейдинговые операции.

В зависимости от типа учетной записи действуют те или иные ограничения. Например, у RobinHood можно совершать всего три трейдинговые операции в пять дней, если остаток на счете менее 25 000 долларов. У Alpaca ограничения не такие жесткие, но все же установлен лимит в 200 запросов в минуту на один ключ API.

RobinHood

Есть несколько библиотек, поддерживающих RobinHood API, но ни одна из них не является официальной. Библиотека Sanko была самой большой, с 1,5 тысяч звезд на GitHub, но ее закрыли. Библиотека LichAmnesia приняла эстафету, но пока что набрала только 99 звезд. Я собираюсь использовать robin_stocks, у которой на момент написания статьи чуть более 670 звезд. Давайте ее установим:

$ pip install robin_stocks

Для большинства действий нужен логин, так что для начала войдем в систему. RobinHood требует многофакторную аутентификацию, так что необходимо ее настроить. Войдите в свою учетную запись, включите двухфакторную аутентификацию и выберите «other» в ответе на вопрос «Какое приложение вы собираетесь использовать?». Вы получите буквенно-цифровой код, который мы применим:

import pyotp
import robin_stocks as robinhood
RH_USER_EMAIL = <<<YOUR EMAIL GOES HERE>>>
RH_PASSWORD = <<<YOUR PASSWORD GOES HERE>>>
RH_MFA_CODE = <<<THE ALPHANUMERIC CODE GOES HERE>>>
timed_otp = pyotp.TOTP(RH_MFA_CODE).now()
login = rh.login(RH_USER_EMAIL, RH_PASSWORD, mfa_code=totp)

Купить или продать — дело нехитрое:

# Buying 5 shares of Google
rh.order_buy_market('GOOG', 5)
# Selling 5 shares of Google
rh.order_sell_market('GOOG', 5)

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

Alpaca

Для Alpaca мы используем библиотеку alpaca-trade-api, у которой на GitHub более 700 звезд. Устанавливаем:

$ pip install alpaca-trade-api

Войдите в учетную запись и получите API key ID и секретный ключ, они нужны для входа в систему:

import alpaca_trade_api as alpaca
ALPACA_KEY_ID = <<<YOUR KEY ID GOES HERE>>>
ALPACA_SECRET_KEY = <<<YOUR SECRET KEY GOES HERE>>>
# Change to https://api.alpaca.markets for live
BASE_URL = 'https://paper-api.alpaca.markets'
api = alpaca.REST(
    ALPACA_KEY_ID, ALPACA_SECRET_KEY, base_url=BASE_URL)

Отправлять поручения здесь несколько сложнее, чем в RobinHood:

# Buying 5 shares of Google
api.submit_order(
    symbol='GOOG', 
    qty='5',
    side='buy',
    type='market',
    time_in_force='day'
)
# Selling 5 shares of Google
api.submit_order(
    symbol='GOOG', 
    qty='5',
    side='sell',
    type='market',
    time_in_force='day'
)

Готово! Напомню, что оставлять свои учетные данные в виде Plain Text — чрезвычайно плохая идея. Но не переживайте, на следующем этапе мы перейдем к переменным среды, это намного безопаснее. Теперь давайте развернем модель в облаке и настроим мониторинг.

Деплоймент и мониторинг

Мы собираемся задеплоить нашу систему в AWS Lambda. Для работы это не лучший вариант, поскольку в Lambda нет хранилища, а обученную модель пришлось бы где-то хранить, например в S3. 

Но пока обойдемся и этим — запланируем ежедневный запуск Lambda и обучение модели на данных за текущий день. Для мониторинга настроим бот в Telegram, который отправляет сообщение с действием и его результатом. AWS Lambda можно пользоваться бесплатно, если не превышать заданные лимиты; но если вы хотите отправлять очень много сообщений, помните о квотах.

Для начала создадим бота. Я опирался на официальную инструкцию из телеграма:

  • Найдите в телеграме пользователя @BotFather.

  • Используйте команду newbot, выберите название и имя пользователя для бота.

  • Получите и сохраните в надежном месте токен, он вам скоро понадобится.

Следующий этап — деплоймент. Есть несколько способов деплоймента в Lambda. Я собираюсь использовать фреймворк serverless, так что давайте его установим и создадим шаблон.

$ npm install serverless --global
$ serverless create --template aws-python3 --path ai_trading_system

Мы создали папку scheduled_tg_bot с тремя файлами: .gitignore, serverless.yml, и handler.py. Serverless.yml определяет деплоймент: что, когда и как будет запущено. А файл handler.py содержит запускаемый код.

import telegram
import sys
import os
CHAT_ID = XXXXXXXX
TOKEN = os.environ['TELEGRAM_TOKEN']

# The global variables should follow the structure: 
#       VARIABLE = os.environ['VARIABLE']
# for instance: 
#       RH_USER_EMAIL = os.environ['RH_USER_EMAIL]
def do_everything():
    # The previous code to get the data, train the model
    # and send the order to the broker goes here.
    return 'The action performed'
def send_message(event, context):
    bot = telegram.Bot(token=TOKEN)
    action_performed = do_everything()    bot.sendMessage(chat_id=CHAT_ID, text=action_performed)

Нужно поменять CHAT_ID на ID группы, канала или диалога, с которыми бот должен взаимодействовать. Здесь можно узнать, как получить ID канала, а здесь — ID группы.

Теперь давайте определим, как запускать код. Откройте serverless.yml и напишите:

org: your-organization-name
app: your-app-name
service: ai_trading_system
frameworkVersion: “>=1.2.0 <2.0.0”
provider:
  name: aws
  runtime: python3.6
  environment:
    TELEGRAM_TOKEN: ${env:TELEGRAM_TOKEN}
    # If using RobinHood    
    RH_USER_EMAIL: ${env:RH_USER_EMAIL}
    RH_PASSWORD: ${env:RH_PASSWORD}
    RH_MFA_CODE: ${env:RH_MFA_CODE}
    # If using Alpaca
    ALPACA_KEY_ID: ${env:ALPACA_KEY_ID}
    ALPACA_SECRET_KEY: ${env:ALPACA_SECRET_KEY}
functions:
  cron:
    handler: handler.send_message
    events:
      # Invoke Lambda function at 21:00 UTC every day
      - schedule: cron(00 21 * * ? *)

Этот код сообщает AWS, какая среда выполнения нам нужна, и берет токен телеграма из нашего собственного окружения, чтобы нам не пришлось его развертывать. После этого мы определяем Сron для ежедневного запуска функции в 21:00.

Единственное, что осталось сделать перед деплойментом, это получить учетные данные AWS и установить их как переменные среды вместе с токеном и остальными переменными как переменные среды. Получить учетные данные достаточно просто.

Из консоли AWS:

  • перейдите в My Security Credentials — Users — Add user;

  • выберите имя пользователя и Programmatic access;

  • на следующей странице выберите Attach existing policies directly — AdministratorAccess;

  • скопируйте и сохраните Access Key ID и Secret Access Key;

Вот и все. Теперь давайте экспортируем учетные данные AWS и токен телеграма. Откройте терминал и напишите:

$ export AWS_ACCESS_KEY_ID=[your key goes here]
$ export AWS_SECRET_ACCESS_KEY=[your key goes here]
$ export TELEGRAM_TOKEN=[your token goes here]# 
If using RobinHood
$ export RH_USER_EMAIL=[your mail goes here]
$ export RH_PASSWORD=[your password goes here]
$ export RH_MFA_CODE=[your mfa code goes here]
    
# If using Alpaca
$ export ALPACA_KEY_ID=[your key goes here]
$ export ALPACA_SECRET_KEY=[your key goes here]

Установите необходимые пакеты локально и выполните деплоймент в AWS:

$ pip3 install -r requirements.txt -t . --system
$ serverless deploy

Готово! Бот будет торговать за нас каждый день в 21:00 и отправлять нам сообщения о совершенном действии. Для апробации концепции неплохо. Пожалуй, можно порадовать приятеля: теперь он может расслабиться и заниматься трейдингом, не заглядывая в смартфон сто раз в день :)

Напомню, что у всех ресурсов, которые мы использовали в этом руководстве, есть собственная документация. Вы можете углубиться в любом направлении, которое вас заинтересует, ведь мы опробовали всего-навсего игрушечную систему! И все-таки я думаю, что эта игрушечная система — хорошее начало для многофункционального сложного продукта. Удачи!

Команда VK Cloud Solutions развивает собственные ML-решения. Будем признательны, если вы их протестируете и дадите обратную связь. Для тестирования пользователям при регистрации начисляем 3000 бонусных рублей.

Читать по теме:

  • Как дата-сайентистам эффективно сотрудничать с дата-инженерами

  • Четыре хитрости в работе с пайплайнами данных, о которых знают не все

  • Настоящее и будущее дата-инжиниринга

In this blog: Use Python to visualize your stock holdings, and then build a trading bot to buy/sell your stocks with our Pre-built Trading Bot runtime.

Recent trends in the global stock markets due to the current COVID-19 pandemic have been far from stable…and far from certain. The last time the market was this tumultuous, many people in the US and abroad lost a lot of money. But a few were fortunate enough to put themselves in a position to profit. The current situation will be no different.

Whether you are a seasoned programmer just getting started with financial trading, or an experienced investor interested in discovering the power of Python, this article is for you. In it, I’ll demonstrate how Python can be used to visualize holdings in your current financial portfolio, as well as how to build a trading bot governed by a simple conditional-based algorithm.

Installing Python for Trading Bots

To follow along with the code in this article, you’ll need to have a recent version of Python installed. I’ll be using a custom build of ActivePython that includes a version of Python and just the packages the project requires. You can get a copy for yourself by doing the following:

  • Download and install the “Trading Bot” runtime by doing the following:
    1. Install the State Tool on Windows using Powershell:
      IEX(New-Object Net.WebClient).downloadString('https://platform.activestate.com/dl/cli/install.ps1')Or install State Tool on Linux or Mac:
      sh <(curl -q https://platform.activestate.com/dl/cli/install.sh)
    2. Run the following command to download the build and automatically install it into a virtual environment:
      state activate Pizza-Team/Trading-Bot

You can find all of the code used in this article in my GitLab repository.

All set? Let’s dive into the details.

Financial Data for Trading Bots

There are many different stock trading platforms out there, some with their own APIs. Robinhood offers a commision-free investing platform that makes trading simple and easy. Additionally, the robin–stocks package extends this simplicity over to Python, supporting features like stock trading, buy/sell options, and purchase cryptocurrencies, as well as giving access to real-time portfolio and market performance.

To follow along with this post, you’ll need to create a Robinhood account. Note that if you’re located outside the US, you’ll need to use another trading platform. In this case, the structure of the trading bot will be the same, but how you execute the trades will be different.

To get started, we’ll first import the packages we need and then log in to the Robinhood platform. Replace the username and password strings with your own account information:

import robin_stocks as r
import pandas as pd
import time

username = 'user@mail.com'
password = 'password'

login = r.login(username,password)

Depending on your security settings, you may require two-factor authentication. Once logged in, you can easily access your holdings by running:

r.build_holdings()

The output is a dictionary that looks something like this:

   {‘KMI’ : {‘price’ : ‘13.990000’,
      ‘quantity’ : ‘1.00000000’,
      ‘average_buy_price’ : ‘0.000’,
      ‘equity’ : ‘13.99’,
      ‘percent_change’ :  ‘0.00’,
      ‘equity_change’ : ‘13.990000’,
      ‘type’ : ‘stock’,
      ‘name’ : ‘Kinder Morgan’,
      ‘id’ : ‘346c3dc3-2ef4-470f-aa67-0471cffeb299’,
      ‘pe_ratio’ : ‘13.939700’,
      ‘percentage’ : ‘100.00’}}

Of course, for bigger portfolios the output will be much longer. You can also access any of your profile information through the profiles module:

r.profiles.load_basic_profile()

There are a few more informative functions that can be used to extract information about your profile. They can be found in the documentation here.

Before we get to buying and selling, it is useful to build a visualization tool to observe historical changes in a given stock. The first thing I do is build a visualize_price() function that does exactly that.

The input is a list of tickers to plot, the time period over which to plot them (can be either day, week, month, 3month, year, or 5year), and whether to include extended trading hours or just regular trading hours (can be extended or regular).

def visualize_price(ticker_list, span = 'year', bounds = 'regular'):   
    for t in range(len(ticker_list)):
        name = str(r.get_name_by_symbol(ticker_list[t]))
        hist = r.stocks.get_historicals(ticker_list[t], span=span, bounds=bounds)
        hist_df = pd.DataFrame()
        for i in range(len(hist)):
            df = pd.DataFrame(hist[i], index = [i])
            hist_df = pd.concat([hist_df,df])
        hist_df.begins_at = pd.to_datetime(hist_df.begins_at, infer_datetime_format=True)
        hist_df.open_price = hist_df.open_price.astype('float32')
        hist_df.close_price = hist_df.close_price.astype('float32')
        hist_df.high_price = hist_df.high_price.astype('float32')
        hist_df.low_price = hist_df.low_price.astype('float32')

        ax = hist_df.plot(x = 'begins_at', y = 'open_price', figsize = (16,8))
        ax.fill_between(hist_df.begins_at, hist_df.low_price, hist_df.high_price, alpha=0.5)
        ax.set_xlabel('Date')
        ax.set_ylabel('Price (USD)')
        ax.legend([ticker_list[t]])
        ax.set_title(name)
    return

You can customize the input ticker list, or use the function below to extract them from your holdings:

def extract_list():
    ticker_list = list(r.build_holdings().keys())
    return ticker_list

To run the functions:

ticker_list = extract_list()
visualize_price(ticker_list, span = 'year', bounds = 'regular')

Since I only have one stock in my holdings, only one plot is given. The plot looks like this:

Stock Chart

In addition to plotting the opening price at each time interval (dark blue line), I’ve included the high and low price over the same time interval (light blue).

Trading Bot Buy/Sell Code

Ideally, the trading bot should look at a predefined set of tickers within the portfolio and decide whether to buy, sell, or hold. The information that the bot uses to make this decision can be anything from how the price changes in a given time period to the sentiment analysis of a tweet from the CEO of the company.

While there are many factors that can be taken into account, resulting in more sophisticated models for determining the bot conditionals, the base functionality of the bot doesn’t change. In our case, I’m simply using the percent_change attribute for each holding to determine whether or not to buy or sell. If the stock price has a drop over a certain percentage the bot will execute a buy. Conversely, if the stock price has a rise over a certain percentage the bot will execute a sell. To implement this behavior, I’ve defined a trading_bot function:

def trading_bot(trading_dict):
    holdings = r.build_holdings()
    holdings_df = pd.DataFrame()
    for i in range(len(holdings)):
        ticker = list(holdings.items())[i][0]
        holding_df = pd.DataFrame(list(holdings.items())[i][1], index = [i])
        holding_df['ticker'] = ticker
        holdings_df = pd.concat([holdings_df, holding_df])
    holdings_df = holdings_df[['ticker', 'price', 'quantity', 'percent_change','average_buy_price', 'equity', 'equity_change','pe_ratio', 'type', 'name', 'id' ]]

    for j in range(len(trading_dict)):
        holding_df = holdings_df[holdings_df.ticker == list(trading_dict.keys())[j]]
        if holding_df['percent_change'].astype('float32')[0] <= list(trading_dict.values())[j][0]:
            buy_string = 'Buying ' + str(holding_df['ticker'][0]) + ' at ' + time.ctime()
            print(buy_string)
            r.orders.order_buy_market(holding_df['ticker'][0],1,timeInForce= 'gfd')
        else:
            print('Nothing to buy')

        if holding_df['percent_change'].astype('float32')[0] >= list(trading_dict.values())[j][1]:
            sell_string = 'Buying ' + str(holding_df['ticker'][0]) + ' at ' + time.ctime()
            print(sell_string)
            r.orders.order_sell_market(holding_df['ticker'][0],1,timeInForce= 'gfd')
        else:
            print('Nothing to sell')

First, the bot pulls the holdings from the Robinhood platform and does some restructuring of the data to create a pandas dataframe. Then, it loops through each ticker present in trading_dict and compares the percent_change value to the buy and sell conditional limits. For example, I can set both limits to 0.5%:

trading_dict = {'KMI': [-0.50, 0.50]}
holdings_df = trading_bot(trading_dict)

The bot will then execute a buy or sell if the percent_change value is less than or greater than half a percent, and prints out the transaction for each holding. Pretty cool right?

That’s it! You can now build your own trading bot using Python

In this article, I demonstrated how Python can be used to build a simple trading bot using packages like pandas and robin-stocks. By taking advantage of the Robinhood trading platform, you can easily visualize the performance of individual holdings within your portfolio.

The buy and sell conditions we set for the bot are relatively simplistic, but this code provides the building blocks for creating a more sophisticated algorithm. The versatility of Python offers the perfect playground for increasing the complexity by, for example, introducing machine learning techniques and other financial metrics. I leave these next steps to those readers interested in creating a more advanced bot.

  • All of the code used in this article can be found in my GitLab repository.
  • Sign up for a free ActiveState Platform account so you can download the Trading Bot runtime environment and build your very own trading bot

Recommended Reads

ActiveState Platform: How to Build a Custom Runtime in 5 minutes?

How to Build a Blockchain in Python (Get Pre-built Runtime)

Top 10 Python Packages for Finance and Financial Modeling

Понравилась статья? Поделить с друзьями:
  • Как написать торгового робота mt4
  • Как написать тонометр
  • Как написать тому фелтону чтобы он ответил
  • Как написать тому кто нравится
  • Как написать тому кому давно не писал