Автоматизация биржевой торговли

  • Вид работы:
    Дипломная (ВКР)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    44,69 Кб
  • Опубликовано:
    2017-08-25
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Автоматизация биржевой торговли

Введение

автоматизация биржевой торговля

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

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

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

Объектом данного исследования является процесс биржевой торговли.

Предметом исследования является автоматизация процесса анализа и биржевой торговли.

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

Фондовые рынки играют очень важную роль в современной экономике. За акциями следят не только трейдеры. Акции отражают реальное состояние дел компании, положение дел в отрасли и в целом в стране. Важно понимать, как будут двигаться акции не только в ближайшем будущем, но и в среднесрочной и долгосрочной перспективах. Более того, нужно быть уверенным в прогнозах.

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

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

Для успешного достижения поставленной цели нужно разработать:

·структуру системы, которая позволит осуществлять анализ исторических временных рядов цен акций, и на основании полученных моделей строить прогнозы изменения цены;

·критерии эффективности, автоматизированной биржевой торговли;

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

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

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

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

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

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

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

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

Все дополнительные материалы, исходный код системы, дополнительные расчёты и таблицы приведены в приложении к работе.

Данная работа основана на теориях и методах из разных областей знания. Большинство моделей, которые будут исследованы и реализованы являются статистическими моделями, если конкретнее, то эконометрические модели временных рядов (Soren Bisgaard, 2011) (Tsay, 2001) (А.И.Орлов, 2009). Также в системе использованы модели машинного обучения. Данная область является достаточно молодой, однако существует множество статей. (Alpaydin, 2004) (Тревор Хасти, 2001). Стоит также упомянуть, что данные модели и критерии не смогут образовать систему. Все связи и причины принадлежат к анализу акций и финансовых рынков (Chan, 2009) (Erlich, 1996) (Schwager, 1996) (Белова Е.В., 2006).

Глава 1. Методология автоматизации биржевой торговли

В современном мире достаточно часто встречается словосочетание «Финансовый рынок». Однако, далеко не все люди правильно понимают, что это такое. Финансовый рынок - это некоторая структура взаимоотношений, которая в ситуации рыночной экономики реализует заимствование, обмен, инвестирование и куплю-продажу экономических благ, где активом-посредником являются деньги (Белова Е.В., 2006).

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

Фондовый рынок или рынок ценных бумаг - это объединение экономических взаимоотношений, в результате которых происходит выпуск и перераспределение ценных бумаг (Schwager, 1996). Появление данного рынка напрямую связано с товарным производством, т.к. производителям постоянно требуется привлечение капитала для развития бизнеса. С помощью выпуска акций и облигаций компании получили возможность мгновенно получать инвестиции для развития новых ответвлений бизнеса, товарных линий и так далее.

Стоит уточнить, что ценная бумага - это денежный документ, составленный по определенным правилам, который удостоверяет имущественные права, которые можно реализовать или передать только при предъявлении данного документа. К ценным бумагам относятся акции, облигации, векселя, чеки и т.д. В данном исследовании осуществляется анализ и торговля акциями.

1.1Виды биржевой торговли

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

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

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

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

Техническая торговля основана на анализе достаточно большого количества индикаторов, графиков и моделей, а также включение в анализ некоторых финансовых показателей о компании (Schwager, 1996). Основным недостатком данного подхода является тот факт, что все решения, принимаемые торговцем, зависят от прошлого, тогда как прошлое не всегда несёт адекватную информацию. Ещё один недостаток заключается в отсутствии идеального индикатора, модели, графика и подхода к анализу. Для каждой акции требуются свои собственные инструменты, релевантность которых можно измениться с течением времени.

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

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

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

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

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

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

Ещё одна интересная классификация заключается в оценке информированности трейдера (Narang, 2009). Данная классификация делит всех трейдеров на две большие категории - информированные и неинформированные. Те, кто принадлежат к первой категории основывают свои решения на определенных видах анализа - фундаментального и технического. Такие трейдеры имеют определенную уверенность в своих действиях и полагаются на данные построенных моделей. Представители второй категории - те люди, которые берут во внимание только то, что говорит им интуиция, в вопросах принятия решений на фондовом рынке. Трейдеры этого вида не используют методы ни фундаментального, ни технического анализа. Просто наблюдая за динамикой на фондовом рынке, данные трейдеры совершают свои сделки, полагаясь на собственный опыт.

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

Дневные трейдеры совершают свои сделки в течение одной торговой сессии (торгового дня). Трейдеры данной категории никогда не переносят открытые позиции на следующий день и закрывают их в конце дня. Основной мотивацией для такого поведения являются большие разрывы между ценами закрытия одного дня и ценами открытия следующего дня. Более того, такой подход позволяет не платить кредит. Одной из особенностей таких участников торгов является склонность к выбору бумаг с высокой изменчивостью цены (волатильностью). Чаще всего такие трейдеры имеют небольшой капитал.

Скальперы и пипсовщики - это те игроки, которые совершают большое количество сделок за короткий промежуток времени, начиная от десятков секунд, заканчивая десятками минут. За счёт того, что представители данной категории за короткий срок совершают множество сделок малой прибыли, суммарно по итогу торгового дня они могут иметь достаточно большую прибыль. Чаще всего скальперы предпочитают использовать бумаги с низкой волатильностью, т.к. любое резкое изменение цены может сильно навредить трейдеру. Процесс скальпинга в целом представляет из себя открытие позиции и следование ей вплоть до изменения направления цены, и в момент закрытия производится закрытие позиции. Прибыль реализуется за счёт простой разницы между ценой покупки и продажи ценной бумаги.

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

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

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

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

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

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

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

Агрессивные трейдеры - это те, кто ставит извлечение прибыли намного выше, чем надежность вложений. Агрессивные трейдеры готовы идти на максимальный риск, чтобы приумножить свой капитал максимально.

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

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

Трейдеров можно классифицировать по целям, ради которых они совершают сделки на финансовых рынках.

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

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

Арбитражёры занимаются стабилизацией рынка в целом. За счёт встречных продаж активов они увеличивают цену одного и снижают цену другого актива. Данный подход позволяет регулировать положение акций на рынке.

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

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

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

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

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

1.2Основные методы анализа движения биржевых цен

На данный момент в современном мире существует несколько подходов к анализу финансовых рынков - фундаментальный, технический, фрактальный.

Фундаментальный анализ основывается на анализе производственных и финансовых показателях каждой компании, в которую собираются вложить деньги (Kijanica, 2005).

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

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

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

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

Технический анализ основывается на трёх аксиомах (Erlich, 1996):

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

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

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

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

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

1.3Обоснование автоматизации биржевой торговли

Классическая торговля в умах большинства людей выглядит таким образом: человек покупает ценную бумагу в некоторый момент времени при определенном значении цены. Затем он ждёт пока цена вырастет до определенного момента, затем продает. Также продажа возможна, если трейдер считает, что цена должна в скором времени изменить направление. За один промежуток времени t1 трейдер зарабатывает y1 (см. рисунок 1), что является разностью между позицией покупки и позицией продажи.

Рисунок 1. Процесс торговли на фондовом рынке в умах большинства.

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

Рисунок 2. Процесс торговли на фондовом рынке тех, кто стремится автоматизировать её.

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

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

Глава 2. Облик системы автоматизированной торговли: структура, функции и алгоритм работы

2.1 Структура системы

.1.1 Описание системы

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

Все алгоритмы системы и те блоки, которые необходимы для анализа реализованы на Python 2.7 с использованием различных специализированных библиотек. База данных, в которой реализуется архивация и хранение исторических данных, реализована на SQL Server 2016. Пользовательская часть приложения реализована с помощью C#.

Систему можно условно разделить на три подсистемы (см. рисунок 3): клиентское приложение, подсистема анализа и подсистема архивации данных.

Рисунок 3. Общая схема работы системы.

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

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

Крайняя подсистема связана с архивацией данных. Данная подсистема является поддерживающей для системы в том смысле, что все данные и тесты, которые проводятся, сохраняются в специальной базе данных. Более того, данная база данных хранит в себе значения всех критериев качества всех моделей для каждого теста, что позволяет оценивать стабильность той или иной модели. Если разбираться в структуре системы более подробно, то в системе можно выделить ряд блоков (см. рисунок 4), а именно, блок работы с данными, блок работы с базой данных, блок визуализации или работы с графиками, торговый блок, аналитический блок, блок оценки качества работы, блок взаимодействия с пользователем. Разберем суть работы каждого блока подробнее.

Рисунок 4. Составляющие системы.

2.1.2 Блок получения данных

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

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

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

Алгоритм работы данной подсистемы достаточно прозрачен и прост (см. рисунок 5). Сначала пользователь вводит название интересующей акции, начало и конец периода, на основе которого будет проводится построение модели. Эта информация запрашивается на сайте. Затем полученные данные обрабатываются и трансформируются для дальнейшего анализа.

Рисунок 5. Алгоритм получения и обработки данных.

В описании данного блока стоит включить ещё вопрос о том, почему был выбран именно данный сервис для доступа к данным. Одной из причин в пользу Yahoo стал тот факт, что это один из самых популярных сервисов, который заслужил доверие многих профессиональных финансистов своей точностью и стабильностью. У yahoo никогда не было проблем с доступом за всё время создание проекта. Данные, которые были получены, всегда имели чёткую структуру. Также хотелось бы отметить высокую скорость обработки запроса и получения данных, по сравнению с другими ресурсами.

.1.3 Блок работы с базой данных

Следующим элементом, реализуемым в системе, является блок работы с базой данных.

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

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

Рисунок 6. Схема базы данных.

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

Industries - отрасли - данная сущность включает в себя все отрасли по Глобальному Стандарту Классификации отраслей.

Company_Stocks - акции компаний - данная сущность включает в себя названия акций компаний и их расшифровку.

Raw_Data - сырые данные - данная сущность включает в себя данные, на которых проводились тесты, по каждой акции.

Test - тест - сущность, которая отражает все тесты, проведенные на модели

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

Model - модель - сущность, которая описывает все модели, которые используются при построении данной системы.

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

Каждая сущность имеет атрибуты, которые позволяют максимально полно описать хранимые данные (таблица 1).

Таблица 1. Сущности и атрибуты базы данных.

