Skip to content

第 3 讲:每月定投(DCA)

本讲要点

定投是按固定周期投入固定金额,不预测涨跌。


1. 名词:DCA 是什么、从何而来

DCA 是英文 Dollar Cost Averaging 的缩写,中文常称定期定额投资,简称定投

  • 含义:每隔固定时间(如每月),投入相同金额买入同一标的;价格低时买到的份额多,价格高时份额少,从而摊平买入成本。
  • 出处:该术语由本杰明·格雷厄姆(Benjamin Graham)在《聪明的投资者》(The Intelligent Investor,1949)中提出并流行。原意是每月或每季投入「相同数量的美元」买入普通股。
  • 与货币无关:名称里的 Dollar 来自英文金融文献的惯用说法,并不表示必须使用美元。本质是「固定金额 + 固定周期」。本课程用人民币计价,例如每月 1000 元

因此:下文写 DCA / 定投,均指同一策略;实验金额以人民币计。


2. 本讲规则(写到可执行)

  1. 投资对象:沪深 300ETF(510300.SS
  2. 每个月第一个交易日
  3. 1000 元(人民币)按当日收盘价买入
  4. 一直持有,中途不卖

3. 回测在算什么

每月买入一次,需跟踪:

含义
当月买入份额1000 / 当日收盘价
累计份额各月买入份额之和
累计成本月数 × 1000(元)
月末市值累计份额 × 月末收盘价
收益率(市值 - 成本) / 成本

4. 代码

python
import numpy as np
import pandas as pd
import yfinance as yf
import matplotlib.pyplot as plt

START, END = "2021-01-01", "2026-03-04"
download_end = (pd.Timestamp(END) + pd.Timedelta(days=1)).strftime("%Y-%m-%d")
df = yf.download(
    "510300.SS", start=START, end=download_end,
    auto_adjust=True, multi_level_index=False, progress=False,
).loc[:END]


def backtest_dca(df, monthly_amount=1000):
    data = df.copy()
    data["month"] = data.index.to_period("M")

    # 每月第一个交易日买入
    first = data.groupby("month").first()
    shares = (monthly_amount / first["Close"]).cumsum()
    cost = monthly_amount * np.arange(1, len(first) + 1)

    # 用每月最后一个交易日估价
    last = data.groupby("month").last()
    value = shares * last["Close"]
    ret = (value.values - cost) / cost

    return pd.DataFrame(
        {
            "total_cost": cost,
            "total_shares": shares.values,
            "portfolio_value": value.values,
            "return": ret,
        },
        index=first.index,
    )


result = backtest_dca(df)
print(f"月数: {len(result)}")
print(f"总投入: {result['total_cost'].iloc[-1]:,.0f} 元")
print(f"最终市值: {result['portfolio_value'].iloc[-1]:,.0f} 元")
print(f"收益率: {result['return'].iloc[-1]:.2%}")

ts = result.index.to_timestamp()
plt.figure(figsize=(10, 4))
plt.plot(ts, result["portfolio_value"], label="市值")
plt.plot(ts, result["total_cost"], "--", label="成本")
plt.legend()
plt.title("定投:市值 vs 成本")
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

5. 运行结果

在固定窗口 2021-01-012026-03-04、每月投入 1000 元的设定下,一次运行得到:

text
投资期间: 2021-01 → 2026-03
月数: 63
总投入: 63,000 元
最终市值: 74,152 元
收益率: 17.70%

对应图像如下:

定投:市值 vs 成本

6. 如何阅读结果

请结合上表与图像观察:

  1. 市值曲线相对成本曲线,多数时间处于上方还是下方?期末相对本金是盈是亏?
  2. 17.70% 的累计收益,能否说明「定投战胜了市场」?还缺少什么对照?
  3. 结合第 2 讲的价格路径(先跌后涨),定投在下跌阶段可能起了什么作用?

说明:上述收益率只度量「相对累计投入」的盈亏,尚不能回答策略是否优于其他规则。定投本身通常主要承担市场涨跌(Beta),是否具有超额能力(Alpha)需引入基准,见下一讲。

脚本版:easy-quant/code/03_dca.py(可同步更新 easy-quant/images/03-dca-value-cost.png)。

上一讲 · 下一讲:与买入持有对照