public void ResetsProperly() { // ema reset is just setting the value and samples back to 0 var ema = new ExponentialMovingAverage(3); foreach (var data in TestHelper.GetDataStream(5)) { ema.Update(data); } Assert.IsTrue(ema.IsReady); Assert.AreNotEqual(0m, ema.Current.Value); Assert.AreNotEqual(0, ema.Samples); ema.Reset(); TestHelper.AssertIndicatorIsInDefaultState(ema); }
/// <summary> /// Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized. /// </summary> public override void Initialize() { SetStartDate(2013, 10, 07); //Set Start Date SetEndDate(2013, 10, 11); //Set End Date SetCash(100000); //Set Strategy Cash // Find more symbols here: http://quantconnect.com/data AddSecurity(SecurityType.Forex, "EURUSD", Resolution.Second); fast = EMA("EURUSD", 60); slow = EMA("EURUSD", 3600); // 3601 because rolling window waits for one to fall off the back to be considered ready var history = History("EURUSD", 3601); foreach (var bar in history) { fast.Update(bar.EndTime, bar.Close); slow.Update(bar.EndTime, bar.Close); } Log(string.Format("FAST IS {0} READY. Samples: {1}", fast.IsReady ? "" : "NOT", fast.Samples)); Log(string.Format("SLOW IS {0} READY. Samples: {1}", slow.IsReady ? "" : "NOT", slow.Samples)); }
public void EMAComputesCorrectly() { const int period = 4; decimal[] values = {1m, 10m, 100m, 1000m}; const decimal expFactor = 2m/(1m + period); var ema4 = new ExponentialMovingAverage(period); decimal current = 0m; for (int i = 0; i < values.Length; i++) { ema4.Update(new IndicatorDataPoint(DateTime.UtcNow.AddSeconds(i), values[i])); if (i == 0) { current = values[i]; } else { current = values[i]*expFactor + (1 - expFactor)*current; } Assert.AreEqual(current, ema4.Current.Value); } }
/// <summary> /// /// </summary> /// <param name="window"></param> /// <param name="input"></param> /// <returns></returns> protected override decimal ComputeNextValue(IReadOnlyWindow <IndicatorDataPoint> window, IndicatorDataPoint input) { decimal hfp; decimal instPeriod; decimal quadrature; decimal currentInPhase; decimal previousInPhase; decimal deltaPhase; decimal medianDeltaPhase; decimal DC; // for convenience var time = input.Time; if (window.IsReady) { _smooth.Add((window[0].Value + 2 * window[1].Value + 2 * window[2].Value + window.MostRecentlyRemoved) / 6); if (!_cycle.IsReady) { // If cycle isn't ready then fill it with a FIR. _cycle.Add((window[0].Value - 2 * window[1].Value + window[2].Value) / 4); } else { // Once is ready, calculate the cycle. hfp = _A * (_smooth[0] - 2 * _smooth[1] + _smooth[2]) + 2 * _B * _cycle[0] - (_B * _B) * _cycle[1]; _cycle.Add(hfp); // Quadrature calculation. instPeriod = 0.5m + 0.08m * _instPeriod.Current.Value; quadrature = (_quadCoeffA * _cycle[0] + _quadCoeffB * _cycle[2] - _quadCoeffB * _cycle[4] - _quadCoeffA * _cycle.MostRecentlyRemoved) * instPeriod; _quadrature.Add(quadrature); currentInPhase = _cycle[3]; previousInPhase = _cycle[4]; // DeltaPhase calculation. if (_quadrature.IsReady && (_quadrature[0] != 0 && _quadrature[1] != 0)) { deltaPhase = (currentInPhase / _quadrature[0] - previousInPhase / _quadrature[1]) / (1 - currentInPhase * previousInPhase / (_quadrature[0] * _quadrature[1])); } else { deltaPhase = 1; } if (deltaPhase < 0.1m) { _deltaPhase.Add(0.1m); // Minimun frequency (longest cycle) 63 bars } else if (deltaPhase > 1.1m) { _deltaPhase.Add(1.1m); } else { _deltaPhase.Add(deltaPhase); } if (_deltaPhase.IsReady) { medianDeltaPhase = Median(_deltaPhase); } else { medianDeltaPhase = 0; } if (medianDeltaPhase == 0) { DC = 15m; } else { DC = 2 * pi / medianDeltaPhase + 0.5m; } _instPeriod.Update(idp(time, DC)); _period.Update(idp(time, _instPeriod.Current)); } } return(_period.Current); }
/// <summary> /// /// </summary> /// <param name="window"></param> /// <param name="input"></param> /// <returns></returns> protected override decimal ComputeNextValue(IReadOnlyWindow <IndicatorDataPoint> window, IndicatorDataPoint input) { decimal hfp; //decimal instPeriod; //decimal quadrature; //decimal currentInPhase; //decimal previousInPhase; //decimal deltaPhase; //decimal medianDeltaPhase; //decimal DC; // for convenience var time = input.Time; // and assume an 8 bar Period _Period.Add(8.0); if (!window.IsReady) { _smooth.Add(window[0].Value); } else { _smooth.Add((window[0].Value + 2 * window[1].Value + 2 * window[2].Value + window.MostRecentlyRemoved) / 6); if (!_cycle.IsReady) { // If cycle isn't ready then fill it with a FIR. _cycle.Add((window[0].Value - 2 * window[1].Value + window[2].Value) / 4); _Quadrature.Add(_cycle[0]); _InPhase.Add(_cycle[0]); _Q2.Add(_cycle[0]); _I2.Add(_cycle[0]); _re.Add(_cycle[0]); _im.Add(_cycle[0]); } else { // Once is ready, calculate the cycle. //hfp = _A * (_smooth[0] - 2 * _smooth[1] + _smooth[2]) + 2 * _B * _cycle[0] - (_B * _B) * _cycle[1]; _cycle.Add(Detrend(_smooth)); // Detrend and InPhase calculation. //instPeriod = (decimal)(.075 * _Period[1] + .54); _Quadrature.Add(Detrend(_cycle)); _InPhase.Add(_cycle[3]); // Advance the phase of InPhase and Detrend by 90 degrees var jI = Detrend(_InPhase); var jQ = Detrend(_Quadrature); // Phasor addition for 3 bar averaging _I2.Add(_InPhase[0] - jQ); _Q2.Add(_Quadrature[0] + jI); // Smooth he I and Q components before applying the discriminator _I2[0] = .2m * _I2[0] + .8m * _I2[1]; _Q2[0] = .2m * _Q2[0] + .8m * _Q2[1]; // Homodyne Discriminator _re.Add(_I2[0] * _I2[1] + _Q2[0] * _Q2[1]); _im.Add(_I2[0] * _Q2[1] - _Q2[1] * _I2[1]); double re = (double)_re[0]; double im = (double)_im[0]; if (_re.Count > 1) { re = (double)(.2m * _re[0] + .8m * _re[1]); im = (double)(.2m * _im[0] + .8m * _im[1]); } if (im != 0.0 && re != 0.0) { _Period[0] = 360 / Math.Atan(im / re); } if (_Period[0] > 1.5 * _Period[1]) { _Period[0] = 1.5 * _Period[1]; } if (_Period[0] < 0.67 * _Period[1]) { _Period[0] = 0.67 * _Period[1]; } if (_Period[0] < 6.0) { _Period[0] = 6.0; } if (_Period[0] > 50.0) { _Period[0] = 50.0; } } _Period[0] = .2 * _Period[0] + .8 * _Period[1]; // the .2 alpha EMA of itself } _SmoothPeriod.Update(idp(time, (decimal)_Period[0])); // the .33 alpha EMA of the Period return(_SmoothPeriod.Current.Value); }