СущностьНазваниеТипКлючОписаниеIndustriesIndustry_CodeVarchar(20)PKКод отрасли по ГСКОIndustriesIndustry_NameNvarchar(1000)Название отрасли по ГСКОCompany_StocksStock_CodeVarchar(20)PKКод акции компании на фондовом рынкеCompany_StocksCompany_NameNvarchar(1000)Название компанииCompany_StocksIndustry_CodeVarchar(20)FKRaw_DataDate_IndexDatetimePKДата, для которой были взяты измеренияRaw_DataStock_CodeVarchar(20)FK, PKRaw_DataTest_CodeIntegerFK, PKRaw_DataOpen_ValueFloatЦена открытия за деньRaw_DataClose_ValueFloatЦена закрытия за деньRaw_DataHigh_ValueFloatНаибольшая цена за деньRaw_DataLow_ValueFloatНаименьшая цена за деньRaw_DataAdj_Close_ValueFloatСкорректированная цена закрытия за деньRaw_DataVolume_ValueIntegerОбъемы за деньTestTest_CodeIntegerPKНомер тестаTestTest_DescriptionNvarchar(1000)Дополнительное описание для тестаTest_ResultTest_CodeIntegerFK, PKTest_ResultParametr_CodeVarchar(20)FK, PKTest_ResultModel_CodeVarchar(20)FK, PKTest_ResultResult_ValueFloat Значение параметра для данного теста, данной моделиEffectiveness_ParametrsParametr_CodeVarchar(20)PKСокращение параметраEffectiveness_ParametrsParametr_NameNvarchar(200)Название параметраEffectiveness_ParametrsParametr_SymbolVarchar(20)Символьное обозначение параметраEffectiveness_ParametrsParametr_DescriptionNvarchar(1000)Дополнительное описание параметраModelModel_CodeVarchar(20)PKСокращенное название моделиModelModel_NameNvarchar(1000)Полное название моделиModelModel_DescriptionNvarchar(1000)Дополнительное описание моделиModelModel_FeaturesNvarchar(1000)Особенности, которые стоит учитывать при построении модели

Все сущности, реализованные в базе данных, связаны между собой:

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

Company_Stock - Raw Data - один ко многим - данная связь отражает, что для определенного значения времени определенные значения показателей цены могут принадлежать только одной акции. Одна акция имеет множество измерений - столько, сколько дней торговалась данная акция на рынке. Тогда как одно измерение принадлежит только одной определенной акции.

Model - Test_Result - один ко многим - для одной модели может быть множество результатов теста, но один результат теста не может относится ко множеству моделей.

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

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

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

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

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


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

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


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

Алгоритм первой части инициируется после блока запроса и обработки данных. После получения данных с сайта создается запись о новом тесте, затем происходит проверка наличия акции в системе. В случае, если акция новая, то система добавляет её в базу данных. Затем происходит запись всех скачанных с сайта данных в таблицу сырых данных (см. рисунок 7)

Рисунок 7. Первая часть алгоритма блока работы с базой данных.

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

Рисунок 8. Вторая часть алгоритма блока работы с базой данных.

.1.4 Блок анализа данных

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

В аналитическом блоке реализованы следующие модели: простого скользящего среднего, треугольного скользящего среднего, экспоненциального скользящего среднего, двойного экспоненциального скользящего среднего, тройного экспоненциального скользящего среднего, логистической регрессии, линейного дискриминантного анализа, квадратичного дискриминантного анализа…

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

Простая скользящая средняя является примитивной моделью сглаживания. Формула данной модели имеет вид:


где n - это период, за который вычисляется скользящая средняя, а p - это непосредственно значение. Код, реализующий метод построения скользящей средней представлен на ниже.


Треугольная скользящая средняя ещё один вид скользящей средней, которая строится на основе определенных весов. Веса распределяются треугольником, т.е. наибольший вес для текущего рассчитываемого значения будет иметь значение в середине периода. Формула треугольной скользящей средней для четного значения периода имеет следующий вид:


где n - это период, за который вычисляется скользящая средняя, а p - это непосредственно значение. Иными словами, треугольная скользящая средняя - это простая скользящая средняя с вдвое меньшим периодом, построенная на основе значений простой скользящей средней с вдвое меньшим периодом, увеличенным на единицу. Реализация в коде имеет вид:

def TriangMovingAverage(array, period): return array.rolling(window=period, win_type='triang').mean()

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

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

,

где n - это период, за который вычисляется скользящая средняя, а p - это непосредственно значение, - коэффициент, который учитывает влияние предыдущих цен. При стремящемся к 0 влияние текущего значения цены будет минимальным, при стремлении к 1 практически не будут учитываться предыдущие цены.

Для того, чтобы понять связь с периодом n, стоит ввести формулу, связывающую эти два показателя. Она имеет вид:

.

Таким образом, мы можем выразить период через и наоборот.

Код, который реализует расчёт экспоненциальной скользящей средней, представлен ниже:

def ExponentialMovingAverage(array, alpha): return array.ewm(alpha=alpha).mean()

Ещё один вид экспоненциальной скользящей средней, который рассчитывается в данной системе, - это двойная экспоненциальная средняя. Этот вид кривой является попыткой снизить временную задержку, которая присуща скользящим средним.

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

.

Реализация на Python имеет следующий вид:

def DoubleExponentialSmoothing(series, period1, period2): alpha = 2 / (period1 + 1) beta = 2 / (period2 + 1) result = [] for n in range(1, len(series)+1): if n == 1: level, trend = series[0], series[1] - series[0] if n >= len(series): value = result[-1] else: value = series[n] last_level, level = level, alpha*value + (1-alpha)*(level+trend) trend = beta*(level-last_level) + (1-beta)*trend result.append(level+trend) return result

Коэффициенты alpha и beta отвечают за период и тренд, соответственно. Однако, стоит обратить внимание, что можно получить тот же результат, если возьмем экспоненциальную скользящую от экспоненциальной скользящей.

Стоит также отметить, что двойное экспоненциальное сглаживание позволяет прогнозировать не на одно, а на два значения вперёд.

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


Тройное экспоненциальное сглаживание является прогностической моделью Холта-Уинтерса, которая позволяет делать прогноз на три дня. Это возможно за счёт того, что каждое последующее (второе и третье) экспоненциальное сглаживание отвечает за тренд и сезонность соответственно.

Другой раздел моделей, который реализован в системе и используется для анализа - это модели дискриминантного анализа. Это раздел вычислительной математики, выделяющий те переменные, которые разделяют наборы признаков по группам. В случае использования методов дискриминантного анализа группы известны заранее, в конкретной системе это группы, которые говорят о падении цены на акцию или её росте (-1) и (1).

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

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

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

Логистическая регрессия - это статистический метод, который предсказывает значения, подгоняя их под логистическую кривую (см. рисунок 9).

Рисунок 9. График логистической кривой.

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


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

В системе данная модель реализована с помощью специализированной библиотеки scikit-learn и метод логистической регрессии имеет вид:

def LogisticRegressionModel(x,y,d): model1 = linear_model.LogisticRegression() model1.fit(x, y) d['Predict_LR'] = model1.predict(x) d["Correct_LR"] = (1.0 + d['Predict_LR'] * d["Actual"]) / 2.0 return d

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

В случае двух групп, ЛДА можно сравнить со множественной регрессией. В нашем случае названия двух групп кодируются как 1 и (-1). При применении метода множественной регрессии мы получим такой же результат. В общем виде ЛДА это приведение функции к виду: . Можно обратить внимание, что те признаки, которые будут обладать наибольшим весовым коэффициентом будут влиять сильнее на итоговое распределение по группам.

В системе данный метод реализован следующим образом:

def LinearDiscriminantModel(x,y,d): model2 = LDA(solver='lsqr', shrinkage='auto').fit(x,y) d['Predict_LDA'] = model2.predict(x) d["Correct_LDA"] = (1.0+d['Predict_LDA']*d["Actual"])/2.0 return d

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

Программная реализация этого метода имеет вид:

def QuadraticDiscriminantModel(x,y,d): model3 = QDA() model3.fit(x, y) d['Predict_QDA'] = model3.predict(x) d["Correct_QDA"] = (1.0 + d['Predict_QDA'] * d["Actual"]) / 2.0

return d

В разделе анализа временных рядов особое место занимают авторегрессионные модели. В системе разработаны следующие модели из данного раздела: авторегресионные модель, авторегрессионная модель - скользящего среднего, авторегрессионная модель интегрированного скользящего среднего и модель авторегресионной условной гетероскедастичности.

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

Авторегресионная модель - это модель временного ряда, в которой значения данного временного ряда в данный момент времени линейным образом зависят от значений, которые были в прошлом. В общем виде модель авторегрессии порядка p имеет вид:


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

Усложненная авторегрессионная модель - скользящего среднего является объединением двух более простых (авторегрессионной модели и модели скользящего среднего). Модель ARMA(p,q) имеет два параметра, а именно два целых числа p и q, которые задают порядок модели: p отвечает за авторегрессионную часть модели, а q - за часть скользящего среднего. Данная модель в общем виде выглядит следующим образом:


где вектора - являются весовыми коэффициентами авторегрессионной и скользящей средней составляющих соответственно.

Интегрированная авторегрессионная модель - скользящего среднего - это модификация модели ARMA(p,q) для нестационарных рядов с разностью порядка d, которое делает ряд стационарным. Данная модель имеет следующее обозначение - ARIMA(p,d,q), однако данную модель можно записать как ARMA(p+d,q). Это значит, что при d=0 получается обычная модель ARMA(p,q). В общем виде модель ARIMA имеет вид:


где - является разностью порядка d.

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


где q - порядок модели, - коэффициенты модели, а


В случае, когда сумма всех коэффициентов модели меньше единицы - временной ряд является стационарным, если эта сумма равна 1, то получаем интегрированную ARCH.

Обобщенной версией модели ARCH является модель GARCH. Данная модель, в отличие от ARCH, предполагает, что значения условной дисперсии зависят не только от квадратов прошлых значений ряда, но и от квадратов прошлых значений условной дисперсии данного ряда. Таким образом формула GARCH-модели имеет вид:


В случае, когда сумма всех коэффициентов модели меньше единицы - временной ряд является стационарным, если эта сумма равна 1, то получаем интегрированную IGARCH.

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



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

.1.5 Блок визуализации данных

Данный блок даёт возможность оценивать данные и модели, построенные по обучающим данным. Иногда зависимости можно заметить на графике, а также оценить качество той или иной модели.

Графики временных рядов позволяют оценить движение данных, а также то, насколько хорошо модель подходит к данному временному ряду (рисунок 10).

Рисунок 10. График временного ряда.

В системе реализованы графики для анализа тренда (рисунок 11). В местах перегибов происходит изменение тренда. Если линия переходит из значения 1 в значение (-1), значит открывается нисходящий тренд. Если линия переходит из значения (-1) в 1, значит открывается восходящий тренд.

Рисунок 11. График поиска трендов.

Более того, существует график, показывающий отклонения графика (рисунок 12). Данный график позволяет оценить и сравнить эффективность того или иного метода анализа визуально.

Рисунок 12. График разностей значений.

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

2.1.6 Блок тестирования результатов анализа

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

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

Таблица 2. Тестовые промежутки.

Тестовый временной промежуток 1Тестовый временной промежуток 2Тестовый временной промежуток 3Тестовый временной промежуток 42017/1/1 - 2017/2/12017/1/1 - 2017/3/12017/1/1 - 2017/4/12017/1/1 - 2017/5/1

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

В данной системе были выбраны и реализованы следующие критерии эффективности: средняя ошибка, абсолютная средняя ошибка, средний процент ошибок, средний абсолютный процент ошибок, средняя квадратичная ошибка, коэффициент детерминации, информационный критерий Аике, байесовский информационный критерий.


.1.7 Торговый блок

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

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

2.1.8 Блок взаимодействия с пользователем

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

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

Рисунок 13. Интерфейс пользовательского блока.

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

