protected override decimal ComputeNextValue(IndicatorDataPoint input) { double realPart = 0; double imagPart = 0; _prices.Add(input); if (!_prices.IsReady) { return(LeadDirection); } for (int i = 0; i < _period; i++) { double temp = (double)_prices[i].Value; realPart = realPart + temp * Math.Cos(2 * Math.PI * i / _period); imagPart = imagPart + temp * Math.Sin(2 * Math.PI * i / _period); } double phase1 = Math.Abs(realPart) > 0.001 ? Math.Atan(imagPart / realPart) : Math.PI / 2 * Math.Sign(imagPart); double phase2 = realPart < 0 ? phase1 + Math.PI : phase1; double phase = phase2 < 0 ? phase2 + 2 * Math.PI : phase2 > 2 * Math.PI ? phase2 - 2 * Math.PI : phase2; _sine.Update(input.EndTime, (decimal)Math.Cos(phase)); _lead.Update(input.EndTime, (decimal)Math.Cos(phase + Math.PI / 4)); _direction = _lead > _sine ? Direction.Up : _lead < _sine ? Direction.Down : _direction; return(LeadDirection); }
protected override decimal ComputeNextValue(IBaseDataBar input) { _bars.Add(input); if (!_bars.IsReady) { return(0m); } double beta = Math.Cos(2 * Math.PI / _period); double gamma = (1 / Math.Cos(4 * Math.PI * (double)_delta / _period)); double alpha = gamma - Math.Sqrt(Math.Pow(gamma, 2) - 1); double p0 = (double)(_bars[0].High + _bars[0].Low) / 2; double p2 = (double)(_bars[2].High + _bars[2].Low) / 2; double bp = _bps.IsReady ? 0.5 * (1 - alpha) * (p0 - p2) + beta * (1 + alpha) * _bps[0] - alpha * _bps[1] : 0.5 * (1 - alpha) * (p0 - p2); _bps.Add(bp); _bpMA.Update(input.Time, (decimal)bp); if (!_bps.IsReady) { return(0m); } double peak = _bps[1] > _bps[0] && _bps[1] > _bps[2] ? _bps[1] : (double)_peak.Current.Value; double valley = _bps[1] < _bps[0] && _bps[1] < _bps[2] ? _bps[1] : (double)_valley.Current.Value; _peak.Update(input.Time, (decimal)peak); _valley.Update(input.Time, (decimal)valley); _peakMA.Update(input.Time, (decimal)peak); _valleyMA.Update(input.Time, (decimal)valley); return(_bpMA.IsReady ? _bpMA : 0m); }
public void NewDataPushesToDerivedIndicators() { var identity = new Identity("identity"); var sma = new SimpleMovingAverage(3); identity.Updated += (sender, consolidated) => { sma.Update(consolidated); }; identity.Update(DateTime.UtcNow, 1m); identity.Update(DateTime.UtcNow, 2m); Assert.IsFalse(sma.IsReady); identity.Update(DateTime.UtcNow, 3m); Assert.IsTrue(sma.IsReady); Assert.AreEqual(2m, sma); }
protected override decimal ComputeNextValue(IBaseDataBar input) { _macd.Update(input.EndTime, input.Close); if (!_macd.IsReady) { return(0m); } var macdBar = new TradeBar { Time = input.Time, EndTime = input.EndTime, Open = _macd, High = _macd, Low = _macd, Close = _macd }; _frac1.Update(macdBar); if (!_frac1.IsReady) { return(0m); } var pf = _pf.IsReady ? _pf + (_factor * (_frac1.FastStoch - _pf)) : _frac1.FastStoch; _pf.Update(input.Time, pf); var pfBar = new TradeBar { Time = input.Time, EndTime = input.EndTime, Open = pf, High = pf, Low = pf, Close = pf }; _frac2.Update(pfBar); if (!_frac2.IsReady) { return(0m); } var pff = _pff.IsReady ? _pff + (_factor * (_frac2.FastStoch - _pff)) : _frac2.FastStoch; _pff.Update(input.Time, pff); return(pff); }
public void TestIdentityInvariants() { // the invariants of the identity indicator is to be ready after // a single sample has been added, and always produce the same value // as the last ingested value var identity = new Identity("test"); Assert.IsFalse(identity.IsReady); const decimal value = 1m; identity.Update(new IndicatorDataPoint(DateTime.UtcNow, value)); Assert.IsTrue(identity.IsReady); Assert.AreEqual(value, identity.Current.Value); }
public void CallsDelegateCorrectly() { var left = new Identity("left"); var right = new Identity("right"); var composite = new CompositeIndicator<IndicatorDataPoint>(left, right, (l, r) => { Assert.AreEqual(left, l); Assert.AreEqual(right, r); return l + r; }); left.Update(DateTime.Today, 1m); right.Update(DateTime.Today, 1m); Assert.AreEqual(2m, composite.Current.Value); }
public void ResetsProperly() { var identity = new Identity("test"); Assert.IsFalse(identity.IsReady); Assert.AreEqual(0m, identity.Current.Value); foreach (var data in TestHelper.GetDataStream(2)) { identity.Update(data); } Assert.IsTrue(identity.IsReady); Assert.AreEqual(2, identity.Samples); identity.Reset(); Assert.IsFalse(identity.IsReady); Assert.AreEqual(0, identity.Samples); }
public void PipesDataFirstWeightedBySecond() { const int period = 4; var value = new Identity("Value"); var weight = new Identity("Weight"); var third = value.WeightedBy(weight, period); var data = Enumerable.Range(1, 10).ToList(); var window = Enumerable.Reverse(data).Take(period); var current = window.Sum(x => 2 * x * x) / (decimal)window.Sum(x => x); foreach (var item in data) { value.Update(new IndicatorDataPoint(DateTime.UtcNow, Convert.ToDecimal(2 * item))); weight.Update(new IndicatorDataPoint(DateTime.UtcNow, Convert.ToDecimal(item))); } Assert.AreEqual(current, third.Current.Value); }
public void GoShortAndClosePosition() { int _period = 7; decimal _tolerance = 0.00001m; decimal _revertPct = 1.015m; DateTime time = DateTime.Now; # region Arrays inputs decimal[] prices = new decimal[20] { 91m, 91m, 91m, 91m, 91m, 91m, 92m, 93m, 94m, 95m, 96m, 97m, 98m, 99m, 100m, 85m, 84m, 83m, 100m, 100m, }; OrderSignal[] expectedOrders = new OrderSignal[20] { OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.goShortLimit , OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.closeShort }; # endregion OrderSignal[] actualOrders = new OrderSignal[expectedOrders.Length]; Identity priceIdentity = new Identity("IdentityIndicator"); ITrendStrategy strategy = new ITrendStrategy(priceIdentity, _period, _tolerance, _revertPct, RevertPositionCheck.vsClosePrice); for (int i = 0; i < prices.Length; i++) { priceIdentity.Update(new IndicatorDataPoint(time, prices[i])); actualOrders[i] = strategy.ActualSignal; if (actualOrders[i] == OrderSignal.goShortLimit) strategy.Position = StockState.shortPosition; Console.WriteLine(i + "| Actual Order:" + actualOrders[i]); time.AddDays(1); } Assert.AreEqual(expectedOrders, actualOrders); }
public void ResetsProperly() { DateTime time = DateTime.Parse("2000-01-01"); # region Arrays inputs decimal[] prices = new decimal[10] { 100m, 100m, 100m, 100m, 100m, 100m, 100m, 100m, 100m, 100m }; #endregion Identity priceIdentity = new Identity("IdentityIndicator"); ITrendStrategy strategy = new ITrendStrategy(priceIdentity, 5); for (int i = 0; i < prices.Length; i++) { priceIdentity.Update(new IndicatorDataPoint(time, prices[i])); time.AddDays(1); } Assert.IsTrue(strategy.ITrend.IsReady, "Instantaneous Trend Ready"); Assert.IsTrue(strategy.ITrendMomentum.IsReady, "Instantaneous Trend Momentum Ready"); Assert.IsTrue(strategy.MomentumWindow.IsReady, "Instantaneous Trend Momentum Window Ready"); strategy.Reset(); TestHelper.AssertIndicatorIsInDefaultState(strategy.ITrend); TestHelper.AssertIndicatorIsInDefaultState(strategy.ITrendMomentum); Assert.IsFalse(strategy.MomentumWindow.IsReady, "Instantaneous Trend Momentum Windows was Reset"); }
public void TestingTolerance() { int _period = 7; decimal _tolerance = 0.15m; decimal _revertPct = 1.015m; DateTime time = DateTime.Now; # region Arrays inputs decimal[] prices = new decimal[20] { 99m, 99m, 99m, 99m, 99m, 99m, 99.25m, 99.5m, 99.75m, 100m, 100.25m, 100.5m, 100.75m, 100m, 100m, 100.1m, 100.2m, 100.3m, 100.4m, 100.5m, }; OrderSignal[] expectedOrders = new OrderSignal[20] { OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.goShortLimit, OrderSignal.doNothing , OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing, OrderSignal.doNothing }; # endregion OrderSignal[] actualOrders = new OrderSignal[expectedOrders.Length]; Identity priceIdentity = new Identity("IdentityIndicator"); ITrendStrategy strategy = new ITrendStrategy(priceIdentity, _period, _tolerance, _revertPct, RevertPositionCheck.vsClosePrice); for (int i = 0; i < prices.Length; i++) { priceIdentity.Update(new IndicatorDataPoint(time, prices[i])); actualOrders[i] = strategy.ActualSignal; Console.WriteLine(i + "| Actual Order:" + actualOrders[i]); time.AddDays(1); } Assert.AreEqual(expectedOrders, actualOrders); }
public void MSAFullTest() { #region Fields int idx = 0; int day = 0; DateTime Time = DateTime.Today; DateTime testTime = Time; double amplitude = 1; int shift = 100; int waveLength = 45; IndicatorDataPoint ssObs; Indicator smoothedSeries = new Identity("SmoothedSeries"); MSAStrategy strategy = new MSAStrategy(smoothedSeries, 2, 3, 0m); #endregion Fields #region Warming up Console.WriteLine("Warming up"); do { ssObs = new IndicatorDataPoint(testTime, SineWave(idx, amplitude * idx, waveLength, shift)); smoothedSeries.Update(ssObs); testTime = testTime.AddMinutes(1); idx++; if (idx > 59) { day++; testTime = Time.AddDays(day); idx = 0; switch (day) { case 1: amplitude = 2; shift = 150; waveLength = 15; break; case 2: amplitude = 1.5; shift = 100; waveLength = 20; break; case 3: amplitude = 3; shift = 180; waveLength = 12; break; default: break; } Console.WriteLine("New day: " + day); } } while (!strategy.IsReady); Console.WriteLine("Strategy ready!\nStarting signal test."); #endregion Warming up #region Testing signals var expectedSignals = new Dictionary<int, OrderSignal>(); expectedSignals.Add(34, OrderSignal.goLong); expectedSignals.Add(40, OrderSignal.goShort); expectedSignals.Add(46, OrderSignal.goLong); expectedSignals.Add(52, OrderSignal.goShort); expectedSignals.Add(58, OrderSignal.goLong); for (int i = 0; i < 60; i++) { ssObs = new IndicatorDataPoint(testTime, SineWave(i, amplitude * i, waveLength, shift)); smoothedSeries.Update(ssObs); Console.WriteLine(string.Format("{0}\t|\t{1}\t|\t{2}", i, ssObs.Value.SmartRounding(), strategy.ActualSignal )); if (expectedSignals.ContainsKey(i)) { Assert.AreEqual(expectedSignals[i], strategy.ActualSignal, string.Format("Bar {0} test.", i)); } else { Assert.AreEqual(OrderSignal.doNothing, strategy.ActualSignal, string.Format("Bar {0} test.", i)); } testTime = testTime.AddMinutes(1); } #endregion Testing signals }
public void MultiChainEMA() { var identity = new Identity("identity"); var delay = new Delay(2); // create the EMA of chained methods var ema = delay.Of(identity).EMA(2, 1); // Assert.IsTrue(ema. == 1); identity.Update(DateTime.UtcNow, 1m); Assert.IsTrue(identity.IsReady); Assert.IsFalse(delay.IsReady); Assert.IsFalse(ema.IsReady); identity.Update(DateTime.UtcNow, 2m); Assert.IsTrue(identity.IsReady); Assert.IsFalse(delay.IsReady); Assert.IsFalse(ema.IsReady); identity.Update(DateTime.UtcNow, 3m); Assert.IsTrue(identity.IsReady); Assert.IsTrue(delay.IsReady); Assert.IsFalse(ema.IsReady); identity.Update(DateTime.UtcNow, 4m); Assert.IsTrue(identity.IsReady); Assert.IsTrue(delay.IsReady); Assert.IsTrue(ema.IsReady); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(TradeBar input) { _price.Update(input.EndTime, (input.Open + input.High + input.Low + input.Value) / 4); _volume.Update(input.EndTime, input.Volume); return(_vwap.Current.Value); }
public void MultiChainMIN() { var identity = new Identity("identity"); var delay = new Delay(2); // create the MIN of the delay of the identity var min = delay.Of(identity).MIN(2); identity.Update(DateTime.UtcNow, 1m); Assert.IsTrue(identity.IsReady); Assert.IsFalse(delay.IsReady); Assert.IsFalse(min.IsReady); identity.Update(DateTime.UtcNow, 2m); Assert.IsTrue(identity.IsReady); Assert.IsFalse(delay.IsReady); Assert.IsFalse(min.IsReady); identity.Update(DateTime.UtcNow, 3m); Assert.IsTrue(identity.IsReady); Assert.IsTrue(delay.IsReady); Assert.IsFalse(min.IsReady); identity.Update(DateTime.UtcNow, 4m); Assert.IsTrue(identity.IsReady); Assert.IsTrue(delay.IsReady); Assert.IsTrue(min.IsReady); }
public void OverHandlesDivideByZero() { var left = new Identity("left"); var right = new Identity("right"); var composite = left.Over(right); var updatedEventFired = false; composite.Updated += delegate { updatedEventFired = true; }; left.Update(DateTime.Today, 1m); Assert.IsFalse(updatedEventFired); right.Update(DateTime.Today, 0m); Assert.IsFalse(updatedEventFired); // submitting another update to right won't cause an update without corresponding update to left right.Update(DateTime.Today, 1m); Assert.IsFalse(updatedEventFired); left.Update(DateTime.Today, 1m); Assert.IsTrue(updatedEventFired); }
public void TimesMultipliesLeftAndRightAfterBothUpdated() { var left = new Identity("left"); var right = new Identity("right"); var composite = left.Times(right); left.Update(DateTime.Today, 1m); right.Update(DateTime.Today, 1m); Assert.AreEqual(1m, composite.Current.Value); left.Update(DateTime.Today, 2m); Assert.AreEqual(1m, composite.Current.Value); left.Update(DateTime.Today, 3m); Assert.AreEqual(1m, composite.Current.Value); right.Update(DateTime.Today, 4m); Assert.AreEqual(12m, composite.Current.Value); }
public void MinusSubtractsLeftAndRightAfterBothUpdated() { var left = new Identity("left"); var right = new Identity("right"); var composite = left.Minus(right); left.Update(DateTime.Today, 1m); right.Update(DateTime.Today, 1m); Assert.AreEqual(0m, composite.Current.Value); left.Update(DateTime.Today, 2m); Assert.AreEqual(0m, composite.Current.Value); left.Update(DateTime.Today, 3m); Assert.AreEqual(0m, composite.Current.Value); right.Update(DateTime.Today, 4m); Assert.AreEqual(-1m, composite.Current.Value); }
/// <summary> /// Computes the next value of this indicator from the given state /// </summary> /// <param name="input">The input given to the indicator</param> /// <returns>A new value for this indicator</returns> protected override decimal ComputeNextValue(TradeBar input) { _price.Update(input.EndTime, GetTimeWeightedAveragePrice(input)); _volume.Update(input.EndTime, input.Volume); return(_vwap.Current.Value); }
public void MultiChain() { var identity = new Identity("identity"); var sma = new SimpleMovingAverage(2); var delay = new Delay(2); // create the SMA of the delay of the identity sma.Of(delay.Of(identity)); identity.Update(DateTime.UtcNow, 1m); Assert.IsTrue(identity.IsReady); Assert.IsFalse(delay.IsReady); Assert.IsFalse(sma.IsReady); identity.Update(DateTime.UtcNow, 2m); Assert.IsTrue(identity.IsReady); Assert.IsFalse(delay.IsReady); Assert.IsFalse(sma.IsReady); identity.Update(DateTime.UtcNow, 3m); Assert.IsTrue(identity.IsReady); Assert.IsTrue(delay.IsReady); Assert.IsFalse(sma.IsReady); identity.Update(DateTime.UtcNow, 4m); Assert.IsTrue(identity.IsReady); Assert.IsTrue(delay.IsReady); Assert.IsTrue(sma.IsReady); Assert.AreEqual(1.5m, sma); }