zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    jq 判断单选是否选中
    C# Split 分隔符为字符串及空格的处理
    MSSQL中的bit类型
    js 判断textarea 不为空
    [转]C#中out 及 ref 区别
    [转]asp.net中时间差的问题
    [转]C# Array 数组 及 一些操作
    Addr、@运算符与Pointer类型
    关于Pascal语言中的分号
    关于以后的文章
  • 原文地址:https://www.cnblogs.com/wgwg/p/13296418.html
Copyright © 2011-2022 走看看