本文使用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) #展示不同时间粒度:如年、月、日、时的走势
来源:CSDN
作者:jp_zhou256
链接:https://blog.csdn.net/jp_zhou256/article/details/83627472