Извлекайте настроения акций из заголовков финансовых новостей, отображайте ежечасные/ежедневные настроения в веб-приложении Flask и развертывайте его в Интернете.

В предыдущей статье я объяснил, как извлекать заголовки новостей с веб-сайта FinViz для любой акции перед анализом данных и оценкой их настроений. strong> с использованием библиотеки NLTK Vader. Мы также построили оценки тональности для разных биржевых тикеров. Не стесняйтесь обращаться к статье ниже, чтобы увидеть, как все работает в деталях.



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

Обновление: это приложение ранее было развернуто в Herokuapp, однако с ноября 2022 года Herokuapp прекратит предоставление бесплатных услуг. Однако вы все равно можете следовать этому руководству, чтобы развернуть его локально на своем компьютере или заплатить поставщику облачных услуг за его развертывание в Интернете.

Код для этой статьи находится в следующем репозитории GitHub.



Анализ настроений в заголовках финансовых новостей Jupyter Notebook похож на код в моей предыдущей статье, но аккуратно упакован в несколько функций. Убедитесь, что вы выполняете установку pip в блокноте Jupyter. Я дам краткий обзор каждой функции и пример ее использования, для полного объяснения не стесняйтесь обращаться к предыдущей статье.

получить_новости()

Функция get_news() принимает название тикера, использует библиотеку urllib3 Python для получения соответствующих заголовков новостей с веб-сайта FinViz и выводит необработанный html-код.

ticker = 'AMZN'
news_table = get_news(ticker)
news_table # pure html code, data is not parsed yet

parse_news()

Функция parse_news() берет необработанный HTML-код сверху и использует библиотеку BeautifulSoup для анализа заголовков и соответствующих дат/времени в Pandas DataFrame.

parsed_news_df = parse_news(news_table)
parsed_news_df.head()

счет_новости()

Функция score_news() принимает кадр данных сверху и дает оценку тональности для каждого заголовка, используя библиотеку NLTK Vader. Он выводит оценки тональности (отрицательная, нейтральная, положительная, совокупная оценка) в виде дополнительных столбцов в DataFrame.

parsed_and_scored_news = score_news(parsed_news_df)
parsed_and_scored_news.head()

plot_hourly_sentiment() и plot_daily_sentiment()

Наконец, функции plot_hourly_sentiment() и plot_daily_sentiment() передискретизируют соответствующие почасовые и дневные оценки тональности в DataFrame выше и отображают их на интерактивной диаграмме с помощью пакета Plotly. ».

plot_hourly_sentiment(parsed_and_scored_news, ticker)
plot_daily_sentiment(parsed_and_scored_news, ticker)

Настроения не всегда положительные, например, за последние пару дней после написания этой статьи у "TSLA" появилось много негативных заголовков.

Создайте веб-приложение Flask

Теперь мы создадим веб-приложение Flask, которое в основном

  • получает пользовательский ввод для биржевого тикера
  • последовательно вызывает перечисленные выше функции
  • выводит сюжеты и заголовки на веб-страницу

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

Если вы новичок в Flask, не стесняйтесь познакомиться с основами создания приложения Flask «Hello World здесь».

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

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

app.py

Файл app.py позволяет нам запустить веб-приложение Flask. Мы импортируем соответствующие пакеты и копируем в файл все 5 описанных ранее функций.

Приложение Flask просто создается в этой строке.

app = Flask(__name__)

Когда пользователь вводит URL-адрес приложения Flask, он по умолчанию перенаправляется на ‘/’. Следовательно, следующий сегмент кода указывает приложению Flask загружать код в файл 'index.html' в папке templates, когда пользователь входит на стандартную (главную) страницу приложения.

@app.route('/')
def index():
    return render_template('index.html')

index.html

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

Давайте посмотрим на файл ‘index.html’. Мы проигнорируем все, что находится между тегами <style> и </style>, так как оно состоит из кода CSS для стилизации веб-страницы и улучшения ее внешнего вида. Без этого кода приложение все равно будет работать (но без цветов).

