// 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)); } }
public void WhenComputing_Then_ResultIsTheSumOfAllDataInTheWindow() { const int period = 5; var sut = new SumComputation(); var window = new RollingWindow <double>(period); for (int i = 0; i < 2 * period; i++) { window.Add(i); var result = sut.Compute(window); Assert.AreEqual(window.Sum(), result); } }
public void OnData(TradeBars data) { if (!_slow.IsReady) { _volume.Add(Securities[Symbol].Volume); _price.Add(Securities[Symbol].Price); return; } var averageVolume = _volume.Sum() / _volume.Count; var volumeSignal = Securities[Symbol].Volume > averageVolume || _volume.Skip(_volume.Count - 7).Any(av => av > averageVolume); var holdings = Portfolio[Symbol].Quantity; if (_openStopMarketOrder != null && _openStopMarketOrder.Status != OrderStatus.Filled) { if (_openStopMarketOrder.Tag.Equals("long") && _price[0] < Securities[Symbol].Price) { var newLongLimit = Securities[Symbol].Price * (1 - 0.05m); _openStopMarketOrder.Update(new UpdateOrderFields { StopPrice = newLongLimit }); } else if (_openStopMarketOrder.Tag.Equals("short") && _price[0] > Securities[Symbol].Price) { var newShortLimit = Securities[Symbol].Price * 1.05m; _openStopMarketOrder.Update(new UpdateOrderFields { StopPrice = newShortLimit }); } } else if (holdings <= 0 && _fast > _slow * (1 + tolerance) && volumeSignal) { Log("BUY >> " + Securities[Symbol].Price); //SetHoldings(Symbol, 1.0); var orderTicket = StopMarketOrder(Symbol, (int)(Portfolio.Cash / Securities[Symbol].Price), Securities[Symbol].Price * (1 - 0.05m), "long"); _openStopMarketOrder?.Cancel(); _openStopMarketOrder = orderTicket; } else if (holdings >= 0 && _fast < _slow * (1 - tolerance) && volumeSignal) { Log("SELL >> " + Securities[Symbol].Price); //SetHoldings(Symbol, -1.0); var shortAmount = Portfolio[Symbol].HoldingsValue == 0 ? Portfolio.Cash : Portfolio[Symbol].HoldingsValue; var orderTicket = StopMarketOrder(Symbol, -(int)(shortAmount / Securities[Symbol].Price), Securities[Symbol].Price * 1.05m, "short"); _openStopMarketOrder?.Cancel(); _openStopMarketOrder = orderTicket; } _volume.Add(Securities[Symbol].Volume); _price.Add(Securities[Symbol].Price); Plot("SMA Cross", "400", _slow.RollingSum / _slow.Period); Plot("SMA Cross", "100", _fast.RollingSum / _fast.Period); Plot("SMA Cross", "Price", Securities[Symbol].Price); }