设想你是一位想开餐厅的大厨。你手里有一本菜谱——比如“周一到周三主打麻辣,周四周五主打清淡”。你不确定这本菜谱能不能赚钱,于是翻出过去一年的顾客点单记录和食材价格账本,在自家厨房里一遍遍模拟:每道菜该卖多少钱、食材进货价是多少、每天客流多大。一番演练后,你终于能判断哪本菜谱更赚钱。这就是“量化交易回测”——只不过菜谱换成了交易策略,点单记录换成了行情数据,厨房换成了回测引擎。本文将带你从零搭建这样一间“试菜厨房”:用事件驱动模型组织流程、清洗历史数据、模拟真实成交、把滑点和手续费算清楚,最后用绩效指标鉴别策略好坏,并警惕“只为熟客定制口味”的过拟合陷阱。

岗位关联

掌握回测平台架构,是量化从业者从“会写策略”到“能验证策略”的分水岭,也是金融工程师搭建策略验证环境的必备能力。

目录
  1. 可视化演示
  2. 回测基础:先弄明白“试菜”是什么
  3. 事件驱动模型:后厨的流水线节奏
  4. 数据清洗:把食材挑拣干净
  5. 撮合模拟:如何模拟顾客下单
  6. 成本建模:漏油的后厨要算清楚
  7. 绩效指标:月底盘账见真章
  8. 过拟合控制:别只为熟客做菜
  9. 架构实践:把后厨盖成放心厨房
  10. AI 应用场景
  11. Python 演示
  12. 常见误区
  13. 面试题

可视化演示

展示系统处理流水线、实时性能指标曲线及多方案对比分析,包含数据流转、吞吐延迟监控与方案评估。

本节配有交互动效(进入视口后自动加载,约 3KB)。

系统可视化 处理流程:输入→处理→模型→输出 性能监控:实时指标 P=L×T

回测基础:先弄明白“试菜”是什么

开餐厅之前,总得先弄清楚“试菜”到底在做什么。所谓试菜,不是凭感觉尝一口,而是把菜谱放进过去一年真实发生的点单场景里,让数据告诉你答案。回测平台做的事情,本质上就是把交易策略放进历史行情中,看它在过去那些日子里能不能赚钱。

放到量化领域,需要解决的问题其实很固定:你能拿到哪些历史数据?策略在哪个时点发出什么信号?这个信号如果当时真下了单,能成交吗?成交之后账户变成什么样?最后用哪些指标判断“这本菜谱到底行不行”?回测平台就是把这一连串问题固化成可重复运行的流程。一个高保真的回测,要求每一步都尽量贴近真实市场,而不是理想化的纸面推演。

回测的第一步是理解收益率——回测里几乎所有绩效指标都从它推导而来。最简单的收益率定义是相邻两个时点的价格变化相对基准值的比例:

你看,只要知道“昨日价格”和“今日价格”,就能算出这盘菜一天带来几成收益。回测平台后续所有复杂的账本和指标,都从这一小步层层搭建——就像大厨试菜,得先尝出每道菜的基本味型,才能谈调整配方。

Rt=Pt−Pt−1Pt−1\displaystyle R_t = \frac{P_t - P_{t-1}}{P_{t-1}}
收益率衡量“今天比昨天涨跌了多少”,它是累计净值、夏普比率、最大回撤等一切绩效指标的源头。
  1. P_t(今日价格)当前时点 t 的资产价格,可以理解为今天这盘菜的售价。
    PtP_t
  2. P_{t-1}(昨日价格)上一个时点 t-1 的价格,是计算变化的基准。
    Pt−1P_{t-1}
  3. P_t - P_{t-1}(绝对价差)今天比昨天贵或便宜了多少,体现价格变动的方向和幅度。
    Pt−Pt−1P_t - P_{t-1}
  4. 除以 P_{t-1}(相对比例)把绝对变化转化为相对昨日价格的百分比,消除不同价格量级的影响,得到可与任何资产比较的收益率。
    Pt−Pt−1Pt−1\frac{P_t - P_{t-1}}{P_{t-1}}

事件驱动模型:后厨的流水线节奏

