python - Jupyter Notebook Python 项目:使用 Plotly-Dash 进行股票分析
问题描述
我正在使用 Jupyter Notebook (Python = 3.7.6) 中的 Dash 和 Plotly 项目进行股票分析。我参加了 3 个股票市场,即香港的恒生、美国的 S&P500 和印度的 Nifty500。我得到了前两个市场的输出,比如实时预测图表,但在印度的情况下,什么都没有出现。
任何人都可以帮助获得印度市场预测图表吗?
谢谢你 :)
代码:
import pandas as pd
from jupyter_plotly_dash import JupyterDash
import re
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import yfinance
app = dash.Dash()
app.layout = html.Div([
dcc.Tabs(id='dashboard-tabs', value='price-tab',children=[
dcc.Tab(label='Stock Price', value='price-tab',children=[
html.Div([html.H2(id='tab1-stock-name',
style={'width':'30%','display':'inline-block'}),
html.H4(id='tab1-ticker',
style={'width':'10%','display':'inline-block'})],
style={'width':'90%','margin':'auto'}),
html.Div(get_tab1_info_box(),
style={'width':'90%','margin':'auto'}),
# Position 1, Info and dropdown
html.Div(get_stats_graph_layout('tab1'),
style={'width':'90%','margin':'auto'})
# Position 2, Table of stats and graph
]), # Tab 1, End price-tab
dcc.Tab(label='Stock/Index Growth', value='change-tab',children=[
html.Div([html.H2('Stock Price Growth vs. Index Growth')],
style={'width':'90%','margin':'auto',
'text-align':'center'}),
# Position 0, Title
html.Div(get_tab2_info_box(),
style={'width':'90%','margin':'auto'}),
# Position 1, Info and dropdown
html.Div(get_stats_graph_layout('tab2'),
style={'width':'90%','margin':'auto'})
# Position 2, Table of stats and graph
]) # Tab 2, End change-tab
]) # End Tabs
]) # End base Div
def verify_ticker(ticker, mkt):
if mkt == 'hk':
tick = re.findall('^\d{1,5}$', ticker)
if len(tick)>0:
tick = str(tick[0])[::-1]
while(len(tick)<4):
tick += '0'
tick = tick[::-1]
tick += '.HK'
return True, tick
else:
return False, None
elif mkt == 'us':
tick = re.findall('^[A-Za-z]{1,4}$', ticker)
if len(tick)>0:
return True, tick[0].upper()
elif mkt == 'ind':
tick = re.findall('^[A-Za-z]{1,4}$', ticker)
if len(tick)>0:
return True, tick[0].upper()
else:
return False, None
return False, None
# Obtain 50- ,100- and 200-day moving average
def getMA(stock, time, date_list):
if 'mo' in time or time=='ytd' or time=='1y':
df = stock.history(period='2y')
elif time=='2y' or time=='3y' or time=='4y':
df = stock.history(period='5y')
else:
df = stock.history(period='10y')
df = df.reset_index()[['Date','Open','Low','High','Close']]
df['MA50'] = df.Close.rolling(50).mean()
df['MA100'] = df.Close.rolling(100).mean()
df['MA200'] = df.Close.rolling(200).mean()
df = df.loc[(df['Date']>=date_list.min()) & (df['Date']<=date_list.max())]
return df
# Generate stock price and graph on Tab 1
@app.callback([Output('tab1-stock-name','children'), # Stock Name
Output('tab1-ticker','children'), # Ticker
Output('tab1-stock-price','children'), # Current Stock Price
Output('tab1-stock-price-change','children'), # Price Change
Output('tab1-stock-price-change','style'),
# Price Change font colour
Output('tab1-stock-price-percentchange','children'),
# Price Percent Change
Output('tab1-stock-price-percentchange','style'),
# Price Precent Change font colour
Output('tab1-error-message','children'), # Error Message
Output('tab1-vis','figure'), # Stock Price Chart
Output('tab1-table','children')], # Table of Stock Stats
[Input('tab1-submit','n_clicks'), # Button
Input('tab1-time-interval','value')], # Time interval
[State('tab1-ticker-input','value'), # Ticker textbox input
State('tab1-market-dropdown', 'value')]) # Market Dropdown input
def get_ticker(n_clicks, time, ticker, mkt):
# For default setting
if ticker == '':
return 'Please Enter a Stock Ticker', \
'','','',{'width':'20%', 'display':'inline-block'},'', \
{'width':'20%', 'display':'inline-block'},'', \
{'data':None}, None
# Verify ticker format in respective to stock market
stockFormat, ticker = verify_ticker(ticker, mkt)
# Catch incorrect
if stockFormat is False:
return 'Wrong Ticker', '#######', '$##.##', '##.##', \
{'width':'20%', 'display':'inline-block'}, '##.##%', \
{'width':'20%', 'display':'inline-block'}, \
'Error! Please try again.', {'data':None}, None
# Obtain stock price and stats
stock = yfinance.Ticker(ticker)
# Catch if stock exists
if stock.history(period='ytd').shape[0] == 0:
return 'Wrong Ticker', '#######', '$##.##', '##.##', \
{'width':'20%', 'display':'inline-block'}, '##.##%', \
{'width':'20%', 'display':'inline-block'}, \
'Error! Please try again.', {'data':None}, None
### Stock Stats for Info Box ###
try:
# Name and price
stock_name = stock.info['longName']
price_list = stock.history(period=time)['Close'].tolist()
price = f'${price_list[-1]:.2f}'
# Price Change
price_change = price_list[-1] - price_list[-2]
price_percent_change = (price_list[-1]/price_list[-2])-1
if price_change > 0:
price_change_colour = {'color':'green'}
else:
price_change_colour = {'color':'red'}
price_change_colour['display']= 'inline-block'
price_change_colour['width']= '20%'
price_change_colour['font-size'] = '150%'
price_change = f'{price_change:.2f}'
price_percent_change = f'{price_percent_change*100:,.2f}%'
df = getMA(stock, time,
stock.history(period=time).reset_index()['Date'])
fig = getCandlestick(df)
table = getTab1Table(stock.history(period=time).reset_index(),
stock.info)
except:
return 'Sorry! Company Not Available', '#######', '$##.##', '##.##', \
{'width':'20%', 'display':'inline-block'}, '##.##%', \
{'width':'20%', 'display':'inline-block'}, \
'Error! Please try again another Company.', {'data':None}, None
return stock_name, ticker, price, price_change, price_change_colour, \
price_percent_change, price_change_colour, '', fig, table
@app.callback([Output('tab2-stock-include','options'),
Output('tab2-stock-include','value')],
[Input('tab2-index-choice','value')])
def generate_dropdown_stocknames(mkt):
if mkt == 'hsi':
stock_list = pd.read_csv('C:\\Users\\Pranav Jaswal\\Desktop\\StockAnalytics-master\\IndexComponents\\HengSengStockList.csv',
dtype=str)
stock_list = stock_list.sort_values('Ticker')
stock_list['label'] = stock_list['Ticker'].astype(str) + '\t' + \
stock_list['Company']
opts = [{'label': label, 'value': ticker} for label, ticker in
zip(stock_list['label'].tolist(),
stock_list['Ticker'].tolist())]
return opts, []
elif mkt == 'sp500':
stock_list = pd.read_csv('C:\\Users\\Pranav Jaswal\Desktop\\StockAnalytics-master\\IndexComponents\\SP500StockList.csv',
engine='python')
stock_list = stock_list.sort_values('Ticker')
stock_list['label'] = stock_list['Ticker']
opts = [{'label': label, 'value': ticker} for label, ticker in
zip(stock_list['label'].tolist(),
stock_list['Ticker'].tolist())]
return opts, []
elif mkt == 'nifty500':
stock_list = pd.read_csv('C:\\Users\\Pranav Jaswal\\Desktop\\StockAnalytics-master\\IndexComponents\\ind_nifty500list.csv',
engine='python')
stock_list = stock_list.sort_values('Ticker')
stock_list['label'] = stock_list['Ticker']
opts = [{'label': label, 'value': ticker} for label, ticker in
zip(stock_list['label'].tolist(),
stock_list['Ticker'].tolist())]
return opts, []
return [], []
@app.callback([Output('tab2-table','children'),
Output('tab2-vis','figure')],
[Input('tab2-index-choice','value'),
Input('tab2-stock-include','value'),
Input('tab2-time-interval','value')])
def generate_tab2_graph(mkt,stocks,time):
# Function to calculate price change relative to the first day
def get_price_change(price_list):
base_price = price_list[0]
return [(price/base_price)-1 for price in price_list]
df_stocks = []
if len(stocks) > 0:
for stock in stocks:
if mkt=='hsi':
stock = stock[1:] + '.HK'
stock_df = yfinance.Ticker(stock).history(period=time)
stock_df = stock_df.reset_index()[['Date','Close']]
stock_df.columns = ['Date',stock]
df_stocks.append(stock_df)
y_ticker = None
index_col = None
if mkt == 'hsi':
y_ticker = '^HSI'
index_col = 'Heng Seng Index'
elif mkt == 'sp500':
y_ticker = '^GSPC'
index_col = 'S&P 500'
elif mkt == 'nifty500':
y_ticker = '^NSEI'
index_col = 'Nifty 50'
else:
return html.Table(), {'data': None}
# Prepare the data set to plot the line chart
index = yfinance.Ticker(y_ticker)
df_index = index.history(period=time).reset_index()[['Date','Close']]
df_index.columns = ['Date', index_col]
# To take out duplicated columns, ie, Date, while concat
if len(stocks) > 0:
for df_temp in df_stocks:
df_index = pd.merge(df_index, df_temp, how='left',on='Date')
# In case there are NA's, fill with last observation
df_index = df_index.fillna(method='backfill', axis=1)
# Drop duplicated columns in case there are
df_index = df_index.loc[:,~df_index.columns.duplicated()]
# Convert from price to percent change relative to Day 1 of the period
for col in df_index.columns:
if col != 'Date':
df_index[col] = get_price_change(df_index[col].tolist())
fig = getLinePlot(df_index, 2)
# Prepare the data set to list the summary on the table
last_close = df_index[index_col].tolist()[-1]*100
df_index_period = index.history(period=time).reset_index()
df_index_52weeks = index.history(period='1y').reset_index()
range_period = (round(df_index_period['Close'].min(),2),
round(df_index_period['Close'].max(),2))
range_52weeks = (round(df_index_52weeks['Close'].min(),2),
round(df_index_52weeks['Close'].max(),2))
volume = (index.history(period=time).reset_index()['Volume'].tolist()[-1],
index.history(period=time).reset_index()['Volume'].mean())
# Generate a table of summary
table = getTab2Table(index_col, last_close, range_period, range_52weeks)
return table, fig
if __name__ == '__main__':
app.run_server(debug=False, port=8000)
解决方案
推荐阅读
- html - 使 div 的宽度与最宽的 div 相同,但不使用 CSS flex 填充屏幕宽度
- java - 与 Vaadin 的项目无法启动
- sorting - Optaplanner 强度比较器是否与分区兼容?
- javascript - 使用命令更改频道权限 (Javascript Discord.js)
- html - 即使在我的边距上使用 vw 单位,Div 也会离开屏幕
- json - 使用 Decodable 解码 JSON 嵌套字典并使用 Core Data 存储它
- flutter - 带有里程碑/步骤分隔符的 CircularProgressIndicator(例如 1/3、2/3、3/3)
- mongodb - 在 Mongodb 中设置 memLimitMB 参数以获得内存限制
- generics - Kotlin 和 Java PECS
- css - 如何完全删除 md-dialog 的背景?