标签(空格分隔): python 量化 ETF tushare pandas
采用tushare来获取数据.
import pandas as pd
import numpy as np
import tushare as ts
import seaborn
from matplotlib import pyplot as plt
import talib
plt.style.use('seaborn')
%matplotlib inline
with open('token.txt') as f:
token = f.readline()
ts.set_token(token)
tushare的最新版本,tushare pro需要注册用户,并设置token来连接. 通过pro.fund_daily
来获取510500从2015年到现在的所有数据,返回的结果是一个pandas dataframe.
pro = ts.pro_api()
df = pro.fund_daily(ts_code='510500.SH', start_date='20150101', end_date='20191010')
print(df.shape[0],df.shape[1]) #计算行数和列数
1000 11
tushare似乎一次最多只能获取1000条数据。如果想获取更长的数据,就需要多次调用pro.fund_daily
然后再进行dataframe的合并。另外取出来的数据的时间是倒序的。数据信息量挺多,包含了开盘价,收盘价,最高价,最低价,成交量等数据.
etf500 = df.sort_values(by='trade_date')
etf500['trade_date'] = pd.to_datetime(etf500['trade_date'],format='%Y%m%d')
etf500.head()
按照时间排序,并把’trade_date’转为日期格式.
将trade_date 设置为索引.
etf500.set_index('trade_date',inplace=True)
etf500.head()
通过dataframe的describe()
方法,大概了解一下数据.
etf500.describe()
从输出结果中看到,etf500的最高涨跌幅度为+/-8%左右.那对我们是一个好消息,至少没有涨停和跌停导致无法交易的时候.
print(etf500['close'].min(),etf500['close'].idxmin())
4.297 2018-10-18 00:00:00
获取一下最低收盘价的价格和日期.
print(etf500['close'].min(),etf500['close'].idxmin())
8.167 2015-11-25 00:00:00
获取一下最高收盘价的价格和日期,大家还记得2015年大牛市,大家爆炒中小盘股的情形吧 .
etf500[etf500['amount'].idxmin():etf500['amount'].idxmin()]
获取一下成交量最低的情况.这个应该是2016年1月"股灾3.0"时期的熔断股灾,成交量只有2000多万.
closed = etf500[['close']]
closed.plot()
closed['MA2'] = talib.SMA(closed.close,timeperiod=2)
closed['MA20']=talib.SMA(closed.close,timeperiod=20)
增加两列,分别是用talib计算2日和20日均线.
closed.plot(figsize=(20,5))
plt.title("STOCK:510500", weight='bold');
closed['pct_chg']=closed.close.pct_change()
pct_chang()计算出每天变化的百分比.
closed['pct_chg'].plot(figsize=(30,5))
closed.loc[np.abs(closed['pct_chg']) >0.065 ] #算出收益率变化最大的几天
看看涨跌最大的几天,估计这些日子在老韭菜的心里是刻骨铭心的.
fig,axes = plt.subplots(1,2,figsize=(15,5))
axes[0].hist(closed['pct_chg'].dropna(),color='g',bins=50)
axes[1].hist(closed['close'].dropna())
看看收益率和收盘价的柱状图. 收益率基本在0%的位置成正态分布.
closed['log_ret'] = np.log(closed.close/closed.close.shift(1)) #计算对数收益率
closed['log_ret'].plot(figsize=(30,5),color='r') #输出对数收益率
cumulative_rets = closed.log_ret.cumsum().values #对数收益率进行累计求和,可以计算出从开始到每个时间点的收益率
plt.figure(figsize=(30, 5))
plt.plot(cumulative_rets)
diff_ma2_ma20 = closed.MA2-closed.MA20
closed['hold'] = np.where(closed.MA2 >closed.MA20,closed.MA2,None) #这里把赋值为None,下面画图好看一点
closed[['MA2','MA20','hold']].plot(figsize=(30,5))
plt.title("STOCK:510500", weight='bold'); #红色的线表示持股的时间
stragy_ret = np.where(closed.hold >0,closed.log_ret, 0)
stragy_ret= stragy_ret.cumsum()
plt.figure(figsize=(30, 5))
plt.plot(stragy_ret)
plt.plot(cumulative_rets)
我们的策略是当2日均线站上20均线后持有.跌破20日均线后卖出.上图就是使用我们的策略和一开始就持有的收益的对比.
print("strage= {},hold ={}".format(np.exp(stragy_ret[-1]),np.exp(cumulative_rets[-1])))
strage= 2.7722754256654154,hold =0.8373846153846146
就是一下使用策略的收益和一开始就持有的收益.使用策略的收益是270%, 而一开始就买入持有到今天只有83%的市值了.
closed.close[-1]/closed.close[0]
0.8373846153846153
确定一下计算结果是否正确?可见如果从2015年9月1日买入510500,并持有到2019年10月,是亏本.
year_ret = np.exp(stragy_ret[-1]/4)
year_ret
1.290354657748639#每年的回报是29%,相当牛逼了?
如果采用均线穿越的方法,能够实现29%的年回报.这个收益率已经能够打败巴菲特了!!!.