试菜厨房里最怕乱套。顾客点单的消息、食材变质的提醒、大厨出菜的信号,如果全挤在一起,后厨必然崩溃。聪明的办法是给每件事贴上时间标签,排成一条按时间先后处理的队列——这就是事件驱动模型的思想。

在回测平台中,这条队列被称作事件队列,队列里装着四类主要事件:市场事件(行情数据到达)、信号事件(策略指标产生交易意图)、订单事件(系统发出买卖委托)、账户事件(成交后资金与仓位变动)。回测引擎每处理完一个事件,再取下一个,按严格的时间顺序推进。

事件驱动模型的核心,是每一轮循环都从队列中取出时间最早的事件处理,保证整个回测不跳步、不穿越:

把事件按时间排好,后厨就永远知道下一道菜该做给谁。回测引擎也一样:行情到了先更新价格,策略觉察到价格变化再决定是否发信号,订单产生后再模拟撮合,撮合完成再更新账户——每一步都踩准节拍,不会“先上菜后点单”。

t∗=min⁡e∈Qe.timestamp\displaystyle t^* = \min_{e \in Q} e.\text{timestamp}
回测引擎每次只处理最“急”的那件事——最早到达的行情、最早触发的信号,确保模拟过程与现实时间线一致。
  1. Q(事件队列)装着所有待处理事件的集合,可以想象成后厨的待办清单。
    QQ
  2. e(队列中的事件)任意一条待处理的记录,它自带类型标记和时间戳。
    e∈Qe \in Q
  3. e.timestamp(事件时间戳)该事件发生的模拟时间,决定它在流水线上的先后顺序。
    e.timestampe.\text{timestamp}
  4. min(取最小时刻)在所有待处理事件中挑出时间戳最小的那一个优先执行;引擎每处理完一个事件,再取下一个,如此循环往复,就完成了一天又一天的模拟。
    t∗=min⁡e∈Qe.timestampt^* = \min_{e \in Q} e.\text{timestamp}

数据清洗:把食材挑拣干净

做菜的第一步不是开火,而是挑食材。从菜市场买来的肉可能有淤血,从账本上抄来的价格可能有错漏——回测平台面对的历史数据同样如此。拿脏数据回测,就像用发臭的食材做菜,再好的菜谱也救不回来。

数据清洗要完成四件事:接入多源数据(交易所、第三方供应商)、剔除错误和重复记录、对缺失值做插值或剔除、把不同时区不同频率的数据对齐到同一时间轴。清洗规则看起来琐碎,却是高保真回测的地基。清洗后的数据会按统一格式落盘存储,供后续撮合和绩效模块反复读取。

清洗中常用对数收益率来检测异常跳变,因为它相比简单收益率具有可加性,连续几天的累计收益可以直接相加:

食材挑拣干净,后厨才能放心下锅。回测平台把清洗后的数据按统一格式存储,后续千百次策略迭代都能直接读取,省下的时间会在反复试菜中成倍回报。

rt=ln⁡(Pt)−ln⁡(Pt−1)\displaystyle r_t = \ln(P_t) - \ln(P_{t-1})
对数收益率将乘法关系转化为加法,便于跨时间累加,也更容易识别数据中的异常跳空。
  1. P_t(今日价格)今天的收盘价或成交价。
    PtP_t
  2. ln(自然对数)以 e 为底的对数变换,将涨跌幅映射为可累加的量。
    ln⁡(Pt)\ln(P_t)
  3. ln(P_{t-1})(昨日价格的对数)对前一天价格做同样的变换,形成差值基准。
    ln⁡(Pt−1)\ln(P_{t-1})
  4. 两者相减(对数收益率)若相邻两天价格连续,对数收益率会在正常范围内波动;若出现极端值,往往意味着数据错误、停牌复牌跳空或流动性缺失,需要被标记出来人工核对。
    ln⁡(Pt)−ln⁡(Pt−1)\ln(P_t) - \ln(P_{t-1})

撮合模拟:如何模拟顾客下单

顾客说要十份宫保鸡丁,后厨不能假装食材无限、转眼就端上十份。真实世界里,食材有库存,交易市场也有“深度”——买一档挂了多少单、卖一档挂了多少钱,决定了你的订单能完成多少。

