1. 程式人生 > >Python資料分析----XX銀行股票分析小娛

Python資料分析----XX銀行股票分析小娛

本文使用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) #展示不同時間粒度:如年、月、日、時的走勢

在這裡插入圖片描述