/// <summary> /// Pushes the tick into this enumerator. This tick will be aggregated into a quote bar /// and emitted after the alotted time has passed /// </summary> /// <param name="data">The new data to be aggregated</param> public void ProcessData(BaseData data) { QuoteBar working; var tick = data as Tick; var qty = tick == null ? 0 : tick.Quantity; var bidPrice = tick == null ? data.Value : tick.BidPrice; var askPrice = tick == null ? data.Value : tick.AskPrice; var bidSize = tick == null ? 0m : tick.BidSize; var askSize = tick == null ? 0m : tick.AskSize; if (!_queue.TryPeek(out working)) { // the consumer took the working bar, or time ticked over into next bar var utcNow = _timeProvider.GetUtcNow(); var currentLocalTime = utcNow.ConvertFromUtc(_timeZone); var barStartTime = currentLocalTime.RoundDown(_barSize); working = new QuoteBar(); working.Update(data.Value, bidPrice, askPrice, qty, bidSize, askSize); working.Period = _barSize; working.Time = barStartTime; working.Symbol = data.Symbol; _queue.Enqueue(working); if (_liveMode) { _realTimeScheduleEventService.ScheduleEvent(_barSize.Subtract(currentLocalTime - barStartTime), utcNow); } } else { // we're still within this bar size's time working.Update(data.Value, bidPrice, askPrice, qty, bidSize, askSize); } }
public void FillsForwardBidAskBars() { var bar1 = new QuoteBar { Bid = new Bar(3m, 4m, 1m, 2m), Ask = new Bar(3.1m, 4.1m, 1.1m, 2.1m), }; var bar2 = new QuoteBar { Bid = null, Ask = null, }; var data = new[] { bar1, bar2 }.ToList(); var enumerator = data.GetEnumerator(); var fillForwardEnumerator = new QuoteBarFillForwardEnumerator(enumerator); // 9:31 Assert.IsTrue(fillForwardEnumerator.MoveNext()); var quoteBar1 = (QuoteBar)fillForwardEnumerator.Current; Assert.AreSame(bar1.Bid, quoteBar1.Bid); Assert.AreSame(bar1.Ask, quoteBar1.Ask); // 9:32 Assert.IsTrue(fillForwardEnumerator.MoveNext()); var quoteBar2 = (QuoteBar)fillForwardEnumerator.Current; Assert.AreSame(quoteBar1.Bid, quoteBar2.Bid); Assert.AreSame(quoteBar1.Ask, quoteBar2.Ask); fillForwardEnumerator.Dispose(); }
public void AccessesByDataType() { var now = DateTime.UtcNow; var tradeBar = new TradeBar { Symbol = Symbols.SPY, Time = now }; var unlinkedData = new UnlinkedData { Symbol = Symbols.SPY, Time = now }; var quoteBar = new QuoteBar { Symbol = Symbols.SPY, Time = now }; var tick = new Tick(now, Symbols.SPY, 1.1m, 2.1m) { TickType = TickType.Trade }; var openInterest = new OpenInterest(now, Symbols.SPY, 1); var split = new Split(Symbols.SPY, now, 1, 1, SplitType.SplitOccurred); var delisting = new Delisting(Symbols.SPY, now, 1, DelistingType.Delisted); var slice = new Slice(now, new BaseData[] { quoteBar, tradeBar, unlinkedData, tick, split, delisting, openInterest }); Assert.AreEqual(slice.Get(typeof(TradeBar))[Symbols.SPY], tradeBar); Assert.AreEqual(slice.Get(typeof(UnlinkedData))[Symbols.SPY], unlinkedData); Assert.AreEqual(slice.Get(typeof(QuoteBar))[Symbols.SPY], quoteBar); Assert.AreEqual(slice.Get(typeof(Tick))[Symbols.SPY], tick); Assert.AreEqual(slice.Get(typeof(Split))[Symbols.SPY], split); Assert.AreEqual(slice.Get(typeof(Delisting))[Symbols.SPY], delisting); Assert.AreEqual(slice.Get(typeof(OpenInterest))[Symbols.SPY], openInterest); }
public void AdjustQuoteBar() { var qb = new QuoteBar( new DateTime(2018, 1, 1), _config.Symbol, new Bar(10, 10, 10, 10), 100, new Bar(10, 10, 10, 10), 100); var factor = 0.5m; var adjustedQb = qb.Clone(qb.IsFillForward).Adjust(_factor); Assert.AreEqual(qb.Value, qb.Close); // bid Assert.AreEqual(qb.Bid.Open * _factor, (adjustedQb as QuoteBar).Bid.Open); Assert.AreEqual(qb.Bid.Close * _factor, (adjustedQb as QuoteBar).Bid.Close); Assert.AreEqual(qb.Bid.High * _factor, (adjustedQb as QuoteBar).Bid.High); Assert.AreEqual(qb.Bid.Low * _factor, (adjustedQb as QuoteBar).Bid.Low); // ask Assert.AreEqual(qb.Ask.Open * _factor, (adjustedQb as QuoteBar).Ask.Open); Assert.AreEqual(qb.Ask.Close * _factor, (adjustedQb as QuoteBar).Ask.Close); Assert.AreEqual(qb.Ask.High * _factor, (adjustedQb as QuoteBar).Ask.High); Assert.AreEqual(qb.Ask.Low * _factor, (adjustedQb as QuoteBar).Ask.Low); }
public void LatestPriceFillModel_UsesLatestPrice() { var symbol = Symbol.Create("BTCUSD", SecurityType.Crypto, "GDAX"); var time = new DateTime(2017, 1, 3, 0, 0, 0); var nextTime = time.AddSeconds(1); var quote = new QuoteBar(time, symbol, new Bar(1, 1, 1, 1), 1, new Bar(2, 2, 2, 2), 2); var trade = new TradeBar(nextTime, symbol, 3, 3, 3, 3, 3); var cryptoSecurity = new Security(SecurityExchangeHours.AlwaysOpen(DateTimeZone.Utc), new SubscriptionDataConfig(typeof(QuoteBar), symbol, Resolution.Second, TimeZones.Utc, TimeZones.Utc, true, true, false), new Cash(CashBook.AccountCurrency, 0, 1m), SymbolProperties.GetDefault(CashBook.AccountCurrency)); cryptoSecurity.Cache.AddData(quote); cryptoSecurity.Cache.AddData(trade); var price = _fillModel.GetPrices(cryptoSecurity, OrderDirection.Sell); Assert.AreEqual(3, price.Open); Assert.AreEqual(3, price.High); Assert.AreEqual(3, price.Low); Assert.AreEqual(3, price.Close); Assert.AreEqual(3, price.Current); }
public void AccessesByDataType() { var tradeBar = new TradeBar { Symbol = Symbols.SPY, Time = DateTime.UtcNow }; var quandl = new Quandl { Symbol = Symbols.SPY, Time = DateTime.Now }; var quoteBar = new QuoteBar { Symbol = Symbols.SPY, Time = DateTime.Now }; var tick = new Tick(DateTime.Now, Symbols.SPY, 1.1m, 2.1m) { TickType = TickType.Trade }; var split = new Split(Symbols.SPY, DateTime.UtcNow, 1, 1, SplitType.SplitOccurred); var delisting = new Delisting(Symbols.SPY, DateTime.UtcNow, 1, DelistingType.Delisted); var slice = new Slice(DateTime.UtcNow, new BaseData[] { quoteBar, tradeBar, quandl, tick, split, delisting }); Assert.AreEqual(slice.Get(typeof(TradeBar))[Symbols.SPY], tradeBar); Assert.AreEqual(slice.Get(typeof(Quandl))[Symbols.SPY], quandl); Assert.AreEqual(slice.Get(typeof(QuoteBar))[Symbols.SPY], quoteBar); Assert.AreEqual(slice.Get(typeof(Tick))[Symbols.SPY], tick); Assert.AreEqual(slice.Get(typeof(Split))[Symbols.SPY], split); Assert.AreEqual(slice.Get(typeof(Delisting))[Symbols.SPY], delisting); }
public void PythonSlice_get_default() { using (Py.GIL()) { dynamic test = PythonEngine.ModuleFromString("testModule", @" from clr import AddReference AddReference(""QuantConnect.Common"") from QuantConnect import * def Test(slice, symbol, default_value): return slice.get(symbol, default_value)").GetAttr("Test"); var pythonSlice = GetPythonSlice(); var expected = new QuoteBar { Symbol = Symbols.EURUSD, Time = DateTime.Now, Value = 9 }; PyObject result = null; Assert.DoesNotThrow(() => result = test(GetPythonSlice(), Symbols.EURUSD, expected)); BaseData actual; Assert.IsTrue(result.TryConvert(out actual)); Assert.AreEqual(expected.Symbol, actual.Symbol); Assert.AreEqual(expected.Value, actual.Value); } }
public void EquitiesIgnoreQuoteBars() { var quoteBar = new QuoteBar { Symbol = Symbols.SPY, Time = DateTime.Now }; var slice = new Slice(DateTime.Now, new[] { quoteBar }); Assert.IsFalse(slice.HasData); Assert.IsTrue(slice.ToList().Count == 0); Assert.IsFalse(slice.ContainsKey(Symbols.SPY)); Assert.Throws <KeyNotFoundException>(() => { var data = slice[Symbols.SPY]; }); Assert.AreEqual(0, slice.Count); var tickQuoteBar = new Tick { Symbol = Symbols.SPY, Time = DateTime.Now, TickType = TickType.Quote }; slice = new Slice(DateTime.Now, new[] { tickQuoteBar }); Assert.IsFalse(slice.HasData); Assert.IsTrue(slice.ToList().Count == 0); Assert.IsFalse(slice.ContainsKey(Symbols.SPY)); Assert.Throws <KeyNotFoundException>(() => { var data = slice[Symbols.SPY]; }); Assert.AreEqual(0, slice.Count); }
private void OnFiveMinutes(object sender, QuoteBar consolidated) { if (!_alma.IsReady || !_psar.IsReady) { return; } if (!Portfolio[symbol].HoldStock) { if (consolidated.Close < _alma && _psar > consolidated.High) { SetHoldings(symbol, -1m); } else if (consolidated.Close > _alma && _psar < consolidated.Low) { SetHoldings(symbol, 1m); } } else { if (Portfolio[symbol].IsLong && consolidated.Close < _psar) { SetHoldings(symbol, 0m); } else if (Portfolio[symbol].IsShort && consolidated.Close > _psar) { SetHoldings(symbol, 0m); } } }
private void DataConsolidated(object sender, QuoteBar e) { var quantity = Math.Truncate((Portfolio.Cash + Portfolio.TotalFees) / Math.Abs(e.Value + 1)); if (!Portfolio.Invested) { Order("BTCUSD", quantity); } else if (Portfolio["BTCUSD"].Quantity == quantity) { Order("BTCUSD", 0.1); } else if (Portfolio["BTCUSD"].Quantity == quantity + 0.1m) { Order("BTCUSD", 0.01); } else if (Portfolio["BTCUSD"].Quantity == quantity + 0.11m) { Order("BTCUSD", -0.02); } else if (Portfolio["BTCUSD"].Quantity == quantity + 0.09m) { //should fail Order("BTCUSD", 0.001); SetHoldings("BTCUSD", -2.0m); SetHoldings("BTCUSD", 2.0m); Quit(); } }
public void RemovePendingLimitOrders(QuoteBar data = null) { foreach (var tradeProfile in _tradeProfiles.Where((oe) => oe.OpenTicket.OrderType == OrderType.Limit)) { var timeComparison = data == null ? 1 : -1; if (data != null) { var orderEvent = tradeProfile.OpenTicket.OrderEvents.First(); var endTime = data.EndTime.ToUniversalTime(); var orderEventTime = orderEvent.UtcTime.Subtract(TimeSpan.FromHours(6)); var span = endTime.Subtract(orderEventTime); timeComparison = span.CompareTo(TimeSpan.FromMinutes(45)); } if (tradeProfile.OpenTicket.Status != OrderStatus.Filled && timeComparison >= 0) { try { tradeProfile.OpenTicket.Cancel(); tradeProfile.StopTicket.Cancel(); } catch (Exception ex) { Console.WriteLine(ex.Message); } tradeProfile.IsTradeFinished = true; } } }
private void MessageEvent(string json) { if (SymbolUpdate == default) { return; } JArray jArray = JArray.Parse(json); string ticker = jArray[0].ToString(); json = jArray[1].ToString(); JObject jo = JObject.Parse(json); long updated = (long)jo["Updated"]; DateTime utcTime = Support.ToTime(updated); string ticker2 = jo["Symbol"].ToString(); string rates = jo["Rates"].ToString(); JArray jRates = JArray.Parse(rates); decimal bid = jRates[0].ToDecimal(); decimal ask = jRates[1].ToDecimal(); decimal high = jRates[2].ToDecimal(); decimal low = jRates[3].ToDecimal(); var bidBar = new Bar(0, 0, 0, bid); var askBar = new Bar(0, 0, 0, ask); var symbol = Symbol.Create(ticker, SecurityType.Forex, Support.Market); var quoteBar = new QuoteBar(utcTime, symbol, bidBar, 0, askBar, 0); SymbolUpdate(quoteBar); }
/// <summary> /// Advances the enumerator to the next element of the collection. /// </summary> /// <returns> /// true if the enumerator was successfully advanced to the next element; false if the enumerator has passed the end of the collection. /// </returns> /// <exception cref="T:System.InvalidOperationException">The collection was modified after the enumerator was created. </exception> public bool MoveNext() { if (!_enumerator.MoveNext()) { return(false); } var bar = _enumerator.Current as QuoteBar; if (bar != null) { if (_previous != null) { if (bar.Bid == null) { bar.Bid = _previous.Bid; } if (bar.Ask == null) { bar.Ask = _previous.Ask; } } _previous = bar; } Current = _enumerator.Current; return(true); }
public void AccessesTradeBarAndQuoteBarForSameSymbol() { var tradeBar = new TradeBar(DateTime.Now, Symbols.BTCUSD, 3000, 3000, 3000, 3000, 100, Time.OneMinute); var quoteBar = new QuoteBar(DateTime.Now, Symbols.BTCUSD, new Bar(3100, 3100, 3100, 3100), 0, new Bar(3101, 3101, 3101, 3101), 0, Time.OneMinute); var tradeBars = new TradeBars { { Symbols.BTCUSD, tradeBar } }; var quoteBars = new QuoteBars { { Symbols.BTCUSD, quoteBar } }; var slice = new Slice(DateTime.Now, new BaseData[] { tradeBar, quoteBar }, tradeBars, quoteBars, null, null, null, null, null, null, null); var tradeBarData = slice.Get<TradeBar>(); Assert.AreEqual(1, tradeBarData.Count); Assert.AreEqual(3000, tradeBarData[Symbols.BTCUSD].Close); var quoteBarData = slice.Get<QuoteBar>(); Assert.AreEqual(1, quoteBarData.Count); Assert.AreEqual(3100, quoteBarData[Symbols.BTCUSD].Bid.Close); Assert.AreEqual(3101, quoteBarData[Symbols.BTCUSD].Ask.Close); slice = new Slice(DateTime.Now, new BaseData[] { tradeBar, quoteBar }); tradeBarData = slice.Get<TradeBar>(); Assert.AreEqual(1, tradeBarData.Count); Assert.AreEqual(3000, tradeBarData[Symbols.BTCUSD].Close); quoteBarData = slice.Get<QuoteBar>(); Assert.AreEqual(1, quoteBarData.Count); Assert.AreEqual(3100, quoteBarData[Symbols.BTCUSD].Bid.Close); Assert.AreEqual(3101, quoteBarData[Symbols.BTCUSD].Ask.Close); }
public void ThrowsWhenPeriodIsSmallerThanDataPeriod() { QuoteBar quoteBar = null; using var creator = new QuoteBarConsolidator(Time.OneHour); creator.DataConsolidated += (sender, args) => { quoteBar = args; }; var time = new DateTime(2022, 6, 6, 13, 30, 1); var bar1 = new QuoteBar { Time = time, Symbol = Symbols.SPY, Bid = new Bar(1, 2, 0.75m, 1.25m), LastBidSize = 3, Ask = null, LastAskSize = 0, Value = 1, Period = TimeSpan.FromDays(1) }; Assert.Throws <ArgumentException>(() => creator.Update(bar1)); }
public void AdjustQuoteBarUsingConfig() { var qb = new QuoteBar( new DateTime(2018, 1, 1), _config.Symbol, new Bar(10, 10, 10, 10), 100, new Bar(10, 10, 10, 10), 100); var adjustedQb = qb.Clone(qb.IsFillForward).Normalize(_config); Assert.AreEqual(qb.Value, qb.Close); // bid Assert.AreEqual(qb.Bid.Open * _factor, (adjustedQb as QuoteBar).Bid.Open); Assert.AreEqual(qb.Bid.Close * _factor, (adjustedQb as QuoteBar).Bid.Close); Assert.AreEqual(qb.Bid.High * _factor, (adjustedQb as QuoteBar).Bid.High); Assert.AreEqual(qb.Bid.Low * _factor, (adjustedQb as QuoteBar).Bid.Low); Assert.AreEqual(qb.LastBidSize / _factor, (adjustedQb as QuoteBar).LastBidSize); // ask Assert.AreEqual(qb.Ask.Open * _factor, (adjustedQb as QuoteBar).Ask.Open); Assert.AreEqual(qb.Ask.Close * _factor, (adjustedQb as QuoteBar).Ask.Close); Assert.AreEqual(qb.Ask.High * _factor, (adjustedQb as QuoteBar).Ask.High); Assert.AreEqual(qb.Ask.Low * _factor, (adjustedQb as QuoteBar).Ask.Low); Assert.AreEqual(qb.LastAskSize / _factor, (adjustedQb as QuoteBar).LastAskSize); }
public void RespectsWritePolicy(WritePolicy?writePolicy, Resolution resolution) { var filePath = LeanData.GenerateZipFilePath(_dataDirectory, _crypto, _date, resolution, TickType.Quote); if (File.Exists(filePath)) { File.Delete(filePath); } var loopCount = 3; var dataPointsPerLoop = 2; for (var i = 0; i < loopCount; i++) { var leanDataWriter = new LeanDataWriter(resolution, _crypto, _dataDirectory, TickType.Quote, writePolicy: writePolicy); var quoteBar = new QuoteBar(Parse.DateTime("3/16/2017 12:00:00 PM").AddHours(i), _crypto, new Bar(1m, 2m, 3m, 4m), 1, new Bar(5m, 6m, 7m, 8m), 2); // same quote twice! it has the same time, so it will be dropped when merging leanDataWriter.Write(Enumerable.Repeat(quoteBar, dataPointsPerLoop)); Assert.IsTrue(File.Exists(filePath)); Assert.IsFalse(File.Exists(filePath + ".tmp")); } var data = QuantConnect.Compression.Unzip(filePath).First().Value; switch (writePolicy) { case WritePolicy.Overwrite: Assert.AreEqual(dataPointsPerLoop, data.Count); break; case WritePolicy.Merge: Assert.AreEqual(loopCount, data.Count); break; case WritePolicy.Append: Assert.AreEqual(dataPointsPerLoop * loopCount, data.Count); break; case null: if (resolution >= Resolution.Hour) { // will merge by default Assert.AreEqual(loopCount, data.Count); } else { // overwrite Assert.AreEqual(dataPointsPerLoop, data.Count); } break; default: throw new ArgumentOutOfRangeException(nameof(writePolicy), writePolicy, null); } }
public void LastCloseAndCurrentOpenPriceShouldBeSameConsolidatedOnCount() { QuoteBar quoteBar = null; var creator = new TickQuoteBarConsolidator(2); creator.DataConsolidated += (sender, args) => { quoteBar = args; }; var reference = DateTime.Today; var tick1 = new Tick { Symbol = Symbols.SPY, Time = reference, TickType = TickType.Quote, AskPrice = 0, BidPrice = 24, }; creator.Update(tick1); var tick2 = new Tick { Symbol = Symbols.SPY, Time = reference, TickType = TickType.Quote, AskPrice = 25, BidPrice = 0, }; creator.Update(tick2); // bar 1 emitted Assert.AreEqual(tick2.AskPrice, quoteBar.Ask.Open); Assert.AreEqual(tick1.BidPrice, quoteBar.Bid.Open); Assert.AreEqual(tick2.AskPrice, quoteBar.Ask.Close); Assert.AreEqual(tick1.BidPrice, quoteBar.Bid.Close); var tick3 = new Tick { Symbol = Symbols.SPY, Time = reference.AddSeconds(1), TickType = TickType.Quote, AskPrice = 36, BidPrice = 35, }; creator.Update(tick3); creator.Update(tick3); // bar 2 emitted // ask is from tick 2 Assert.AreEqual(tick2.AskPrice, quoteBar.Ask.Open, "Ask Open not equal to Previous Close"); // bid is from tick 1 Assert.AreEqual(tick1.BidPrice, quoteBar.Bid.Open, "Bid Open not equal to Previous Close"); Assert.AreEqual(tick3.AskPrice, quoteBar.Ask.Close, "Ask Close incorrect"); Assert.AreEqual(tick3.BidPrice, quoteBar.Bid.Close, "Bid Close incorrect"); }
public void QuoteBarParseDoesNotScaleOptionsWithNonEquityUnderlying() { var factory = new QuoteBar(); var underlying = Symbol.CreateFuture("ES", QuantConnect.Market.CME, new DateTime(2021, 3, 19)); var optionSymbol = Symbol.CreateOption( underlying, QuantConnect.Market.CME, OptionStyle.American, OptionRight.Put, 4200m, SecurityIdentifier.DefaultDate); var config = new SubscriptionDataConfig( typeof(QuoteBar), optionSymbol, Resolution.Minute, TimeZones.Chicago, TimeZones.Chicago, true, false, false, false, TickType.Quote, true, DataNormalizationMode.Raw); var quoteLine = "40560000,1.0,1.5,1.0,1.5,90.0,1.0,1.5,1.0,1.5,100.0"; var stream = new StreamReader(new MemoryStream(Encoding.UTF8.GetBytes(quoteLine))); var unscaledQuoteBarFromLine = (QuoteBar)factory.Reader(config, quoteLine, new DateTime(2020, 9, 22), false); var unscaledQuoteBarFromStream = (QuoteBar)factory.Reader(config, stream, new DateTime(2020, 9, 22), false); Assert.AreEqual(new DateTime(2020, 9, 22, 11, 17, 0), unscaledQuoteBarFromLine.EndTime); Assert.AreEqual(optionSymbol, unscaledQuoteBarFromLine.Symbol); Assert.AreEqual(1m, unscaledQuoteBarFromLine.Bid.Open); Assert.AreEqual(1.5m, unscaledQuoteBarFromLine.Bid.High); Assert.AreEqual(1m, unscaledQuoteBarFromLine.Bid.Low); Assert.AreEqual(1.5m, unscaledQuoteBarFromLine.Bid.Close); Assert.AreEqual(90m, unscaledQuoteBarFromLine.LastBidSize); Assert.AreEqual(1m, unscaledQuoteBarFromLine.Ask.Open); Assert.AreEqual(1.5m, unscaledQuoteBarFromLine.Ask.High); Assert.AreEqual(1m, unscaledQuoteBarFromLine.Ask.Low); Assert.AreEqual(1.5m, unscaledQuoteBarFromLine.Ask.Close); Assert.AreEqual(100m, unscaledQuoteBarFromLine.LastAskSize); Assert.AreEqual(new DateTime(2020, 9, 22, 11, 17, 0), unscaledQuoteBarFromStream.EndTime); Assert.AreEqual(optionSymbol, unscaledQuoteBarFromStream.Symbol); Assert.AreEqual(1m, unscaledQuoteBarFromStream.Bid.Open); Assert.AreEqual(1.5m, unscaledQuoteBarFromStream.Bid.High); Assert.AreEqual(1m, unscaledQuoteBarFromStream.Bid.Low); Assert.AreEqual(1.5m, unscaledQuoteBarFromStream.Bid.Close); Assert.AreEqual(90m, unscaledQuoteBarFromStream.LastBidSize); Assert.AreEqual(1m, unscaledQuoteBarFromStream.Ask.Open); Assert.AreEqual(1.5m, unscaledQuoteBarFromStream.Ask.High); Assert.AreEqual(1m, unscaledQuoteBarFromStream.Ask.Low); Assert.AreEqual(1.5m, unscaledQuoteBarFromStream.Ask.Close); Assert.AreEqual(100m, unscaledQuoteBarFromStream.LastAskSize); }
public void EnterTradeSignal(QuoteBar data, bool isWarmingUp) { EnterSignal.Scan(data); if (!isWarmingUp && IsTradable && (EnterSignal.Signal == SignalType.Long || EnterSignal.Signal == SignalType.Short) && _security.Exchange.ExchangeOpen) { //Creates a new trade profile once it enters a trade var profile = new TradeProfile(_symbol, _security.VolatilityModel.Volatility, _risk, data.Price, _maximumTradeSize); if (!profile.IsSpreadTradable(data)) { return; } profile.ExitSignal = ExitSignal.ExitSignalFactory(profile); if (profile.Quantity > 0 && _tradeProfiles.Count == 0) { var hmmPrediction = 1m;// _hmmPositionSizing.PredictionRisk(); var quantity = (int)((int)EnterSignal.Signal * profile.Quantity * hmmPrediction); var askLimit = data.Ask.Close - (1m / 10000m); var bidLimit = data.Bid.Close + (1m / 10000m); var limitPrice = EnterSignal.Signal == SignalType.Long ? askLimit : bidLimit; try { profile.OpenTicket = _orderMethods.MarketOrder(_symbol, quantity, false, ((int)EnterSignal.Signal).ToString()); //profile.OpenTicket = _orderMethods.LimitOrder(_symbol, quantity, OrderUtil.RoundOrderPrices(_security, limitPrice), ((int)EnterSignal.Signal).ToString()); var stopPrice = data.Close - (int)EnterSignal.Signal * profile.DeltaStopLoss; profile.StopTicket = _orderMethods.StopMarketOrder(_symbol, -quantity, OrderUtil.RoundOrderPrices(_security, stopPrice)); } catch (Exception ex) { Console.WriteLine(ex.Message); } //var stopPrice = profile.OpenTicket.AverageFillPrice - (int)EnterSignal.Signal * profile.DeltaStopLoss; /*Console.WriteLine("{0} {1} {2} {3}", * profile.OpenTicket.OrderEvents.Select((oe) => oe.Direction).First() == OrderDirection.Buy ? "Buy " : "Sell", * profile.OpenTicket.AverageFillPrice, * profile.StopTicket.Get(OrderField.StopPrice), * Math.Abs(data.Ask.Close - data.Bid.Close) * 10000 * );*/ /*profile.StopTicket = _orderMethods.StopLimitOrder(_symbol, -(int) EnterSignal.Signal * profile.Quantity, * profile.OpenTicket.AverageFillPrice - (int) EnterSignal.Signal * profile.DeltaStopLoss, * profile.OpenTicket.AverageFillPrice - (int) EnterSignal.Signal * profile.DeltaStopLoss);*/ _tradeProfiles.Add(profile); } } }
public void PlotSignal(QuoteBar current, int prediction, double logLikelihood) { Plot("Prediction", "Pred", prediction); Plot("Probability", "Prob", logLikelihood); Plot("Plotter", "Price", current.Value); Plot("Plotter", "EMA", _ema[current.Symbol]); Plot("Plotter", "Prediction", prediction); Plot("Plotter", "Probability", logLikelihood); }
public void ExitTradeSignal(QuoteBar data) { foreach (var tradeProfile in _tradeProfiles.Where(x => !x.IsTradeFinished)) { tradeProfile.ExitSignal.Scan(data); var timedExit = false; try { var orderEvent = tradeProfile.OpenTicket.OrderEvents.FirstOrDefault((oe) => oe.Status == OrderStatus.Filled); if (orderEvent != null) { var endTime = data.EndTime.ToUniversalTime(); var orderEventTime = orderEvent.UtcTime.Subtract(TimeSpan.FromHours(6)); var span = endTime.Subtract(orderEventTime); var timeComparison = span.CompareTo(TimeSpan.FromMinutes(270)); // TODO: Timed Exit //timedExit = timeComparison > 0 && OrderUtil.IsUnprofitable(data.Close, orderEvent); } } catch (Exception ex) { Console.Error.WriteLine(ex); } if ((tradeProfile.ExitSignal.Signal == SignalType.Exit || EnterSignal.Signal == SignalType.Exit || EnterSignal.Signal == SignalType.Reverse || timedExit) && tradeProfile.StopTicket.Status != OrderStatus.Filled && _security.Exchange.ExchangeOpen) { try { //Console.WriteLine("Quantity: {0}", tradeProfile.OpenTicket.QuantityFilled); if (tradeProfile.OpenTicket.QuantityFilled != 0) { tradeProfile.ExitTicket = _orderMethods.MarketOrder(_symbol, -(int)tradeProfile.OpenTicket.QuantityFilled, false, ((int)EnterSignal.Signal).ToString()); //tradeProfile.ExitTicket = _orderMethods.LimitOrder(_symbol, -(int) tradeProfile.OpenTicket.QuantityFilled, data.Price); } else { tradeProfile.OpenTicket.Cancel(); } tradeProfile.StopTicket.Cancel(); } catch (Exception ex) { Console.WriteLine(ex.Message); } tradeProfile.IsTradeFinished = true; } } }
public void Scan(QuoteBar data) { /*if (Signal == SignalType.PendingLong && data.Close > _shortTermMA) * { * Signal = SignalType.Long; * } * else if (Signal == SignalType.PendingShort && data.Close < _shortTermMA) * { * Signal = SignalType.Short; * }*/ }
public void Scan(QuoteBar data) { if (_tradeProfile.ProfitLossRatio > _targetProfitLossRatio) { Signal = SignalType.Exit; } else { Signal = SignalType.NoSignal; } }
public void PlotSignal(QuoteBar current, decimal ema, decimal slope, decimal stc, decimal stoch, int prediction, int signal) { Plot("Plotter", "Close", current.Close); Plot("Plotter", "EMA", ema); Plot("Plotter", "Diff", (current.Close - ema) * 10000m); Plot("Plotter", "Slope", slope); Plot("Plotter", "STC", stc); Plot("Plotter", "STOCH", stoch); Plot("Plotter", "Prediction", prediction); Plot("Plotter", "Signal", signal); }
public void Setup() { var time = new DateTime(2017, 1, 3, 0, 0, 0); var nextTime = time.AddSeconds(1); _symbol = Symbol.Create("BTCUSD", SecurityType.Crypto, "GDAX"); _quote = new QuoteBar(time, _symbol, new Bar(1, 1, 1, 1), 1, new Bar(2, 2, 2, 2), 2); _trade = new TradeBar(nextTime, _symbol, 3, 3, 3, 3, 3); _fillModel = new TestableLatestFillModel(); }
private static void UpdateContract(FuturesContract contract, QuoteBar quote) { if (quote.Ask != null && quote.Ask.Close != 0m) { contract.AskPrice = quote.Ask.Close; contract.AskSize = (long)quote.LastAskSize; } if (quote.Bid != null && quote.Bid.Close != 0m) { contract.BidPrice = quote.Bid.Close; contract.BidSize = (long)quote.LastBidSize; } }
/// <summary> /// Immediately submits orders for the specified portfolio targets. /// </summary> /// <param name="algorithm">The algorithm instance</param> /// <param name="targets">The portfolio targets to be ordered</param> public override void Execute(QCAlgorithmFramework algorithm, IPortfolioTarget[] targets) { //So target.Quantity represents the ABSOLUTE holding value in the portfolio (usually based on indicator magnitude) // - the execution model should seek to bring the portfolio in line with it. _targetsCollection.AddRange(targets); foreach (var target in _targetsCollection.OrderByMarginImpact(algorithm)) { //only care about derivatives if (!target.Symbol.HasUnderlying) { continue; } var existing = algorithm.Securities[target.Symbol].Holdings.Quantity + algorithm.Transactions.GetOpenOrders(target.Symbol).Sum(o => o.Quantity); decimal quantity = target.Quantity - existing; if (quantity != 0) { if (target.Quantity == 0) { //CLOSING a position, we want to do so immediately //TODO: maybe skew it? algorithm.MarketOrder(target.Symbol, quantity); } else if (MinutesTilClose(algorithm) <= 30) { algorithm.MarketOrder(target.Symbol, target.Quantity); } else { //Adding or entering new position QuoteBar quote = algorithm.CurrentSlice[target.Symbol]; algorithm.LimitOrder(target.Symbol, quantity, Math.Round(quote.Bid.Close + (quote.Ask.Close - quote.Bid.Close) / 2, 2)); } } } //TODO: try resubmitting the order to closer to the spread as time goes by before cancelling/market ordering //convert to market order within 30 mins foreach (var order in algorithm.Transactions.GetOpenOrders(o => (algorithm.CurrentSlice.Time - o.CreatedTime).TotalMinutes >= 30)) { algorithm.Transactions.CancelOrder(order.Id); algorithm.MarketOrder(order.Symbol, order.Quantity); } _targetsCollection.Clear(); }
/// <summary> /// Gets the history for the requested securities /// </summary> /// <param name="requests">The historical data requests</param> /// <param name="sliceTimeZone">The time zone used when time stamping the slice instances</param> /// <returns>An enumerable of the slices of data covering the span specified in each request</returns> public override IEnumerable <Slice> GetHistory(IEnumerable <HistoryRequest> requests, DateTimeZone sliceTimeZone) { List <Slice> result = new(); var slice1Date = new DateTime(2008, 01, 03, 5, 0, 0); var slice2Date = new DateTime(2013, 06, 28, 13, 32, 0); TradeBar tradeBar1 = new TradeBar { Symbol = Symbols.SPY, Time = DateTime.Now }; TradeBar tradeBar2 = new TradeBar { Symbol = Symbols.AAPL, Time = DateTime.Now }; var quoteBar1 = new QuoteBar { Symbol = Symbols.SPY, Time = DateTime.Now }; var tick1 = new Tick(DateTime.Now, Symbols.SPY, 1.1m, 2.1m) { TickType = TickType.Trade }; var split1 = new Split(Symbols.SPY, DateTime.Now, 1, 1, SplitType.SplitOccurred); var dividend1 = new Dividend(Symbols.SPY, DateTime.Now, 1, 1); var delisting1 = new Delisting(Symbols.SPY, DateTime.Now, 1, DelistingType.Delisted); var symbolChangedEvent1 = new SymbolChangedEvent(Symbols.SPY, DateTime.Now, "SPY", "SP"); Slice slice1 = new Slice(slice1Date, new BaseData[] { tradeBar1, tradeBar2, quoteBar1, tick1, split1, dividend1, delisting1, symbolChangedEvent1 }, slice1Date); TradeBar tradeBar3 = new TradeBar { Symbol = Symbols.MSFT, Time = DateTime.Now }; TradeBar tradeBar4 = new TradeBar { Symbol = Symbols.SBIN, Time = DateTime.Now }; var quoteBar2 = new QuoteBar { Symbol = Symbols.SBIN, Time = DateTime.Now }; var tick2 = new Tick(DateTime.Now, Symbols.SBIN, 1.1m, 2.1m) { TickType = TickType.Trade }; var split2 = new Split(Symbols.SBIN, DateTime.Now, 1, 1, SplitType.SplitOccurred); var dividend2 = new Dividend(Symbols.SBIN, DateTime.Now, 1, 1); var delisting2 = new Delisting(Symbols.SBIN, DateTime.Now, 1, DelistingType.Delisted); var symbolChangedEvent2 = new SymbolChangedEvent(Symbols.SBIN, DateTime.Now, "SBIN", "BIN"); Slice slice2 = new Slice(slice2Date, new BaseData[] { tradeBar3, tradeBar4, quoteBar2, tick2, split2, dividend2, delisting2, symbolChangedEvent2 }, slice2Date); result.Add(slice1); result.Add(slice2); return(result); }
public void Scan(QuoteBar data) { _signal.Scan(data); if (_signal.Signal != _previousSignalType) { Signal = _signal.Signal; } else { Signal = SignalType.NoSignal; } _previousSignalType = _signal.Signal; }