4、DataFrame基礎(chǔ)操作鞏固-股票分析
需求:股票分析
- 使用tushare包獲取某股票的歷史行情數(shù)據(jù)。
- 輸出該股票所有收盤比開盤上漲3%以上的日期。
- 輸出該股票所有開盤比前日收盤跌幅超過2%的日期。
- 假如我從2010年1月1日開始,每月第一個交易日買入1手股票,每年最后一個交易日賣出所有股票,到今天為止,我的收益如 何?
(1)下載tushare財經(jīng)數(shù)據(jù)接口包
終端命令行執(zhí)行:
pip install tushare
(2)進(jìn)入官網(wǎng)https://tushare.pro/
注冊登錄后,進(jìn)入個人主頁,找到接口TOKEN,進(jìn)行復(fù)制,我們在下面將會用到。

(2)導(dǎo)入相關(guān)包
import tushare as ts
import pandas as pd
from pandas import DataFrame,Series
import numpy as np
import datetime as dt
import time
token='自己的上面復(fù)制的token'
ts.set_token(token)
pro = ts.pro_api()
(3)調(diào)用接口獲取股票的信息
注:更多接口方法可以在http://tushare.org/ 進(jìn)行查看
獲取茅臺的 每日股價信息
df = pro.daily(ts_code = '600519.SH',start_date='20000101')
df

(4)對股票信息按照時間進(jìn)行排序
# 排序
# DataFrame.sort_values(by, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last')
# axis:{0 or ‘index’, 1 or ‘columns’}, default 0,默認(rèn)按照索引排序,即縱向排序,如果為1,則是橫向排序
# by:str or list of str;如果axis=0,那么by="列名";如果axis=1,那么by="行名";
# ascending:布爾型,True則升序,可以是[True,False],即第一字段升序,第二個降序
# inplace:布爾型,是否用排序后的數(shù)據(jù)框替換現(xiàn)有的數(shù)據(jù)框
# kind:排序方法,{‘quicksort’, ‘mergesort’, ‘heapsort’}, default ‘quicksort’。似乎不用太關(guān)心
# na_position : {‘first’, ‘last’}, default ‘last’,默認(rèn)缺失值排在最后面
df.sort_values(axis = 0, by = 'trade_date',inplace=True)
df

(5) 將獲取的股票信息存儲到本地
# 通過調(diào)用 to_xxx 方法將數(shù)據(jù)存儲到本地
df.to_csv('./motai.csv')
(6)將本地存儲的文件讀入到df
df = pd.read_csv('./motai.csv')
df.head()

(7)需要得讀取出來的數(shù)據(jù)進(jìn)行處理
# drop 中 axis 為1表示刪除列,為0表示刪除行,inplace 為 True 表示覆蓋原有數(shù)據(jù)
df.drop(labels='Unnamed: 0',axis=1,inplace=True)
df.head()

(8)查看每一列的數(shù)據(jù)類型
df.info()

(9)將trade_date轉(zhuǎn)為時間類型
#將int類型轉(zhuǎn)為時間類型
df['trade_date'] = pd.to_datetime(df['trade_date'],format='%Y%m%d')
df.info()

(10)設(shè)置trade_date列為索引
df.set_index('trade_date',inplace=True)
df

(11)輸出該股票所有收盤比開盤上漲3%以上的日期。
#偽代碼:(收盤 - 開盤) / 開盤 > 0.03
(df['open'] - df['close']) / df['open'] > 0.03
#在分析的過程中,如果產(chǎn)生了boolean值,可以將boolean作為行索引,可以取出值為True的行數(shù)據(jù)
df.loc[(df['open'] - df['close']) / df['open'] > 0.03].index #獲取到收盤比開盤上漲3%以上的日期

(12)輸出該股票所有開盤比前日收盤跌幅超過2%的日期。
# 偽代碼:(開盤 - 前日收盤) / 前日開盤 < 0.02
old = df['close'].shift(1) #將收盤價整體下移一位
old.head()

(13)找到開盤價低于上一天收盤價2%以上的日期
(df['open'] - old) / old < -0.02

(14)將布爾值作為行索引
df.loc[(df['open'] - old) / old < -0.02].index #獲取到符合條件的日期

(15)剩余需求
- 假如我從2010年1月1日開始,每月第一個交易日買入1手股票,每年最后一個交易日賣出所有股票,到今天為止,我的收益如 何?
- 分析
- 時間節(jié)點(diǎn):2010-2021年
- 一手股票:100支
- 買:
- 一個完整的年需要買入1200支股票
- 一個完整的年需要賣出1200支股票
- 買賣股票的單價:
- 都使用開盤價
(16)截取df,從日期2010年1月,截取到2021年12月
# 對行索引進(jìn)去切片
new_df = df['2010-01':'2021-12']
new_df

(17)買股票:找到每個月的第一個交易日(捕獲到開盤價) --> 每個月的第一行數(shù)據(jù)。
# 根據(jù)月份從原始數(shù)據(jù)中提取指定的值
# 每個月的第一個交易日行數(shù)據(jù)
# resample('M') 把數(shù)據(jù)按照月份進(jìn)去切割
df_monthly = new_df.resample('M').first() #數(shù)據(jù)是沒有錯的,索引有問題,不影響使用
df_monthly

(18)買入股票花費(fèi)的總金額
cost = df_monthly['open'].sum()*100
cost

(19)賣出股票掙到的錢
注:特殊情況:2021年買入的股票沒有賣出去
# resample('A')按照年份進(jìn)行切割
new_df.resample('A').last()
# 將2021年最后一行切出去
df_yearly = new_df.resample('A').last()[:-1]
df_yearly

(20)賣出股票到手的錢
resv = df_yearly['open'].sum()*1200
resv

(21) 計算出最后一年有幾個月:
len(df.loc['2021-01-01':].resample('M').last())

(22)最后在手中剩余的股票價值加到總收益中
#使用昨天的收盤價作為剩余股票的單價
last_monry = len(df.loc['2021-01-01':].resample('M').last()) * 100 * new_df['close'][-1]
last_monry

(23)計算總收益
resv + last_monry - cost

總結(jié):假如我從2010年1月1日開始,每月第一個交易日買入1手股票,每年最后一個交易日賣出所有股票,到今天為止,我的收益為846587元,收益還是很不錯的。