Lean icon indicating copy to clipboard operation
Lean copied to clipboard

ExponentialMovingAverage first value calculation

Open jhonabreul opened this issue 3 years ago • 0 comments

Expected Behavior

When testing TSI and TRIX indicators (which depend on EMA) against TradingView data, tests don't pass. According to TradingView's description of EMA, the first value after the indicator is warmed up (Samples == period) should be calculated as a SMA of the first N=period elements. Other references also indicate this (StockCharts, Investopedia 1, Investopedia 2, Sciencing, Corporate Finance Institute, TheTradingBible, WarrorTrading, Groww, Ashtrade).

After changing ExponentialMovingAverage to return 0 during the warmup period, the SMA of the first N=period samples as the first elements and then using the EMA formula for the following samples, tests pass for the TradingView data:

https://github.com/QuantConnect/Lean/blob/0bc087954e9358565eb9cffed53a508f01015580/Indicators/ExponentialMovingAverage.cs#L99

Actual Behavior

Currently, Lean's EMA indicator returns identity for the first sample and then uses the formula for the following ones, even during the warmup period: https://github.com/QuantConnect/Lean/blob/0bc087954e9358565eb9cffed53a508f01015580/Indicators/ExponentialMovingAverage.cs#L95-L99

This way of computing EMA is described here and that is how is is implemented in CRAN's pracma package in R.

Potential Solution

The idea would be to study which way of computing EMA is the right one. In case the SMA approach is correct, the solution would include changing EMA indicator to wait for the warmup period and then start the EMA calculation with the SMA of the first N=period samples.

Also, this would require checking that all the indicators that use or depend on EMA pass their own tests as well.

Reproducing the Problem

Export TSI or TRIX data from TradingView and run tests agains it, it will fail. Now, change EMA to the following, and tests should now pass:

if (Samples <= _period)
{
    return ((Samples - 1) * Current.Value + input.Value) * Samples;
}

return input.Value * _k + Current.Value * (1 - _k);

System Information

N/A

Checklist

  • [x] I have completely filled out this template
  • [x] I have confirmed that this issue exists on the current master branch
  • [x] I have confirmed that this is not a duplicate issue by searching issues
  • [x] I have provided detailed steps to reproduce the issue

jhonabreul avatar May 12 '22 20:05 jhonabreul