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

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

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

Репозиторий GitHub

Для доступа к базе кода, которую я буду обсуждать в этом сообщении в блоге, есть ссылка на репозиторий GitHub. Я приветствую любые отзывы или комментарии по моему коду и подходу (пожалуйста, будьте любезны).

Подход и реализация

Перед тем, как взяться за этот проект, я изучил PostgreSQL в рамках моей онлайн курсовой работы. В нашем внутреннем курсе использовался Ruby и интерфейс командной строки для изучения основ SQL. Я использовал psqlconsole и ее многочисленные мета-команды для создания и взаимодействия с нашими таблицами в различных базах данных.

Однако я хотел интегрировать эти знания в Python и максимально автоматизировать процесс.

Мой код Python обрабатывает следующее:

  1. Создание схемы базы данных, которая включает все наши таблицы и столбцы (например, имена столбцов, типы, ограничения, внешние ключи). Ссылка на код.
  2. Поиск в Википедии списка акций, котирующихся на S&P 500. Ссылка на код.
  3. Поиск в Yahoo Finance данных фондового рынка. Собранные данные включают дату, открытие, максимум, минимум, закрытие, скорректированное закрытие и объем. Ссылка на код.
  4. Вывод текстового файла для любых данных о запасах, которые нам не удалось собрать.
  5. Вывод текстового файла для всех собранных нами данных о запасах в дополнение к первой и последней дате сбора данных.

Вот несколько замечательных библиотек, которые мне пришлось изучить и использовать в этом проекте: psycopg2, fix_yahoo_financeи bs4.

Чтобы выполнить вышеуказанные требования, я решил разделить каждый ключевой компонент на отдельный скрипт Python. Вы можете найти все шаги и объяснения в прилагаемом файле README.md и в репозитории GitHub.

«Концептуальный» уровень ERD

Здесь мы видим следующие отношения:

  • exchange имеет отношение (1: M) к символу.
  • symbol имеет отношение (1: M) к daily_data.
  • data_vendor имеет отношение (1: M) с daily_data. В будущем можно будет расширить нашу таблицу daily_data, чтобы учесть данные о запасах с идентичными датами поступать от других поставщиков данных. Это установит (M: M) отношения и потребует третьей таблицы «перекрестных ссылок».

ERD «Физический» уровень

Финансовые данные Yahoo - "легкие" дни прошли

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

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

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

Эффективность массовой загрузки PostgreSQL

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

Наша дата начала для наших данных - 30.12.2004, а конечная дата - 12.12.2017. Эти даты произвольны, так как я просто хотел получить хороший набор рыночных данных для будущего использования. В этом диапазоне дат примерно 3245 торговых дней. С 505 акциями, включенными в список S&P 500, мы можем оценить примерно 1 638 725 строк ожидаемых строк.

Фактический результат 1 506 514 строк данных связан с двумя проблемами:

  1. Нам не удалось получить данные по небольшому количеству акций. Всего в выведенном текстовом файле «failed_symbols.txt» появилось 13 символов.
  2. Некоторые данные, которые были получены для данного рынка, на самом деле не вернулись к нашей начальной дате 30.12.2004. Данные по некоторым акциям были извлечены позже.

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

Ссылаясь на psycopg2 документацию на cur.executemany, мы видим, что это не быстрее, чем простое выполнение execute() в цикле.

Для любой будущей потребности во вставке больших объемов данных есть другие решения, о которых я смог прочитать. Вот один из немногих интересных сообщений, в котором обсуждаются массовые параметры SQLINSERT. (ВНИМАНИЕ: сообщение в блоге датировано 2015 годом. У меня нет связи с автором и веб-сайтом, и я не тестировал объясненные варианты.)

Последние мысли

На мой взгляд, этот проект получился очень удачным. Хотя мой онлайн-курс научил меня PostgreSQL в рамках Ruby и интерфейса командной строки, я смог применить хорошо изученные основы в «питоническом» подходе к созданию хранилища данных.

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