// Updates this model using the new price information in the specified security instance // Update is a mandatory method public void Update(Security security, BaseData data) { var timeSinceLastUpdate = data.EndTime - _lastUpdate; if (timeSinceLastUpdate >= _periodSpan && data.Price > 0m) { if (_lastPrice > 0) { _window.Add(data.Price / _lastPrice - 1.0m); _needsUpdate = _window.IsReady; } _lastUpdate = data.EndTime; _lastPrice = data.Price; } if (_window.Count() < 2) { Volatility = 0; return; } if (_needsUpdate) { _needsUpdate = false; var mean = _window.Average(); var std = Math.Sqrt((double)_window.Sum(x => (x - mean) * (x - mean)) / _window.Count()); Volatility = Convert.ToDecimal(std * Math.Sqrt(252d)); } }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="timeWindow"></param> /// <param name="window"></param> /// <param name="time"></param> /// <param name="input">The input given to the indicator</param> /// <returns> /// A new value for this indicator /// </returns> protected override DoubleArray Forward(IReadOnlyWindow <long> timeWindow, IReadOnlyWindow <DoubleArray> window, long time, DoubleArray input) { if (window.Count >= 3) { _multipliedDiffWindow.Add((window[0].Value - window[1].Value) * (window[1].Value - window[2].Value)); } // Estimate the indicator if less than 50% of observation are zero. Avoid division by // zero and estimations with few real observations in case of forward filled data. if (IsReady && _multipliedDiffWindow.Count(obs => Math.Abs(obs) < ZeroEpsilon) < 0.5 * _multipliedDiffWindow.Count) { var mc = _multipliedDiffWindow.Count(obs => obs > 0); var mRc = _multipliedDiffWindow.Count(obs => obs < 0); return(100.0d * mc / (mc + mRc)); } return(50.0d); }
double GetSuccessRatio() { return((pastPerf.Count() > 2) ? pastPerf.Where(x => x > 0).Count() * 1.0 / pastPerf.Count() : 0); }