Группа элементов «Аналитический блок» - это та часть, куда пользователь вводит искомые данные. Данная группа элементов содержит две другие группы элементов («Начало периода» и «Конец периода»), поле ввода названия акции, а также кнопку «Анализ». Группа элементов «Начало периода» содержит поля для ввода года, месяца и дня начало периода для анализа. Группа элементов «Конец периода» содержит поля для ввода года, месяца и дня начало периода для анализа. При нажатии кнопки «Анализ» инициируется процесс анализа данных.

Группа элементов «Результат анализа» - тот блок, который содержит в себе таблицу, в которую выводятся результаты анализа.

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

Группа элементов «Торговый блок» содержит в себе поле для ввода начального капитала (при подключении к реальному брокеру выводится сумма на счёте), поле для вывода результирующего капитала после торговой сессии и текстовый блок, куда выводятся отметки по покупке и продаже акций. Кнопка «Начать торговлю» инициирует процесс торговли с созданной системой стратегией.

.2 Основной функционал системы

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

·скачивания данных;

·обработки и подготовки данных;

·архивации данных;

·визуализации данных;

·анализа данных;

·улучшения параметров аналитических моделей;

·тестирования работы моделей;

·проверки качества и эффективности моделей;

·имитации торговли.

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

Функция скачивания данных заключается в формировании запроса от пользователя, передачу его на сайт yahoo.finance.com и получение готовых данных с сайта. Данная функция позволяет получать данные практически по всем ценным бумага, представленным на сайте. Актуальность данной функции для системы велика, т.к. без данных анализ невозможен. Более того, в системе данная функция реализована таким образом, что пользователь способен получить данные за любой временной период. Блок, который реализует функцию не создаёт никаких лишних файлов и проверок, что позволяет исполнять скачивание данных за достаточно короткий промежуток времени.

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

Ещё одна функция, завязанная на обработке и работе с данными - это функция архивация данных. Её наличие не так очевидно и необходимо на первый взгляд. Учитывая, что получение данных не вызывает никаких проблем и занимает небольшое количество времени, как и сам анализ. Однако, стоит отметить при активном использовании системы и проведении множества тестов на различных данных возникнет вопрос о стабильности системы и сравнении результатов всех тестов, дабы выделить те модели и те критерии, которые показывают наиболее релевантные результаты. Отсюда исходит необходимость хранения истории работы с системой. Данная функция берёт загруженный набор данных для тестов и сохраняет их в специализированной базе данных. Более того, архивируются не только сами данные, но и качественные результаты эффективности работы каждой модели.

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

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

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

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

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

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

.3 Алгоритм работы системы

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

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

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

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

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

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

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

Разобрав все взаимосвязи системы, можно описать алгоритм работы системы (см. рисунок 14). Работа системы начинается с того момента, когда пользователь вводит данные и отправляет их на дальнейший анализ. Затем критерии запроса из блока взаимодействия с пользователем передаются в блок получения данных. После завершения скачивания и обработки данных они сохраняются в базе данных и одновременно передаются в блок анализа данных. На основе скачанных и подготовленных данных производится построения моделей и затем информация обо всех построенных моделях передается в тестовый блок. В тестовом блоке все модели проходят тестирование на некоторых тестовых наборах данных. На основе полученных результатов производится расчёт критериев эффективности. Затем все эти данные сохраняются в базе данных и выводятся пользователю. После получения результатов анализа пользователь может отобразить данные на графике или запустить имитацию торгов. На этом цикл работы системы завершается, и пользователь может инициировать повторный анализ для другой акции или для другого временного периода.

Рисунок 14. Алгоритм работы системы.

Глава 3. Оценка эффективности автоматической биржевой системы

3.1Выбор критериев эффективности

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

Первый критерий, который показывает непосредственно само отклонение - это среднее абсолютное отклонение. Данный критерий показывает среднюю ошибку для модели по модулю. При увеличении значения данного показателя актуальность прогнозов конкретной модели теряется. Формула для расчёта имеет вид:


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

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


где - это реальное значение показателя, а - спрогнозированное системой.

Средний абсолютный процент ошибок - это ещё один универсальный критерий для сравнения моделей между собой. В связи с тем, что ошибка выражается в процентах, мы можем сравнивать качество работы на разных временных рядах для одной акции и на одном временном ряде для разных акций. Такой подход позволяет выявить слабые и сильные стороны моделей и подобрать наиболее подходящую под конкретный случай. Формула имеет вид:


где - это реальное значение показателя, а - спрогнозированное системой.

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

где - это значения множества, а - это среднее значение по всему множеству.

Ещё один критерий, который используется для оценки качества моделей - это коэффициент детерминации. R^2 - это доля дисперсии объясняемой переменной, моделирование которой происходит с помощью данного набора переменных. Иначе говоря, основной смысл данного критерия заключен в том, что чем ближе значение к 1, тем лучше построенная модель соответствует набору данных. Для адекватности модели значение показателя должны быть больше 0.5. Формула для расчёта данного коэффициента имеет вид:


где - дисперсия случайной ошибки модели, - дисперсия зависящей переменной.

Следующие три коэффициента относятся только к авторегрессионным моделям.

Первый такой критерий в системе - это информационный критерий Акаике (AIC). Данный критерий применяется только для оценки статистических моделей. Более того, статистическая модель должна строится с помощью метода максимального правдоподобия. Формула для расчета данного критерия в общем случае имеет вид:

где k - это число параметров модели, а L - максимум функции правдоподобия. AIC можно выразить также через количество наблюдений и остаточную сумму квадратов, тогда формула примет следующий вид:


где n - это число наблюдений, а RSS - остаточная сумма квадратов.

Другой информационный критерий, используемый для оценки и сравнения авторегресиионных моделей - это байесовский критерий информации (BIC). В отличие от критерия AIC, BIC накладывает штраф за сложность модели, иными словами за увеличение количества объясняющих переменных. Формула BIC имеет вид:


Ещё один критерий, который является аналогом AIC и BIC, называется критерий Ханна-Квин (HQC). Данный критерий также используется для выбора наилучшей модели.


3.2Методика исследования эффективности

В данной работе проверка работы системы будет производится на акциях двух компаний, принадлежащих отрасли информационных технологий, а именно Microsoft. Анализ будет проводится на двух временных промежутках (таблица 3) с учётом ограничения, которое накладывается тестовым блоком. Временные промежутки для анализа представлены в таблице. Анализ будет проводится по цене закрытия.

Таблица 3. Временные промежутки для анализа.

Временной промежуток 1Временной промежуток 22013/1/1 - 2016/12/312015/1/1 - 2016/12/31

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

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

Сначала происходит построение всех скользящих средних. Так как это всего лишь сглаживающие прямые, которые не зависят от размера обучающей выборки, то данные скользящие построены для второго временного промежутка. Простая, треугольная и экспоненциальная скользящие средние построены для трёх разных периодов: быстрого (10), среднего (50) и медленного (100). Такой выбор периодов обусловлен тем, что определение тренда зависит от пересечения или взаимного расположения скользящих средних разных периодов. В нашей системе проверяется верность данного утверждения. Для каждой скользящей средней из всех приведенных выше строится три графика - график временного ряда, график разностей и трендовый график. Для скользящих средних ещё вычисляются критерии MAE, MPE, MAPE и MSE. Данные критерии позволят оценить качество той или иной скользящей средней и сравнить их типы. Касаемо двойной и тройной экспоненциальных скользящих средних, то для них, помимо периодов 10, 50, 100, был выбран ряд параметров beta (для beta [0.25;0.5]) и gamma (для gamma [0.05;0.1]) и с помощью графиков и критериев эффективности, у нас появится возможность определить наилучший вариант с показателями.

Дальше происходит моделирование с помощью методов дискриминантного анализа: логистической регрессии, линейного и квадратичного дискриминантных анализов. Во-первых, в системе происходит сравнение двух типов входных данных: бинарного и количественного. Также происходит поиск оптимального количества переменных для анализа, с учётом минимизации количества параметров и максимизации показателей. В системе рассматривается несколько вариантов: 2, 5, 10, 25. Затем для проверки значений строятся прогнозы на тестовых данных. Для сравнения и оценки результатов производится расчёт показателей MPE для обучающей и тестовой выборок.


3.3Анализ результатов моделирования

После проведения анализа и тестирования данных стоит проанализировать непосредственно полученные результаты. Анализ результатов будет проводится в том же порядке, в котором проводилось моделирование. Первые результаты отображают характеристики и графики простой скользящей средней для трёх исследуемых периодов (рисунок 15).

Рисунок 15. Графики простой скользящей средней.

Первое на что стоит обратить внимание - это то, как реагирует скользящая средняя на резкие скачки цен. Это отражается на графиках разностей. Чем больше период скользящей средней, тем она менее чувствительна к резким ценовым изменениям. Обращая внимания на критерии эффективности, можно заметить, что значения MAE и MSE растут при увеличении периода, что ещё раз подтверждает, что скользящая с большим период лучше отображает тренд. Данное утверждение является верным для всех типов скользящих средних, реализованных в системе.

Другая скользящая средняя - это треугольная скользящая средняя. На графике временного ряда для данной кривой (рисунок 16) отчётливо видно, что кривая с наименьшим периодом повторяет линию реального временного ряда, наиболее качественным образом, тогда как скользящие средней и медленной скорости проявляют себя неадекватно заданному временному ряду.

Рисунок 16. Графики треугольной скользящей средней.

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

Рисунок 17. График экспоненциальной скользящей средней.

Следующий этап анализа заключается в построении моделей классификации методами дискриминантного анализа. Для начала нужно оценить, какого типа набор данных даёт качественные значения для прогнозирования: бинарный или количественный. В случае с моделью логистической регрессии процент верных предсказаний на обучающей выборке равен 55,34203 и на обучаемой выборке 51,41613 для бинарного набора данных, а для количественного набора данных 54,98242 на обучающей выборке и 50,91265 на обучаемой выборке. Данный показатель говорит, что в случае логистической регрессии целесообразнее использовать бинарный набор данных. Для линейного дискриминантного анализа для бинарного набора данных процентный показатель ошибки равен 56,23453 и 52,92742 для обучающей и обучаемой выборкой соответственно. Тогда как для количественного набора данных процентный показатель ошибки для обучающейся выборки равен 54,29462, а для обучаемой 51,39874. Однако, для квадратичного дискриминантного анализа количественный набор данных выдает процент корректных значений равный 57,32093 для обучающих и 53,83722 для обучаемых данных, тогда как для бинарного набора данных эти коэффициенты равны 55,39273 и 51,90234 соответственно. Исходя из этого, для данной системы логистическая регрессия и линейный дискриминантный анализ должны быть построены на бинарном наборе данных, а квадратичный дискриминантный анализ - на количественном.

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

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

Другой критерий, который может оказаться важным для построения итоговых моделей на основании дискриминантного анализа, количество параметров, на основе которых происходит построение моделей данных и их последующие анализ и прогнозирование. В данном исследовании для логистической регрессии наиболее релевантным оказалось наименьшее из рассмотренных значений количества параметров, как для обучающей, так и для обучаемой выборок. Для линейного дискриминантного анализа наиболее релевантными для обучающей выборки оказались значения в диапазоне от 10 до 25, тогда как для обучаемой выборки они проявили себя хуже, чем обычно. Соответственно, определить набор, который будет выдавать качественные результаты для метода линейного дискриминантного анализа оказалось невозможным. Касаясь дискриминантного анализа, то качество результатов повышается, исходя из критерия, вместе с увеличением количества переменных. Однако, стоит отметить, что разница между получаемыми значениями для обучающей и обучаемой выборок составляет больше 20%.

