Audit by Codex.
Confirmed defects in BacktestingKit/Engine/BKPresets.swift:
smaCrossoverPreset and emaCrossoverPreset enter when fast < slow and exit when fast >= slow, inverted for long crossover strategies.
stochasticFastPreset compares Fast %K with another Fast %K series using identical parameters, so entry is always true once populated and exit is always false. It should compare %K with %D.
bollingerPreset enters when lowerBand < close, which is true during ordinary in-band prices. A lower-band mean-reversion entry must test close <= lowerBand (or the operand-equivalent comparison).
customPreset returns a config whose policy is .sma, despite being selected as .customStrategy.
Acceptance criteria:
- Align rule directions with the current native AlgoTrade presets and the library’s own direct crossover/Bollinger strategy behavior.
- Add focused assertions for every policy preset’s indicator operands and comparisons.
- Add behavioral checks showing bullish crossover entry/bearish exit, Fast %K/%D entry and exit reachability, lower-band Bollinger entry selectivity, and custom policy identity.
- Keep v2/v3 rule conversion parity.
Separate design decision: policy *Crossover rules currently encode an above/below regime, not an edge-detected crossing event. Decide whether legacy parity or true crossover semantics is required before changing that behavior.
Audit by Codex.
Confirmed defects in
BacktestingKit/Engine/BKPresets.swift:smaCrossoverPresetandemaCrossoverPresetenter when fast < slow and exit when fast >= slow, inverted for long crossover strategies.stochasticFastPresetcompares Fast %K with another Fast %K series using identical parameters, so entry is always true once populated and exit is always false. It should compare %K with %D.bollingerPresetenters when lowerBand < close, which is true during ordinary in-band prices. A lower-band mean-reversion entry must test close <= lowerBand (or the operand-equivalent comparison).customPresetreturns a config whose policy is.sma, despite being selected as.customStrategy.Acceptance criteria:
Separate design decision: policy
*Crossoverrules currently encode an above/below regime, not an edge-detected crossing event. Decide whether legacy parity or true crossover semantics is required before changing that behavior.