Инструкции и информационный текст

HTML-файл сообщает браузеру что отображать на веб-странице, а также ее форматирование. Например, мы видим следующий сегмент кода для распечатки заголовка и инструкций в верхней части веб-страницы. <h1> и <h3> – это теги header, благодаря которым заключенный в них текст выглядит на веб-странице большим и жирным.

<h1 style="padding:10px">Bohmian's Stock News Sentiment Analyzer</h1>
   
<h3>Enter a Stock Ticker Symbol to See the Hourly and Daily Sentiment Scores of the Stock</h3>

Мы также распечатываем некоторую информацию внизу страницы и небольшую финансовую оговорку. :) Теги <p> — это теги абзаца, которые заключают теги внутри абзаца, а <a> и href позволяют нам вставлять ссылки.

<p>
The sentiment is obtained by performing sentimental analysis on recent news headlines using the 
<a href="https://www.nltk.org/_modules/nltk/sentiment/vader.html">NLTK Sentiment Vader Python library</a>.<br><br>
    The recent news headlines are obtained from <a href="https://finviz.com">FinViz website</a>.
    <br><br>
    <i>Disclaimer: This page is not meant to represent any form of financial advice. 
    Any investments you make will carry risk so remember to do your due diligence and research before doing so.</i>
</p>

Форма для публикации пользовательского ввода

Это самая важная часть html-кода. Мы создаем форму, заключая ее в теги <form>. В первой строке мы видим action=“sentiment”, это говорит браузеру направить пользователя в ‘/sentiment’ после отправки формы. method=“POST” означает, что при отправке формы к приложению будет отправлен запрос POST, поскольку пользователь отправляет данные (т. е. интересующий его тикер) в веб-приложение для дальнейшей обработки.

<form action="sentiment" method="POST" align="center">
      
     <b>Stock Ticker Symbol: </b> 
     <input id="text_field" name="ticker" type="text" required>     
     <center><input id="submit_button" type="Submit" class="push_button blue"></center>
     
</form>

<input id=“text_field” name=“ticker” type=“text” required> создает текстовое поле для ввода пользователем. Важно отметить, что атрибут name=”ticker” позволяет приложению Flask идентифицировать это поле ввода по его имени и позже извлекать введенный пользователем текст.

<input id=”submit_button” type=”Submit” class=”push_button blue”> просто создает кнопку отправки.

Что происходит после того, как пользователь вводит данные?

Ранее мы упоминали, что пользователь будет перенаправлен на /sentiment после отправки формы и выполнения POST-запроса. Итак, давайте вернемся к соответствующему сегменту нашего файла app.py, чтобы посмотреть, как это обрабатывается. Первая строка кода ниже указывает приложению подготовиться к обработке запроса метода POST в маршруте ‘/sentiment’.

Код ticker = flask.request.form[‘ticker’].upper() говорит приложению запрашивать текст, который пользователь ввел в поле, которое мы назвали «бегущей строкой» ранее (вспомним name=‘ticker’) в HTML-коде. Он преобразует ввод в текст в верхнем регистре, поскольку биржевые тикеры обычно в верхнем регистре.

Следующие 5 строк кода (строки с 5 по 9 выше) последовательно применяют наши 5 функций, чтобы получить и проанализировать данные новостей, прежде чем выводить график Plotly в виде объектов fig_hourly и fig_daily.

Затем следующие 2 строки (строки 11 и 12) кодируют графические диаграммы в объекты в формате JSON graphJSON_hourly и graphJSON_daily в JavaScript, которые необходимы для отображения веб-страницей графиков. позже.

Последняя строка указывает приложению Flask отображать шаблон, указанный в файле 'sentiment.html', и передавать объекты graphJSON, заголовок и Сгенерированные нами строки description, а также parsed_and_scored_news DataFrame для них. Эти объекты в конечном итоге будут интерпретированы в код 'sentiment.html' для отображения на веб-странице.

