沪深300ETF量化回测

选用工具

backtrader

注意事项:
1 每月定投 1000元 找当月最近的交易日
2 要设置开始与结束日期

代码如下

import akshare as ak
import pandas as pd
import backtrader as bt
import datetime


# 获取沪深 300 ETF 数据
def fetch_etf_data(symbol="510300"):
    # 使用 akshare 的 fund_etf_hist_em 接口获取 ETF 数据
    df = ak.fund_etf_hist_em(symbol=symbol, period="daily", adjust='qfq')

    # 转换日期格式
    df['日期'] = pd.to_datetime(df['日期'])  # 假设日期列名为 '日期'
    df.set_index('日期', inplace=True)

    # 重命名列以符合 Backtrader 的格式要求
    df.rename(columns={
        '开盘': 'Open',  # 假设开盘价列名为 '开盘'
        '最高': 'High',  # 假设最高价列名为 '最高'
        '最低': 'Low',  # 假设最低价列名为 '最低'
        '收盘': 'Close',  # 假设收盘价列名为 '收盘'
        '成交量': 'Volume'  # 假设成交量列名为 '成交量'
    }, inplace=True)

    return df


# 定义定投策略
class DingTouStrategy(bt.Strategy):
    params = (
        ('monthday', 1),  # 每月定投日期(1 表示每月 1 号)
        ('amount', 1000),  # 每次定投金额
    )

    def __init__(self):
        self.last_month = -1

    def next(self):
        current_date = self.data.datetime.date()
        current_month = current_date.month

        # 如果当前月份已经处理过,跳过
        if current_month == self.last_month:
            return

        # 检查当前日期是否为定投日
        if current_date.day >= self.params.monthday:
            # 如果当前日期是交易日,执行定投
            if self.data.close[0] > 0:  # 确保当前日期是交易日
                self.execute_ding_tou(current_date)
                self.last_month = current_month

    def execute_ding_tou(self, current_date):
        price = self.data.close[0]
        size = int(self.params.amount / price)
        if size > 0:
            self.buy(size=size)
            print(f'{current_date}: 定投买入 {size} 份,价格 {price:.3f}')


# 主函数
def main():
    # 获取沪深 300 ETF 数据
    etf_data = fetch_etf_data(symbol="510300")

    # 创建回测引擎
    cerebro = bt.Cerebro()

    # 加载沪深 300 ETF 数据
    data = bt.feeds.PandasData(
        dataname=etf_data,  # 使用 akshare 获取的数据
        fromdate=datetime.datetime(2012, 5, 1),  # 沪深 300 ETF 上市时间
        todate=datetime.datetime(2025, 1, 1),  # 结束日期
        timeframe=bt.TimeFrame.Days,  # 日线数据
        compression=1
    )

    # 将数据添加到引擎
    cerebro.adddata(data)

    # 添加策略到引擎
    cerebro.addstrategy(DingTouStrategy)

    # 设置初始资金
    initial_cash = 152000  # 初始资金 15.2 万元
    cerebro.broker.set_cash(initial_cash)

    # 设置交易手续费(假设为 0.1%)
    cerebro.broker.setcommission(commission=0.000)

    # 运行回测
    print('初始资金: %.2f' % cerebro.broker.getvalue())
    cerebro.run()
    print('最终资金: %.2f' % cerebro.broker.getvalue())

    # 绘制回测结果
    cerebro.plot()


# 运行主函数
if __name__ == "__main__":
    main()

测试结果
1 cash代表现金
2 value代表总价值 就是股票价值+剩余现金
3 测试结果表明12年累计投入本金15.2万元,最后得到收益20.9万元 累计收益率37% 每年不到3%
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鸭梨山大哎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值