Это первый проект в моей серии статей по количественному финансированию, цель которого - объединить мои навыки разработки программного обеспечения и опыт работы с хедж-фондами в различных сложных и интересных проектах.
С тех пор как я достиг отличной точки остановки в моем путешествии по разработке программного обеспечения (подробнее об этом вы можете прочитать здесь), я хотел создать хранилище данных фондового рынка, которое можно было бы использовать в качестве основа для будущих проектов.
Объединение новых навыков программирования с предыдущим опытом работы с Python позволило бы мне взяться за простые, но интересные количественные проекты. Для меня это также возможность поделиться своей страстью к количественному пространству, а также изучить новые предметы. Эта база данных PostgreSQL - первый шаг в достижении этой цели.
Репозиторий GitHub
Для доступа к базе кода, которую я буду обсуждать в этом сообщении в блоге, есть ссылка на репозиторий GitHub. Я приветствую любые отзывы или комментарии по моему коду и подходу (пожалуйста, будьте любезны).
Подход и реализация
Перед тем, как взяться за этот проект, я изучил PostgreSQL в рамках моей онлайн курсовой работы. В нашем внутреннем курсе использовался Ruby и интерфейс командной строки для изучения основ SQL. Я использовал psql
console и ее многочисленные мета-команды для создания и взаимодействия с нашими таблицами в различных базах данных.
Однако я хотел интегрировать эти знания в Python и максимально автоматизировать процесс.
Мой код Python обрабатывает следующее:
- Создание схемы базы данных, которая включает все наши таблицы и столбцы (например, имена столбцов, типы, ограничения, внешние ключи). Ссылка на код.
- Поиск в Википедии списка акций, котирующихся на S&P 500. Ссылка на код.
- Поиск в Yahoo Finance данных фондового рынка. Собранные данные включают дату, открытие, максимум, минимум, закрытие, скорректированное закрытие и объем. Ссылка на код.
- Вывод текстового файла для любых данных о запасах, которые нам не удалось собрать.
- Вывод текстового файла для всех собранных нами данных о запасах в дополнение к первой и последней дате сбора данных.
Вот несколько замечательных библиотек, которые мне пришлось изучить и использовать в этом проекте: 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 строк данных связан с двумя проблемами:
- Нам не удалось получить данные по небольшому количеству акций. Всего в выведенном текстовом файле «failed_symbols.txt» появилось 13 символов.
- Некоторые данные, которые были получены для данного рынка, на самом деле не вернулись к нашей начальной дате 30.12.2004. Данные по некоторым акциям были извлечены позже.
Прежде чем приступить к рефакторингу любого кода, мне нужен был простой подход к массиву INSERT
данных о фондовом рынке.
Ссылаясь на psycopg2
документацию на cur.executemany
, мы видим, что это не быстрее, чем простое выполнение execute()
в цикле.
Для любой будущей потребности во вставке больших объемов данных есть другие решения, о которых я смог прочитать. Вот один из немногих интересных сообщений, в котором обсуждаются массовые параметры SQLINSERT
. (ВНИМАНИЕ: сообщение в блоге датировано 2015 годом. У меня нет связи с автором и веб-сайтом, и я не тестировал объясненные варианты.)
Последние мысли
На мой взгляд, этот проект получился очень удачным. Хотя мой онлайн-курс научил меня PostgreSQL в рамках Ruby и интерфейса командной строки, я смог применить хорошо изученные основы в «питоническом» подходе к созданию хранилища данных.
Теперь у нас есть данные, необходимые для выполнения различных проектов количественных исследований, ориентированных на справедливость.