wgwg

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

 

分类:

技术点:

相关文章: