首页 > 技术文章 > 06-03 练习题

xiaoyuanqujing 2019-10-12 14:30 原文

_____egon新书python全套来袭请看:https://egonlin.com/book.html

一、股票数据分析

题目:

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

答案:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tushare as ts

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

df = ts.get_k_data("600519",start="1988-01-01")
df.to_csv("E:\\Test\\600519.csv")
df = pd.read_csv("E:\\Test\\600519.csv", index_col='date', parse_dates=['date'])[['open','close','high','low']]
df

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

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

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

df[(df['open'] - df['close'].shift(1)) / df['close'].shift(1) <= -0.02].index

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

price_last = df['open'][-1]  # 当天开盘价
df = df['2010-01':] #剔除首尾无用的数据

df_monthly = df.resample("M").first()  # 每个月第一天的数据
df_yearly = df.resample("A").last()[:-1]  # 每年最后一天的数据

cost_money = 0
hold = 0
for year in range(2010, 2020):
    cost_money -= df_monthly[str(year)]['open'].sum()*100  # 每月第一天买入一手
    hold += len(df_monthly[str(year)]['open']) * 100  # 当前持有股票数量
    if year != 2019:
        cost_money += df_yearly[str(year)]['open'][0] * hold  # 每年最一天卖出所有股票(卖出价格以当天开盘价为准)
        hold = 0  # 持有股票归零

cost_money += hold * price_last  # 当前收益和当前持有股票价值之和

print(cost_money)

二、查看历史金叉死叉日期

题目

1、使用tushare包获取某股票的历史行情数据
2、使用pandas包计算该股票历史数据的5日均线和60日均线
3、使用matplotlib包可视化历史数据的收盘价和两条均线
4、分析输出所有金叉日期和死叉日期
5、如果我从假如我从2010年1月1日开始,初始资金为100000元,金叉尽量买入,死叉全部卖出,则到今天为止,我的炒股收益率如何?

答案

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import tushare as ts

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

df = ts.get_k_data("600623",start="1988-01-01")  
df.to_csv("E:\\Test\\600623.csv")
df = pd.read_csv("E:\\Test\\600623.csv",index_col='date', parse_dates=['date'])[['open','close','low','high']]

2、使用pandas包计算该股票历史数据的5日均线和60日均线

求取均线有三种方式:

# 创建五日均线和30均线列为缺失值
df['ma5'] = np.nan
df['ma30'] = np.nan

# 第一种方式:
# 五日均值
for i in range(4, len(df)):
    df.loc[df.index[i],'ma5'] = df['close'][i-4:i+1].mean()
    
# 30日均值
for i in range(29, len(df)):
    df.loc[df.index[i],'ma30'] = df['close'][i-29:i+1].mean()
    
# 第二种方式:
(df['close'].cumsum() - df['close'].cumsum().shift(1).fillna(0).shift(4)) / 5

# 第三种方式:
df['ma5']=df['close'].rolling(5).mean()
df['ma30']=df['close'].rolling(30).mean()

以上三种方式都可以实现,只是一个实现思路的问题。

3、使用matplotlib包可视化历史数据的收盘价和两条均线

df[['ma5','ma30']].plot()
plt.show()

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

"""
金叉:短期均线上穿长期均线,买入信号
死叉:短期均线下穿长期均线,卖出信号
"""

golden_cross = []
death_cross = []
# 第一种方式:
for i in range(1,len(df)):
    if df['ma5'][i] >= df['ma30'][i] and df['ma5'][i-1] < df['ma30'][i-1]:
        golden_cross.append(df.index[i].to_pydatetime())
        
        
    if df['ma5'][i] <= df['ma30'][i] and df['ma5'][i-1] > df['ma30'][i-1]:
        death_cross.append(df.index[i].to_pydatetime())
# 第二种方法:
"""
ma5 < ma30 T -->F 金叉
ma5 >= ma30 T --> F 死叉
FF -> 死叉  TT -> 金叉
"""
sr1 = df['ma5'] < df['ma30']
sr2 = df['ma5'] >= df['ma30']

death_cross = df[sr1 & sr2.shift(1)].index
golden_cross = df[~(sr1 | sr2.shift(1))].index

5、如果我从假如我从2010年1月1日开始,初始资金为100000元,金叉尽量买入,死叉全部卖出,则到今天为止,我的炒股收益率如何?

first_money = 100000
money = first_money
hold = 0 #持有多少股
sr1 = pd.Series(1, index=golden_cross)
sr2 = pd.Series(0, index=death_cross)
# 合并数据,1代表金叉,0代表死叉,排序
sr = sr1.append(sr2).sort_index()

for i in range(0, len(sr)):
    p = df['open'][sr.index[i]]
    if sr.iloc[i] == 1:
        #金叉
        buy = (money // (100 * p))
        hold += buy*100
        money -= buy*100*p
    else:
        money += hold * p
        hold = 0

# 当前开盘价
p = df['open'][-1]
now_money = hold * p + money

# 收益
print(now_money - first_money)
# 收益率
print((now_money - first_money)/first_money)

推荐阅读