Заключение

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

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

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

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

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

Список литературы

1.Alpaydin, E. (2004). Introduction to Machine Learning.

.Chan, E. P. (2009). Quantitative Trading: How to Build Your Own Algorithmic Trading Business. New Jersey: John Wiley & Sons, Inc.

.Erlich, A. A. (1996). Technical Analysis Handbook for the Commodity and Financial Markets. Moscow: INFRA - M .

.Kijanica, A. S. (2005). Fundamental Analysis of the Financial Markets. Saint-Petersburg: Piter.

.Microsoft. (2017). социальная сеть разработчиков. Получено из MSDN: https://msdn.microsoft.com/ru-ru/dn308572.aspx

.Narang, R. K. (2009). Inside The Black Box. New Jersey: John Wiley & Sons, Inc.

.Schwager, J. D. (1996). Technical Analysis. New Jersey: John Wiley & Sons, Inc.

.Soren Bisgaard, M. K. (2011). Time Series Analysis and Forecasting by Example.

.Tsay, R. S. (2001). Analysis of Financial Time Series.

.А.И.Орлов. (2009). Эконометрика : учебник для вузов. Ростов: Феникс.

.Белова Е.В., О. Д. (2006). Технический анализ финансовых рынков. Москва.

.Бокс, Д. (1970). Time series analysis, forecasting and control.

.Тревор Хасти, Р. Т. (2001). The Elements of Statistical Learning.

Приложения

Блок анализа данных

