Skip to content

Commit 64fe4ba

Browse files
authored
Update LinearWeightedMovingAverage (QuantConnect#7798)
* Add improvements and unit tests * Add Improvements
1 parent 2a82c6f commit 64fe4ba

File tree

4 files changed

+46
-29
lines changed

4 files changed

+46
-29
lines changed

Indicators/LinearWeightedMovingAverage.cs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ namespace QuantConnect.Indicators
3333
/// </summary>
3434
public class LinearWeightedMovingAverage : WindowIndicator<IndicatorDataPoint>, IIndicatorWarmUpPeriodProvider
3535
{
36+
private readonly int _denominator;
3637
/// <summary>
3738
/// Required period, in data points, for the indicator to be ready and fully initialized.
3839
/// </summary>
@@ -46,6 +47,7 @@ public class LinearWeightedMovingAverage : WindowIndicator<IndicatorDataPoint>,
4647
public LinearWeightedMovingAverage(string name, int period)
4748
: base(name, period)
4849
{
50+
_denominator = (period * (period + 1)) / 2;
4951
}
5052

5153
/// <summary>
@@ -66,22 +68,14 @@ public LinearWeightedMovingAverage(int period)
6668
protected override decimal ComputeNextValue(IReadOnlyWindow<IndicatorDataPoint> window, IndicatorDataPoint input)
6769
{
6870
// our first data point just return identity
69-
if (window.Size == 1)
71+
if (!IsReady)
7072
{
71-
return input.Value;
73+
return 0;
7274
}
7375

7476
var numerator = 0m;
75-
var denominator = 0;
7677
var index = window.Size;
7778

78-
// The denominator is calculated each time in case the Size is less than the period.
79-
// There may be a more efficient way of calculating the factorial.
80-
for (var i = 0; i <= index; i++)
81-
{
82-
denominator += i;
83-
}
84-
8579
// If the indicator is not ready, the LWMA will still be correct
8680
// because the numerator has the minimum of the Size (number of
8781
// entries or the Samples (the allocated space)
@@ -90,7 +84,7 @@ protected override decimal ComputeNextValue(IReadOnlyWindow<IndicatorDataPoint>
9084
{
9185
numerator += (index-- * window[i].Value);
9286
}
93-
return numerator / denominator;
87+
return numerator / _denominator;
9488
}
9589
}
9690
}

Tests/Indicators/LinearWeightedMovingAverageTests.cs

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,17 @@
2121
namespace QuantConnect.Tests.Indicators
2222
{
2323
[TestFixture]
24-
public class LinearWeightedMovingAverageTests
24+
public class LinearWeightedMovingAverageTests : CommonIndicatorTests<IndicatorDataPoint>
2525
{
26+
protected override string TestFileName => "spx_lwma.csv";
27+
28+
protected override string TestColumnName => "LWMA";
29+
30+
protected override IndicatorBase<IndicatorDataPoint> CreateIndicator()
31+
{
32+
return new LinearWeightedMovingAverage(6);
33+
}
34+
2635
[TestCase(1)]
2736
[TestCase(2)]
2837
[TestCase(3)]
@@ -46,27 +55,15 @@ public void ComputesCorrectly(int period)
4655
Assert.AreEqual(current, lwma.Current.Value);
4756
}
4857

49-
[TestCase(1)]
50-
[TestCase(2)]
51-
[TestCase(3)]
52-
[TestCase(4)]
53-
[TestCase(5)]
54-
// See http://en.wikipedia.org/wiki/Moving_average
55-
// for the formula and the numbers in this test.
56-
public void ResetsProperly(int period)
58+
[Test]
59+
public override void ResetsProperly()
5760
{
58-
var values = new[] { 77m, 79m, 79m, 81m, 83m };
59-
var weights = Enumerable.Range(1, period).ToArray();
60-
var current = weights.Sum(i => i * values[i - 1]) / weights.Sum();
61-
62-
var lwma = new LinearWeightedMovingAverage(period);
63-
var time = DateTime.UtcNow;
61+
var lwma = new LinearWeightedMovingAverage(6);
6462

65-
for (var i = 0; i < period; i++)
63+
foreach (var data in TestHelper.GetDataStream(8))
6664
{
67-
lwma.Update(time.AddSeconds(i), values[i]);
65+
lwma.Update(data);
6866
}
69-
Assert.AreEqual(current, lwma.Current.Value);
7067
Assert.IsTrue(lwma.IsReady);
7168
Assert.AreNotEqual(0m, lwma.Current.Value);
7269
Assert.AreNotEqual(0, lwma.Samples);

Tests/QuantConnect.Tests.csproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,9 @@
364364
<ProjectReference Include="..\ToolBox\QuantConnect.ToolBox.csproj" />
365365
</ItemGroup>
366366
<ItemGroup>
367+
<Content Include="TestData\spx_lwma.csv">
368+
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
369+
</Content>
367370
<Content Include="TestData\spy_10_min.txt">
368371
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
369372
</Content>

Tests/TestData/spx_lwma.csv

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
Date,Close,LWMA
2+
5/1/2023 00:00:00,4167.87,0
3+
5/2/2023 00:00:00,4119.58,0
4+
5/3/2023 00:00:00,4090.75,0
5+
5/4/2023 00:00:00,4061.22,0
6+
5/5/2023 00:00:00,4136.25,0
7+
5/8/2023 00:00:00,4138.12,4115.91
8+
5/9/2023 00:00:00,4119.17,4115.97
9+
5/10/2023 00:00:00,4137.64,4123.6242
10+
5/11/2023 00:00:00,4130.62,4128.4133
11+
5/12/2023 00:00:00,4124.08,4129.4352
12+
5/15/2023 00:00:00,4136.28,4130.95
13+
5/16/2023 00:00:00,4109.90,4124.9252
14+
5/17/2023 00:00:00,4158.77,4134.2076
15+
5/18/2023 00:00:00,4198.05,4152.8271
16+
5/19/2023 00:00:00,4191.98,4166.8357
17+
5/22/2023 00:00:00,4192.63,4178.1080
18+
5/23/2023 00:00:00,4145.58,4172.6733
19+
5/24/2023 00:00:00,4115.24,4158.1271
20+
5/25/2023 00:00:00,4151.28,4153.6238
21+
5/26/2023 00:00:00,4205.45,4164.9542
22+
5/30/2023 00:00:00,4205.52,4175.9523
23+
5/31/2023 00:00:00,4179.83,4178.9657

0 commit comments

Comments
 (0)