各个指标
1. 近N日收益率
近N日收益率 = (当日累计收益 - N日前的累计收益) / N日前的累计收益
2. 当周/月/年平均收益率
这里需要区分不同时间段的起始与终止区间
区间收益率 = (区间终值累计收益 - 区间初始累计收益) / 区间初始累计收益
示例代码
import pandas as pd
import numpy as np
from copy import deepcopy
def fund_net_analyze(net_value_series, normalize_first_data=True):
"""
计算:近5日收益率,近20日收益率,近60日收益率,
当年平均收益率,当月平均收益率,当周平均收益率
:return:
"""
net_value_series = deepcopy(net_value_series)
net_value_series.index = pd.to_datetime(net_value_series.index)
net_value_series.sort_index(inplace=True)
net_value_series.dropna(inplace=True)
# 首日归一
if normalize_first_data:
net_value_series = net_value_series / net_value_series.iloc[0]
collect_df = pd.DataFrame({"单位净值": net_value_series})
# 开始计算历史滚动收益
collect_df['近5日收益'] = (collect_df['单位净值'] - collect_df['单位净值'].shift(5)) / collect_df['单位净值'].shift(5)
collect_df['近20日收益'] = (collect_df['单位净值'] - collect_df['单位净值'].shift(20)) / collect_df['单位净值'].shift(20)
collect_df['近60日收益'] = (collect_df['单位净值'] - collect_df['单位净值'].shift(60)) / collect_df['单位净值'].shift(60)
# 开始计算当年/月/周收益
# FutureWarning: weekofyear and week have been deprecated, please use DatetimeIndex.isocalendar().week instead,
collect_df['__year'] = collect_df.index.isocalendar().year.astype(str)
collect_df['__month'] = collect_df['__year'] + "_" + collect_df.index.month.astype(str)
collect_df['__week'] = collect_df['__year'] + "_" + collect_df.index.isocalendar().week.astype(str)
collect_df["当年平均收益率"] = collect_df.groupby("__year").apply(
lambda v_df: (v_df['单位净值'] - v_df['单位净值'].iloc[0]) / v_df['单位净值'] / (
v_df.index - v_df.index[0]).days).values
collect_df["当月平均收益率"] = collect_df.groupby("__month").apply(
lambda v_df: (v_df['单位净值'] - v_df['单位净值'].iloc[0]) / v_df['单位净值'] / (
v_df.index - v_df.index[0]).days).values
collect_df["当周平均收益率"] = collect_df.groupby("__week").apply(
lambda v_df: (v_df['单位净值'] - v_df['单位净值'].iloc[0]) / v_df['单位净值'] / (
v_df.index - v_df.index[0]).days).values
collect_df.drop(["__year", "__month", "__week"], axis=1, inplace=True)
return collect_df
def main():
# 生成数据
_size = 500
net_value = 1 + pd.Series(np.random.normal(0, 0.01, size=_size)).cumsum()
net_value.index = pd.date_range("2024-01-01", periods=_size)
# net_value为生成的净值数据
# 计算各项指标
collect_df = fund_net_analyze(net_value)
collect_df.loc[:, "近5日收益":] = collect_df.loc[:, "近5日收益":].applymap(
lambda x: format(x * 100, ".2f") + "%" if not pd.isna(x) else x)
print(collect_df.tail())
if __name__ == '__main__':
main()