/// <summary> /// Downloads a list of TradeBars at the requested resolution /// </summary> /// <param name="symbol">The symbol</param> /// <param name="startTimeUtc">The starting time (UTC)</param> /// <param name="endTimeUtc">The ending time (UTC)</param> /// <param name="resolution">The requested resolution</param> /// <param name="requestedTimeZone">The requested timezone for the data</param> /// <returns>The list of bars</returns> public override IEnumerable <TradeBar> DownloadTradeBars(Symbol symbol, DateTime startTimeUtc, DateTime endTimeUtc, Resolution resolution, DateTimeZone requestedTimeZone) { var oandaSymbol = SymbolMapper.GetBrokerageSymbol(symbol); var startUtc = startTimeUtc.ToString("yyyy-MM-ddTHH:mm:ssZ"); var candles = GetCandles(oandaSymbol, startUtc, OandaBrokerage.MaxBarsPerRequest, resolution, ECandleFormat.midpoint); foreach (var candle in candles) { var time = OandaBrokerage.GetDateTimeFromString(candle.time); if (time > endTimeUtc) { break; } yield return(new TradeBar( time.ConvertFromUtc(requestedTimeZone), symbol, Convert.ToDecimal(candle.openMid), Convert.ToDecimal(candle.highMid), Convert.ToDecimal(candle.lowMid), Convert.ToDecimal(candle.closeMid), 0, resolution.ToTimeSpan())); } }
/// <summary> /// Event handler for streaming ticks /// </summary> /// <param name="data">The data object containing the received tick</param> private void OnDataReceived(RateStreamResponse data) { if (data.IsHeartbeat()) { PricingConnectionHandler.KeepAlive(DateTime.UtcNow); return; } if (data.tick == null) { return; } var securityType = SymbolMapper.GetBrokerageSecurityType(data.tick.instrument); var symbol = SymbolMapper.GetLeanSymbol(data.tick.instrument, securityType, Market.Oanda); var time = OandaBrokerage.GetDateTimeFromString(data.tick.time); // live ticks timestamps must be in exchange time zone DateTimeZone exchangeTimeZone; if (!_symbolExchangeTimeZones.TryGetValue(symbol, out exchangeTimeZone)) { exchangeTimeZone = MarketHoursDatabase.FromDataFolder().GetExchangeHours(Market.Oanda, symbol, securityType).TimeZone; _symbolExchangeTimeZones.Add(symbol, exchangeTimeZone); } time = time.ConvertFromUtc(exchangeTimeZone); var bidPrice = Convert.ToDecimal(data.tick.bid); var askPrice = Convert.ToDecimal(data.tick.ask); var tick = new Tick(time, symbol, bidPrice, askPrice); EmitTick(tick); }
/// <summary> /// Downloads a list of QuoteBars at the requested resolution /// </summary> /// <param name="symbol">The symbol</param> /// <param name="startTimeUtc">The starting time (UTC)</param> /// <param name="endTimeUtc">The ending time (UTC)</param> /// <param name="resolution">The requested resolution</param> /// <param name="requestedTimeZone">The requested timezone for the data</param> /// <returns>The list of bars</returns> public override IEnumerable <QuoteBar> DownloadQuoteBars(Symbol symbol, DateTime startTimeUtc, DateTime endTimeUtc, Resolution resolution, DateTimeZone requestedTimeZone) { var oandaSymbol = SymbolMapper.GetBrokerageSymbol(symbol); var startUtc = startTimeUtc.ToString("yyyy-MM-ddTHH:mm:ssZ"); // Oanda only has 5-second bars, we return these for Resolution.Second var period = resolution == Resolution.Second ? TimeSpan.FromSeconds(5) : resolution.ToTimeSpan(); var candles = GetCandles(oandaSymbol, startUtc, OandaBrokerage.MaxBarsPerRequest, resolution, ECandleFormat.bidask); foreach (var candle in candles) { var time = OandaBrokerage.GetDateTimeFromString(candle.time); if (time > endTimeUtc) { break; } yield return(new QuoteBar( time.ConvertFromUtc(requestedTimeZone), symbol, new Bar( Convert.ToDecimal(candle.openBid), Convert.ToDecimal(candle.highBid), Convert.ToDecimal(candle.lowBid), Convert.ToDecimal(candle.closeBid) ), 0, new Bar( Convert.ToDecimal(candle.openAsk), Convert.ToDecimal(candle.highAsk), Convert.ToDecimal(candle.lowAsk), Convert.ToDecimal(candle.closeAsk) ), 0, period)); } }
/// <summary> /// Returns a DateTime from an RFC3339 string (with high resolution) /// </summary> /// <param name="time">The time string</param> private static DateTime GetTickDateTimeFromString(string time) { // remove nanoseconds, DateTime.ParseExact will throw with 9 digits after seconds return(OandaBrokerage.GetDateTimeFromString(time.Remove(25, 3))); }