目录
交易日数据在一些金融数据的统计中比较常见。本文主要介绍一下,数据的获取以及一些频率的转换。由于周度的相对会复杂一点,后续专门用一篇文章来介绍。
1. 源代码
先直接看一下整体的代码。
import pandas as pd
import akshare as ak
class TRADE_DAY(object):
'''
获取不同频率下(除周度),对应区间的交易日,不含开始和终止日期,
除非二者刚好符合相应的频率
'''
def __init__(self, data, st, et):
'''
st: str,开始日期,格式如'2023-03-01'
et: str,终止日期,格式如'2023-03-01'
data:转换后的交易日数据源
'''
self.st = st
self.et = et
self.data = data
@classmethod
def data_change(cls, trade_day):
# 对初始的数据进行清洗转换,此处可依据获取的数据源进行自主转换
# 转换后的数据格式为DataFrame,只有一列,列名为date,值的格式为str,例如'2023-03-03'
new_df = pd.DataFrame({'date': trade_day['trade_date']})
new_df['date'] = new_df['date'].apply(lambda x:
pd.to_datetime(str(x)).strftime("%Y-%m-%d"))
return new_df
def get_trading_day(self):
# 获取起始日对应的交易日日度数据
data = self.data
Trading_day = data.loc[(data['date'] >= self.st) & (data['date'] <= self.et)]
return Trading_day
def get_frequency_date(self, frequency_list):
# 获取起始日对应的各频率的日期
df = TRADE_DAY.get_trading_day(self)
df['year'] = df['date'].apply(lambda x: pd.to_datetime(x).year)
df['month'] = df['date'].apply(lambda x: pd.to_datetime(x).month)
st_year = pd.to_datetime(self.st).year
et_year = pd.to_datetime(self.et).year + 1
year_list = [x for x in range(st_year, et_year)]
all_day = []
for year in year_list:
one_df = df.loc[df['year'] == year]
for month in frequency_list:
one_data = one_df.loc[one_df['month'] == month]
if one_data.empty:
pass
else:
res_day = one_data['date'].max()
all_day.append(res_day)
new_df = pd.DataFrame({'date': all_day})
return new_df
def get_month_date(self):
# 获取区间对应的月度交易日日期
frequency_list = [x for x in range(1, 13)]
new_df = TRADE_DAY.get_frequency_date(self, frequency_list)
return new_df
def get_quarter_date(self):
# 获取区间对应的季度交易日日期
frequency_list = [3, 6, 9, 12]
new_df = TRADE_DAY.get_frequency_date(self, frequency_list)
return new_df
def get_half_year_date(self):
# 获取区间对应的半年度交易日日期
frequency_list = [6, 12]
new_df = TRADE_DAY.get_frequency_date(self, frequency_list)
return new_df
def get_year_date(self):
# 获取区间对应的年度交易日日期
frequency_list = [12]
new_df = TRADE_DAY.get_frequency_date(self, frequency_list)
return new_df
def add_date(date, st, et):
# date:TRADE_DAY对应获取的交易日数据
# 对所获频率的日期加上开始和结束日
new_date = pd.DataFrame({'date': [st, et]})
new_date = new_date.append(date)
new_date = new_date.drop_duplicates()
add_date = new_date.sort_values(by=['date'], ascending=True)
return add_date
2. 案例演示
先进行前期的数据转换以及传参。需要注意的是,获取的数据一般不包含开始和结束日期,除非刚好二者属于对应频率的数据。因此,增加一个add_date函数来完善此需求。另外,akshare交易日数据仅更新到2023年底,如截止日超过此区间,需要更换相应的数据源。
if __name__ == '__main__':
# 输入参数
trade_date = ak.tool_trade_date_hist_sina()
st, et = '2020-02-01', '2023-07-01'
# 对原始数据进行转换
data = TRADE_DAY.data_change(trade_date)
# 传入参数
Trade = TRADE_DAY(data, st, et)
2.1 获取日度数据
day_df = Trade.get_trading_day()
对应结果为:
2.2 获取月度数据
month_df = Trade.get_month_date()
对应结果为:
2.3 获取季度数据
quarter_df = Trade.get_quarter_date()
对应结果为:
2.4 获取半年度数据
half_year_df = Trade.get_half_year_date()
对应结果为:
2.5 获取年度数据
year_df = Trade.get_year_date()
对应结果为:
2.6 添加开始和结束日期
quarter_df = Trade.get_quarter_date()
new_quarter_df = add_date(quarter_df, st, et)
对应结果为:
此处需要注意的是,开始和结束日期可能不是交易日,对应加入序列可能会造成影响。在后续的文章中 会对此进行优化。
本期分享到此结束,有和问题欢迎讨论。