使用 Stream 构建交互式财务数据分析仪表板
在本博客中,我将向您介绍如何使用 streamlit 构建和部署仪表板以进行实时财务数据分析。
📌_注意_:
本教程仅用于教育目的,未经进一步分析不应用于进行金融投资
入门:
那么,您是否需要成为编码天才或金融爱好者才能理解我们将要讨论的内容?
不,我只需要你对编程(如循环、函数)有基本的直觉,并从公司和消费者的角度了解股票作为一种金融投资。
如果您觉得自己错过了理解某些行话,我将在以后的文章中介绍金融和编程概念以及机器学习的深入教程。敬请期待😊
股票数据基础
在不深入研究技术定义的情况下,我们可以将股票理解为公司股权的一部分。如果有人声称他们拥有 100000 股股票的公司拥有 50000 股股票,则松散地暗示他们拥有该公司 50% 的股份。
现在,您可能想知道为什么公司希望随机的人在他们的公司中拥有部分所有权?嗯,答案是在财务上增长并获得投资。每当一个人收购一家公司的股票时,您往往会为公司可以用于其运营或任何工作的价格付出代价(这听起来可能类似于债券,但详细的分析和差异将在未来的博客中介绍) .
继续前进,这些股票需要从每个人都可以信任的特定地方购买,并针对潜在的欺诈行为进行监管。这个平台被称为证券交易所。在美国,最受欢迎的是 NYSE(纽约证券交易所),而在印度,最受欢迎的两个是 BSE(孟买证券交易所)和 NSE(国家证券交易所)
股票的价格是波动的。有几个人试图买卖它,就像您在生活中观察到的任何其他商品一样,有两股连续的供需浪潮,价格往往会波动。
通常,在一天中的几个小时内允许买卖股票的行为(有时称为交易)。对于纽约证券交易所,时间为美国东部时间上午 9:30 至下午 3:30。股票开盘时的价格(即我们被允许交易的时间)称为开盘价,而市场收盘时的价格(即我们不允许交易的时间)称为收盘价。在当天的交易窗口期间(我上面提到的时间),股票触及的最高价称为高价,而跌至的最低价称为低价。
📌_注意_:
- 开盘价、收盘价、最高价和最低价可能相同也可能不同
*一天的收盘价和第二天的开盘价可能相同也可能不同(有一个有趣的原因,我希望您自己探索!)
- Open、High、Low、Close 的概念可以扩展到 1 小时、5 分钟、1 分钟甚至一周的间隔。但是对于这个分析,我们将简单地使用 1Day 间隔(即一天中的整个交易窗口)
出于我们的目的,我们将使用 API 调用直接从 NYSE 获取股票价格数据。
现在,什么是流光?
好吧,streamlit 是一个 python 包,它可以让我们使用 python 本地构建端到端应用程序,而无需参与前端开发。此外,我们可以使用我们在 IDE 或 Jupyter Notebook 上进行分析时已经构建的功能来构建高度可定制和交互式的仪表板。
如果您不熟悉 Python,请不要担心大多数命令就像您用简单的英语编写一样简单。
安装 Streamlit
-
打开你的终端
-
创建一个新的虚拟环境并激活它[可选]
-
获取包
pip install streamlit
📌 注意:
- 我们需要更多的软件包来进行数据分析 -
pip install numpy matplotlib pandas pandas_datareader
- pandas:用于处理数据框中的结构化数据
- numpy:用于数值计算和数组计算
- matplotlib:用于绘图
- pandas_datareader:用于获取我们的股票数据(在我们的例子中)
出发
- 移动到您喜欢的工作目录,创建一个新的子目录并打开它。
cd projects
mkdir PyFinAnalysis
cd PyFinAnalysis
- 创建一个新的python文件。我更愿意称它为app.py
touch app.py
- 现在,打开你最喜欢的 IDE。我个人更喜欢VSCode
code .
- 让我们导入我们的库
from datetime import datetime
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import pandas_datareader as pdr
import streamlit as st
📌 注意:
- datetime:用于处理与日期和时间相关的对象
- import mr_john_doe as ci:在 Python 中导入库时,我们倾向于根据方便或社区设置的标准对其进行缩写,以便稍后调用它们的函数。想象一下,如果 John Doe 先生是你的班主任,你必须写几份关于他的工作的报告。不用每次都用他的名字,你可以称他为 CI,这是班上每个人都容易理解的东西。
- 定义主函数
def main():
st.title("PyFinAnalytics)
if __name__ == main():
main()
我们在 main 函数中定义仪表板代码库的核心,并将其设置为 Python 解释器执行脚本时调用的第一个方法。
-
函数
st.title根据作为参数传递给它的字符串打印出应用程序的标题。 -
要查看输出,请打开终端(确保您仍在同一位置)
流式运行 app.py
祖兹 100033
* 您的浏览器将打开并重定向到本地主机上的端口(8501 或 80)。你应该能够看到这样的东西👇🏼

* 恭喜🥳🥳 你已经构建了你的第一个流光应用程序!
## 一次深入研究一个功能的组件!
#### 获取库存数据
让我们定义一个函数`fetch_stock_data( )`,它以开始日期、结束日期和股票代码作为输入,并返回一个数据框,用于在给定的时间范围内(包括两个日期)由该代码唯一标识的股票的每日价格变动
我们使用`pandas-datareader`库从[雅虎财经](https://finance.yahoo.com/)网站获取股票数据。
def fetch_stock_data(ticker, start_date, end_date):
"""
Fetch stock data from Yahoo Finance
"""
stock_data = pdr.get_data_yahoo(ticker, start_date, end_date)
return stock_data
📌_注意_:
> * 我可以直接在 main 函数中完成上述操作,但我的目标是向您展示如何使用之前代码的模块化组件来构建仪表板。
* 现在,为了让应用程序具有交互性,我们希望用户实时输入数据。为了实现这一点,让我们使用 streamlit 定义输入部分
* 为了获取日期,我们将在 main 方法中使用`st.date_input()`函数并传递标签(即字段的标识文本)、我们希望用户从中选择的日期范围以及扩展的帮助消息。
* 我们会为开始日期和结束日期执行此操作。
* 由于开始日期不能晚于结束日期,因此我们很明显限制使用选择开始日期之前的结束日期。
start_date = st.date_input(
label = "Start Date",
min_value=datetime(2000, 1, 1),
max_value=datetime.today(),
help="Enter the date from which you want to analyse the stock data",
)
end_date = st.date_input(
label = "End Date",
min_value=start_date,
max_value=datetime.today(),
help="Enter the date till which you want to analyse the stock data",
)
📌_注意_:
> * 日期时间对象的定义格式为 YYYY-MM-DD 或 YYYY-MM-DD-HH-MM-SS
> *[datetime.today](http://datetime.today)( ) 使用系统时钟实时给出当前日期的日期
* 你可以在本地主机上的应用上看到类似的东西。

👀请注意,该应用程序不允许我选择 2021 年 10 月 8 日之前的日期作为我的结束日期,因为它是我的开始日期。此外,2021 年 10 月 29 日(我写这篇博客的那一天)之后的所有日期也都被屏蔽了。将鼠标悬停在左侧的❔按钮上可以看到弹出的帮助文本。
* 继续前进,我们需要股票代码,它基本上是一个唯一的字符串,用于识别在特定市场上市的股票。为此,我们使用`st.text_input( )`函数创建一个输入文本框。除了对输入的任何限制外,这些参数与最后一个函数中使用的参数相似。
ticker = st.text_input(
label="Ticker",
help="Enter the symbol used to uniquely identify publicly traded shares of your company of interest on the stock market",
)
* 输出会是这样的👇🏼

* 让我们使用从用户输入中获得的值来调用我们之前定义的`fetch_stock_data( )`函数,并将获得的数据帧存储在变量`stock_data`中
stock_data = fetch_stock_data(ticker, start_date, end_date)
* 在生产中,可能会出现用户输入无效股票代码的情况,导致 API 调用失败,并且我们的仪表板会出现错误。为了解决这个问题,我们使用了 try-except(类似于 try-catch)块
try:
stock_data = fetch_stock_data(ticker, start_date, end_date)
except:
st.error("Oops😅! You have chosen an invalid ticker")
* `st.error( ) function`倾向于在文本框内打印错误消息,红色背景色表示出现问题,需要纠正
* 最后,我们使用`st.button( )`函数创建一个按钮,以便在用户确定分析所需的输入值后,他们可以命令我们的仪表板获取数据,而不是在输入数据时立即执行。
if st.button("Get Market Data"):
try:
stock_data = fetch_stock_data(ticker, start_date, end_date)
except:
st.error("Oops😅! You have chosen an invalid ticker")

* 与按钮的交互返回一个布尔值(未按下时默认为False),该值被馈送到条件语句以决定是否获取数据并执行后续分析操作。
## 显示数据
在使用`st.write( )`函数的 streamlit 中,我们可以渲染多种类型的数据,从文本到 Markdown 再到数据帧。它就像一只适合所有人的鞋子。但是,为了充分利用 streamlit 的潜力,最好使用专用函数来格式化每种数据类型的输出。
if st.button("Get Market Data"):
try:
stock_data = fetch_stock_data(ticker, start_date, end_date)
# Display the stock data
st.dataframe(stock_data)
except:
st.error("Oops😅! You have chosen an invalid ticker")
* `st.dataframe( )`帮助我们围绕数据框构建一个交互式组件,以便用户可以滚动浏览数据框的行和列,而不会分散在整个页面上。

## 收盘价分析
现在,我们可以使用`Close`列(或在 pandas 中技术上称为系列)获得以下内容:
* 最高收盘价是多少?
max_closing_price = stock_data["Close"].max()
st.markdown(f"Highest Close Price for {ticker}: {round(max_closing_price,4)}")
* 观察到的最高价格是什么时候?
max_date = stock_data[stock_data["Close"] == max_closing_price].index[0]
st.markdown(f"Highest Close Price for {ticker} was observed on: {max_date}")
* 最低收盘价是多少?
min_closing_price = stock_data["Close"].min()
st.markdown(f"Lowest Close Price for {ticker}: {round(min_closing_price,4)}")
* 观察到的最低价格是什么时候?
min_date = stock_data[stock_data["Close"] == min_closing_price].index[0]
st.markdown(f"Lowest Close Price for {ticker} was observed on:: {min_date}")
* `st.markdown( )`函数呈现输入文本,就好像它是 Markdown 语法一样。例如,为了使文本加粗,我们将其括在双星或下划线之间,而为了将其变为斜体,我们将其括在单星或下划线之间。我们还可以通过将适当的降价语法传递给这个函数来打印出编号列表、未编号列表、标题、下划线文本和链接。
📌_注意_:
> * 所有价格四舍五入到小数点后四位
* 现在,让我们为这个分析构建一个函数,并在 main 方法中调用它
def close_price_analysis(stock_data, ticker):
# What was the highest closing price for the stock?
max_closing_price = stock_data["Close"].max()
st.markdown(f"__Highest Close price for {ticker}:__ {round(max_closing_price,4)}")
# When was the highest closing price for the stock observed?
max_date = stock_data[stock_data["Close"] == max_closing_price].index[0]
st.markdown(f"__Highest Close Price for {ticker} was observed on:__ {max_date}")
# What was the lowest closing price for the stock?
min_closing_price = stock_data["Close"].min()
st.markdown(f"__Lowest Close price for {ticker}:__ {round(min_closing_price,4)}")
# When was the lowest closing price for the stock observed?
min_date = stock_data[stock_data["Close"] == min_closing_price].index[0]
st.markdown(f"__Lowest Close Price for {ticker} was observed on:__ {min_date}")
* 在我们显示数据之后,我们将在我们的主函数中调用这个函数。
Basic closing price analysis
st.markdown(" ")
st.markdown("### Basic Stock Price Analysis")
close_price_analysis(stock_data, ticker)
📌_注意_:
> * 👀请注意,我们故意在前一个元素之后留了一个空行,以使其具有视觉吸引力。
> * 此外,我们为正在执行的分析设置了一个副标题。
> * 最后通过传递数据帧和其他必要参数调用适当的函数(在这种情况下为股票代码)
> * 这是我们为仪表板中的所有组件所遵循的模式

# 绘制收盘价走势图
def plot_close_price(stock_data, ticker):
"""
Method to plot the movement of close price of the stock
"""
fig, ax = plt.subplots(figsize=(10, 5))
ax = fig.add_subplot(111)
ax.plot(stock_data["Close"])
ax.set_title(f"{ticker} stock price movement")
ax.set_xlabel("Date")
ax.grid(True)
st.pyplot(fig)
* 函数名后面的字符串称为docstring。它用于使将来使用此代码的开发人员更容易理解函数。
* 我们使用`matplotlib.pyplot`定义一个图形对象,其大小为 10 x 5 像素
* 通常,一个图可能包含多个称为子图的图,可以通过 (row\_no, column\_no, fig\_no) 访问。
* 使用来自`stock_data["Close"]`系列的数据点绘制散点图。
* 使用`ax.set_title( )`、`ax.set_xlable( )`、`ax.set_ylable( )`和`ax.grid( )`方法设置标题、轴标签和网格。
* Streamlit 对 matplotlib 的本机函数 \`st.pyplot( )' 的包装用于显示图形。
* 和上一部分类似,我们要在main函数中调用这个方法。
Close price movement
st.markdown(" ")
st.markdown("### Stock Price Movement")
plot_close_price(stock_data, ticker)

## 每日变化
每日变化可以简单地通过将当天的收盘价减去前一天的收盘价再除以前一天的收盘价的值来计算。我们使用`pct_change( )`的方法来实现这个
def get_daiy_change(stock_data):
stock_data["Daily Change"] = stock_data["Close"].pct_change() * 100
return stock_data
更多推荐

所有评论(0)