贵州茅台 SH600519
双均线策略回测(5日均线、30日均线,金叉买入,死叉卖出)
交易从 2010年开始,2019年底结束。
10万初始资金
尽量买入(按手),尽量卖出,均以开盘价
未计算手续费
最终盈亏(见底部)
import akshare as ak
import pandas as pd
df = ak.stock_zh_index_daily(symbol="sh600519")
df.to_csv('./sh600519.csv')
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.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
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
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 |
---|
(df['open']-df['close'])/df['open'] > 0.03
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)
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)
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
earn
390654.0
earn-pay
-3771785.0
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)
death_date = df.loc[death_ex].index
golden_ex = -(s1 | s2.shift(1))
golden_date = df.loc[golden_ex].index
s1 = pd.Series(data=1,index=golden_date)
s2 = pd.Series(data=0,index=death_date)
s= pd.concat([s1,s2],axis=0)
s = s.sort_index()
s = s['2010':'2020']
capital = 100000
money = capital
hold = 0
for i in range(0,len(s)):
p = df.loc[s.index[i]]['open']
if s[i] == 1:
hand_count = money // (p*100)
hold = hand_count * 100
money -= hold*p
else:
money += hold*p
hold = 0
print(money-capital)
6193.0
(没算手续费,没算利息,没亏,十年啊,太尴尬了,金叉,死叉不可信啊!)
jupyter的源文件,如果想要得话就给我留言吧,我发出来。