return render_template('sentiment.html',graphJSON_hourly=graphJSON_hourly, graphJSON_daily=graphJSON_daily, header=header,table=parsed_and_scored_news.to_html(classes='data'),description=description)

настроения.html

Мы хотим, чтобы на этой последней странице отображалось следующее:

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

Давайте взглянем на соответствующие части кода в файле ‘sentiment.html’.

Ранее из нашего app.py мы передали в шаблон строки header и description. Доступ к нему осуществляется с помощью приведенного ниже кода {{header}} и {{description}}, заключенного в теги заголовка <h1> и <div> соответственно. <div> обозначает раздел или раздел на веб-странице.

Между заголовком и описанием мы также создаем 2 раздела веб-страницы с 2 диаграммами, chart и chart2. Позже мы будем использовать Javascript для заполнения этих диаграмм соответствующими диаграммами настроений.

<div id="chart" class="chart"></div>
<div id="chart2" class="chart2"></div>

После кода {{description}} мы печатаем таблицу из кадра данных, который мы передали ранее, используя код {{ table|safe }}. Напомним, что это parsed_and_scored_news DataFrame, который состоит из даты и времени, новостей и оценок настроений.

Теперь осталось заполнить графики chart и chart2. Последняя часть нашего кода написана на JavaScript, как показано ниже. Сначала мы передаем ссылку на скрипт на странице Plotly, чтобы мы могли использовать функции Plotly.plot. Затем мы передаем в функции Plotly.plot наши объекты graphJSON_hourly и graphJSON_daily, которые мы определили ранее в файле app.py, и отображаем их в chart и chart2 соответственно.

<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script type="text/javascript">
  var graph_hourly = {{graphJSON_hourly | safe}};
  Plotly.plot('chart',graph_hourly,{}); 
  var graph_daily = {{graphJSON_daily | safe}};  
  Plotly.newPlot('chart2',graph_daily,{});    
</script>

Протестируйте приложение Flask

Теперь мы готовы протестировать это приложение Flask. Нам нужно перейти в командную строку и ввести 'python app.py' в папке 'stock_sentiment_webapp'. Это запустит приложение Flask. Если все работает нормально, вы должны увидеть этот вывод.

Затем перейдите в браузер и введите http://127.0.0.1:5000/. Ваше приложение Flask должно загрузиться, и вы успешно развернули это приложение локально.

Разверните веб-приложение Flask на облачной платформе Heroku.

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

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

  1. Во-первых, вам нужно создать учетную запись на GitHub и Herokuapp.
  2. Затем вам нужно добавить файлы Procfile и requirements.txt из моего репозитория GitHub. «Procfile» просто сообщает облаку Herokuapp, что нужно запускать его как веб-приложение Python, а файл «requirements.txt» сообщает Herokuapp установить все пакеты Python, перечисленные внутри, для запуска приложения. Не стесняйтесь открывать файлы, чтобы посмотреть.
  3. Создайте репозиторий GitHub, назовите его как хотите и загрузите в него все содержимое папки stock_sentiment_webapp.
  4. В Herokuapp создайте новое приложение и дайте ему имя, которое вам нравится.

Затем свяжите свою учетную запись GitHub, найдите свой репозиторий на GitHub и нажмите Подключиться.

Наконец, после того, как вы нажмете «Развернуть ветку», Herokuapp начнет устанавливать требования и собирать приложение.

Как только все будет сделано, вы увидите это и сможете просматривать свое приложение в Интернете!

Поздравляем!

Если вам понравилась эта статья, не стесняйтесь проверить мои другие статьи. :)







Не стесняйтесь следовать за мной, чтобы получать обновления, когда я пишу больше статей!

Запланируйте сеанс DDIChat в Data Science / AI / ML / DL:



Подайте заявку на участие в программе DDIChat Expert здесь.
Работайте с DDI: https://datadriveninvestor.com/collaborate
Подпишитесь на DDIntel здесь.