使用Python对股票数据进行分析

          最近越发痴迷研究金融产品,不仅仅是因为前段时间重新对板块进行了新的布局,也相信如果理财是一生都需要做的事也愿意花时间去好好研究一下.大部分人一致认为定投会受益,说的人多了大家也就不去验证了.今天突然心血来潮看有关金融的书籍发现一种很玄学的手段去买卖股票

          也对  "定投的受益数据 "与 "玄学受益数据"做一个数据上验证

验证步骤如下:

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   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: 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 data


DatetimeIndex(['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].index

DatetimeIndex(['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()*100

7779065.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-cost

999771.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)
df

	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
...	...	...	...	...	...	...	...
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()
ma30


date
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_date

DatetimeIndex(['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_date


DatetimeIndex(['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*100
        money-=(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_money

51976209.09999999

收益  51976209.09999999

本内容只作为根据以往的一种数据参考,双均线是影响因素之一 并不是造成盈亏的最终因素.

  • 2
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值