撮合模拟负责模拟订单与对手盘的交手过程。成交判定的原则是“价匹配、量优先”:买入单要和卖一价撮合,卖出单要和买一价撮合;当挂单数量不足时,订单只能部分成交。成交之后,撮合模块立即更新仓位记录和资金账户:买入增加持仓、扣减现金,卖出减少持仓、增加现金,并同步更新保证金占用。撮合算法的核心,就是成交数量取策略需求量与对手盘深度两者中的较小值:

撮合模拟让回测不至于“纸上谈兵”。等你真正在回测报告中看到“想买 100 股只买到 65 股”,你才会明白市场的流动性像后厨库存一样有限——真实感,就是这么一分一毫抠出来的。

Vfill=min⁡(Vsignal, Vdepth)\displaystyle V_{\text{fill}} = \min\left(V_{\text{signal}},\ V_{\text{depth}}\right)
成交量的上限由市场流动性决定:你想要的量再大,也填不满市场的“锅”。
  1. V_signal(策略期望成交量)策略根据信号计算出想要买入或卖出的数量,比如大厨想进的十份食材。
    VsignalV_{\text{signal}}
  2. V_depth(对手盘深度)在当前价位上市场愿意接走的数量,相当于后厨此刻的可用库存。
    VdepthV_{\text{depth}}
  3. min(取最小值)当期望量超出深度时,多出的部分只能挂单等待或放弃,成交数量被深度牢牢钳制。
    min⁡(Vsignal, Vdepth)\min\left(V_{\text{signal}},\ V_{\text{depth}}\right)

成本建模:漏油的后厨要算清楚

做菜过程中总会漏油、溅水、烂食材。放在交易里,这些“损耗”就是滑点、手续费、冲击成本——如果试菜时忽略它们,开张后会被真实账单打得措手不及。

滑点是指实际成交价与期望价之间的偏差:大单快速买入会把价格推高,卖出又会压低价格。手续费则由交易所佣金、印花税、过户费等构成,每一笔成交都要扣除。保证金占用还会影响资金利用率,冲击成本则在大单交易时格外显著。建模时常用如下公式描述滑点:

把滑点和手续费算进回测,利润表才不会虚胖。现实是:一个在纸面回测中年化 30% 的策略,扣掉成本和损耗后可能只剩 15%——账算得越细,留下来的策略才越皮实。

Pfill=Pmarket+k×σ×sign(Q)\displaystyle P_{\text{fill}} = P_{\text{market}} + k \times \sigma \times \text{sign}(Q)
滑点与市场波动率成正比,波动越大、订单越急,成交价格偏离市价越多。
  1. P_market(当前市价)下单那一刻的市场最优报价。
    PmarketP_{\text{market}}
  2. σ(波动率)市场价格在单位时间内的波动剧烈程度,可以理解为后厨里的“火候”,火越大溅油越多。
    σ\sigma
  3. k(滑点系数)刻画订单大小和流动性的调节系数,体现“你这一勺下去溅出多少油”。
    kk
  4. sign(Q)(交易方向符号)买入取 +1,卖出取 -1,表示滑点总是往不利于自己的方向偏移。
    sign(Q)\text{sign}(Q)

绩效指标:月底盘账见真章

月底大厨要盘账:这个月赚了多少、翻台率如何、有没有哪几天的流水跌得让人睡不着觉。回测里的绩效指标就是交易的“账本”,其中最让交易员揪心的就是最大回撤。

最大回撤衡量的是净值从历史最高点回落的最大幅度。它告诉你:就算策略整体赚钱,过程中也可能经历让人肉疼的深坑。公式定义为:

除了最大回撤,账本上还有收益率、夏普比率(单位风险的超额回报)、胜率和盈亏比。这些指标放在一起,相当于一张完整的体检单:能赚多少钱是进攻,扛多大回撤是防守,攻守兼备才是好策略。

MDD=max⁡t(1−NAVtmax⁡s≤tNAVs)\displaystyle \text{MDD} = \max_{t}\left(1 - \frac{\text{NAV}_t}{\max_{s \le t}\text{NAV}_s}\right)
最大回撤是风险的核心度量之一:它回答“用这个策略,最多可能亏多少”。回撤越大,策略持有过程越煎熬,越可能在黎明前割肉离场。
  1. NAV_t(第 t 日净值)账户在第 t 天的总资产价值,按初始资金归一化。
    NAVt\text{NAV}_t
  2. max_{s≤t} NAV_s(历史峰值)从开始到第 t 天为止的净值最高点,是回撤的比较基准。
    max⁡s≤tNAVs\max_{s \le t} \text{NAV}_s
  3. 1 - NAV_t / 峰值(当日回撤比例)当前净值相对历史高点的跌幅,衡量“从山顶摔下来多少”。
    1−NAVtmax⁡s≤tNAVs1 - \frac{\text{NAV}_t}{\max_{s \le t} \text{NAV}_s}
  4. 取全局最大回撤在所有时点中取最大跌幅,即整个回测区间最惨烈的那次下跌。
    max⁡t(1−NAVtmax⁡s≤tNAVs)\max_{t}\left(1 - \frac{\text{NAV}_t}{\max_{s \le t}\text{NAV}_s}\right)

过拟合控制:别只为熟客做菜

如果你把菜谱调整到完美匹配过去一年的每一位老顾客,换一批新客人可能立刻无人问津。回测中最危险的陷阱就是过拟合:策略在样本内收益惊人,一出样本外就变吃土。

过拟合的成因是策略参数过多而数据窗口太短,或是在回测中反复用同一段数据调参。控制方法首推样本外测试——把数据分成训练段和验证段,训练段上开发策略,验证段上检验策略。两者收益差距越大,往往说明过拟合越严重:

避开过拟合没有银弹,只有纪律:样本外测试、参数敏感性分析、多市场多周期的稳健性评估。就像大厨不能只招待熟客,好策略必须经得起陌生市场的考验。

Roos=λ×Ris+ε\displaystyle R_{\text{oos}} = \lambda \times R_{\text{is}} + \varepsilon
λ 值越接近 1,说明样本内的优秀表现越能延续到样本外;λ 显著小于 1,策略很可能是在“背题”。
  1. R_is(样本内收益)策略在训练数据上取得的收益,俗称“考场上背过的题”。
    RisR_{\text{is}}
  2. R_oos(样本外收益)策略在未参与调参的数据上实现的收益,是“没见过的考题”。
    RoosR_{\text{oos}}
  3. λ(泛化系数)刻画样本内表现向样本外迁移的比例,λ 越接近 1,策略越稳健。
    λ\lambda
  4. ε(噪声项)无法被解释的随机误差,提醒我们短期表现永远包含运气成分。
    ε\varepsilon

架构实践:把后厨盖成放心厨房

试菜厨房光有好菜谱不够,还得有合理的动线:冰箱、案板、灶台如何摆放,决定了大厨忙起来顺不顺手。回测平台同样讲究架构分层,模块之间各司其职,互不纠缠。

一个可维护的回测平台通常划分为数据层、策略层、撮合层、风控层和绩效层。数据层负责读取与清洗历史行情;策略层根据行情产生交易信号;撮合层把信号变成成交;风控层做仓位和资金约束;绩效层最终输出指标报告。各层通过事件总线通信,替换策略或换数据源都只需改动局部,每层还可以独立做单元测试和回归测试。

性能是平台的另一条腿。回测要处理海量事件,常用吞吐量衡量处理速度:

架构好坏的检验标准是“改起来快不快、跑起来快不快、查错快不快”。像一间布局合理的后厨,哪怕来了几百道新菜单,也能有条不紊地转起来。

S=NeventsTwall\displaystyle S = \frac{N_{\text{events}}}{T_{\text{wall}}}
吞吐量越高,单次回测耗时越短,策略迭代创新越快。百万级事件在高效引擎中只需毫秒级即可跑完。
  1. N_events(事件总数)回测过程中产生的所有行情、信号、订单事件的数量。
    NeventsN_{\text{events}}
  2. T_wall(墙钟耗时)从回测开始到结束真实经过的时间,用秒表测量。
    TwallT_{\text{wall}}
  3. 两者相除(吞吐量)单位时间处理的事件数。吞吐量越高,平台跑得越快,也意味着可以承载更密集的模拟和更多的策略试验。
    NeventsTwall\frac{N_{\text{events}}}{T_{\text{wall}}}

AI 应用场景

量化对冲基金策略研发验证平台

阶段:数据准备与模型验证阶段

解决的问题:过去研究员用 Excel 手工验证策略,效率低且容易引入前视偏差。回测平台将数据清洗、信号生成、撮合、绩效一体化,研究员在统一事件流水线上迭代策略,从“想一个跑一个”变为“批量并行验证”,让“试菜”过程又快又准。

具体案例:某私募基金用事件驱动回测平台验证中证 500 指数增强策略,在 10 年日线数据上同时测试 200 组参数组合,借助样本外测试淘汰了 70% 的过拟合策略,最终上线策略的样本外夏普比率比样本内仅衰减 0.3。

券商风控团队极端行情压力测试

阶段:模型风险评估阶段

解决的问题:新策略上线前,风控部门需要知道它在极端行情(如 2020 年疫情暴跌)中会亏多少。回测平台的事件驱动特性可以精确复现历史极端时刻的逐笔成交,评估产品最大回撤和尾部风险,像试菜时要特意测试“最挑剔的客人会不会砸场子”。

具体案例:某券商场外衍生品部门对做市策略进行压力回测,在 2015 年股灾数据上加入手续费和滑点模型后,发现原策略最大回撤从 8% 上升到 21%,因此触发风控阈值调整,降低了实盘仓位。

量化 SaaS 平台的在线回测服务

阶段:数据服务与模型验证阶段

解决的问题:互联网量化平台面向个人开发者提供在线回测能力,需要在多租户环境下高效调度计算资源。平台把回测引擎做成事件驱动的微服务,行情数据列式存储、按需加载,让每个用户都能拥有一间“随时开放的试菜厨房”。

具体案例:某量化云平台将回测引擎打包为容器化服务,用户在网页上编辑策略参数,提交后平均 3 秒完成一次 10 年日线回测,并通过绩效指标报表和过拟合检测报告辅助用户判断策略质量。

Python 演示

python59 行
import random def generate_prices(n=200, start=100.0, vol=0.01):    prices = [start]    for _ in range(n - 1):        prices.append(prices[-1] * (1 + random.uniform(-vol, vol)))    return prices def moving_average(data, window):    result = []    s = 0.0    for i, v in enumerate(data):        s += v        if i >= window:            s -= data[i - window]        result.append(s / min(i + 1, window))    return result def backtest(prices, fast_win=5, slow_win=10, fee_rate=0.0005, slippage=0.0001):    fast = moving_average(prices, fast_win)    slow = moving_average(prices, slow_win)    cash = 100000.0    shares = 0    trades = []    equity_curve = []    for i in range(1, len(prices)):        if fast[i] > slow[i] and fast[i - 1] <= slow[i - 1] and shares == 0:            price = prices[i] * (1 + slippage)            shares = int(cash / price / 100) * 100            cash -= shares * price * (1 + fee_rate)            trades.append((i, 'buy', price, shares))        elif fast[i] < slow[i] and fast[i - 1] >= slow[i - 1] and shares > 0:            price = prices[i] * (1 - slippage)            cash += shares * price * (1 - fee_rate)            trades.append((i, 'sell', price, shares))            shares = 0        equity_curve.append(cash + shares * prices[i])    return equity_curve, trades, equity_curve[-1] - 100000.0 def compute_sharpe(equity_curve):    returns = []    for i in range(1, len(equity_curve)):        prev = equity_curve[i - 1]        if prev > 0:            returns.append(equity_curve[i] / prev - 1)    if not returns:        return 0.0    avg = sum(returns) / len(returns)    var = sum((r - avg) ** 2 for r in returns) / len(returns)    return avg / (var ** 0.5) if var > 0 else 0.0 if __name__ == '__main__':    random.seed(42)    prices = generate_prices()    equity, trades, profit = backtest(prices)    sr = compute_sharpe(equity)    print('trade count:', len(trades))    print('net profit: %.2f' % profit)    print('sharpe: %.3f' % sr)
目的:实现一个带滑点和手续费的迷你双均线回测引擎,跑完 200 天模拟行情后输出成交次数、净利润和夏普比率。
  1. prices.append(prices[-1] * (1 + random.uniform(-vol, vol)))用随机游走生成模拟行情,相当于先“编造”一份历史点单记录。
  2. cash -= shares * price * (1 + fee_rate)买入时按成交价加手续费扣减现金,把交易成本真实计入账本。
  3. shares = int(cash / price / 100) * 100以整手(100 股)为单位买入,模拟 A 股最小交易单位约束。
  4. equity_curve.append(cash + shares * prices[i])每日收盘后按“现金 + 持仓市值”计算账户净值,画出资金曲线。
  5. avg / (var ** 0.5) if var > 0 else 0.0用平均收益除以波动率计算夏普比率,衡量每单位风险的回报。

常见误区

误区我写的策略在回测里年化 50%,最大回撤只有 10%,这肯定是稳赚的印钞机,直接实盘!

正解回测高收益可能来自过拟合、前视偏差或被忽略的交易成本。回测忠实模拟的是“过去某个特定的市场环境”,而未来市场永远在变。就像你用老顾客的喜好定制了一桌菜,他们吃得很开心,可新顾客进门却觉得口味太怪。真正好策略要在样本外、多周期、多市场上经得住考验。

为何常见:人总是喜欢看到高收益数据,而选择性忽略回测中的隐藏假设,这是“幸存者偏差”的思维惯性。

误区回测嘛,信号在收盘后产生,按收盘价成交不是最合理的吗?何必搞得那么复杂?

正解收盘价往往只是理论价,真实成交会受流动性、涨跌停、停牌影响。用收盘价撮合等于默认买卖盘永远有无限量,自然会高估收益。要像后厨核对库存一样核对每档挂单量,按撮合算法模拟实际成交。

为何常见:初学者往往先接触按收盘价成交的简单回测框架,形成了先入为主的简化观念。

误区交易所的数据是权威的,直接拿来跑不就行了吗?为什么还要花时间清洗?

正解历史数据存在复权缺口、停牌记录、异常跳变、时区错位等问题。如果直接把未复权价格用于计算收益,除权日那天的收益率会莫名其妙地暴跌。数据清洗是回测平台的地基,地基不牢,金碧辉煌的回测结果也是空中楼阁。

为何常见:清洗过程枯燥且不产生直接的“故事点”,容易被忽略,但它的价值在出现问题后才显现。

误区回测只是看策略方向对不对,把手续费设成零能节省计算,等真上实盘再算手续费不迟。

正解对于高频策略而言,即便万分之一的手续费也会在数千次交易中吞噬全部超额收益;滑点在流动性差的市场上可能让每笔交易多付出 0.5% 的代价。零成本回测相当于试菜时不计算燃气费和食材损耗,账目必然失真。

为何常见:默认参数往往基于“先跑通再完善”的开发节奏,成本模块常在最后才补上,久而久之被忽略。

误区我在训练段上开发策略,在验证段上测试,样本外收益也很高,这说明策略稳健,可以放心实盘。

正解一次样本外测试还不够,因为验证段仍只代表一段特定历史行情。需要通过分段滚动测试、参数敏感性分析和多市场数据验证,确认策略不是恰好拟合了验证段。就像试菜合格不代表每天客人都买账,还需要在小范围试营业中持续观察。

为何常见:样本外测试远比“纯回测”显得严谨,让人觉得有了护身符,但其实它的统计效力有限。

面试题

Q1. 回测平台的核心目标是什么?

单选题 · easy

  • A.用历史数据验证策略的可行性与稳健性← 正确答案
  • B.预测未来市场价格的精确走势
  • C.在真实实盘环境中完成自动交易
  • D.统计策略在过去所有交易次数

答案:A。回测本质是“用历史数据验策略”,就像试菜厨房。B 是预测问题,不是回测;C 是实盘交易系统;D 只是统计游戏,都不是核心目标。

Q2. 事件驱动模型中,引擎每轮循环应当优先处理哪类事件?

单选题 · mid

  • A.最新生成的信号事件
  • B.时间戳最早的那一个事件← 正确答案
  • C.资金量最大的订单事件
  • D.系统随机选择的事件

