1-2-python数据分析-DataFrame基础操作巩固-股票分析、双均线策略制定

tushare财经数据接口包

  • pip install tushare
  • 作用:提供相关指定的财经数据
  • 相关文档:http://tushare.org/

需求:股票分析

  • 使用tushare包获取某股票的历史行情数据。
  • 输出该股票所有收盘比开盘上涨3%以上的日期。
  • 输出该股票所有开盘比前日收盘跌幅超过2%的日期。
  • 假如我从2010年1月1日开始,每月第一个交易日买入1手股票,每年最后一个交易日卖出所有股票,到今天为止,我的收益如何?

数据处理

使用tushare包获取某股票的历史行情数据

df = ts.get_k_data(code='600519',start='1999-01-10')

df的持久化存储 df.to_xxx()

#将df的数据存储到本地
df.to_csv('./maotai.csv')

加载外部数据 pd.read_xxx()

#加载外部数据到df中:read_xxx()
df = pd.read_csv('./maotai.csv')
df.head()

 将Unnamed: 0列进行删除

在drop系列的函数中

  • axis=0表示的行,1表示的是列
  • inplace=True将删除操作直接作用原始数据
df.drop(labels='Unnamed: 0', axis=1, inplace=True)
df.head()

将date列的字符串类型的时间转换成时间序列类型

df['date'] = pd.to_datetime(df['date'])
df['date'].dtype  # dtype('<M8[ns]')

将date列作为源数据的行索引

df.set_index('date', inplace=True)
df.head()

 数据分析

1 、输出该股票所有收盘比开盘上涨3%以上的日期

  • (收盘-开盘)/开盘 > 0.03
(df['close']-df['open']) / df['open'] >0.03

 

 经验:在df的相关操作中如果一旦返回了布尔值,下一步马上将布尔值作为原始数据的行索引

将满足需求的行数据获取(收盘比开盘上涨3%以上)

# 发现布尔值可以作为df的行索引,可以直接取出true对应的行数据
df.loc[(df['close'] - df['open']) / df['open'] > 0.03]

 获取满足要求的日期

df.loc[(df['close']-df['open']) / df['close'] > 0.03].index

DatetimeIndex(['2001-08-28', '2001-09-10', '2001-12-21', '2002-01-18',
               '2002-01-31', '2003-01-14', '2003-10-29', '2004-01-05',
               '2004-01-14', '2004-01-29',
               ...
               '2019-09-12', '2019-09-18', '2020-02-11', '2020-03-02',
               '2020-03-10', '2020-04-02', '2020-04-22', '2020-05-06',
               '2020-07-06', '2020-07-07'],
              dtype='datetime64[ns]', name='date', length=299, freq=None)

2、输出该股票所有开盘比前日收盘跌幅超过2%的日期

  • (开盘 - 前日收盘) / 前日收盘 < -0.02
  • shift(n) 可以使该列整体移动n行,正数表示下移,负数表示上移
df.loc[(df['open']-df['close'].shift(1)) / df['close'].shift(1) < -0.02].index

DatetimeIndex(['2001-09-12', '2002-06-26', '2002-12-13', '2004-07-01',
               '2004-10-29', '2006-08-21', '2006-08-23', '2007-01-25',
               '2007-02-01', '2007-02-06', '2007-03-19', '2007-05-21',
               '2007-05-30', '2007-06-05', '2007-07-27', '2007-09-05',
               '2007-09-10', '2008-03-13', '2008-03-17', '2008-03-25',
               '2008-03-27', '2008-04-22', '2008-04-23', '2008-04-29',
               '2008-05-13', '2008-06-10', '2008-06-13', '2008-06-24',
               '2008-06-27', '2008-08-11', '2008-08-19', '2008-09-23',
               '2008-10-10', '2008-10-15', '2008-10-16', '2008-10-20',
               '2008-10-23', '2008-10-27', '2008-11-06', '2008-11-12',
               '2008-11-20', '2008-11-21', '2008-12-02', '2009-02-27',
               '2009-03-25', '2009-08-13', '2010-04-26', '2010-04-30',
               '2011-08-05', '2012-03-27', '2012-08-10', '2012-11-22',
               '2012-12-04', '2012-12-24', '2013-01-16', '2013-01-25',
               '2013-09-02', '2014-04-25', '2015-01-19', '2015-05-25',
               '2015-07-03', '2015-07-08', '2015-07-13', '2015-08-24',
               '2015-09-02', '2015-09-15', '2017-11-17', '2018-02-06',
               '2018-02-09', '2018-03-23', '2018-03-28', '2018-07-11',
               '2018-10-11', '2018-10-24', '2018-10-25', '2018-10-29',
               '2018-10-30', '2019-05-06', '2019-05-08', '2019-10-16',
               '2020-01-02', '2020-02-03', '2020-03-13', '2020-03-23'],
              dtype='datetime64[ns]', name='date', freq=None)

3、假如我从2010年1月1日开始,每月第一个交易日买入1手(100支)股票,每年最后一个交易日卖出所有股票,到今天为止,我的收益如何?

  • 买股票
    • 每月的第一个交易日根据开盘价买入一手股票
    • 一个完整的年需要买入12次12手1200支股票(1手股票100支)
  • 卖股票
    • 每年最后一个交易日根据开盘价(12-31)卖出所有的股票
    • 一个完整的年需要卖出1200支股票
  • 注意:2020年这个人只能买入700支股票,无法卖出。但是在计算总收益的时候需要将剩余股票的价值也计算在内
    • 剩余股票价值如何计算:
      • 700 * 买入当日的开盘价

取2010年到2020年的数据

new_df = df['2010':'2020'] # 如果行索引为时间序列类型数据,就可以这样索引取值 

 数据的重新取样resample

  • M代表的是月
