Python資料分析----XX銀行股票分析小娛
阿新 • • 發佈:2018-11-05
本文使用Facebook的Prophet工具對XX銀行的股票進行分析和預測,just for fun!如下是分析過程中的收穫和隨筆記錄。
1. 對DataFrame型別的資料中的某一列資料進行歸一化處理
1.1.code
import pandas as pd import numpy as np import matplotlib.pyplot as plt data=pd.read_csv('C:/Users/Administrator/Desktop/txt.csv') #data.plot() #data.columns #ndex(['Date', 'Price'], dtype='object') #data.info() #歸一化部分程式碼 min1=min(data['Price']) max1=max(data['Price']) def to_onevec(x): x1=(x-min1)/(max1-min1) return x1 #處理完後重新塞回去資料就更新 data['Price']=data['Price'].apply(lambda x:to_onevec(x)) #針對DataFrame和Series型別的資料可以使用apply遍歷他們中的每一個元素:並對每一個元素執行同樣的操作(如:資料的歸一化、對數變換、統一減掉均值、取絕對值等)
1.2.效果
2. 安裝Prophet
pip install pystan ==>貼上到QQ瀏覽器使用迅雷加速下載檔案 https://files.pythonhosted.org/packages/ed/dc/386aa9acc6c3f89ef56f75255a2de97bb8593f3109e01ebbe20ab2a4718e/pystan-2.18.0.0-cp35-cp35m-win_amd64.whl pip install C:\Users\Administrator\AppData\Local\conda\conda\envs\tensorflow\Lib\site-packages\pystan-2.18.0.0-cp35-cp35m-win_amd64.whl pip install fbprophet import fbprophet #檢驗安裝成功
3. XX銀行股票分析走起
"""python3股票資料分析預測""" import fix_yahoo_finance as yf import pandas_datareader.data as web import matplotlib.pyplot as plt import datetime #1.讀取資料 yf.pdr_override() end=datetime.datetime.now() start=end-10*datetime.timedelta(days=365) #取到10年的資料,從當前向過去回退10年 #讀取平安銀行資料 df_csvsave=web.get_data_yahoo('000001.SZ',start,end) print(df_csvsave) df_csvsave.index df_csvsave.columns plt.subplots(figsize=(15,8)) plt.plot(df_csvsave['Open']) plt.plot(df_csvsave['High']) #plt.plot(df_csvsave['Low']) #plt.plot(df_csvsave['Close']) plt.show()
import pandas_datareader as pdr
pdr1=pdr.get_data_fred('GS10') #取到某一列
#2.檢查缺失值
df_csvsave.isnull().values.sum() #0
#視覺化股票走勢圖
from matplotlib import pyplot as plt
df_csvsave['Close'].plot(figsize=(16,9)) #畫出收盤價格走勢
#3.繪圖的樣式
#plt.style.available檢視全部的繪圖樣式,推薦:繪圖樣式
#'fivethirtyeight','dark_background','seaborn-whitegrid'
plt.style.use('fivethirtyeight')
df_csvsave.plot(figsize=(16,9)) #發現沒有出現四條曲線,原因是量綱的不同=>對資料做歸一化
#由於上述Volume是極值,故把有用的Open(開盤價)和Close(收盤價)等都淹沒了,所以對資料的量綱進行統一化很重要。如下將對資料進行歸一化處理。均勻資料使用區間縮放法來做歸一化
#4.使用區間法歸一化:處理後重新覆蓋寫回
df_csvsave=(df_csvsave-df_csvsave.min())/(df_csvsave.max()-df_csvsave.min())
plt.style.use('seaborn-whitegrid')
df_csvsave.plot(figsize=(16,9)) #歸一化只是使得向量計算點積更方便,但是不會改變資料走勢
#5.載入畫出K線的包
from mpl_finance import candlestick2_ohlc
year2018=df_csvsave['2018-01-01':'2018-10-20'] #拿出指定時間段的資料
fig,ax=plt.subplots(figsize=(16,9)) #畫布和畫板
candlestick2_ohlc(ax,year2018.Open,year2018.High,year2018.Low,year2018.Close,colorup='g',colordown='r',width=.5,alpha=.6) #注意K線條的順序
#
#6.繪製對比變化
import numpy as np
year_2018_close=year2018.Close
year_2018_close.shift(-1) #取到昨天的資料,(2號,3號)
year_2018_close.shift(1) #取到今天的資料,(3號,4號)
log_change=np.log(year_2018_close)-np.log(year_2018_close.shift(1)) #取昨天的資料和求取明天的資料,都用shift向前滑動1天,或者向後滑動1天。
fig,ax=plt.subplots(figsize=(16,9)) #畫布和畫板
ax.plot(log_change)
#畫圖方法很多不是固定的
ax.axhline(y=0,color='red') #畫出一條橫線來標記一下走勢圖相對於y=0的偏離程度
#圖的含義:點在上面今天相對於昨天是漲了,點在下面今天相對於昨天是跌了。
#繪製當日於上日的漲跌柱狀圖
x1=np.arange(len(log_change))+1
plt.subplots(figsize=(16,9))
plt.bar(x1,log_change,width = 0.8) #left=水平刻度個數,hight=縱軸座標刻度個數
#繪製漲跌天數之間的比例
pos,neg=[],[]
def up_down(x):
if x>0:
pos.append(1)
else:
neg.append(1)
log_change.apply(lambda x:up_down(x)) #apply用於Series和DataFrame的遍歷(遍歷他們中的每一個元素,可以結合lambda函式對每個值做特定的處理:如歸一化、取對數,與均值做差值)
up_dwon_rate=np.sum(pos)/np.sum(neg)
0.7545454545454545
#7.股票交易策略
short_rolling=year_2018_close.rolling(window=5).mean() #滑動視窗的大小window=5越大走勢曲線相對會更平滑一些
long_rolling=year_2018_close.rolling(window=15).mean()
fig,ax=plt.subplots(figsize=(16,9)) #畫布和畫板
p1,=ax.plot(year_2018_close.index,year_2018_close,label="blue--short(day)")
p2,=ax.plot(short_rolling.index,short_rolling,label="red--window=5")
p3,=ax.plot(long_rolling.index,long_rolling,label="yellow--window=15")
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[::-1], labels[::-1])
#rolling平滑的目的:想要時間更長一點,去抵消掉股價在短時間內的波動,通俗來說,除非你是那種短期操作者
#甚至當天買了當天就賣出。除此之外,如果你想要持股的時間在7天,半個月甚至是1月,那麼你就可以通過一個
#長期的變化去平滑掉短期波動帶來的影響。從而找到你適合買入和賣出的點。
#演算法導論中使用最大子陣列的方式來研究股票的走勢,一定程度上和滑動平均很像。
fig,ax=plt.subplots(figsize=(16,9))
short_long=np.sign(short_rolling-long_rolling)
buy_sell=np.sign(short_long-short_long.shift(1))
#股票整體下滑的年份是很難賺到錢,基本不夠手續費。選擇上證指數整體上升的年份做投資,
#相對來說比較能夠賺到錢。
#buy_sell.plot(ax=ax) #這個語句很好用,可以直接畫圖,但是發現y=0的水平線畫不出來
ax.plot(buy_sell) #type(buy_sell)=Series
ax.axhline(y=0,color='red')
plt.show()
#粗略的來看,可以認為紅線上方的是適合買入的時機,紅色以下是適合賣出的時間。
#適合買入的時間節點
buyin=buy_sell[buy_sell==1]
#適合賣出的時間節點
buyout=buy_sell[buy_sell==-1]
#可以選出相鄰兩個時間點計算交易收益
year_2018_close['2018-07-16']-year_2018_close['2018-07-13']
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
#觀察資料發現包含很多的0和np.nan=None==>過濾一下方便買入賣出點的視覺化
"""
鏈式法則:不斷的對原始資料做處理,處理成特定的資料結構,再根據該特定的資料結構的特點(list,DataFrame,Series,array,tuple,dict)繼續對資料結構做操作,一直到完成業務需要截止
Series和DataFrame可以使用apply遍歷每一個元素,對每一個元素執行相同的處理操作;
array,list等等只能通過map()來實現遍歷每一個元素,對每一個元素執行相同的處理操作;
x = list(map(lambda xx:xx.strftime('%Y-%m-%d'),buy_sell[np.abs(buy_sell)>0].index.tolist())) #type(buy_sell)=Series
"""
#只想要取到年月日作為字串索引,如何擷取datetime型別的資料
#x= buy_sell[np.abs(buy_sell)>0]
#y = buy_sell[np.abs(buy_sell)>0] #非空數值
"""正確的一版程式"""
x1= np.arange(0,len(buy_sell[np.abs(buy_sell)>0]))
y1 = buy_sell[np.abs(buy_sell)>0]
plt.subplots(figsize=(21,13))
#x=pd.Series(x)
#type(x.head(1)) #str
#y.index=x[:] #將x的值賦給y的索引
plt.plot(x1, y1, marker='o')
for xy in zip(x1, y1):
if xy[1]>0:
plt.annotate("%s" % 'buyin', xy=xy, xytext=(-20, 10), textcoords='offset points')
if xy[1]<0:
plt.annotate("%s" % 'saleout', xy=xy, xytext=(-20, 10), textcoords='offset points')
plt.xticks(range(len(x1)),y1.index,rotation=90)
plt.show()
"""測試版本1:正確"""
x1= np.arange(0,len(buy_sell))
y1 = buy_sell
fig,ax=plt.subplots(figsize=(60,41))
#x=pd.Series(x)
#type(x.head(1)) #str
#y.index=x[:] #將x的值賦給y的索引
plt.plot(x1, y1, marker='o')
for xy in zip(x1, y1):
if xy[1]>0:
plt.annotate("%s" % 'buyin', xy=xy, xytext=(-20, 10), textcoords='offset points')
if xy[1]<0:
plt.annotate("%s" % 'saleout', xy=xy, xytext=(-20, 10), textcoords='offset points')
ax.axhline(y=0,color='red')
plt.xticks(range(len(x1)),y1.index,rotation=90)
plt.show()
#圖形的橫座標是:2018-01-02 00:00:00 ~2018-10-19 00:00:00
#8.股票預測:時間序列的預測----長期才會比較可行,短期不可信
#Prophet加性模型預測
import fbprophet #facebook的模組
data=df_csvsave['Close'].reset_index() #重新指定index,因為之前是Date是作為index
#Dataframe must have columns 'ds' and 'y' with the dates and values respectively.
data=data.rename(columns={'Date':'ds','Close':'y'}) #列名的重名令
changepoint_prior=[0.01,0.02,0.03,0.04,0.05,0.06,0.1]
count=0
for iten in range(0,1):
model=fbprophet.Prophet(changepoint_prior_scale=changepoint_prior[iten],daily_seasonality=True)
model.fit(data)
#預設情況下,Prophet能夠滿足附加的季節性,這意味著季節性的影響是加到趨勢中得到了最後的預報
forecst_df=model.make_future_dataframe(periods=365,freq='D')
forecast=model.predict(forecst_df)
model.plot(forecast,xlabel='Date',ylabel='Close Price')
#繪圖中黑色表示真實資料;藍色表示預測資料
#9.變化點觀測
#Prophet提供了幫助我們繪製股票價格變化點,變化點代表時間序列上升與下降的變化時刻
from fbprophet.plot import add_changepoints_to_plot
fig=model.plot(forecast)
a=add_changepoints_to_plot(fig.gca(),model,forecast)
plt.title('changepoint_prior_scale=%f ,fbprophet prediction curve' % iten)
plt.savefig('D:/momo_%d.png' % count )
count+=1
changepoint_prior_scale=0.01 ,fbprophet prediction curve
changepoint_prior_scale=0.02 ,fbprophet prediction curve
changepoint_prior_scale=0.03 ,fbprophet prediction curve
changepoint_prior_scale=0.04 ,fbprophet prediction curve
changepoint_prior_scale=0.05 ,fbprophet prediction curve
changepoint_prior_scale=0.06 ,fbprophet prediction curve
changepoint_prior_scale=0.1 ,fbprophet prediction curve
#10.多維度變化趨勢觀測
from fbprophet.plot import plot_components
model.plot_components(forecast) #展示不同時間粒度:如年、月、日、時的走勢