Руководство: как использовать Python для алгоритмической торговли на бирже. Часть 1



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

    Среди наиболее популярных в сфере финансов языков программирования можно отметить R и Python, также часто используются C++, C# и Java. В опубликованном на сайте DataCamp руководстве речь идет о том, как начать использовать Python для создания финансовых приложений — мы представляем вам серию статей-адаптаций глав этого материала.

    Структура руководства:

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

    Введение: простым языком об устройстве сферы финансов


    Прежде чем окунуться в мир торговых стратегий, имеет смысл коснуться базовых понятий. Однако это не означает, что то, о чем пойдет речь ниже, рассчитано совсем на новичков. Будет здорово, если вы предварительно ознакомитесь с курсом по использованию Python для работы с данными, а также представляете себе, как работать со списками и пакетами Python, а также хотя бы на базовом уровне знакомы с NumPy и Pandas.

    Акции и торговля на бирже


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

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

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

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

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

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

    Данные временных рядов


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



    По оcи X расположены даты, а цена — на оси Y. «Последовательные равные промежутки времени» в данном случае означает, что по временной оси даты расположены с двухнедельным интервалом: можно сравнить 3/7/2005 и 3/31/2005, а также 4/5/2005 и 4/19/2005 (здесь даты записаны в принятом в США формате, когда сначала идет месяц, а затем день).

    Однако финансовые данные обычно включают не два параметра (цена и дата), а пять — помимо величины торгового периода, это цена открытия торгового периода, наивысшая и низшая цена в его рамках, а также цена в момент закрытия периода. Это значит, что если мы рассматривает дневной период, то анализ данных даст нам информацию о том, на каком уровне находилась цена в момент старта и завершения торгов в выбранный день, а также какой была максимальная и минимальная цена в ходе торгов.

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

    Основы Python для сферы финансов: Pandas


    Одним из самых востребованных инструментов при использовании Python для разработки финансовых приложений является пакет Pandas. Он нужен уже в самом начале, но по мере углубления в процесс разработки понадобятся и такие пакеты как NumPy, SciPy, Matplotlib.

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

    Импорт финансовых данных


    Пакет pandas-datareader позволяет получать данные из таких источников, как Google, Yahoo! Finance или Всемирный банк — подробнее о доступных источниках данных написано в документации. В этом руководстве будет рассматриваться получение данных с сервиса Yahoo! Finance. Для начала работы необходимо установить последнюю версию пакета с помощью pip:

    pip install pandas-datareader

    Инструкции по установке версии в разработке представлены здесь.

    import pandas_datareader as pdr
    import datetime 
    aapl = pdr.get_data_yahoo('AAPL', 
                              start=datetime.datetime(2006, 10, 1), 
                              end=datetime.datetime(2012, 1, 1))

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

    Важно также понимать, что несмотря на то, что pandas-datareader — это удобный инструмент для загрузки данных, он далеко не единственный для Python. Также можно использовать библиотеки вроде Quandl, которая позволяет получать данные с сервиса Google Finance:

    import quandl 
    aapl = quandl.get("WIKI/AAPL", start_date="2006-10-01", end_date="2012-01-01")

    Также многим известно, что в сфере финансов для анализа данных очень популярен Excel. Для удобства будущей работы можно интегрировать этот инструмент с Python (подробнее по ссылке).

    Работа с данными временных рядов


    Для импортирования данных мы использовали pandas_datareader. В результате возник объект aapl — это DataFrame, то есть двумерная именованная структура данных со столбцами потенциально разных типов. Первое, что следует сделать при работе с таким фреймом — запустить функции head() и tail() для того, чтобы взглянуть на первый и последний столбцы датафрейма. Для получения полезной статистической сводки по скачанным данным можно воспользоваться функцией describe().

    Пример этого кода можно найти на странице исходного материала.

    Данные содержат четыре столбца с ценой открытия и закрытия торгового периода, а также максимальной и минимальной ценой — мы рассматриваем дневные интервалы и акции Apple. Также мы получаем два дополнительных столбца: Volume и Adj Close. Первый из них используется для того, чтобы зафиксировать количество акций, с которыми совершались сделки в торговый день. Второй столбец — это «отрегулированная» цена закрытия (adjusted closing price), это значит, что в цену закрытия периода были добавлены все действия с акциями, которые могли быть совершены до момента открытия следующего торгового дня.

    Если нужно сохранить данные в CSV-файл, это можно сделать с помощью функции to_csv(), а прочитать файл можно с помощью read_csv() — это полезно для ситуаций, когда источник данных меняется и доступ к ним временно теряется.

    import pandas as pd
    aapl.to_csv('data/aapl_ohlc.csv')
    df = pd.read_csv('data/aapl_ohlc.csv', header=0, index_col='Date', parse_dates=True)

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

    Для того, чтобы посмотреть на индекс и столбцы данных следует использовать атрибуты index и columns. Затем можно выделить подмножество из десяти последних наблюдений в столбце column. Для изолирования этих значений следует использовать квадратные скобки. Последнее значение помещается в переменную ts, а проверка ее типа осуществляется с помощью функции type().

    # Inspect the index 
    aapl.index
     
    # Inspect the columns
    aapl.columns
     
    # Select only the last 10 observations of `Close`
    ts = aapl['Close'][-10:]
     
    # Check the type of `ts` 
    type(ts)

    Использование квадратных скобок удобно, но это не самый характерный способ при работе с Pandas. Поэтому также стоит рассмотреть функции loc() и iloc(): первая из них используется для label-based индексирования, а последняя для позиционального индексирования.

    На практике, это значит, что можно передать ярлык ряда вроде 2007 или 2006-11-01 в функцию loc(), а целые числа вроде 22 или 43 передаются функции iloc().

    # Inspect the first rows of November-December 2006
    print(aapl.loc[pd.Timestamp('2006-11-01'):pd.Timestamp('2006-12-31')].head())
     
    # Inspect the first rows of 2007 
    print(aapl.loc['2007'].head())
     
    # Inspect November 2006
    print(aapl.iloc[22:43])
     
    # Inspect the 'Open' and 'Close' values at 2006-11-01 and 2006-12-01
    print(aapl.iloc[[22,43], [0, 3]])

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

    Помимо индексирования есть несколько способов узнать о данных больше. Можно, к примеру, попробовать создать семпл из 20 строк данных, а затем переформатировать их таким образом, чтобы appl стал не дневным значением и месячным. Сделать это можно с помощью функций sample() и resample():

    # Sample 20 rows
    sample = aapl.sample(20)
     
    # Print `sample`
    print(sample)
     
    # Resample to monthly level 
    monthly_aapl = aapl.resample('M').mean()
     
    # Print `monthly_aapl`
    print(monthly_aapl)

    Прежде чем перейти к визуализации данных и проведению финансового анализа, можно начать вычислять разницу между ценами открытия и закрытия торгового периода. Эту арифметическую операцию можно с помощью Pandas — нужно вычесть значения столбца Open данных appl из столбца Close. Или, другими словами, вычесть aapl.Close из aapl.Open. Получившийся результат будет храниться в новом столбце датафрейма aapl под названием diff, который можно удалить с помощью функции del:

    # Add a column `diff` to `aapl` 
    aapl['diff'] = aapl.Open - aapl.Close
     
    # Delete the new `diff` column
    del aapl['diff']

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

    Визуализация данных временных рядов


    Помимо анализа данных с помощью функций head(), tail() и индексирования, также возможна их визуализация. Благодаря интеграции Pandas с инструментом для создания графиков Matplotlib это можно сделать довольно легко. Нужно лишь использовать функцию plot() и передать ей релевантные параметры. Кроме того, если добавить параметр grid, то получившийся график будет наложен на сетку.

    # Import Matplotlib's `pyplot` module as `plt`
    import matplotlib.pyplot as plt
     
    # Plot the closing prices for `aapl`
    aapl['Close'].plot(grid=True)
     
    # Show the plot
    plt.show()

    Этот код дает вот такой график:



    В следующей части руководства речь пойдет о финансовом анализе данных временных рядов с помощью Python.

    Продолжение следует…..

    Другие материалы по теме финансов и фондового рынка от ITinvest:


    • +18
    • 39,4k
    • 4
    ITI Capital
    258,00
    Лучший онлайн-брокер для работы на бирже
    Поделиться публикацией

    Комментарии 4

      0
      Говоря о python / pandas / matplotlib, очень странно не упомянуть о jupyter notebook (бывший ipython notebook). Без него работа со всем этим превращается в куда более утомительное и менее наглядное занятие.
        0
        Согласен. Это must have.
        Сам сеичас по работе занимаюсь анализом и прогнозом временных рядов, ищу решение. Но имея опыт в сфере биржевых систем могу сказать сразу, все анализы временных рядов в этой сфере не более чем кидание монетки. Движение цен не предсказывается. Цена может пойти как вверх так и вниз. Задним числом конечно же все это можно уже обосновать. Впрочем как обучающая статья, анализ бизржевой информации вполне может использоваться.
          0
          Да, вы правы. Об этом будет еще упоминание в следующих частях материала
            0
            Да уж… Я с ним успел забыть когда в последний раз WingIDE открывал. Всё делается прямо на месте. Совершенно исключительная штука. Сейчас увлечён языком Scala, даже посматриваю в его сторону как на замену питону. И одно из самых приятных моих открытий тоже было то, что Jupyter его поддерживает. Не представляю себе как раньше без этого жил.

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

          Самое читаемое