# 将2010年到2020年所有的月份数据去取出来分组,取出每个月第一条数据

df_monthly = new_df.resample(rule='M').first()
df_monthly

#下图为部分数据示例,date显示的其实是每月的第一个交易日,这个是它内部bug导致这个原因

 计算买入股票一共花了多少钱

cost = df_monthly['open'].sum() * 100   # 4636917.100000001

 数据的重新取样resample

  • A代表的是年
df_yearly = new_df.resample(rule='A').last()[0:-1]   # 去掉2020年最后的那条数据
df_yearly

 计算卖出股票收入多少钱

income = df_yearly['open'].sum() * 1200   # 4368184.8

计算剩余股票的价值

last = df['open'][-1] * 700   # 1182300.0

计算总收益

income + last - cost   # 913567.6999999993

需求:双均线策略制定

  • 使用tushare包获取某股票的历史行情数据
  • 计算该股票历史数据的5日均线和30日均线
    • 什么是均线?
      • 对于每一个交易日,都可以计算出前N天的移动平均值,然后把这些移动平均值连起来,成为一条线,就叫做N日移动平均线。移动平均线常用线有5天、10天、30天、60天、120天和240天的指标。
        • 5天和10天的是短线操作的参照指标,称做日均线指标;
        • 30天和60天的是中期均线指标,称做季均线指标;
        • 120天和240天的是长期均线指标,称做年均线指标。
    • 均线计算方法:MA=(C1+C2+C3+...+Cn)/N C:某日收盘价 N:移动平均周期(天数)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pandas import Series, DataFrame
import tushare as ts

df = ts.get_k_data(code='600519', start='1999-01-10')  # ts获取数据
df.to_csv('./maotai.csv')  #  保存数据
df = pd.read_csv('./maotai.csv')  # 读取数据
df.drop(labels='Unnamed: 0', axis=1, inplace=True)  # 删除Unnamed: 0列
df['date'] = pd.to_datetime(df['date'])  # 时间由字符串转到时间
df.set_index('date', inplace=True)  # 将date设置为索引
df.head()  # 查看数据前5行

计算并制定双均线

# rolling(5)拿到每个数据的前5个数据,算他本身
# mean() 求平均
# 前几个数据显示NaN是因为它前边没有足够数据

df = df['2010':'2020']

ma5 = df['close'].rolling(5).mean() 
ma30 = df['close'].rolling(30).mean()

plt.plot(ma5[50:200])
plt.plot(ma30[50:200])

 

分析输出所有金叉日期和死叉日期

  • 股票分析技术中的金叉和死叉,可以简单解释为:
    • 分析指标中的两根线,一根为短时间内的指标线,另一根为较长时间的指标线。
    • 如果短时间的指标线方向拐头向上,并且穿过了较长时间的指标线,这种状态叫“金叉”;
    • 如果短时间的指标线方向拐头向下,并且穿过了较长时间的指标线,这种状态叫“死叉”;
    • 一般情况下,出现金叉后,操作趋向买入;死叉则趋向卖出。当然,金叉和死叉只是分析指标之一,要和其他很多指标配合使用,才能增加操作的准确性。

 数据分析

  • 如果我从假如我从2010年1月1日开始,初始资金为100000元,金叉尽量买入,死叉全部卖出,则到今天为止,我的炒股收益率如何?
  • 分析:
    • 买卖股票的单价使用开盘价
    • 买卖股票的时机
    • 最终手里会有剩余的股票没有卖出去
      • 会有。如果最后一天为金叉,则买入股票。估量剩余股票的价值计算到总收益。
        • 剩余股票的单价就是用最后一天的收盘价。

将时间节点的金叉和死叉日期全部找出

注意:金叉日期、死叉日期不可能连续

death_date = df.loc[s1&s2.shift(1)].index   # 死叉日期
gold_date = df.loc[~(s1|s2.shift(1))].index  # 金叉日期

将金叉日期和死叉日期分别存储到两个Series中,将日期作为Series的索引,将0和1作为Series的value值

  • value为1对应的日期为金叉日期
  • value为0对应的日期为死叉日期
series_1 = Series(data=1, index=gold_date)
series_2 = Series(data=0, index=death_date)

# 将金叉和死叉日期进行级联操作,并按时间索引升序排序
# 去除前30条的数据,因为这些日期存在金叉或死叉日期连续
series_all = series_1.append(series_2).sort_index()[30:]

收益计算

  • 金叉尽量买入,死叉全部卖出,买卖股票的单价使用开盘价
  • 特殊情况:昨天为金叉只能买入不能卖出,手里如果有剩余的股票也是需要将其价值计算到总收益
first_money = 100000 # 本金(不可变)
cost_money = 100000 # (可变)
hold = 0 # 持有股票的支数

for index in series_all.index:

    # index就是series_all的显示索引
    if series_all[index] == 1:  # 当日为金叉,需要买入股票

        # 找出购买股票的单价
        price = df['open'][index]

        # 所有的钱尽量买入股票的手数
        hand = cost_money // (price * 100)
        hold = hand * 100  # 一共买入了多少只股票

        # 将买股票花的钱从cost_money中减出
        cost_money -= (hold * price)

    else:  # 卖出股票
        # 找出卖股票的单价
        price = df['open'][index]
        cost_money += (price * hold)
        hold = 0 

# 计算剩余股票的实际价值(如何知道是否存有剩余股票)
last_money = hold * df['open'][-1]

# 总收益
print(last_money + cost_money - first_money)

2194722.0999999996

 

posted @ 2020-07-13 22:53  电竞杰森斯坦森  阅读(1002)  评论(0编辑  收藏  举报