Skip to content

Commit 884b594

Browse files
authored
fix: Correct wrong default periods in obsolete GetPvo (#2214)
1 parent 66422a0 commit 884b594

3 files changed

Lines changed: 76 additions & 1 deletion

File tree

docs/migration/v3.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ defect versus changing intended behavior](https://github.com/facioquo/stock-indi
7575
`ToPrs()` and pre-`3.0.0` behavior. **If you called `GetPrs()` on `3.0.x`, stored values and any
7676
thresholds tuned against them must be revalidated; new values are the reciprocal of
7777
old ones.** Callers of `ToPrs()` were never affected.
78+
- **`GetPvo()` used the wrong default periods.** The shim declared
79+
`fastPeriods: 9, slowPeriods: 12` where both v2 and `ToPvo()` declare `12` and `26`,
80+
so calling `GetPvo()` with no arguments silently computed a differently-parameterized
81+
PVO. Corrected in `3.0.1`. **If you called `GetPvo()` without explicit periods on `3.0.x`, stored values
82+
must be revalidated.** Callers who passed explicit periods, and callers of `ToPvo()`,
83+
were never affected.
7884
- **`GetPrs()` with no `lookbackPeriods` threw.** The unspecified lookback was mapped to
7985
`0`, which validation rejects, so the shim's own default raised
8086
`ArgumentOutOfRangeException`. As of `3.0.1` it computes with a null `PrsPercent`, as

src/Obsolete.V3.Indicators.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -724,7 +724,7 @@ public static IEnumerable<PrsResult> GetPrs(
724724
[Obsolete("Rename `GetPvo(..)` to `ToPvo(..)`", false)]
725725
public static IEnumerable<PvoResult> GetPvo(
726726
this IEnumerable<IBar> bars,
727-
int fastPeriods = 9, int slowPeriods = 12, int signalPeriods = 9)
727+
int fastPeriods = 12, int slowPeriods = 26, int signalPeriods = 9)
728728
=> bars.ToSortedList().ToPvo(fastPeriods, slowPeriods, signalPeriods);
729729

730730
[ExcludeFromCodeCoverage]
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
namespace StaticSeries;
2+
3+
/// <summary>
4+
/// Tests for the obsolete v3 <c>GetPvo</c> shim, which must return what the pre-3.0.0
5+
/// API returned.
6+
/// </summary>
7+
/// <remarks>
8+
/// The shim declared <c>9, 12, 9</c> where both v2 and <c>ToPvo</c> declare
9+
/// <c>12, 26, 9</c> — the correct values shifted one position. Calling the documented
10+
/// default therefore computed a different indicator, silently: the result is a
11+
/// well-formed PVO, just not the one asked for. Nothing here called the shim, so
12+
/// nothing caught it.
13+
/// </remarks>
14+
[TestClass]
15+
public class PvoObsoleteShimTests : TestBaseWithPrecision
16+
{
17+
[TestMethod]
18+
public void GetPvoDefaultsMatchToPvo()
19+
{
20+
#pragma warning disable CS0618 // exercising the obsolete shim is the point
21+
List<PvoResult> shim = Bars.GetPvo().ToList();
22+
#pragma warning restore CS0618
23+
24+
IReadOnlyList<PvoResult> expected = Bars.ToPvo();
25+
26+
shim.Should().HaveCount(expected.Count);
27+
shim.Select(static r => r.Pvo).Should().Equal(expected.Select(static r => r.Pvo));
28+
shim.Select(static r => r.Signal).Should().Equal(expected.Select(static r => r.Signal));
29+
shim.Select(static r => r.Histogram).Should().Equal(expected.Select(static r => r.Histogram));
30+
}
31+
32+
[TestMethod]
33+
public void GetPvoDefaultsAreNotTheShiftedPeriods()
34+
{
35+
// guards the specific 3.0.0 regression: the shim declared 9, 12, 9
36+
#pragma warning disable CS0618
37+
List<PvoResult> shim = Bars.GetPvo().ToList();
38+
#pragma warning restore CS0618
39+
40+
IReadOnlyList<PvoResult> shifted = Bars.ToPvo(9, 12, 9);
41+
42+
shim[^1].Pvo.Should().NotBeApproximately(shifted[^1].Pvo!.Value, Money6);
43+
}
44+
45+
[TestMethod]
46+
public void GetPvoMatchesKnownValues()
47+
{
48+
// anchors the shim to absolute values, so a co-regression in ToPvo cannot
49+
// move both sides of the comparison above and pass unnoticed
50+
#pragma warning disable CS0618
51+
List<PvoResult> shim = Bars.GetPvo().ToList();
52+
#pragma warning restore CS0618
53+
54+
shim.Should().HaveCount(502);
55+
shim[501].Pvo.Should().BeApproximately(10.439509, Money6);
56+
}
57+
58+
[TestMethod]
59+
public void GetPvoWithExplicitPeriodsMatchesToPvo()
60+
{
61+
#pragma warning disable CS0618
62+
List<PvoResult> shim = Bars.GetPvo(10, 20, 7).ToList();
63+
#pragma warning restore CS0618
64+
65+
IReadOnlyList<PvoResult> expected = Bars.ToPvo(10, 20, 7);
66+
67+
shim.Select(static r => r.Pvo).Should().Equal(expected.Select(static r => r.Pvo));
68+
}
69+
}

0 commit comments

Comments
 (0)