前言
- 随着金融市场的不断发展,基金作为一种集合投资工具,为投资者提供了多样化的投资选择。它涵盖了股票型基金、债券型基金、混合型基金等多种类型,能够满足不同投资者的风险偏好和投资目标。个人投资者参与基金投资的规模不断扩大,而定投作为一种相对简单且有效的投资策略受到越来越多投资者的关注。
- 基金定投涉及长期的资金投入,投资者在选择定投基金以及确定定投策略时,需要了解不同基金在不同市场环境下的表现。传统的投资建议往往基于定性分析或者简单的历史业绩回顾,缺乏系统性和科学性。
- 通过模拟定投回测,投资者可以了解某只基金在过去较长一段时间内(如 5 年、10 年)采用定投策略的收益情况,包括平均年化收益率、最大回撤等关键指标。这有助于投资者判断该基金是否适合定投,避免盲目投资。
- 例如,对于一只波动较大的股票型基金,通过回测发现其定投在长期能够获得较高的收益,并且最大回撤在投资者可承受范围内,那么投资者可以考虑将其作为定投的选择之一。
- 回测可以比较不同定投参数(如定投频率、定投金额、定投起始时间等)对收益的影响。投资者可以根据自己的资金状况和投资目标,找到最适合自己的定投策略。
定投回测的步骤
1.安装和导入必要的库
- pip install akshare
- pip install pandas
- pip install matplotlib
2.获取基金历史行情数据
- 使用
akshare
的基金数据接口获取指定基金的历史净值数据
3.定义定投策略和参数
- 设定定投的时间间隔(如每月定投)、每次定投的金额等参数。
- 例如,每月定投 1000 元,从基金数据的起始日期开始定投。
4.模拟定投过程并计算资产变化
- 根据定投策略,计算每次定投后持有的基金份额和资产总值。
- 计算基金份额:基金份额 = 定投金额 / 基金净值。
- 计算资产总值:资产总值 = 基金份额累计 * 基金净值。
5.可视化
- 使用matplotlib对定投期间收益率进行可视化展示
6.量化回测实战代码实现
import warnings
warnings.filterwarnings('ignore')
import datetime
import pandas as pd
import matplotlib.pyplot as plt
import akshare as ak
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['font.family'] = 'sans-serif'
plt.rcParams['axes.unicode_minus'] = False
# 获取基金列表
def get_fund_list():
df = ak.fund_open_fund_rank_em(symbol="全部")
# print("字段结构", len(df), "/".join(df.columns))
# 16290 序号/基金代码/基金简称/日期/单位净值/累计净值/日增长率/近1周/近1月/近3月/近6月/近1年/近2年/近3年/今年来/成立来/自定义/手续费
df = df[df["近1年"] > 0]
return df[["基金代码", "基金简称"]].values.tolist()
# 获取指定基金历史行情数据
def get_fund_history(code="013490"):
df = ak.fund_open_fund_info_em(symbol=code, indicator="单位净值走势")
# print("字段结构",len(df), "/".join(df.columns))
# 695 净值日期/单位净值/日增长率
df.rename(columns={"净值日期": "date", "单位净值": "net_value", "日增长率": "day_growth"}, inplace=True)
return df
# 示例:选择"摩根标普500指数(QDII)人民币C"指定定投时间窗口测试
# 指定定投时间窗口
start_date=datetime.datetime(2023, 8, 1)
end_date=datetime.datetime(2024, 8, 1)
# 指定定投基金代码和基金名称,所有基金列表可通过get_fund_list函数来获取
fund_code,fund_name="019305","摩根标普500指数(QDII)人民币C"
df = get_fund_history(fund_code)
df = df[["date", "net_value"]]
df['date'] = pd.to_datetime(df['date'])
df['index'] = df['date']
df = df[df["date"] > start_date]
df = df[df["date"] < end_date]
df = df.set_index("index")
df['day_of_week'] = df["date"].dt.day_name() # Monday/Tuesday/Wednesday/Thursday/Friday/Saturday/Sunday
df['day_of_week1'] = df["date"].dt.weekday # 0-6
fees = 0.001 # 假设基金买入交易手续费率为0.1%
df["涨跌幅"] = df["net_value"].pct_change() # 基金净值涨跌幅
df["每期定投金额"] = 100 # 每天定投100元
df["每期定投金额1"]=0
df["每期定投金额1"][df["day_of_week"]=="Wednesday"] = 100 # 每周三定投100元
df["每期定投份额"] = df["每期定投金额"]/(1 - fees) / df["net_value"] # 每期购买的份额
df["累计定投金额"] = df["每期定投金额"].cumsum() # 累计定投的金额
df["累计持有份额"] = df["每期定投份额"].cumsum() # 累计定投的份额
df["累计持仓净值"] = df["累计持有份额"] * df["net_value"] # 累计持有份额金额
df["收益率"] = df["累计持仓净值"] / df["累计定投金额"] - 1 # 累计持有收益率
profit_rate = df["收益率"].iloc[-1]
profit = df["累计持仓净值"].iloc[-1]-df["累计定投金额"].iloc[-1]
print(f"定投股票{fund_code}/{fund_name},收益率:{profit_rate:0.2%},收益金额:{profit:0.2f}元")
# 定投收益率可视化
ax = df[["收益率"]].plot(
figsize=(16, 8),
grid=True,
legend=True,
title="基金定投的收益率曲线"
)
ax.legend(loc="upper right", bbox_to_anchor=(1, 0.5))
ax.text(df.index[-1], df["收益率"][-1], f"收益率:{profit_rate:0.2%}\n收益金额:{profit:0.2f}元")
plt.show()
执行结果: