VolumeWeightedAveragePriceExecutionModel silently degenerates on daily resolution

未关闭
#10,011 1 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
2/5
预计耗时
1-3 小时
新手友好度
55/100
Issue 类型
文档
描述清晰度
描述清楚
活跃度
活跃
技术栈
csharp
领域
backend

调研方向

The relevant files are Algorithm.Framework/Execution/VolumeWeightedAveragePriceExecutionModel.cs, where PriceIsFavorable compares bid and ask against data.VWAP, and Indicators/IntradayVwap.cs, where the sums reset at each date boundary. Start by confirming the daily-resolution reasoning in the issue, then add a <remarks> block to both class documentations stating the model is intraday-only and that daily or coarser resolution degrades the indicator to the bar's typical price. Done when both remarks are present and build cleanly. Behaviour changes such as rejecting daily input need a maintainer decision first.

由索引模型根据 Issue 内容生成。

描述

Summary

VolumeWeightedAveragePriceExecutionModel is an intraday execution model, but it accepts any subscription resolution. On daily data the IntradayVwap indicator resets at every bar, so the "VWAP" it compares against is just that bar's typical price, and the model silently degrades into "buy below the bar midpoint, sell above it".

Nothing warns about it, and the class documentation does not say the model is intraday only, so this is easy to hit by accident.

What happens with daily data

IntradayVwap accumulates within a date only:

// Indicators/IntradayVwap.cs:41-47
// reset vwap on daily boundaries
if (_lastDate != input.EndTime.Date)
{
    _sumOfVolume = 0m;
    _sumOfPriceTimesVolume = 0m;
    _lastDate = input.EndTime.Date;
}

and for a TradeBar it accumulates (High + Low + Close) / 3 (:103).

With Resolution.Daily every bar starts a new date, so the sums are zeroed before each accumulation and the indicator returns exactly that bar's typical price. PriceIsFavorable then reduces to:

// Algorithm.Framework/Execution/VolumeWeightedAveragePriceExecutionModel.cs:147-168
if (unorderedQuantity > 0)
{
    if (data.Security.BidPrice < data.VWAP) { return true; }   // bid < (H+L+C)/3
}
else
{
    if (data.Security.AskPrice > data.VWAP) { return true; }   // ask > (H+L+C)/3
}

Both conditions are roughly a coin flip around the bar midpoint, so the model keeps trading at random while paying the spread. Order sizing is capped at 1% of the bar's volume (MaximumOrderQuantityPercentVolume, default 0.01m), so the damage is bounded, but the result has nothing to do with VWAP. Since the model's name promises intraday execution, a user who backtests it on daily data has no way to tell that the premise does not hold.

The indicator behaviour is intended (#9703 / #9705 made Reset() consistent with it), so this is not a bug in IntradayVwap. The gap is that the model does not validate its input, and the docs do not call it out.

StandardDeviationExecutionModel does not have this problem: an SMA and standard deviation over N daily bars are meaningful.

Options
  1. Documentation only — add a <remarks> to the model (and to IntradayVwap) saying it is an intraday model, and that at daily resolution or coarser the indicator degenerates to the bar's typical price. No behaviour change, no risk.

  2. Reject the input — throw in OnSecuritiesChanged when a security with Resolution.Daily or coarser is added, with a message pointing at ImmediateExecutionModel / StandardDeviationExecutionModel for daily algorithms. This is correct but breaks any existing algorithm that currently does this, so it needs a deliberate decision.

  3. Warn once — CONTRIBUTING.md says framework modules must stay silent ("production code should be silent unless there is a fatal exception ... logging or debugging is not allowed inside LEAN framework modules"), and the only exceptions left in Algorithm.Framework are PearsonCorrelationPairsTradingAlphaModel and OpenInterestFutureUniverseSelectionModel. So this would need an explicit waiver; mentioning it for completeness.

I would suggest 1 now and consider 2 for a future major release. Happy to open a PR with the documentation change, or with either of the others if you prefer.

Version

Verified against master at 138382568 (2026-11-02).

主要语言
C#
星标
22.4k
派生
5.4k
平均合并
1 天 22 小时
30 天内合并 PR
55

环境准备

在 Codespaces 中打开

在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

QuantConnect/Lean 的其他 Issue

查看 QuantConnect/Lean 的全部 Issue

相似的 Issue

更多 C# Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。