import DataBlock as dbimport pandas as pdimport datetime as dtimport AnalysisBlock as abimport matplotlib.pyplot as pltimport TestBlock as tbimport statsmodels.tsa.stattools as tsa_testimport statsmodels.tsa.arima_model as ARIMAimport numpy as npfile = open('TestFile.Txt','r')n = file.readlines()Stock_Name = n[0].strip('\n')Stock_Start_Year = str(n[1].strip('\n'))Stock_Start_Month = str(n[2].strip('\n'))Stock_Start_Day = str(n[3].strip('\n'))Stock_End_Year = str(n[4].strip('\n'))Stock_End_Month = str(n[5].strip('\n'))Stock_End_Day = str(n[6].strip('\n'))Stock_Start_Year_Tr = '2016'Stock_Start_Month_Tr = '8'Stock_Start_Day_Tr = '9'Stock_End_Year_Tr = '2017'Stock_End_Month_Tr = '5'Stock_End_Day_Tr = '1'CloseData1 = pd.DataFrame(db.Get_Close_Percent(Stock_Name,dt.datetime(int(Stock_Start_Year), int(Stock_Start_Month), int(Stock_Start_Day)),dt.datetime(int(Stock_End_Year),int(Stock_End_Month), int(Stock_End_Day))))CloseData1Tr = pd.DataFrame(db.Get_Close_Percent(Stock_Name,dt.datetime(int(Stock_Start_Year_Tr), int(Stock_Start_Month_Tr), int(Stock_Start_Day_Tr)),dt.datetime(int(Stock_End_Year_Tr),int(Stock_End_Month_Tr), int(Stock_End_Day_Tr))))CloseData1B = pd.DataFrame(db.Get_Close_Direction(Stock_Name,dt.datetime(int(Stock_Start_Year), int(Stock_Start_Month), int(Stock_Start_Day)),dt.datetime(int(Stock_End_Year),int(Stock_End_Month), int(Stock_End_Day))))CloseData1TrB = pd.DataFrame(db.Get_Close_Direction(Stock_Name,dt.datetime(int(Stock_Start_Year_Tr), int(Stock_Start_Month_Tr), int(Stock_Start_Day_Tr)),dt.datetime(int(Stock_End_Year_Tr),int(Stock_End_Month_Tr), int(Stock_End_Day_Tr))))Stock_Start_Year = '2013'Stock_End_Month_Tr = '3'CloseData2 = pd.DataFrame(db.Get_Close_Percent(Stock_Name,dt.datetime(int(Stock_Start_Year), int(Stock_Start_Month), int(Stock_Start_Day)),dt.datetime(int(Stock_End_Year),int(Stock_End_Month), int(Stock_End_Day))))CloseData2Tr = pd.DataFrame(db.Get_Close_Percent(Stock_Name,dt.datetime(int(Stock_Start_Year_Tr), int(Stock_Start_Month_Tr), int(Stock_Start_Day_Tr)),dt.datetime(int(Stock_End_Year_Tr),int(Stock_End_Month_Tr), int(Stock_End_Day_Tr))))CloseData2B = pd.DataFrame(db.Get_Close_Direction(Stock_Name,dt.datetime(int(Stock_Start_Year), int(Stock_Start_Month), int(Stock_Start_Day)),dt.datetime(int(Stock_End_Year),int(Stock_End_Month), int(Stock_End_Day))))CloseData2TrB = pd.DataFrame(db.Get_Close_Direction(Stock_Name,dt.datetime(int(Stock_Start_Year_Tr), int(Stock_Start_Month_Tr), int(Stock_Start_Day_Tr)),dt.datetime(int(Stock_End_Year_Tr),int(Stock_End_Month_Tr), int(Stock_End_Day_Tr))))listErrors = []tssN = 0.0tssNT = 0.0ts1,ts2 = ab.LogisticRegressionModel(2,CloseData2,CloseData2Tr)tssN+=ts1tssNT+=ts2listErrors.append('#1 LogReg-N-2 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LogisticRegressionModel(5,CloseData2,CloseData2Tr)tssN+=ts1tssNT+=ts2listErrors.append('#1 LogReg-N-5 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LogisticRegressionModel(10,CloseData2,CloseData2Tr)tssN+=ts1tssNT+=ts2listErrors.append('#1 LogReg-N-10 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LogisticRegressionModel(25,CloseData2,CloseData2Tr)tssN+=ts1tssNT+=ts2listErrors.append('#1 LogReg-N-25 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(2,CloseData2,CloseData2Tr)tssN+=ts1tssNT+=ts2listErrors.append('#1 LDA-N-2 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(5,CloseData2,CloseData2Tr)tssN+=ts1tssNT+=ts2listErrors.append('#1 LDA-N-5 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(10,CloseData2,CloseData2Tr)tssN+=ts1tssNT+=ts2listErrors.append('#1 LDA-N-10 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(25,CloseData2,CloseData2Tr)tssN+=ts1tssNT+=ts2listErrors.append('#1 LDA-N-25 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(2,CloseData2,CloseData2Tr)tssN+=ts1tssNT+=ts2listErrors.append('#1 QDA-N-2 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(5,CloseData2,CloseData2Tr)tssN+=ts1tssNT+=ts2listErrors.append('#1 QDA-N-5 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(10,CloseData2,CloseData2Tr)tssN+=ts1tssNT+=ts2listErrors.append('#1 QDA-N-10 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(25,CloseData2,CloseData2Tr)tssN+=ts1tssNT+=ts2listErrors.append('#1 QDA-N-25 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LogisticRegressionModel(2,CloseData2B,CloseData2TrB)tssN+=ts1tssNT+=ts2listErrors.append('#1 LogReg-B-2 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LogisticRegressionModel(5,CloseData2B,CloseData2TrB)tssN+=ts1tssNT+=ts2listErrors.append('#1 LogReg-B-5 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LogisticRegressionModel(10,CloseData2B,CloseData2TrB)tssN+=ts1tssNT+=ts2listErrors.append('#1 LogReg-B-10 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LogisticRegressionModel(25,CloseData2B,CloseData2TrB)tssN+=ts1tssNT+=ts2listErrors.append('#1 LogReg-B-25 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(2,CloseData2B,CloseData2TrB)tssN+=ts1tssNT+=ts2listErrors.append('#1 LDA-B-2 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(5,CloseData2B,CloseData2TrB)tssN+=ts1tssNT+=ts2listErrors.append('#1 LDA-B-5 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(10,CloseData2B,CloseData2TrB)tssN+=ts1tssNT+=ts2listErrors.append('#1 LDA-B-10 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(25,CloseData2B,CloseData2TrB)tssN+=ts1tssNT+=ts2listErrors.append('#1 LDA-B-25 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(2,CloseData2B,CloseData2TrB)tssN+=ts1tssNT+=ts2listErrors.append('#1 QDA-B-2 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(5,CloseData2B,CloseData2TrB)tssN+=ts1tssNT+=ts2listErrors.append('#1 QDA-B-5 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(10,CloseData2B,CloseData2TrB)tssN+=ts1tssNT+=ts2listErrors.append('#1 QDA-B-10 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(25,CloseData2B,CloseData2TrB)tssN+=ts1tssNT+=ts2listErrors.append('#1 QDA-B-25 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))print "Nmean: " , tssN/24print "NTmean: " , tssNT/24import mathimport sklearn.metrics as mdef get_MAE(real,predict): result = 0.0 for i in range(len(real)): result += abs(real[i] - predict[i]) result /= len(real) return resultdef get_MPE(real,predict): result = 0.0 for i in range(len(real)): result += (real[i] - predict[i])/real[i] result /= len(real) return result*100def get_MAPE(real,predict): result = 0.0 for i in range(len(real)): result += abs(real[i] - predict[i])/real[i] result /= len(real) return result*100def get_MSE(real,predict): result = 0.0 for i in range(len(real)): result += (real[i] - predict[i])*(real[i] - predict[i]) result /= (len(real)-1) return math.sqrt(result)def get_R_2(real,predict): return m.r2_score(real,predict)def get_all_mistakes(name,real,predict): return name + " MAE: " + str(get_MAE(real,predict)) + " MPE: " + str(get_MPE(real,predict)) + "% MAPE: " + str(get_MAPE(real,predict)) + "% MSE: " + str(get_MSE(real,predict))

import pandas as pdimport numpy as npfrom sklearn import preprocessingfrom sklearn import linear_modelfrom sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA,QuadraticDiscriminantAnalysis as QDAdef DataTrend(sma1,name1,sma2,name2,count): sma1 = pd.DataFrame(sma1) sma1.rename(columns={'Today':name1},inplace=True) sma2 = pd.DataFrame(sma2) sma2.rename(columns = {'Today': name2}, inplace = True) TrendList = sma1.join(sma2, how='inner') TrendList = TrendList[count:] TrendList['Trend'] = np.sign(TrendList[name1]-TrendList[name2]) return TrendListdef SimpleMovingAverage(array, period): return array.rolling(window=period).mean()def TriangMovingAverage(array, period): return array.rolling(window=period, win_type='triang').mean()def ExponentialMovingAverage(array, period): alpha = 2.0/(period + 1.0) return array.ewm(alpha=alpha).mean()def DoubleExponentialSmoothing(series, period1, beta): alpha = 2.0 / (period1 + 1.0) result = [] for n in range(1, len(series)+1): if n == 1: level, trend = series[0], series[1] - series[0] if n >= len(series): value = result[-1] else: value = series[n] last_level, level = level, alpha*value + (1-alpha)*(level+trend) trend = beta*(level-last_level) + (1-beta)*trend result.append(level+trend) return resultclass HoltWinters: def __init__(self, series, slen, alpha, beta, gamma, n_preds, scaling_factor=1.96): self.series = series self.slen = slen self.alpha = alpha self.beta = beta self.gamma = gamma self.n_preds = n_preds self.scaling_factor = scaling_factor def initial_trend(self): sum = 0.0 for i in range(self.slen): sum += float(self.series[i+self.slen] - self.series[i]) / self.slen return sum / self.slen def initial_seasonal_components(self): seasonals = {} season_averages = [] n_seasons = int(len(self.series)/self.slen) for j in range(n_seasons): season_averages.append(sum(self.series[self.slen*j:self.slen*j+self.slen])/float(self.slen)) for i in range(self.slen): sum_of_vals_over_avg = 0.0 for j in range(n_seasons): sum_of_vals_over_avg += self.series[self.slen*j+i]-season_averages[j] seasonals[i] = sum_of_vals_over_avg/n_seasons return seasonals def triple_exponential_smoothing(self): self.result = [] self.Smooth = [] self.Season = [] self.Trend = [] self.PredictedDeviation = [] self.UpperBond = [] self.LowerBond = [] seasonals = self.initial_seasonal_components() for i in range(len(self.series)+self.n_preds): if i == 0: smooth = self.series[0] trend = self.initial_trend() self.result.append(self.series[0]) self.Smooth.append(smooth) self.Trend.append(trend) self.Season.append(seasonals[i%self.slen]) self.PredictedDeviation.append(0) self.UpperBond.append(self.result[0] + self.scaling_factor * self.PredictedDeviation[0]) self.LowerBond.append(self.result[0] - self.scaling_factor * self.PredictedDeviation[0]) continue if i >= len(self.series): m = i - len(self.series) + 1 self.result.append((smooth + m*trend) + seasonals[i%self.slen]) self.PredictedDeviation.append(self.PredictedDeviation[-1]*1.01) else: val = self.series[i] last_smooth, smooth = smooth, self.alpha*(val-seasonals[i%self.slen]) + (1-self.alpha)*(smooth+trend) trend = self.beta * (smooth-last_smooth) + (1-self.beta)*trend seasonals[i%self.slen] = self.gamma*(val-smooth) + (1-self.gamma)*seasonals[i%self.slen] self.result.append(smooth+trend+seasonals[i%self.slen]) self.PredictedDeviation.append(self.gamma * np.abs(self.series[i] - self.result[i]) + (1-self.gamma)*self.PredictedDeviation[-1]) self.UpperBond.append(self.result[-1] + self.scaling_factor * self.PredictedDeviation[-1]) self.LowerBond.append(self.result[-1] - self.scaling_factor * self.PredictedDeviation[-1]) self.Smooth.append(smooth) self.Trend.append(trend) self.Season.append(seasonals[i % self.slen])def LogisticRegressionModel(numb_params,Series,Series_tr): cols = [] for i in range(0, numb_params): cols.extend(["Lag%s" % str(i + 1)]) Series = pd.DataFrame(Series) x = Series[cols] y = Series["Direction"] d = pd.DataFrame(index=y.index) d["Actual"] = y Series_tr = pd.DataFrame(Series_tr) x_tr = Series_tr[cols] y_tr = Series_tr["Direction"] d_tr = pd.DataFrame(index=y_tr.index) d_tr["Actual"] = y_tr model1 = linear_model.LogisticRegression().fit(x, y) d['Predict_LR'] = model1.predict(x) d_tr['Predict_LR'] = model1.predict(x_tr) d["Correct_LR"] = (1.0 + d['Predict_LR'] * d["Actual"]) / 2.0 d_tr["Correct_LR"] = (1.0 + d_tr['Predict_LR'] * d_tr["Actual"]) / 2.0 hit_rate1 = np.mean(d["Correct_LR"]) hit_rate1_tr = np.mean(d_tr["Correct_LR"]) return (hit_rate1 * 100), (hit_rate1_tr * 100)def LinearDiscriminantModel(numb_params,Series,Series_tr): cols = [] for i in range(0, numb_params): cols.extend(["Lag%s" % str(i + 1)]) Series = pd.DataFrame(Series) x = Series[cols] y = Series["Direction"] d = pd.DataFrame(index=y.index) d["Actual"] = y Series_tr = pd.DataFrame(Series_tr) x_tr = Series_tr[cols] y_tr = Series_tr["Direction"] d_tr = pd.DataFrame(index=y_tr.index) d_tr["Actual"] = y_tr model1 = LDA().fit(x, y) d['Predict_LR'] = model1.predict(x) d_tr['Predict_LR'] = model1.predict(x_tr) d["Correct_LR"] = (1.0 + d['Predict_LR'] * d["Actual"]) / 2.0 d_tr["Correct_LR"] = (1.0 + d_tr['Predict_LR'] * d_tr["Actual"]) / 2.0 hit_rate1 = np.mean(d["Correct_LR"]) hit_rate1_tr = np.mean(d_tr["Correct_LR"]) return (hit_rate1 * 100), (hit_rate1_tr * 100)def QuadraticDiscriminantModel(numb_params,Series,Series_tr): cols = [] for i in range(0, numb_params): cols.extend(["Lag%s" % str(i + 1)]) Series = pd.DataFrame(Series) x = Series[cols] y = Series["Direction"] d = pd.DataFrame(index=y.index) d["Actual"] = y Series_tr = pd.DataFrame(Series_tr) x_tr = Series_tr[cols] y_tr = Series_tr["Direction"] d_tr = pd.DataFrame(index=y_tr.index) d_tr["Actual"] = y_tr model1 = QDA().fit(x, y) d['Predict_LR'] = model1.predict(x) d_tr['Predict_LR'] = model1.predict(x_tr) d["Correct_LR"] = (1.0 + d['Predict_LR'] * d["Actual"]) / 2.0 d_tr["Correct_LR"] = (1.0 + d_tr['Predict_LR'] * d_tr["Actual"]) / 2.0 hit_rate1 = np.mean(d["Correct_LR"]) hit_rate1_tr = np.mean(d_tr["Correct_LR"]) return (hit_rate1 * 100), (hit_rate1_tr * 100)

import pandas_datareader as drimport pandas as pdimport numpy as npdef Get_Data (stock_name,start_date,end_date): ts = dr.DataReader(stock_name, "google", start_date, end_date) return tsdef Get_Full_Data(stock_name,start_date,end_date): ts = dr.DataReader(stock_name, "google", start_date, end_date) ts['Median'] = (ts.High + ts.Low)/2 ts['Typical'] = (ts.High + ts.Low + ts.Close) / 3 ts['Weighted'] = (ts.High + ts.Low + 2*ts.Close) / 4 return tsdef Get_Deltas(stock_name,start_date,end_date): ts = Get_Data(stock_name, start_date, end_date) ts1 = pd.DataFrame(index=ts.index) ts1['DeltaHighLow'] = ts['High']-ts['Low'] ts1["DirectionHL"] = np.sign(ts['High']-ts['Low']) ts1['DeltaOpenClose'] = ts['Close']-ts['Open'] ts1["DirectionOC"] = np.sign(ts['Close']-ts['Open']) return ts1def Get_Open(stock_name, start_date, end_date): ts = Get_Data(stock_name, start_date, end_date) ts1 = pd.DataFrame(index=ts.index) ts1["Today"] = ts["Open"] count = 100 for i in range(0, count): ts1["Lag%s" % str(i + 1)] = ts["Open"].shift(i + 1) ts1 = ts1[count + 1:] return ts1def Get_Close(stock_name, start_date, end_date): ts = Get_Data(stock_name, start_date, end_date) ts1 = pd.DataFrame(index=ts.index) ts1["Today"] = ts["Close"] count = 25 for i in range(0, count): ts1["Lag%s" % str(i + 1)] = ts["Close"].shift(i + 1) ts1 = ts1[count + 1:] return ts1def Get_High(stock_name, start_date, end_date): ts = Get_Data(stock_name, start_date, end_date) ts1 = pd.DataFrame(index=ts.index) ts1["Today"] = ts["High"] count = 100 for i in range(0, count): ts1["Lag%s" % str(i + 1)] = ts["High"].shift(i + 1) return ts1def Get_Low(stock_name, start_date, end_date): ts = Get_Data(stock_name, start_date, end_date) ts1 = pd.DataFrame(index=ts.index) ts1["Today"] = ts["Low"] count = 100 for i in range(0, count): ts1["Lag%s" % str(i + 1)] = ts["Low"].shift(i + 1) return ts1def Get_AdjClose(stock_name, start_date, end_date): ts = Get_Data(stock_name, start_date, end_date) ts1 = pd.DataFrame(index=ts.index) ts1["Today"] = ts["Adj Close"] count = 100 for i in range(0, count): ts1["Lag%s" % str(i + 1)] = ts["Adj Close"].shift(i + 1) return ts1def Get_Median(stock_name, start_date, end_date): ts = Get_Full_Data(stock_name, start_date, end_date) ts1 = pd.DataFrame(index=ts.index) ts1["Today"] = ts["Median"] count = 100 for i in range(0, count): ts1["Lag%s" % str(i + 1)] = ts["Median"].shift(i + 1) return ts1def Get_Typical(stock_name, start_date, end_date): ts = Get_Full_Data(stock_name, start_date, end_date) ts1 = pd.DataFrame(index=ts.index) ts1["Today"] = ts["Typical"] count = 100 for i in range(0, count): ts1["Lag%s" % str(i + 1)] = ts["Typical"].shift(i + 1) return ts1def Get_Weighted(stock_name, start_date, end_date): ts = Get_Full_Data(stock_name, start_date, end_date) ts1 = pd.DataFrame(index=ts.index) ts1["Today"] = ts["Weighted"] count = 100 for i in range(0, count): ts1["Lag%s" % str(i + 1)] = ts["Weighted"].shift(i + 1) return ts1def Get_Open_Percent(stock_name, start_date, end_date): ts2 = Get_Open(stock_name, start_date, end_date) ts = pd.DataFrame(index=ts2.index) ts["Today"] = ts2["Today"].pct_change() * 100.0 for i, x in enumerate(ts2["Today"]): if (abs(x) < 0.0001): ts["Today"][i] = 0.0001 count = 100 for i in range(0, count): ts["Lag%s" % str(i + 1)] = ts2["Lag%s" % str(i + 1)].pct_change() * 100.0 ts = ts[count + 1:] ts["Direction"] = np.sign(ts["Today"]) return tsdef Get_Close_Percent(stock_name, start_date, end_date): ts2 = Get_Close(stock_name, start_date, end_date) ts = pd.DataFrame(index=ts2.index) ts["Today"] = ts2["Today"].pct_change() * 100.0 for i, x in enumerate(ts2["Today"]): if (abs(x) < 0.0001): ts["Today"][i] = 0.0001 count = 25 for i in range(0, count): ts["Lag%s" % str(i + 1)] = ts2["Lag%s" % str(i + 1)].pct_change() * 100.0 ts = ts[count + 1:] ts["Direction"] = np.sign(ts["Today"]) return tsdef Get_High_Percent(stock_name, start_date, end_date): ts2 = Get_High(stock_name, start_date, end_date) ts = pd.DataFrame(index=ts2.index) ts["Today"] = ts2["Today"].pct_change() * 100.0 for i, x in enumerate(ts2["Today"]): if (abs(x) < 0.0001): ts["Today"][i] = 0.0001 count = 100 for i in range(0, count): ts["Lag%s" % str(i + 1)] = ts2["Lag%s" % str(i + 1)].pct_change() * 100.0 ts = ts[count + 1:] ts["Direction"] = np.sign(ts["Today"]) return tsdef Get_Low_Percent(stock_name, start_date, end_date): ts2 = Get_Low(stock_name, start_date, end_date) ts = pd.DataFrame(index=ts2.index) ts["Today"] = ts2["Today"].pct_change() * 100.0 for i, x in enumerate(ts2["Today"]): if (abs(x) < 0.0001): ts["Today"][i] = 0.0001 count = 100 for i in range(0, count): ts["Lag%s" % str(i + 1)] = ts2["Lag%s" % str(i + 1)].pct_change() * 100.0 ts = ts[count + 1:] ts["Direction"] = np.sign(ts["Today"]) return tsdef Get_AdjClose_Percent(stock_name, start_date, end_date): ts2 = Get_AdjClose(stock_name, start_date, end_date) ts = pd.DataFrame(index=ts2.index) ts["Today"] = ts2["Today"].pct_change() * 100.0 for i, x in enumerate(ts2["Today"]): if (abs(x) < 0.0001): ts["Today"][i] = 0.0001 count = 25 for i in range(0, count): ts["Lag%s" % str(i + 1)] = ts2["Lag%s" % str(i + 1)].pct_change() * 100.0 ts = ts[count + 1:] ts["Direction"] = np.sign(ts["Today"]) return tsdef Get_Median_Percent(stock_name, start_date, end_date): ts2 = Get_Median(stock_name, start_date, end_date) ts = pd.DataFrame(index=ts2.index) ts["Today"] = ts2["Today"].pct_change() * 100.0 for i, x in enumerate(ts2["Today"]): if (abs(x) < 0.0001): ts["Today"][i] = 0.0001 count = 25 for i in range(0, count): ts["Lag%s" % str(i + 1)] = ts2["Lag%s" % str(i + 1)].pct_change() * 100.0 ts = ts[count + 1:] ts["Direction"] = np.sign(ts["Today"]) return tsdef Get_Typical_Percent(stock_name, start_date, end_date): ts2 = Get_Typical(stock_name, start_date, end_date) ts = pd.DataFrame(index=ts2.index) ts["Today"] = ts2["Today"].pct_change() * 100.0 for i, x in enumerate(ts2["Today"]): if (abs(x) < 0.0001): ts["Today"][i] = 0.0001 count = 25 for i in range(0, count): ts["Lag%s" % str(i + 1)] = ts2["Lag%s" % str(i + 1)].pct_change() * 100.0 ts = ts[count + 1:] ts["Direction"] = np.sign(ts["Today"]) return tsdef Get_Weighted_Percent(stock_name, start_date, end_date): ts2 = Get_Weighted(stock_name, start_date, end_date) ts = pd.DataFrame(index=ts2.index) ts["Today"] = ts2["Today"].pct_change() * 100.0 for i, x in enumerate(ts2["Today"]): if (abs(x) < 0.0001): ts["Today"][i] = 0.0001 count = 25 for i in range(0, count): ts["Lag%s" % str(i + 1)] = ts2["Lag%s" % str(i + 1)].pct_change() * 100.0 ts = ts[count + 1:] ts["Direction"] = np.sign(ts["Today"]) return tsdef Get_Open_Direction(stock_name, start_date, end_date): ts2 = Get_Open(stock_name, start_date, end_date) ts = pd.DataFrame(index=ts2.index) ts["Direction"] = ts2["Today"].pct_change() * 100.0 count = 25 for i in range(0, count): ts["DirectionLag%s" % str(i + 1)] = ts2["Lag%s" % str(i + 1)].pct_change() * 100.0 ts = ts[count + 1:] ts["Direction"] = np.sign(ts["Direction"]) for i in range(0, count): ts["DirectionLag%s" % str(i + 1)] = np.sign(ts["DirectionLag%s" % str(i + 1)]) return tsdef Get_Close_Direction(stock_name, start_date, end_date): ts2 = Get_Close(stock_name, start_date, end_date) ts = pd.DataFrame(index=ts2.index) ts["Direction"] = ts2["Today"].pct_change() * 100.0 count = 25 for i in range(0, count): ts["Lag%s" % str(i + 1)] = ts2["Lag%s" % str(i + 1)].pct_change() * 100.0 ts = ts[count + 1:] ts["Direction"] = np.sign(ts["Direction"]) for i in range(0, count): ts["Lag%s" % str(i + 1)] = np.sign(ts["Lag%s" % str(i + 1)]) return ts= pd.DataFrame(db.Get_Close_Direction(Stock_Name,dt.datetime(int(Stock_Start_Year), int(Stock_Start_Month), int(Stock_Start_Day)),dt.datetime(int(Stock_End_Year),int(Stock_End_Month), int(Stock_End_Day))))CloseDataTrBi = pd.DataFrame(db.Get_Close_Direction(Stock_Name,dt.datetime(int(Stock_Start_Year_Tr), int(Stock_Start_Month_Tr), int(Stock_Start_Day_Tr)),dt.datetime(int(Stock_End_Year_Tr),int(Stock_End_Month_Tr), int(Stock_End_Day_Tr))))listErrors = []fig, axes = plt.subplots(nrows=3, ncols=1)axes[0].plot(pd.DataFrame(CloseData1.Today),Label='General Open Data')ts=pd.DataFrame(CloseData1.Today)axes[0].plot(ab.SimpleMovingAverage(ts,10),Label='SMA-10')axes[0].plot(ab.SimpleMovingAverage(ts,50),Label='SMA-50')axes[0].plot(ab.SimpleMovingAverage(ts,100),Label='SMA-100')axes[0].legend(fontsize = 'xx-small')axes[0].set_title('SMA time series')axes[1].plot(pd.DataFrame(CloseData1.Today).diff(),Label='General Open Data')ts=pd.DataFrame(CloseData1.Today)axes[1].plot(ab.SimpleMovingAverage(ts,10).diff(),Label='SMA-10')axes[1].plot(ab.SimpleMovingAverage(ts,50).diff(),Label='SMA-50')axes[1].plot(ab.SimpleMovingAverage(ts,100).diff(),Label='SMA-100')axes[1].legend(fontsize = 'xx-small')axes[1].set_title('SMA diffs')TrendList1 = ab.DataTrend(ab.SimpleMovingAverage(ts,10),'SMA-10',ab.SimpleMovingAverage(ts,50),'SMA-50',100)TrendList2 = ab.DataTrend(ab.SimpleMovingAverage(ts,10),'SMA-10',ab.SimpleMovingAverage(ts,100),'SMA-100',100)TrendList3 = ab.DataTrend(ab.SimpleMovingAverage(ts,50),'SMA-50',ab.SimpleMovingAverage(ts,100),'SMA-100',100)axes[2].plot(TrendList1.Trend,Label='SMA-10-50')axes[2].plot(TrendList2.Trend,Label='SMA-10-100')axes[2].plot(TrendList3.Trend,Label='SMA-50-100')axes[2].legend(fontsize = 'xx-small')axes[2].set_title('SMA trends')fig.tight_layout()fig.savefig("SMA111.png")sma1 = ab.SimpleMovingAverage(ts,10)['Today'].values.tolist()ts1 = ts['Today'].values.tolist()sma2 = ab.SimpleMovingAverage(ts,50)['Today'].values.tolist()ts2 = ts['Today'].values.tolist()sma3 = ab.SimpleMovingAverage(ts,100)['Today'].values.tolist()ts3 = ts['Today'].values.tolist()listErrors.append(tb.get_all_mistakes('SMA-10',ts1[10:],sma1[10:]))listErrors.append(tb.get_all_mistakes('SMA-50',ts2[50:],sma2[50:]))listErrors.append(tb.get_all_mistakes('SMA-100',ts3[100:],sma3[100:]))#TMAfig, axes = plt.subplots(nrows=3, ncols=1)axes[0].plot(pd.DataFrame(CloseData1.Today),Label='General Open Data')ts=pd.DataFrame(CloseData1.Today)axes[0].plot(ab.TriangMovingAverage(ts,10),Label='TMA-10')axes[0].plot(ab.TriangMovingAverage(ts,50),Label='TMA-50')axes[0].plot(ab.TriangMovingAverage(ts,100),Label='TMA-100')axes[0].legend(fontsize = 'xx-small')axes[0].set_title('TMA time series')axes[1].plot(pd.DataFrame(CloseData1.Today).diff(),Label='General Open Data')ts=pd.DataFrame(CloseData1.Today)axes[1].plot(ab.TriangMovingAverage(ts,10).diff(),Label='TMA-10')axes[1].plot(ab.TriangMovingAverage(ts,50).diff(),Label='TMA-50')axes[1].plot(ab.TriangMovingAverage(ts,100).diff(),Label='TMA-100')axes[1].legend(fontsize = 'xx-small')axes[1].set_title('TMA time series')TrendList1 = ab.DataTrend(ab.TriangMovingAverage(ts,10),'TMA-10',ab.TriangMovingAverage(ts,50),'TMA-50',100)TrendList2 = ab.DataTrend(ab.TriangMovingAverage(ts,10),'TMA-10',ab.TriangMovingAverage(ts,100),'TMA-100',100)TrendList3 = ab.DataTrend(ab.TriangMovingAverage(ts,50),'TMA-50',ab.TriangMovingAverage(ts,100),'TMA-100',100)axes[2].plot(TrendList1.Trend,Label='TMA-10-50')axes[2].plot(TrendList2.Trend,Label='TMA-10-100')axes[2].plot(TrendList3.Trend,Label='TMA-50-100')axes[2].legend(fontsize = 'xx-small')axes[2].set_title('TMA time series')fig.tight_layout()fig.savefig("TMA111.png")sma1 = ab.TriangMovingAverage(ts,10)['Today'].values.tolist()ts1 = ts['Today'].values.tolist()sma2 = ab.TriangMovingAverage(ts,50)['Today'].values.tolist()ts2 = ts['Today'].values.tolist()sma3 = ab.TriangMovingAverage(ts,100)['Today'].values.tolist()ts3 = ts['Today'].values.tolist()listErrors.append(tb.get_all_mistakes('TMA-10',ts1[10:],sma1[10:]))listErrors.append(tb.get_all_mistakes('TMA-50',ts2[50:],sma2[50:]))listErrors.append(tb.get_all_mistakes('TMA-100',ts3[100:],sma3[100:]))#EMAfig, axes = plt.subplots(nrows=3, ncols=1)axes[0].plot(pd.DataFrame(CloseData1.Today),Label='General Open Data')ts=pd.DataFrame(CloseData1.Today)axes[0].plot(ab.ExponentialMovingAverage(ts,10.0),Label='EMA-10')axes[0].plot(ab.ExponentialMovingAverage(ts,50.0),Label='EMA-50')axes[0].plot(ab.ExponentialMovingAverage(ts,100.0),Label='EMA-100')axes[0].legend(fontsize = 'xx-small')axes[0].set_title('EMA time series')axes[1].plot(pd.DataFrame(CloseData1.Today).diff(),Label='General Open Data')ts=pd.DataFrame(CloseData1.Today)axes[1].plot(ab.ExponentialMovingAverage(ts,10.0).diff(),Label='EMA-10')axes[1].plot(ab.ExponentialMovingAverage(ts,50.0).diff(),Label='EMA-50')axes[1].plot(ab.ExponentialMovingAverage(ts,100.0).diff(),Label='EMA-100')axes[1].legend(fontsize = 'xx-small')axes[1].set_title('EMA time series')TrendList1 = ab.DataTrend(ab.ExponentialMovingAverage(ts,10.0),'EMA-10',ab.ExponentialMovingAverage(ts,50.0),'EMA-50',100)TrendList2 = ab.DataTrend(ab.ExponentialMovingAverage(ts,10.0),'EMA-10',ab.ExponentialMovingAverage(ts,100.0),'EMA-100',100)TrendList3 = ab.DataTrend(ab.ExponentialMovingAverage(ts,50.0),'EMA-50',ab.ExponentialMovingAverage(ts,100.0),'EMA-100',100)axes[2].plot(TrendList1.Trend,Label='EMA-10-50')axes[2].plot(TrendList2.Trend,Label='EMA-10-100')axes[2].plot(TrendList3.Trend,Label='EMA-50-100')axes[2].legend(fontsize = 'xx-small')axes[2].set_title('EMA time series')fig.tight_layout()fig.savefig("EMA111.png")sma1 = ab.ExponentialMovingAverage(ts,10.0)['Today'].values.tolist()ts1 = ts['Today'].values.tolist()sma2 = ab.ExponentialMovingAverage(ts,50.0)['Today'].values.tolist()ts2 = ts['Today'].values.tolist()sma3 = ab.ExponentialMovingAverage(ts,100.0)['Today'].values.tolist()ts3 = ts['Today'].values.tolist()listErrors.append(tb.get_all_mistakes('EMA-10',ts1[10:],sma1[10:]))listErrors.append(tb.get_all_mistakes('EMA-50',ts2[50:],sma2[50:]))listErrors.append(tb.get_all_mistakes('EMA-100',ts3[100:],sma3[100:]))fig, axes = plt.subplots(nrows=3, ncols=1)axes[0].plot(pd.DataFrame(CloseData1.Today),Label='General Open Data')ts=pd.DataFrame(CloseData1.Today)list2 = ab.DoubleExponentialSmoothing(CloseData1.Today,10.0,0.25)axes[0].plot(pd.DataFrame(list2,index = CloseData1.index.tolist()),Label='DEMA-10-0.25')list3 = ab.DoubleExponentialSmoothing(CloseData1.Today,10.0,0.5)axes[0].plot(pd.DataFrame(list3,index = CloseData1.index.tolist()),Label='DEMA-10-0.5')axes[0].legend(fontsize = 'xx-small')axes[0].set_title('DEMA-10 time series')ts1 = ts['Today'].values.tolist()listErrors.append(tb.get_all_mistakes('DEMA-10-0.25',ts1,list2))listErrors.append(tb.get_all_mistakes('DEMA-10-0.5',ts1,list3))axes[1].plot(pd.DataFrame(CloseData1.Today),Label='General Open Data')ts=pd.DataFrame(CloseData1.Today)list2 = ab.DoubleExponentialSmoothing(CloseData1.Today,50.0,0.25)axes[1].plot(pd.DataFrame(list2,index = CloseData1.index.tolist()),Label='DEMA-50-0.25')list3 = ab.DoubleExponentialSmoothing(CloseData1.Today,50.0,0.5)axes[1].plot(pd.DataFrame(list3,index = CloseData1.index.tolist()),Label='DEMA-50-0.5')axes[1].legend(fontsize = 'xx-small')axes[1].set_title('DEMA-50 time series')ts1 = ts['Today'].values.tolist()listErrors.append(tb.get_all_mistakes('DEMA-50-0.25',ts1,list2))listErrors.append(tb.get_all_mistakes('DEMA-50-0.5',ts1,list3))axes[2].plot(pd.DataFrame(CloseData1.Today),Label='General Open Data')ts=pd.DataFrame(CloseData1.Today)list2 = ab.DoubleExponentialSmoothing(CloseData1.Today,100.0,0.25)axes[2].plot(pd.DataFrame(list2,index = CloseData1.index.tolist()),Label='DEMA-100-0.25')list3 = ab.DoubleExponentialSmoothing(CloseData1.Today,100.0,0.5)axes[2].plot(pd.DataFrame(list3,index = CloseData1.index.tolist()),Label='DEMA-100-0.5')axes[2].legend(fontsize = 'xx-small')axes[2].set_title('DEMA-100 time series')ts2 = ts['Today'].values.tolist()listErrors.append(tb.get_all_mistakes('DEMA-100-0.25',ts2,list2))listErrors.append(tb.get_all_mistakes('DEMA-100-0.5',ts2,list3))fig.tight_layout()fig.savefig("DEMA111.png")fig, axes = plt.subplots(nrows=3, ncols=1)axes[0].plot(pd.DataFrame(CloseData1.Today),Label='General Open Data')ts=pd.DataFrame(CloseData1.Today)a = ab.HoltWinters(CloseData1.Today,100,2.0/(10.0+1),0.25,0.05,0)a.triple_exponential_smoothing()list1 = a.resultaxes[0].plot(pd.DataFrame(list1,index = CloseData1.index.tolist()),Label='TEMA-10-0.25-0.05')a = ab.HoltWinters(CloseData1.Today,100,2.0/(10.0+1),0.5,0.05,0)a.triple_exponential_smoothing()list2 = a.resultaxes[0].plot(pd.DataFrame(list2,index = CloseData1.index.tolist()),Label='TEMA-10-0.5-0.05')a = ab.HoltWinters(CloseData1.Today,100,2.0/(10.0+1),0.25,0.1,0)a.triple_exponential_smoothing()list3 = a.resultaxes[0].plot(pd.DataFrame(list3,index = CloseData1.index.tolist()),Label='TEMA-10-0.25-0.1')a = ab.HoltWinters(CloseData1.Today,100,2.0/(10.0+1),0.5,0.1,0)a.triple_exponential_smoothing()list4 = a.resultaxes[0].plot(pd.DataFrame(list3,index = CloseData1.index.tolist()),Label='TEMA-10-0.5-0.1')axes[0].legend(fontsize = 'xx-small')axes[0].set_title('TEMA-10 time series')ts1 = ts['Today'].values.tolist()listErrors.append(tb.get_all_mistakes('TEMA-10-0.25-0.05',ts1,list1))listErrors.append(tb.get_all_mistakes('TEMA-10-0.5-0.05',ts1,list2))listErrors.append(tb.get_all_mistakes('TEMA-10-0.25-0.1',ts1,list3))listErrors.append(tb.get_all_mistakes('TEMA-10-0.5-0.1',ts1,list4))axes[1].plot(pd.DataFrame(CloseData1.Today),Label='General Open Data')ts=pd.DataFrame(CloseData1.Today)a = ab.HoltWinters(CloseData1.Today,100,2.0/(50.0+1),0.25,0.05,0)a.triple_exponential_smoothing()list1 = a.resultaxes[1].plot(pd.DataFrame(list1,index = CloseData1.index.tolist()),Label='TEMA-50-0.25-0.05')a = ab.HoltWinters(CloseData1.Today,100,2.0/(50.0+1),0.5,0.05,0)a.triple_exponential_smoothing()list2 = a.resultaxes[1].plot(pd.DataFrame(list2,index = CloseData1.index.tolist()),Label='TEMA-50-0.5-0.05')a = ab.HoltWinters(CloseData1.Today,100,2.0/(50.0+1),0.25,0.1,0)a.triple_exponential_smoothing()list3 = a.resultaxes[1].plot(pd.DataFrame(list3,index = CloseData1.index.tolist()),Label='TEMA-50-0.25-0.1')a = ab.HoltWinters(CloseData1.Today,100,2.0/(50.0+1),0.5,0.1,0)a.triple_exponential_smoothing()list4 = a.resultaxes[1].plot(pd.DataFrame(list3,index = CloseData1.index.tolist()),Label='TEMA-50-0.5-0.1')axes[1].legend(fontsize = 'xx-small')axes[1].set_title('TEMA-50 time series')ts1 = ts['Today'].values.tolist()listErrors.append(tb.get_all_mistakes('TEMA-50-0.25-0.05',ts1,list1))listErrors.append(tb.get_all_mistakes('TEMA-50-0.5-0.05',ts1,list2))listErrors.append(tb.get_all_mistakes('TEMA-50-0.25-0.1',ts1,list3))listErrors.append(tb.get_all_mistakes('TEMA-50-0.5-0.1',ts1,list4))axes[2].plot(pd.DataFrame(CloseData1.Today),Label='General Open Data')ts=pd.DataFrame(CloseData1.Today)a = ab.HoltWinters(CloseData1.Today,100,2.0/(100.0+1),0.25,0.05,0)a.triple_exponential_smoothing()list1 = a.resultaxes[2].plot(pd.DataFrame(list1,index = CloseData1.index.tolist()),Label='TEMA-100-0.25-0.05')a = ab.HoltWinters(CloseData1.Today,100,2.0/(100.0+1),0.5,0.05,0)a.triple_exponential_smoothing()list2 = a.resultaxes[2].plot(pd.DataFrame(list2,index = CloseData1.index.tolist()),Label='TEMA-100-0.5-0.05')a = ab.HoltWinters(CloseData1.Today,100,2.0/(100.0+1),0.25,0.1,0)a.triple_exponential_smoothing()list3 = a.resultaxes[2].plot(pd.DataFrame(list3,index = CloseData1.index.tolist()),Label='TEMA-100-0.25-0.1')a = ab.HoltWinters(CloseData1.Today,100,2.0/(100.0+1),0.5,0.1,0)a.triple_exponential_smoothing()list4 = a.resultaxes[2].plot(pd.DataFrame(list3,index = CloseData1.index.tolist()),Label='TEMA-100-0.5-0.1')axes[2].legend(fontsize = 'xx-small')axes[2].set_title('TEMA-100 time series')ts1 = ts['Today'].values.tolist()listErrors.append(tb.get_all_mistakes('TEMA-100-0.25-0.05',ts1,list1))listErrors.append(tb.get_all_mistakes('TEMA-100-0.5-0.05',ts1,list2))listErrors.append(tb.get_all_mistakes('TEMA-100-0.25-0.1',ts1,list3))listErrors.append(tb.get_all_mistakes('TEMA-100-0.5-0.1',ts1,list4))fig.tight_layout()fig.savefig("TEMA111.png")ts1,ts2 = ab.LogisticRegressionModel(2,CloseData,CloseDataTr)listErrors.append('LogReg-N-2 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LogisticRegressionModel(5,CloseData,CloseDataTr)listErrors.append('LogReg-N-5 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LogisticRegressionModel(10,CloseData,CloseDataTr)listErrors.append('LogReg-N-10 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LogisticRegressionModel(25,CloseData,CloseDataTr)listErrors.append('LogReg-N-25 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LogisticRegressionModel(100,CloseData,CloseDataTr)listErrors.append('LogReg-N-100 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LogisticRegressionModel(2,CloseDataBi,CloseDataTrBi)listErrors.append('LogReg-B-2 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LogisticRegressionModel(5,CloseDataBi,CloseDataTrBi)listErrors.append('LogReg-B-5 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LogisticRegressionModel(10,CloseDataBi,CloseDataTrBi)listErrors.append('LogReg-B-10 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LogisticRegressionModel(25,CloseDataBi,CloseDataTrBi)listErrors.append('LogReg-B-25 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LogisticRegressionModel(100,CloseDataBi,CloseDataTrBi)listErrors.append('LogReg-B-100 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(2,CloseData,CloseDataTr)listErrors.append('LDA-N-2 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(5,CloseData,CloseDataTr)listErrors.append('LDA-N-5 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(10,CloseData,CloseDataTr)listErrors.append('LDA-N-10 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(25,CloseData,CloseDataTr)listErrors.append('LDA-N-25 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(100,CloseData,CloseDataTr)listErrors.append('LDA-N-100 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(2,CloseDataBi,CloseDataTrBi)listErrors.append('LDA-B-2 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(5,CloseDataBi,CloseDataTrBi)listErrors.append('LDA-B-5 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(10,CloseDataBi,CloseDataTrBi)listErrors.append('LDA-B-10 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(25,CloseDataBi,CloseDataTrBi)listErrors.append('LDA-B-25 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.LinearDiscriminantModel(100,CloseDataBi,CloseDataTrBi)listErrors.append('LDA-B-100 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(2,CloseData,CloseDataTr)listErrors.append('QDA-N-2 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(5,CloseData,CloseDataTr)listErrors.append('QDA-N-5 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(10,CloseData,CloseDataTr)listErrors.append('QDA-N-10 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(25,CloseData,CloseDataTr)listErrors.append('QDA-N-25 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(100,CloseData,CloseDataTr)listErrors.append('QDA-N-100 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(2,CloseDataBi,CloseDataTrBi)listErrors.append('QDA-B-2 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(5,CloseDataBi,CloseDataTrBi)listErrors.append('QDA-B-5 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(10,CloseDataBi,CloseDataTrBi)listErrors.append('QDA-B-10 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(25,CloseDataBi,CloseDataTrBi)listErrors.append('QDA-B-25 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))ts1,ts2 = ab.QuadraticDiscriminantModel(100,CloseDataBi,CloseDataTrBi)listErrors.append('QDA-B-100 MPE_tr: ' + str(ts1) + ' MPE_test: '+ str(ts2))for i in range(len(listErrors)): print listErrors[i]

import pyodbcimport pandas as pddef Get_Stocks(): cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=ASUS\SERVER;DATABASE=DiplomaDataBase;Trusted_Connection=True') cursor = cnxn.cursor() querry = "select I.[Industry_Code],[Industry_Name],[Stock_Code],[Company_Name] from [dbo].[Company_Stocks] CS inner join [dbo].[Industries] I on CS.[Industry_Code]=I.[Industry_Code] order by 1,3 " cursor.execute(querry) list=[] for row in cursor: list.append([j for j in row]) cnxn.commit() return listdef Get_Results(): cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=ASUS\SERVER;DATABASE=DiplomaDataBase;Trusted_Connection=True') cursor = cnxn.cursor() querry = "select TR.Test_Code,M.Model_Name,EF.Parametr_Name,tr.Result_Value from [dbo].[Effectiveness_Parametrs] EF inner join [dbo].[Test_Result] TR on EF.Parametr_Code=TR.Parametr_Code inner join [dbo].[Model] M on TR.Model_Code=M.Model_Code order by 1" cursor.execute(querry) list=[] for row in cursor: list.append([j for j in row]) cnxn.commit() return listdef Insert_Test(Test_Name): cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=ASUS\SERVER;DATABASE=DiplomaDataBase;Trusted_Connection=True') cursor = cnxn.cursor() querry = "insert into [dbo].[Test] values ((select count(*)+1 from Test),'"+Test_Name+"' + (select count(*)+1 from Test))" cursor.execute(querry) cnxn.commit() cursor = cnxn.cursor() querry = "select count(*) from Test" cursor.execute(querry) list=[] for row in cursor: list.append([j for j in row]) cnxn.commit() return list[0][0]def Insert_Industry(Code,Name): cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=ASUS\SERVER;DATABASE=DiplomaDataBase;Trusted_Connection=True') cursor = cnxn.cursor() querry = "select * from [dbo].[Industries]" cursor.execute(querry) list=[] for row in cursor: list.append([j for j in row]) cnxn.commit() a=0 for row in list: if(row[0]==Code and row[1]==Name): a = 1 if (a==0): cursor = cnxn.cursor() querry = "Insert into [dbo].[Industries] values ('" +Code + "','" + Name+"')" cursor.execute(querry) cnxn.commit()def Insert_Stocks(Code,Name,ICode): cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=ASUS\SERVER;DATABASE=DiplomaDataBase;Trusted_Connection=True') cursor = cnxn.cursor() querry = "select * from [dbo].[Stocks]" cursor.execute(querry) list=[] for row in cursor: list.append([j for j in row]) cnxn.commit() a=0 for row in list: if(row[0]==Code and row[1]==Name and row[2]==ICode): a = 1 if (a==0): cursor = cnxn.cursor() querry = "Insert into [dbo].[Stocks] values ('" +Code + "','" + Name+"','"+ICode+"')" cursor.execute(querry) cnxn.commit()def Insert_Params(Code,Name,Description): cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=ASUS\SERVER;DATABASE=DiplomaDataBase;Trusted_Connection=True') cursor = cnxn.cursor() querry = "select * from [dbo].[Effectiveness_Parametrs]" cursor.execute(querry) list=[] for row in cursor: list.append([j for j in row]) cnxn.commit() a=0 for row in list: if(row[0]==Code): a = 1 if (a==0): cursor = cnxn.cursor() querry = "insert into [dbo].[Effectiveness_Parametrs] ([Parametr_Code],[Parametr_Name],[Parametr_Description]) values ('" +Code + "','" + Name+"','"+Description+"')" cursor.execute(querry) cnxn.commit()def Insert_Model(Code,Name,Features,Description): cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=ASUS\SERVER;DATABASE=DiplomaDataBase;Trusted_Connection=True') cursor = cnxn.cursor() querry = "select * from [dbo].[Model]" cursor.execute(querry) list=[] for row in cursor: list.append([j for j in row]) cnxn.commit() a=0 for row in list: if(row[0]==Code): a = 1 if (a==0): cursor = cnxn.cursor() querry = "insert into [dbo].[Model] ([Model_Code],[Model_Name],[Model_Features],[Model_Description]) values ('" +Code + "','" + Name+"','"+Features+"','"+Description+"')" cursor.execute(querry) cnxn.commit()def Insert_Test_Result(Test,Parametr,Model,Value): cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=ASUS\SERVER;DATABASE=DiplomaDataBase;Trusted_Connection=True') cursor = cnxn.cursor() querry = "insert into [dbo].[Test_Result] ([Test_Code],[Result_Value],[Parametr_Code],[Model_Code]) values ('"+Test+"','"+Value+"','"+Parametr+"','"+Model+"')" cursor.execute(querry) cnxn.commit()def Insert_Raw_Data(Date,Open,Close,High,Low,Adj_CLose,Volume,Stock,Test): cnxn = pyodbc.connect('DRIVER={SQL Server};SERVER=ASUS\SERVER;DATABASE=DiplomaDataBase;Trusted_Connection=True') cursor = cnxn.cursor() querry = "insert into [dbo].[Raw_Data] values ('"+Date+"',"+str(Open)+","+str(Close)+","+str(High)+","+str(Low)+","+str(Adj_CLose)+","+str(Volume)+",'"+Stock+"',"+str(Test)+")" cursor.execute(querry) cnxn.commit()def Insert_Raw_Data_Series(Series,test_number,stock_name): Series = pd.DataFrame(Series) list2 = Series.values.tolist() list1 = [] for i in range(len(list2)): list1.append(str(Series.index[i])) for i in range(len(list2)): Insert_Raw_Data(list1[i], list2[i][0], list2[i][1], list2[i][2], list2[i][3], list2[i][5], list2[i][4], stock_name, test_number)