答案:B。事件队列按时间戳排序,最早的事件最先处理,保证模拟与现实时间线一致。信号事件和订单事件只是事件类型,不决定优先级;随机选择会破坏时间顺序。

Q3. 数据清洗环节通常需要处理哪些问题?

多选题 · mid

  • A.处理除权除息导致的复权缺口← 正确答案
  • B.补齐停牌期间的缺失数据← 正确答案
  • C.对齐不同时区的交易时间← 正确答案
  • D.调整策略过拟合的参数

答案:ABC。ABC 都是数据层的典型问题:复权、缺失值、时区对齐直接决定收益率计算的正确性。D 是策略模型层面的过拟合问题,不属于数据清洗范畴。

Q4. 关于最大回撤,下列哪项描述是正确的?

单选题 · hard

  • A.净值从历史峰值到谷值的最大跌幅← 正确答案
  • B.衡量策略累计总收益的指标
  • C.所有亏损交易金额的加总
  • D.平均每笔交易的亏损金额

答案:A。最大回撤刻画净值从历史峰值回落到最低点的最大幅度,公式为 MDD = max(1 - NAV_t/峰值)。B 描述的是累计收益,C 是总亏损,D 是平均亏损,都不对。

Q5. 滑点产生的主要原因是什么?

单选题 · mid

  • A.交易员输入订单发生误操作
  • B.市场波动与订单冲击导致偏离← 正确答案
  • C.交易所通信网络出现延迟
  • D.策略计算信号程序错误

答案:B。滑点源于市场波动和自身订单对价格的冲击,可用 P_fill = P_market + k×σ×sign(Q) 建模。A 是操作风险,C 是技术延迟,D 是模型错误,都不是滑点本质。

Q6. 以下哪些方法可以有效降低策略过拟合风险?

多选题 · hard

  • A.将策略放在样本外数据上测试← 正确答案
  • B.对关键参数做敏感性分析← 正确答案
  • C.在不同市场与时段做稳健性评估← 正确答案
  • D.增加策略可调参数的数量

答案:ABC。ABC 是经典过拟合控制手段:样本外测试检验泛化能力,参数敏感性检查结果是否依赖特定取值,稳健性评估验证跨市场适用性。D 恰好相反,参数越多越容易过拟合。

Q7. 夏普比率衡量的是什么?

单选题 · easy

  • A.策略在回测中的总收益规模
  • B.每承担一单位风险获得的超额回报← 正确答案
  • C.策略在历史中的交易次数
  • D.策略最大回撤的百分比值

答案:B。夏普比率 = (组合收益 - 无风险收益) / 收益波动率,是“每冒一分险换几分超额回报”的风险调整后收益指标。A 是绝对收益,C 是交易频率,D 是风险指标,都不全面。

Q8. 回测撮合中,成交数量通常如何确定?

单选题 · mid

  • A.期望量与对手盘深度的较小值← 正确答案
  • B.策略期望成交量的两倍
  • C.对手盘挂单深度的一半
  • D.系统随机生成的整数值

答案:A。V_fill = min(V_signal, V_depth),成交数量由策略期望量和市场深度共同决定。市场流动性有限,期望再大也只能按深度成交,就像后厨库存不足只能部分出菜。

Q9. 以下属于回测绩效指标的有?

多选题 · easy

  • A.累计收益率指标← 正确答案
  • B.最大回撤指标← 正确答案
  • C.胜率与盈亏比指标← 正确答案
  • D.数据库连接数指标

答案:ABC。ABC 都是常见绩效维度:累计收益看进攻,最大回撤看防守,胜率与盈亏比看交易质量。D 是系统运行指标,与策略绩效无关。

Q10. 假设某策略样本内年化收益 40%,样本外年化收益 5%,最可能的原因是什么?

单选题 · extreme

  • A.市场风格切换导致策略逻辑暂时失效
  • B.策略过拟合使样本内表现无法推广← 正确答案
  • C.历史数据清洗环节出现了严重错误
  • D.回测中设置了过高的交易手续费

答案:B。样本内高样本外低是过拟合的典型信号(R_oos = λ×R_is + ε,λ 显著小于 1)。A 是市场变化,但最直接的诊断结论是过拟合;C、D 是工程问题,不会系统性表现为样本内外收益的悬殊差距。