calculating Moving averages - review fixes jagathkumarks/jagathkumarks@gmail.com

This commit is contained in:
Jagath Kumar 2024-03-20 10:18:42 +05:30
parent a4da7fe15b
commit 80f0ac6b10
5 changed files with 37 additions and 38 deletions

View File

@ -15,10 +15,8 @@ public class ExponentialMovingAverage {
public double calculateEMA(double newValue) { public double calculateEMA(double newValue) {
if (previousEMA == null) { if (previousEMA == null) {
// First data point, EMA is same as the value itself
previousEMA = newValue; previousEMA = newValue;
} else { } else {
// Calculate EMA using the formula: EMA = alpha * newValue + (1 - alpha) * previousEMA
previousEMA = alpha * newValue + (1 - alpha) * previousEMA; previousEMA = alpha * newValue + (1 - alpha) * previousEMA;
} }
return previousEMA; return previousEMA;

View File

@ -24,7 +24,7 @@ public class MovingAverageByCircularBuffer {
} }
double sum = 0; double sum = 0;
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
sum += buffer[i]; //buffer[(head + i) % buffer.length]; sum += buffer[i];
} }
return sum / count; return sum / count;
} }

View File

@ -5,19 +5,20 @@ import org.junit.Test;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
public class ExponentialMovingAverageUnitTest { public class ExponentialMovingAverageUnitTest {
@Test(expected = IllegalArgumentException.class) @Test(expected = IllegalArgumentException.class)
public void when_alpha_is_invalid_should_throw_exception() { public void whenAlphaIsInvalid_shouldThrowException() {
new ExponentialMovingAverage(0); // Alpha outside valid range new ExponentialMovingAverage(0);
} }
@Test @Test
public void when_first_value_is_added_EMA_should_be_same_as_value() { public void whenFirstValueIsAdded_shouldHaveExponentialMovingAverageSameAsValue() {
ExponentialMovingAverage ema = new ExponentialMovingAverage(0.5); ExponentialMovingAverage ema = new ExponentialMovingAverage(0.5);
assertEquals(10.0, ema.calculateEMA(10.0), 0.001); assertEquals(10.0, ema.calculateEMA(10.0), 0.001);
} }
@Test @Test
public void when_values_are_added_EMA_should_update_correctly() { public void whenValuesAreAdded_shouldUpdateExponentialMovingAverageCorrectly() {
ExponentialMovingAverage ema = new ExponentialMovingAverage(0.4); ExponentialMovingAverage ema = new ExponentialMovingAverage(0.4);
assertEquals(10.0, ema.calculateEMA(10.0), 0.001); assertEquals(10.0, ema.calculateEMA(10.0), 0.001);
assertEquals(14.0, ema.calculateEMA(20.0), 0.001); assertEquals(14.0, ema.calculateEMA(20.0), 0.001);
@ -25,14 +26,14 @@ public class ExponentialMovingAverageUnitTest {
} }
@Test @Test
public void when_alpha_is_closer_to_one_EMA_should_respond_faster_to_changes() { public void whenAlphaIsCloserToOne_exponentialMovingAverageShouldRespondFasterToChanges() {
ExponentialMovingAverage ema1 = new ExponentialMovingAverage(0.2); ExponentialMovingAverage ema1 = new ExponentialMovingAverage(0.2);
ExponentialMovingAverage ema2 = new ExponentialMovingAverage(0.8); ExponentialMovingAverage ema2 = new ExponentialMovingAverage(0.8);
assertEquals(10.0, ema1.calculateEMA(10.0), 0.001); assertEquals(10.0, ema1.calculateEMA(10.0), 0.001);
assertEquals(10.0, ema2.calculateEMA(10.0), 0.001); assertEquals(10.0, ema2.calculateEMA(10.0), 0.001);
assertEquals(12.0, ema1.calculateEMA(20.0), 0.001); // Responds slower assertEquals(12.0, ema1.calculateEMA(20.0), 0.001);
assertEquals(18.0, ema2.calculateEMA(20.0), 0.001); // Responds faster assertEquals(18.0, ema2.calculateEMA(20.0), 0.001);
} }
} }

View File

@ -6,30 +6,30 @@ import static org.junit.Assert.assertEquals;
public class MovingAverageByCircularBufferUnitTest { public class MovingAverageByCircularBufferUnitTest {
@Test @Test
public void when_initial_average_is_calculated_it_should_be_zero() { public void whenInitialAverageIsCalculated_shouldReturnNAN() {
MovingAverageByCircularBuffer ma = new MovingAverageByCircularBuffer(5); MovingAverageByCircularBuffer ma = new MovingAverageByCircularBuffer(5);
assertEquals(Double.NaN, ma.getMovingAverage(), 0.001); // Empty buffer assertEquals(Double.NaN, ma.getMovingAverage(), 0.001);
} }
@Test @Test
public void when_values_are_added_average_should_update_correctly() { public void whenValuesAreAdded_shouldUpdateAverageCorrectly() {
MovingAverageByCircularBuffer ma = new MovingAverageByCircularBuffer(3); MovingAverageByCircularBuffer ma = new MovingAverageByCircularBuffer(3);
ma.add(10); ma.add(10);
assertEquals(10.0, ma.getMovingAverage(), 0.001); assertEquals(10.0, ma.getMovingAverage(), 0.001);
ma.add(20); ma.add(20);
assertEquals(15.0, ma.getMovingAverage(), 0.001); assertEquals(15.0, ma.getMovingAverage(), 0.001);
ma.add(30); ma.add(30);
assertEquals(20.0, ma.getMovingAverage(), 0.001); assertEquals(20.0, ma.getMovingAverage(), 0.001);
} }
@Test @Test
public void when_window_size_is_full_oldest_value_should_be_overwritten() { public void whenWindowSizeIsFull_shouldOverrideTheOldestValue() {
MovingAverageByCircularBuffer ma = new MovingAverageByCircularBuffer(2); MovingAverageByCircularBuffer ma = new MovingAverageByCircularBuffer(2);
ma.add(10); ma.add(10);
ma.add(20); ma.add(20);
assertEquals(15.0, ma.getMovingAverage(), 0.001); assertEquals(15.0, ma.getMovingAverage(), 0.001);
ma.add(30); // Overwrites 10 ma.add(30);
assertEquals(25.0, ma.getMovingAverage(), 0.001); assertEquals(25.0, ma.getMovingAverage(), 0.001);
} }
} }

View File

@ -7,13 +7,13 @@ import static org.junit.Assert.assertEquals;
public class MovingAverageWithApacheCommonsMathUnitTest { public class MovingAverageWithApacheCommonsMathUnitTest {
@Test @Test
public void when_initial_average_is_calculated_it_should_be_NAN() { public void whenInitialAverageIsCalculated_shouldReturnNAN() {
MovingAverageWithApacheCommonsMath movingAverageCalculator = new MovingAverageWithApacheCommonsMath(5); MovingAverageWithApacheCommonsMath movingAverageCalculator = new MovingAverageWithApacheCommonsMath(5);
assertEquals(Double.NaN, movingAverageCalculator.getMovingAverage(), 0.001); assertEquals(Double.NaN, movingAverageCalculator.getMovingAverage(), 0.001);
} }
@Test @Test
public void when_values_are_added_average_should_update_correctly() { public void whenValuesAreAdded_shouldUpdateAverageCorrectly() {
MovingAverageWithApacheCommonsMath movingAverageCalculator = new MovingAverageWithApacheCommonsMath(3); MovingAverageWithApacheCommonsMath movingAverageCalculator = new MovingAverageWithApacheCommonsMath(3);
movingAverageCalculator.add(10); movingAverageCalculator.add(10);
assertEquals(10.0, movingAverageCalculator.getMovingAverage(), 0.001); assertEquals(10.0, movingAverageCalculator.getMovingAverage(), 0.001);
@ -24,13 +24,13 @@ public class MovingAverageWithApacheCommonsMathUnitTest {
} }
@Test @Test
public void when_window_size_is_full_oldest_value_should_be_dropped() { public void whenWindowSizeIsFull_shouldDropTheOldestValue() {
MovingAverageWithApacheCommonsMath ma = new MovingAverageWithApacheCommonsMath(2); MovingAverageWithApacheCommonsMath ma = new MovingAverageWithApacheCommonsMath(2);
ma.add(10); ma.add(10);
ma.add(20); ma.add(20);
assertEquals(15.0, ma.getMovingAverage(), 0.001); assertEquals(15.0, ma.getMovingAverage(), 0.001);
ma.add(30); ma.add(30);
assertEquals(25.0, ma.getMovingAverage(), 0.001); // 10 dropped, 20 and 30 remain assertEquals(25.0, ma.getMovingAverage(), 0.001);
} }
} }