美股日线只拆股不除权会差多少?FMP 分红复权行情(Dividend Adjusted API)与总回报率计算实战
在搭建美股中长期回测、红利因子选股或定投收益复盘管线时,许多量化开发者默认直接调用标准日线接口拉取收盘价计算收益率,却忽略了美股行情数据源的一项关键口径分工:标准日线接口通常只做拆合股调整(Split-Adjusted Only),并不扣除历次现金分红。更隐蔽的是,FMP 在 /stable/historical-price-eod/ 路径下提供了四套不同复权层级的日线端点,其中未复权端点与分红复权端点共用完全相同的字段名 adjClose,极易在跨脚本调用时发生口径混用。
我们对 10 只代表性美股与 ETF 在 5 年完整窗口(2021-10-29 至 2026-10-30)的实盘对账显示:若误用仅拆股复权日线替代分红复权日线,高股息与分红成长标的 5 年累计总回报率会少算 25 至 83 个百分点;其中威瑞森与月度派息不动产信托 Realty Income 的 5 年价格回报率分别为 -15.59% 与 -17.70%,而计入现金分红复权后的总回报率实为 +16.18% 与 +7.62%,直接导致回测盈亏方向反转。
为什么用默认日线接口(historical-price-eod/full)算高股息美股回报率会严重失真?
在 Chart(股票行情接口)大类下,开发者最常调用的 Stock Price and Volume Data(日线完整行情接口,/stable/historical-price-eod/full)返回的 close 字段,仅对历史股票拆细(Stock Split)与合股(Reverse Split)做了前复权折算,并未对季度或月度现金派息做除权下调。用该序列首尾相除算出的只是价格回报率(Price Return);只有调用专门的 Dividend Adjusted Price Chart(分红复权日K线接口,/stable/historical-price-eod/dividend-adjusted)读取 adjClose,才能得到包含股息除权调整的分红复权总回报率(Total Return)。
为直观量化两套序列在中长期回测中的偏差幅度,我们选取高股息消费/电信蓝筹、月度派息 REIT、能源与金融龙头、宽基与红利 ETF 以及分红成长股共 10 只标的,拉取 2021-10-29 至 2026-10-30(整 5 年)的实盘定盘数据,并结合 Dividends Company(公司分红派息接口,/stable/dividends)汇总区间派息次数与拆股后累计每股股息,实测对账结果如下(数据快照截至 2026-10-30):
| 标的 (symbol) | 5年派息次数与累计 adjDividend | 2021-10-29 仅拆股 close | 2021-10-29 分红复权 adjClose | 2026-10-30 期末收盘价 | 5年价格回报率 (仅拆股) | 5年总回报率 (分红复权) | 5年总回报差值 (年化 CAGR 差) |
|---|---|---|---|---|---|---|---|
| 奥驰亚 (MO) | 20 次 · 19.81 美元 | 44.11 美元 | 30.03 美元 | 78.03 美元 | +76.90% | +159.84% | +82.94 个百分点 (+8.96%/年) |
| 博通 (AVGO) | 20 次 · 10.54 美元 | 53.17 美元 | 48.67 美元 | 326.08 美元 | +513.28% | +569.98% | +56.70 个百分点 (+2.56%/年) |
| 埃克森美孚 (XOM) | 20 次 · 19.04 美元 | 64.47 美元 | 54.11 美元 | 187.25 美元 | +190.45% | +246.05% | +55.61 个百分点 (+4.41%/年) |
| 威瑞森 (VZ) | 20 次 · 13.40 美元 | 52.99 美元 | 38.50 美元 | 44.73 美元 | -15.59% | +16.18% | +31.77 个百分点 (+6.38%/年) |
| 红利 ETF (SCHD) | 20 次 · 4.76 美元 | 25.84 美元 | 21.62 美元 | 35.78 美元 | +38.47% | +65.49% | +27.03 个百分点 (+3.87%/年) |
| 可口可乐 (KO) | 20 次 · 9.59 美元 | 56.37 美元 | 48.69 美元 | 94.08 美元 | +66.90% | +93.22% | +26.33 个百分点 (+3.29%/年) |
| 摩根大通 (JPM) | 20 次 · 24.35 美元 | 169.89 美元 | 150.07 美元 | 337.04 美元 | +98.39% | +124.59% | +26.20 个百分点 (+2.88%/年) |
| Realty Income (O) | 62 次 · 16.06 美元 | 69.17 美元 | 52.90 美元 | 56.93 美元 | -17.70% | +7.62% | +25.31 个百分点 (+5.30%/年) |
| 标普 500 ETF (SPY) | 20 次 · 34.52 美元 | 459.25 美元 | 429.55 美元 | 755.72 美元 | +64.56% | +75.93% | +11.38 个百分点 (+1.49%/年) |
| 苹果 (AAPL) | 20 次 · 4.90 美元 | 149.80 美元 | 146.11 美元 | 344.63 美元 | +130.06% | +135.87% | +5.81 个百分点 (+0.59%/年) |
从工程回测角度审视上述实盘对账,有两处核心机制直接决定因子有效性:
- 高派息防御股与 REITs 的盈亏方向逆转:威瑞森(VZ)与按月派息的商业地产信托 Realty Income(O,5 年内共除息 62 次)将绝大部分自由现金流用于现金分红。若策略误用
historical-price-eod/full计算收益,两只标的会被判定为 5 年亏损逾 15% 的劣质资产;而在historical-price-eod/dividend-adjusted口径下,历次除息将 2021-10-29 的前复权成本基数分别下调至 38.50 美元与 52.90 美元,还原出 +16.18% 与 +7.62% 的正收益。 - 分红成长股早期除息因子的乘数放大效应:博通(AVGO)5 年累计拆股后派息
adjDividend仅 10.54 美元(约为 2021-10-29 拆股后收盘价 53.17 美元的 19.8%),但其 5 年分红复权总回报率却比价格回报率高出 56.70 个百分点。原因在于 2021 至 2023 年博通拆股后收盘价处于 42.71 至 114.70 美元相对低位,期间每次除息产生的等比例前复权因子累积下调了期初成本基数(由 53.17 美元下调至 48.67 美元);随着 2024 至 2026 年股价涨至 326.08 美元(较 2021–2023 年价格区间放大约 2.8 至 7.6 倍),早期除息因子对区间复权总回报的贡献被同步放大。
FMP 四套日线接口(full / dividend-adjusted / non-split-adjusted / light)的字段命名与复权口径有什么区别?
FMP 在 /stable/historical-price-eod/ 路径下共提供四套股票日线端点:除前文提到的 full 与 dividend-adjusted 外,还包括 Unadjusted Stock Price(未复权日线行情接口,/stable/historical-price-eod/non-split-adjusted)与 Stock Chart Light(日线行情(精简版)接口,/stable/historical-price-eod/light)。
这四套端点最容易让初次接入的开发者踩坑的地方,在于返回 JSON 的字段名与实际复权状态并不按字面对应。我们以博通(AVGO)在 2024-06-21(处于 2024-06-24 除息日前一交易日、且处于 2024-07-15 的 1 拆 10 拆股之前)这一天的四套接口真实返回报文为例:
// 1. /stable/historical-price-eod/non-split-adjusted?symbol=AVGO(未拆股、未除权的交易所原始挂牌价,但字段名却带 adj 前缀!)
[{"symbol": "AVGO", "date": "2024-06-21", "adjOpen": 1695.7, "adjHigh": 1714, "adjLow": 1651.4, "adjClose": 1658.6, "volume": 9999900}]
// 2. /stable/historical-price-eod/full?symbol=AVGO(仅拆股前复权、不含分红除权,字段名为标准 open/high/low/close)
[{"symbol": "AVGO", "date": "2024-06-21", "open": 169.57, "high": 171.4, "low": 165.14, "close": 165.86, "volume": 99999000, "change": -3.7, "changePercent": -2.19, "vwap": 167.9925}]
// 3. /stable/historical-price-eod/light?symbol=AVGO(精简版,price 与 full 的 close 完全一致,仅拆股前复权)
[{"symbol": "AVGO", "date": "2024-06-21", "price": 165.86, "volume": 99999000}]
// 4. /stable/historical-price-eod/dividend-adjusted?symbol=AVGO(拆股 + 现金分红双重前复权,字段名同样为 adjOpen..adjClose)
[{"symbol": "AVGO", "date": "2024-06-21", "adjOpen": 165.61, "adjHigh": 167.4, "adjLow": 161.29, "adjClose": 161.99, "volume": 99999000}]
为看清这四套接口在跨越现金除息日(2024-06-24,除息 5.25 美元/拆股前)与股票拆细生效日(2024-07-15,1 股拆 10 股)时的数值跳变规律,我们将博通在四个关键交易日的实盘返回数值整理对照如下:
| 接口端点段 | 返回价格与成交量字段名 | 复权口径定义 | 2024-06-21 (除息前一日) | 2024-06-24 (除息生效日) | 2024-07-12 (拆股前末日) | 2024-07-15 (1拆10首日) |
|---|---|---|---|---|---|---|
non-split-adjusted | adjOpen ~ adjClose · volume | 未复权原始挂牌价:不拆股、不除权,保留历史交易当日盘面真实报价与原始股数 | 收 1658.60 美元 · 量 999.99 万 | 收 1592.20 美元 · 量 585.75 万 | 收 1700.70 美元 · 量 304.53 万 | 收 171.42 美元 · 量 2299.92 万 |
full | open ~ close · volume · vwap | 仅拆合股前复权:拆股前价格除以 10、成交量乘以 10;不含现金分红除权 | 收 165.86 美元 · 量 9999.90 万 | 收 159.22 美元 · 量 5857.54 万 | 收 170.07 美元 · 量 3045.30 万 | 收 171.42 美元 · 量 2299.92 万 |
light | price · volume | 仅拆合股前复权(精简流):price 恒等于 full 接口的 close,省去开高低与涨跌字段 | 价 165.86 美元 · 量 9999.90 万 | 价 159.22 美元 · 量 5857.54 万 | 价 170.07 美元 · 量 3045.30 万 | 价 171.42 美元 · 量 2299.92 万 |
dividend-adjusted | adjOpen ~ adjClose · volume | 拆合股 + 现金分红双重前复权:在 full 基础上,每跨越一次除息日向历史回溯累乘除权因子 | 收 161.99 美元 · 量 9999.90 万 | 收 156.00 美元 · 量 5857.54 万 | 收 166.63 美元 · 量 3045.30 万 | 收 167.95 美元 · 量 2299.92 万 |
在编写数据清洗管线时,务必重点防范以下三项接口差异:
- 严防
non-split-adjusted与dividend-adjusted的同名字段混用:两套接口的收盘价字段均命名为adjClose,但non-split-adjusted的adjClose在 2024-07-12 到 2024-07-15 之间会从 1700.70 美元直接断崖跳水至 171.42 美元(单日名义暴跌 -89.92%)。因此回测入库时应在本地表结构中显式重命名为raw_close、split_adj_close与div_adj_close。 full接口的changePercent仅反映日内涨跌幅,不含隔夜跳空与除息缺口:如 2024-07-15 博通拆股首日开盘 170.00 美元、收盘 171.42 美元,full返回的changePercent为 +0.83529%(即(171.42 − 170.00) ÷ 170.00),而相对于前一交易日收盘价 170.07 美元的跨日真实涨幅为 +0.79379%(关于退市与拆股日线跳空的完整清洗逻辑,可参见 美股回测幸存者偏差与历史成分股实战)。- 与 Massive(原 Polygon.io)日线复权机制的区别:Massive 的聚合日线接口通过布尔参数
adjusted=true控制复权,但即便开启adjusted=true也仅做拆合股调整,不提供内置现金分红复权的日线端点;而 FMP 则将两者拆分为独立的full与dividend-adjusted端点(两套平台在复权与盘口颗粒度上的完整差异对比见 FMP vs Massive 选型横评)。
分红复权日线(dividend-adjusted)底层的等比例前复权因子是怎么算出来的?
如果要在本地数据库中维护可增量更新的前复权因子表,或者验证第三方行情的分红复权精度,就必须弄清 Calendar(市场日历接口)大类下 Dividends Company(公司分红派息接口,/stable/dividends)与 Stock Split Details(公司拆合股明细接口,/stable/splits)是如何同日线行情勾稽的。
我们先看博通(AVGO)在 2024 年跨越 T+1 交收改革与 10 拆 1 拆股前后的真实分红记录与拆股记录:
// /stable/splits?symbol=AVGO(2024-07-15 生效 10 拆 1 正向拆股)
[{"symbol": "AVGO", "date": "2024-07-15", "numerator": 10, "denominator": 1, "splitType": "stock-split"}]
// /stable/dividends?symbol=AVGO(2024 年三期真实记录,注意对比 adjDividend、dividend、recordDate 与年化 yield)
[
{"symbol": "AVGO", "date": "2024-09-19", "recordDate": "2024-09-19", "paymentDate": "2024-09-30", "declarationDate": "2024-09-05", "adjDividend": 0.53, "dividend": 0.53, "yield": 1.2573169274877556, "frequency": "Quarterly"},
{"symbol": "AVGO", "date": "2024-06-24", "recordDate": "2024-06-24", "paymentDate": "2024-06-28", "declarationDate": "2024-06-12", "adjDividend": 0.525, "dividend": 5.25, "yield": 1.2781057656073358, "frequency": "Quarterly"},
{"symbol": "AVGO", "date": "2024-03-20", "recordDate": "2024-03-21", "paymentDate": "2024-03-29", "declarationDate": "2024-03-06", "adjDividend": 0.525, "dividend": 5.25, "yield": 1.5438871473354232, "frequency": "Quarterly"}
]
从上述报文中可以提炼出三条决定回测准确性的核心工程规则:
1. 拆股前分红必须取 adjDividend,严禁将原始 dividend 与 full 日线混算
在 2024-06-24 除息日(处于 1 拆 10 之前),博通实际向每股原始流通股派发现金 dividend: 5.25 美元(对应除息前一日未拆股收盘价 1658.60 美元,单季派息率约 0.3165%;接口返回的 yield: 1.2781 为按除息日价格折算的年化股息率百分比)。而在拆股后回看历史,/stable/dividends 已将其折算为拆股后口径 adjDividend: 0.525 美元(对应 full 接口拆股复权收盘价 165.86 美元)。若误拿原始 dividend = 5.25 去除以 full 的拆股复权价 165.86 美元,单季股息率会被人为放大 10 倍变成 3.17%,计算出的前复权价格也会严重失真。
2. 分红日历四个日期字段的回测时点分工
/stable/dividends 每条记录包含四个日期字段:董事会宣告日 declarationDate、除息日 date(Ex-Dividend Date)、股权登记日 recordDate 与资金到账日 paymentDate。如上方报文所示,在 2024 年 5 月 28 日美股全面实行 T+1 交收制度之前,2024-03-20 那期分红的除息日 date(2024-03-20)比股权登记日 recordDate(2024-03-21)早 1 个交易日;而自 2024-06-24 起,date 与 recordDate 已合并为同一交易日。在二级市场交易中,交易所于除息日 date 当天开盘前下调基准参考价,凡在 date 前一交易日收盘时持有股票的投资者即享有本期分红权。因此,前复权除权因子严格在除息日 date 与前一交易日之间生效。
3. 等比例累乘前复权递推公式与手算对拍
不同于部分看盘软件采用的“简单减法除权”(直接从历史股价中减去累计分红金额,回溯期较长时极易把早期低价股减成负数),FMP 的 /stable/historical-price-eod/dividend-adjusted 采用等比例累乘前复权递推法(Proportional Backward Adjustment)。设某次除息日拆股调整后每股派息为 adjDividend,除息日前一交易日在 full 接口下的拆股复权收盘价为 prev_close,则递推公式为:
- 单期除权因子公式:
factor = 1 − adjDividend ÷ prev_close - 历史任意交易日
t的分红复权收盘价:adjClose = round(close × cum_factor, 2)(其中cum_factor为交易日t之后所有已生效除息因子的连乘积)
(注:该因子生成的除息日复权收益为 当日收盘价 ÷ (prev_close − adjDividend) − 1,用于构建连续的含息复权价格序列,与普通现金分红下 (当日收盘价 + adjDividend) ÷ prev_close − 1 的单期持有公式存在极微小的二阶代数差异。)我们以博通截至 2026 年 10 月最近的两次除息(2026-09-21 与 2026-06-22,每次 adjDividend 均为 0.65 美元)亲手验算一轮:
- 最新除息日(2026-09-21)及之后:由于后续尚无新的已生效除息,累计乘数
cum_factor = 1.000000,因此 2026-09-21 当日dividend-adjusted的adjClose(362.66 美元)与full的close(362.66 美元)完全相等。 - 回溯跨越 2026-09-21 除息日:除息前最后一个交易日为 2026-09-18,当日
full接口close为 357.61 美元,代入公式得单期除权因子1 − 0.65 ÷ 357.61 ≈ 0.99818238;2026-09-18 当日的分红复权收盘价即为357.61 × 0.99818238 ≈ 356.96 美元(与接口返回值adjClose: 356.96分毫不差)。 - 继续回溯至上一次除息日(2026-06-22):当日
full接口close为 392.13 美元,乘以同一累计因子 0.99818238 得 391.42 美元,同样与接口返回值adjClose: 391.42精确吻合(若误按简单减法392.13 − 0.65 = 391.48计算,单次除息即产生 0.06 美元偏差)。 - 同日开高低价格同步等比例缩放:同一交易日的
adjOpen、adjHigh、adjLow均乘以相同的累计因子cum_factor,从而保证单根 K 线的日内振幅比例与上下影线形态在复权前后严格不变。
如何用 Python 自动对账价格回报率、分红复权总回报率与前复权因子?
在实际工程中,我们可以编写一段 Python 审计脚本,同时拉取 historical-price-eod/full、historical-price-eod/dividend-adjusted 与 dividends 三套接口,一方面批量输出各标的的价格回报率、分红复权总回报率及年化 CAGR 差值,另一方面直接用 full 的 close 配合 dividends 的 adjDividend 独立累乘复算期初前复权价 reconst_d0(乘以期末比值 ac1 / c1 对齐复权基准,使任意历史截断区间均能与官方 dadj_d0 逐分钱对拍验证)。
运行脚本前,请先在终端设置环境变量 FMP_KEY:
# Linux / macOS 终端设置环境变量
export FMP_KEY="你的密钥"
# Windows PowerShell 设置环境变量
$env:FMP_KEY="你的密钥"
完整可运行的对账与复算代码如下:
import os
import requests
BASE_URL = "https://quote-fmp.com/stable"
API_KEY = os.environ["FMP_KEY"]
def fetch_api(endpoint: str, params: dict) -> list:
resp = requests.get(f"{BASE_URL}/{endpoint}", params={**params, "apikey": API_KEY}, timeout=25)
resp.raise_for_status()
return resp.json()
def audit_dividend_total_return(symbol: str, start_date: str, end_date: str, years: float = 5.0) -> dict:
full_rows = fetch_api("historical-price-eod/full", {"symbol": symbol, "from": start_date, "to": end_date})
dadj_rows = fetch_api("historical-price-eod/dividend-adjusted", {"symbol": symbol, "from": start_date, "to": end_date})
div_rows = fetch_api("dividends", {"symbol": symbol})
full_map = {r["date"]: r["close"] for r in full_rows}
dadj_map = {r["date"]: r["adjClose"] for r in dadj_rows}
dates = sorted(full_map.keys())
d0, d1 = dates[0], dates[-1]
date_idx = {dt: i for i, dt in enumerate(dates)}
# 提取区间内除息记录(使用拆股对齐后的 adjDividend,缺失除息日行情时显式报错)
window_divs = [d for d in div_rows if d0 < d["date"] <= d1 and d.get("adjDividend")]
factor = 1.0
for d in sorted(window_divs, key=lambda x: x["date"], reverse=True):
ex_dt = d["date"]
if ex_dt not in date_idx or date_idx[ex_dt] == 0:
raise ValueError(f"{symbol} 缺失除息日 {ex_dt} 或前一交易日行情,无法完整核验")
prev_close = full_map[dates[date_idx[ex_dt] - 1]]
factor *= (1.0 - d["adjDividend"] / prev_close)
c0, c1 = full_map[d0], full_map[d1]
ac0, ac1 = dadj_map[d0], dadj_map[d1]
price_ret = (c1 / c0 - 1.0) * 100.0
total_ret = (ac1 / ac0 - 1.0) * 100.0
return {
"symbol": symbol,
"divs": len(window_divs),
"sum_adj_div": round(sum(d["adjDividend"] for d in window_divs), 2),
"full_d0": c0,
"dadj_d0": ac0,
"reconst_d0": round(c0 * factor * (ac1 / c1), 2),
"end_close": c1,
"price_ret_pct": round(price_ret, 2),
"total_ret_pct": round(total_ret, 2),
"gap_pct": round(total_ret - price_ret, 2),
"cagr_gap_pct": round((((ac1 / ac0) ** (1.0 / years) - (c1 / c0) ** (1.0 / years)) * 100.0), 2),
}
for sym in ["MO", "VZ", "O", "XOM", "KO", "JPM", "SPY", "SCHD", "AAPL", "AVGO"]:
print(audit_dividend_total_return(sym, "2021-10-29", "2026-10-30"))
实盘运行上述脚本,终端输出结果如下(第一节表一即根据上述函数返回结果整理):
{'symbol': 'MO', 'divs': 20, 'sum_adj_div': 19.81, 'full_d0': 44.11, 'dadj_d0': 30.03, 'reconst_d0': 30.04, 'end_close': 78.03, 'price_ret_pct': 76.9, 'total_ret_pct': 159.84, 'gap_pct': 82.94, 'cagr_gap_pct': 8.96}
{'symbol': 'VZ', 'divs': 20, 'sum_adj_div': 13.4, 'full_d0': 52.99, 'dadj_d0': 38.5, 'reconst_d0': 38.5, 'end_close': 44.73, 'price_ret_pct': -15.59, 'total_ret_pct': 16.18, 'gap_pct': 31.77, 'cagr_gap_pct': 6.38}
{'symbol': 'O', 'divs': 62, 'sum_adj_div': 16.06, 'full_d0': 69.17, 'dadj_d0': 52.9, 'reconst_d0': 52.9, 'end_close': 56.93, 'price_ret_pct': -17.7, 'total_ret_pct': 7.62, 'gap_pct': 25.31, 'cagr_gap_pct': 5.3}
{'symbol': 'XOM', 'divs': 20, 'sum_adj_div': 19.04, 'full_d0': 64.47, 'dadj_d0': 54.11, 'reconst_d0': 54.1, 'end_close': 187.25, 'price_ret_pct': 190.45, 'total_ret_pct': 246.05, 'gap_pct': 55.61, 'cagr_gap_pct': 4.41}
{'symbol': 'KO', 'divs': 20, 'sum_adj_div': 9.59, 'full_d0': 56.37, 'dadj_d0': 48.69, 'reconst_d0': 48.7, 'end_close': 94.08, 'price_ret_pct': 66.9, 'total_ret_pct': 93.22, 'gap_pct': 26.33, 'cagr_gap_pct': 3.29}
{'symbol': 'JPM', 'divs': 20, 'sum_adj_div': 24.35, 'full_d0': 169.89, 'dadj_d0': 150.07, 'reconst_d0': 150.07, 'end_close': 337.04, 'price_ret_pct': 98.39, 'total_ret_pct': 124.59, 'gap_pct': 26.2, 'cagr_gap_pct': 2.88}
{'symbol': 'SPY', 'divs': 20, 'sum_adj_div': 34.52, 'full_d0': 459.25, 'dadj_d0': 429.55, 'reconst_d0': 429.54, 'end_close': 755.72, 'price_ret_pct': 64.56, 'total_ret_pct': 75.93, 'gap_pct': 11.38, 'cagr_gap_pct': 1.49}
{'symbol': 'SCHD', 'divs': 20, 'sum_adj_div': 4.76, 'full_d0': 25.84, 'dadj_d0': 21.62, 'reconst_d0': 21.62, 'end_close': 35.78, 'price_ret_pct': 38.47, 'total_ret_pct': 65.49, 'gap_pct': 27.03, 'cagr_gap_pct': 3.87}
{'symbol': 'AAPL', 'divs': 20, 'sum_adj_div': 4.9, 'full_d0': 149.8, 'dadj_d0': 146.11, 'reconst_d0': 146.11, 'end_close': 344.63, 'price_ret_pct': 130.06, 'total_ret_pct': 135.87, 'gap_pct': 5.81, 'cagr_gap_pct': 0.59}
{'symbol': 'AVGO', 'divs': 20, 'sum_adj_div': 10.54, 'full_d0': 53.17, 'dadj_d0': 48.67, 'reconst_d0': 48.67, 'end_close': 326.08, 'price_ret_pct': 513.28, 'total_ret_pct': 569.98, 'gap_pct': 56.7, 'cagr_gap_pct': 2.56}
可以看到,在本次核验的 10 只标的中,用等比例累乘公式从 full 序列独立复算的 reconst_d0 与官方 dividend-adjusted 返回的 dadj_d0 在 6 只标的上完全一致(0.00 美元误差),其余 4 只标的(MO、XOM、KO、SPY)最大反推差额仅为 0.01 美元。
常见问题(FAQ):分红复权行情与批量回测中的高频疑问
1. 全市场日线批量接口(eod-bulk)返回的是拆股复权价还是分红复权价?
Eod Bulk(日线行情批量接口,/stable/eod-bulk)同时返回仅拆股的 close 与包含拆股及现金分红回溯调整的 adjClose(与 dividend-adjusted 同源等值)。仅在查询日之后尚未发生新拆股或除息时,该日 close 与 adjClose 才相等;一旦后续发生除息或拆股,历史切片的 adjClose 会被回溯下调(见 FMP Bulk 批量接口建库实战)。本地增量维护时,需结合 Dividends Calendar(分红派息日历接口,/stable/dividends-calendar)、拆股日历及历史数据修订记录同步刷新复权因子。
2. 做技术指标回测和长期多因子回测,分别该选哪套日线接口?
不能仅凭持仓周期长短指定唯一接口。若需还原历史实际成交价、订单簿挂单价或期权行权价,应使用未复权的 non-split-adjusted;计算连续技术指标或中长期多因子收益时,则取决于策略如何处理拆股与除息缺口,分别选用仅拆股的 full 或含分红复权的 dividend-adjusted。如需在本地跑通上述对账脚本,可前往 快速接入指南 申领 15 天 Ultimate 全接口试用密钥(20 RPM / 0.3 GiB,支持微信支付与人民币按月订阅)。