贵州茅台 SH600519
双均线策略回测(5日均线、30日均线,金叉买入,死叉卖出)
交易从 2010年开始,2019年底结束。
10万初始资金
尽量买入(按手),尽量卖出,均以开盘价
未计算手续费
最终盈亏(见底部)
import akshare as ak
import pandas as pd
#获取某只股票的历史行情代码
df = ak.stock_zh_index_daily(symbol="sh600519")
#将结果写入到CSV文件中
df.to_csv('./sh600519.csv')
#将本地存储的数据读到DataFrame中
df = pd.read_csv('./sh600519.csv')
df.head()
Unnamed: 0 | date | open | high | low | close | volume | |
---|---|---|---|---|---|---|---|
0 | 0 | 2001-08-27 | 34.51 | 37.78 | 32.85 | 35.55 | 40631800 |
1 | 1 | 2001-08-28 | 34.99 | 37.00 | 34.61 | 36.86 | 12964779 |
2 | 2 | 2001-08-29 | 36.98 | 37.00 | 36.10 | 36.38 | 5325275 |
3 | 3 | 2001-08-30 | 36.28 | 37.51 | 36.00 | 37.10 | 4801306 |
4 | 4 | 2001-08-31 | 37.15 | 37.62 | 36.80 | 37.01 | 2323148 |
#删除df中指定的列
#axis=1 表示轴心为行,删除的是列
df.drop(labels='Unnamed: 0',axis=1,inplace=True)
df.head()
date | open | high | low | close | volume | |
---|---|---|---|---|---|---|
0 | 2001-08-27 | 34.51 | 37.78 | 32.85 | 35.55 | 40631800 |
1 | 2001-08-28 | 34.99 | 37.00 | 34.61 | 36.86 | 12964779 |
2 | 2001-08-29 | 36.98 | 37.00 | 36.10 | 36.38 | 5325275 |
3 | 2001-08-30 | 36.28 | 37.51 | 36.00 | 37.10 | 4801306 |
4 | 2001-08-31 | 37.15 | 37.62 | 36.80 | 37.01 | 2323148 |
#查看每一列对应的数据类型
df['date'].dtype
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5047 entries, 0 to 5046
Data columns (total 6 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 date 5047 non-null object
1 open 5047 non-null float64
2 high 5047 non-null float64
3 low 5047 non-null float64
4 close 5047 non-null float64
5 volume 5047 non-null int64
dtypes: float64(4), int64(1), object(1)
memory usage: 236.7+ KB
#将Data这一列转换为时间类型
df['date'] = pd.to_datetime(df['date'])
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 5047 entries, 0 to 5046
Data columns (total 6 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 date 5047 non-null datetime64[ns]
1 open 5047 non-null float64
2 high 5047 non-null float64
3 low 5047 non-null float64
4 close 5047 non-null float64
5 volume 5047 non-null int64
dtypes: datetime64[ns](1), float64(4), int64(1)
memory usage: 236.7 KB
#将 date这一列作为源数据的行索引
df.set_index('date',inplace=True)
df.head()
open | high | low | close | volume | |
---|---|---|---|---|---|
date | |||||
2001-08-27 | 34.51 | 37.78 | 32.85 | 35.55 | 40631800 |
2001-08-28 | 34.99 | 37.00 | 34.61 | 36.86 | 12964779 |
2001-08-29 | 36.98 | 37.00 | 36.10 | 36.38 | 5325275 |
2001-08-30 | 36.28 | 37.51 | 36.00 | 37.10 | 4801306 |
2001-08-31 | 37.15 | 37.62 | 36.80 | 37.01 | 2323148 |
#所有收盘价比开盘价上涨3%以上的日期
(df['open']-df['close'])/df['open'] > 0.03
#如果布尔值Series作为行索引,则可以去出true对应行数据,忽略false对应的行数据
df.loc[(df['open']-df['close'])/df['open'] > 0.03]
#取得日期
df.loc[(df['open']-df['close'])/df['open'] > 0.03].index
DatetimeIndex(['2001-10-10', '2001-11-07', '2001-11-16', '2001-12-20',
'2002-01-04', '2002-01-17', '2002-01-28', '2002-04-17',
'2002-11-08', '2003-01-02',
...
'2021-07-26', '2021-07-27', '2021-07-29', '2021-08-17',
'2021-08-26', '2021-10-18', '2021-12-29', '2022-01-13',
'2022-01-28', '2022-03-07'],
dtype='datetime64[ns]', name='date', length=189, freq=None)
#所有开盘比钱日收盘跌幅超过2%的日期
#将收盘价整体下移一行,用来取得前收盘
df['close'].shift(1)
df.loc[(df['open']-df['close'].shift(1))/df['close'].shift(1) < -0.02].index
DatetimeIndex(['2001-09-12', '2002-06-26', '2002-07-25', '2002-12-13',
'2003-07-14', '2004-07-01', '2004-10-29', '2005-08-05',
'2006-05-25', '2006-08-21',
...
'2020-03-23', '2020-10-26', '2021-02-26', '2021-03-04',
'2021-04-28', '2021-08-20', '2021-11-01', '2022-03-14',
'2022-03-15', '2022-03-28'],
dtype='datetime64[ns]', name='date', length=101, freq=None)
#假如从2010年1月1日开始,
#每个月第一个交易日买入1手股票
#每年最后一个交易日卖出所有的股票
#到今天为止,我的收益如何?
#买卖股票用开盘价
# 取10年的集合
#df['2010-01-01':'2019-12-31']
#resample数据的重新取样
#根据月份从原始数据中指定的数据
#每月第一个行数据,则买入股票所花费的金额为
#注意,这里数据没问题,但是索引是有问题的
#df['2010-01-01':'2019-12-31'].resample('M').first()['open']
pay = df['2010-01-01':'2019-12-31'].resample('M').first()['open'].sum()*100
pay
4162439.0
#取每年的最后一个交易日
earn = df['2010-01-01':'2019-12-31'].resample('A').last()['open'].sum()*100
#如果要删掉一个数据则用df['2010-01-01':'2019-12-31'].resample('A').first()[:-1]
earn
390654.0
#计算总收益
earn-pay
-3771785.0
#均线计算 MA=(C1+C2+CN)/N,其中C是收盘价,N是移动平均天数
# 5,10,30,60,120,240 常见的N日均线
ma5 = df['close'].rolling(5).mean()
ma30 = df['close'].rolling(30).mean()
#均线画图
import matplotlib.pyplot as plt
plt.plot(ma5[50:180])
plt.plot(ma30[50:180])
[<matplotlib.lines.Line2D at 0x1e47b57d360>]
ma5 = ma5[30:]
ma30 = ma30[30:]
s1 = ma5 < ma30
s2 = ma5 > ma30
df = df[30:]
death_ex = s1 & s2.shift(1) #判断死叉的条件,一组BOOL值
death_date = df.loc[death_ex].index
golden_ex = -(s1 | s2.shift(1)) #判断金叉的条件,一组BOOL值
golden_date = df.loc[golden_ex].index
#交易从 2010年开始,10万初始资金,尽量买入(按手),尽量卖出,均以开盘价
s1 = pd.Series(data=1,index=golden_date)
s2 = pd.Series(data=0,index=death_date)
#s = s1.append(s2)
s= pd.concat([s1,s2],axis=0)
s = s.sort_index()
s = s['2010':'2020']
capital = 100000 # 初始资金10万
money = capital #当前有多少活动资金
hold = 0 #持有的股票数
for i in range(0,len(s)):
p = df.loc[s.index[i]]['open']
if s[i] == 1: #金叉,需要买进
#print(p)
hand_count = money // (p*100)
hold = hand_count * 100
money -= hold*p
else:
#将 hold的股票卖出去
money += hold*p
hold = 0
print(money-capital)
6193.0
(没算手续费,没算利息,没亏,十年啊,太尴尬了,金叉,死叉不可信啊!)
jupyter的源文件,如果想要得话就给我留言吧,我发出来。
今天的文章贵州茅台股票量价分析_贵州茅台介绍分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/67545.html