最近越发痴迷研究金融产品,不仅仅是因为前段时间重新对板块进行了新的布局,也相信如果理财是一生都需要做的事也愿意花时间去好好研究一下.大部分人一致认为定投会受益,说的人多了大家也就不去验证了.今天突然心血来潮看有关金融的书籍发现一种很玄学的手段去买卖股票
也对 "定投的受益数据 "与 "玄学受益数据"做一个数据上验证
验证步骤如下:
1.以茅台发行到今天的数据为例,计算每个月 月初定投 月末进行卖出的受益
1.1获取茅台发行到现在的所有成交数据,保存到本地存储
-Date:2022/4/5
-Author:RenJiaXing
-Subject:equity analyst
pip install tushare
Requirement already satisfied: tushare in d:\an\lib\site-packages (1.2.84)Note: you may need to restart the kernel to use updated packages.
Requirement already satisfied: pandas in d:\an\lib\site-packages (from tushare) (1.3.4)
Requirement already satisfied: simplejson in d:\an\lib\site-packages (from tushare) (3.17.6)
Requirement already satisfied: requests in d:\an\lib\site-packages (from tushare) (2.26.0)
Requirement already satisfied: websocket-client==0.57.0 in d:\an\lib\site-packages (from tushare) (0.57.0)
Requirement already satisfied: lxml in d:\an\lib\site-packages (from tushare) (4.6.3)
Requirement already satisfied: bs4 in d:\an\lib\site-packages (from tushare) (0.0.1)
Requirement already satisfied: six in d:\an\lib\site-packages (from websocket-client==0.57.0->tushare) (1.16.0)
Requirement already satisfied: beautifulsoup4 in d:\an\lib\site-packages (from bs4->tushare) (4.10.0)Requirement already satisfied: soupsieve>1.2 in d:\an\lib\site-packages (from beautifulsoup4->bs4->tushare) (2.2.1)
Requirement already satisfied: pytz>=2017.3 in d:\an\lib\site-packages (from pandas->tushare) (2021.3)
Requirement already satisfied: python-dateutil>=2.7.3 in d:\an\lib\site-packages (from pandas->tushare) (2.8.2)
Requirement already satisfied: numpy>=1.17.3 in d:\an\lib\site-packages (from pandas->tushare) (1.20.3)
Requirement already satisfied: certifi>=2017.4.17 in d:\an\lib\site-packages (from requests->tushare) (2021.10.8)
Requirement already satisfied: urllib3<1.27,>=1.21.1 in d:\an\lib\site-packages (from requests->tushare) (1.26.7)
Requirement already satisfied: idna<4,>=2.5 in d:\an\lib\site-packages (from requests->tushare) (3.2)
Requirement already satisfied: charset-normalizer~=2.0.0 in d:\an\lib\site-packages (from requests->tushare) (2.0.4)import tushare as ts
import pandas as pd
from pandas import DataFrame,Series
import numpy as np
#Climb down the stock information
df=ts.get_k_data(code='600519',start='2000-01-01')#Get the stock information stored locally
df.to_csv('./maotai.csv')#Read local stock information
df=pd.read_csv('./maotai.csv')Unnamed: 0 date open close high low volume code
0 0 2001-08-27 -91.359 -91.174 -90.778 -91.654 406318.00 600519
1 1 2001-08-28 -91.274 -90.941 -90.916 -91.341 129647.79 600519
2 2 2001-08-29 -90.920 -91.027 -90.916 -91.076 53252.75 600519
3 3 2001-08-30 -91.044 -90.899 -90.826 -91.094 48013.06 600519
4 4 2001-08-31 -90.890 -90.915 -90.806 -90.952 23231.48 600519
... ... ... ... ... ... ... ... ...
4919 4919 2022-03-28 1625.000 1660.800 1664.800 1604.000 57542.00 600519
4920 4920 2022-03-29 1661.500 1667.000 1691.500 1661.500 25935.00 600519
4921 4921 2022-03-30 1698.000 1730.100 1730.100 1695.000 42433.00 600519
4922 4922 2022-03-31 1720.000 1719.000 1738.600 1708.800 25174.00 600519
4923 4923 2022-04-01 1729.940 1780.010 1793.000 1721.690 44862.00 600519
4924 rows × 8 columns
从获取结果可以看出该股票从成立2001-8-27 第一次发行, 到现在2022-4-1 一共有4923开盘数据
1.2 对数据进行处理,为后续的工作准备
#Delete data that is not used for reading data, and process data types
#删除df中指定的一列 drop:label 为下标
#axis为轴向 1表示列 0表示行 inplace为true表示在原数据中修改
df.drop(labels='Unnamed: 0',axis=1,inplace=True)
df.head()
date open close high low volume code
0 2001-08-27 -91.359 -91.174 -90.778 -91.654 406318.00 600519
1 2001-08-28 -91.274 -90.941 -90.916 -91.341 129647.79 600519
2 2001-08-29 -90.920 -91.027 -90.916 -91.076 53252.75 600519
3 2001-08-30 -91.044 -90.899 -90.826 -91.094 48013.06 600519
4 2001-08-31 -90.890 -90.915 -90.806 -90.952 23231.48 600519
#Look at the data type for each column
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4924 entries, 0 to 4923
Data columns (total 7 columns):# Column Non-Null Count Dtype
--- ------ -------------- ----- 0 date 4924 non-null object 1 open 4924 non-null float642 close 4924 non-null float643 high 4924 non-null float644 low 4924 non-null float645 volume 4924 non-null float646 code 4924 non-null int64
dtypes: float64(5), int64(1), object(1)
memory usage: 269.4+ KB#Change the date data type to facilitate subsequent data processing
#Converts the date obj type to the time type
df['date']=pd.to_datetime(df['date'])<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4924 entries, 0 to 4923
Data columns (total 7 columns):# Column Non-Null Count Dtype
--- ------ -------------- ----- 0 date 4924 non-null datetime64[ns]1 open 4924 non-null float64 2 close 4924 non-null float64 3 high 4924 non-null float64 4 low 4924 non-null float64 5 volume 4924 non-null float64 6 code 4924 non-null int64
dtypes: datetime64[ns](1), float64(5), int64(1)
memory usage: 269.4 KB#Use the date column as the row index of the original data
df.set_index('date',inplace=True)open close high low volume code
date
2001-08-27 -91.359 -91.174 -90.778 -91.654 406318.00 600519
2001-08-28 -91.274 -90.941 -90.916 -91.341 129647.79 600519
2001-08-29 -90.920 -91.027 -90.916 -91.076 53252.75 600519
2001-08-30 -91.044 -90.899 -90.826 -91.094 48013.06 600519
2001-08-31 -90.890 -90.915 -90.806 -90.952 23231.48 600519
对获取的数据数据类型等进行习惯性的重新设置
1.3 计算需求:
①小练习(其实就是网不太好,连接口总是断 测试一下)
- 获取闭盘比开盘上涨3%的日期
#Find the date when the stock closed up more than 3% from the opening
#伪代码 (收盘-开盘)/开盘>0.03
(df['open']-df['close'])/df['open']>0.03#If a Boolean value is generated during analysis, the next step is to use the Boolean as the row index
#If a Boolean is used as a row index, it can fetch true's data
df.loc[(df['open']-df['close'])/df['open']>0.03].index#Get true row dataDatetimeIndex(['2006-05-29', '2006-06-12', '2006-10-09', '2006-10-25','2006-11-14', '2006-11-16', '2006-11-29', '2006-11-30','2006-12-11', '2006-12-14',...'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=680, freq=None)
- 获取开盘比前一天下跌2%的日期
#Find all the dates when the stock opened down more than 2% from the previous day's close
#伪代码:(开盘-前日收盘)/前日收盘<-0.02
(df['open']-df['close'].shift(1))/df['close'].shift(1)<-0.02
df.loc[(df['open']-df['close'].shift(1))/df['close'].shift(1)<-0.02].indexDatetimeIndex(['2006-02-13', '2006-04-17', '2006-04-18', '2006-04-19','2006-04-20', '2006-05-25', '2006-05-30', '2006-12-27','2007-01-04', '2007-01-22',...'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=378, freq=None)
②计算定投定卖的受益
需求分析:
时间节点: 2020-01-01到现在
实行过程:每个月月初进行定投1手(100股) 月末进行卖出
new_df=df['2010-01':]
#Buy stocks: Find out the corresponding row data for the first trading day of each month (opening price)
#Extract specified data from raw data by month for data resampling
df_monthly=new_df.resample('M').first()open close high low volume code
date
2010-01-31 35.594 34.047 35.594 33.573 44304.88 600519
2010-02-28 33.250 33.258 33.776 31.845 29655.94 600519
2010-03-31 31.424 31.267 32.176 31.079 21734.74 600519
2010-04-30 25.662 26.624 26.954 25.647 23980.83 600519
2010-05-31 2.529 3.017 3.708 1.702 23975.16 600519
... ... ... ... ... ... ...
2021-12-31 1950.000 1932.990 1959.950 1919.020 26254.00 600519
2022-01-31 2055.000 2051.230 2068.950 2014.000 33843.00 600519
2022-02-28 1900.990 1867.960 1913.560 1850.000 35150.00 600519
2022-03-31 1802.000 1858.480 1863.570 1802.000 47379.00 600519
2022-04-30 1729.940 1780.010 1793.000 1721.690 44862.00 600519
148 rows × 6 columns#The total amount of money spent on buying a stock
cost=df_monthly['open'].sum()*1007779065.800000001#The valuation of shares that have not been sold in 2022 is included in the total earnings
last_monry=200*new_df['close'][-1]#Calculate total revenue
resv+last_monry-cost999771.0
可以看出 从2020-01-01 到今天 每个月定投100股 到今天(当然这个月的没有卖出 以最近闭盘价格进行估值计算), 到目前为止应该受益 999771.0元
2.以茅台发行到今天的数据为例,使用双均线策略玄学受益
- 获取5日均线和30日均线
#Double moving average strategy formulation
df=pd.read_csv('./maotai.csv').drop(labels='Unnamed: 0',axis=1)
dfdate open close high low volume code
0 2001-08-27 -91.359 -91.174 -90.778 -91.654 406318.00 600519
1 2001-08-28 -91.274 -90.941 -90.916 -91.341 129647.79 600519
2 2001-08-29 -90.920 -91.027 -90.916 -91.076 53252.75 600519
3 2001-08-30 -91.044 -90.899 -90.826 -91.094 48013.06 600519
4 2001-08-31 -90.890 -90.915 -90.806 -90.952 23231.48 600519
... ... ... ... ... ... ... ...
4919 2022-03-28 1625.000 1660.800 1664.800 1604.000 57542.00 600519
4920 2022-03-29 1661.500 1667.000 1691.500 1661.500 25935.00 600519
4921 2022-03-30 1698.000 1730.100 1730.100 1695.000 42433.00 600519
4922 2022-03-31 1720.000 1719.000 1738.600 1708.800 25174.00 600519
4923 2022-04-01 1729.940 1780.010 1793.000 1721.690 44862.00 600519
4924 rows × 7 columns#Change the date data type to facilitate subsequent data processing
#Converts the date obj type to the time type
df['date']=pd.to_datetime(df['date'])#Use the date column as the row index of the original data
df.set_index('date',inplace=True)df.head()open close high low volume code
date
2001-08-27 -91.359 -91.174 -90.778 -91.654 406318.00 600519
2001-08-28 -91.274 -90.941 -90.916 -91.341 129647.79 600519
2001-08-29 -90.920 -91.027 -90.916 -91.076 53252.75 600519
2001-08-30 -91.044 -90.899 -90.826 -91.094 48013.06 600519
2001-08-31 -90.890 -90.915 -90.806 -90.952 23231.48 600519#计算该股票的五日均线和 60日均线
#均线:对于每一个交易日,都可以计算前N天的移动平均值 并将这些移动
#平均值连接成为一条线a\5天和10天的是短线操作,称为日均线指标b\30天和60天的是中期均线指标 称为季均线指标c\120和240的是长期均线指标 称为年均线指标ma5=df['close'].rolling(5).mean()
ma30=df['close'].rolling(30).mean()
ma30date
2001-08-27 NaN
2001-08-28 NaN
2001-08-29 NaN
2001-08-30 NaN
2001-08-31 NaN...
2022-03-28 1771.946333
2022-03-29 1764.492333
2022-03-30 1759.077333
2022-03-31 1753.477667
2022-04-01 1749.244667
Name: close, Length: 4924, dtype: float64#画出五日均线
import matplotlib.pyplot as plt
%matplotlib inline
plt.plot(ma5)
plt.plot(ma30)
由于两条线的密度和像素因素,两条线几乎重合 再对数据进行计划处理
- 对数据进行截取细化,再次画出两条均线的折线图
plt.plot(ma5[50:180])
plt.plot(ma30[50:180])
- 对数据进行重新分析
分析输出所有的金叉日期和死叉日期
我们分析指标中的两根线 一根为短时间内的指标线 一根为长时间的指标线
a\ 如果短时间的指标方向朝上 并且穿过了较长时间的指标线
这种状态叫做金叉
b\ 如果短时间的指标方向朝下 并且穿过了较长时间的指标线
这种状态叫做死叉
一般情况下出现金叉后操作趋向买入
ma5=ma5[30:]
ma30=ma30[30:]
s1=ma5<ma30
s2=ma5>ma30
df=df[30:]death_ex=s1&s2.shift(1)#判断死叉的条件
df.loc[death_ex]#死叉对应的行数据
death_date=df.loc[death_ex].index
death_dateDatetimeIndex(['2002-01-17', '2002-01-30', '2002-03-29', '2002-07-29','2002-12-27', '2003-03-17', '2003-04-22', '2003-06-20','2003-06-30', '2003-08-04',...'2020-03-18', '2020-08-10', '2020-09-21', '2020-10-27','2021-03-01', '2021-04-15', '2021-05-06', '2021-06-22','2021-11-04', '2022-01-06'],dtype='datetime64[ns]', name='date', length=104, freq=None)#判断金叉的条件
golden_ex=-(s1|s2.shift(1))
golden_date=df.loc[golden_ex].index
golden_dateDatetimeIndex(['2001-08-27', '2001-08-28', '2001-08-29', '2001-08-30','2001-08-31', '2001-09-03', '2001-09-04', '2001-09-05','2001-09-06', '2001-09-07',...'2020-03-03', '2020-04-02', '2020-08-19', '2020-10-14','2020-11-05', '2021-04-02', '2021-04-16', '2021-05-20','2021-09-16', '2021-11-23'],dtype='datetime64[ns]', name='date', length=133, freq=None)
需求:--假如从2010年1月1日开始初始资金100000元,金叉尽量买入 死叉全部卖出,则到今天为止 收益如何?
分析:
--买卖股票的单价使用开盘单价
--买卖的时间
--最终手中会有剩余的没有卖出,估量剩余的价值
s1=Series(data=1,index=golden_date)
s2=Series(data=0,index=death_date)
s=s1.append(s2)
s=s.sort_index()s=s['2010':]frist_money=100000#本金
money=frist_money#可变资金
hold=0#购买股数 100股=1手for i in range(0,len(s)):if s[i]==1:time=s.index[i]#金叉时间p=df.loc[time] ['open']#购买单价hand_count=money//(p*100)hold=hand_count*100money-=(hold*p)#购买后剩余钱数else:death_time=s.index[i]p_death=df.loc[death_time] ['open']money+=(p_death*hold)hold=0
#判断最后一天为金叉还是死叉
last_monry=hold*df['close'][-1]
#总收益
money+last_monry-frist_money51976209.09999999
收益 51976209.09999999
本内容只作为根据以往的一种数据参考,双均线是影响因素之一 并不是造成盈亏的最终因素.