from __future__ import (absolute_import, division, print_function, unicode_literals)import backtrader as btimport DataBlock as dbimport pandas as pdimport datetime as dtfile = open('TestFile.Txt','r')n = file.readlines()Stock_Name = 'G00G'Stock_Start_Year = 2014Stock_Start_Month = 1Stock_Start_Day = 1Stock_End_Year = 2014Stock_End_Month = 5Stock_End_Day = 1GeneralData = pd.DataFrame(db.Get_Data(Stock_Name,dt.datetime(int(Stock_Start_Year), int(Stock_Start_Month), int(Stock_Start_Day)),dt.datetime(int(Stock_End_Year),int(Stock_End_Month), int(Stock_End_Day))))class TestStrategy(bt.Strategy): params = ( ('maperiod', 15), ) def log(self, txt, dt=None): ''' Logging function fot this strategy''' dt = dt or self.datas[0].datetime.date(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): self.dataclose = self.datas[0].close self.order = None self.buyprice = None self.buycomm = None self.sma = bt.indicators.SimpleMovingAverage( self.datas[0], period=self.params.maperiod) bt.indicators.ExponentialMovingAverage(self.datas[0], period=25) bt.indicators.WeightedMovingAverage(self.datas[0], period=25, subplot=True) bt.indicators.StochasticSlow(self.datas[0]) bt.indicators.MACDHisto(self.datas[0]) rsi = bt.indicators.RSI(self.datas[0]) bt.indicators.SmoothedMovingAverage(rsi, period=10) bt.indicators.ATR(self.datas[0], plot=False) def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: return if order.status in [order.Completed]: if order.isbuy(): self.log( 'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.buyprice = order.executed.price self.buycomm = order.executed.comm else: self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.bar_executed = len(self) elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.log('Order Canceled/Margin/Rejected') self.order = None def notify_trade(self, trade): if not trade.isclosed: return self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' % (trade.pnl, trade.pnlcomm)) def next(self): self.log('Close, %.2f' % self.dataclose[0]) if self.order: return if not self.position: if self.dataclose[0] > self.sma[0]: self.log('BUY CREATE, %.2f' % self.dataclose[0]) self.order = self.buy() else: if self.dataclose[0] < self.sma[0]: self.log('SELL CREATE, %.2f' % self.dataclose[0]) self.order = self.sell()if __name__ == '__main__': cerebro = bt.Cerebro() cerebro.addstrategy(TestStrategy) data = bt.feeds.PandasData( dataname=GeneralData) cerebro.adddata(data) cerebro.broker.setcash(100000.0) cerebro.addsizer(bt.sizers.FixedSize, stake=10) cerebro.broker.setcommission(commission=0.05) print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue()) cerebro.run() print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())

Похожие работы на - Автоматизация биржевой торговли

 

Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!