/// <summary> /// Event handler for streaming ticks /// </summary> /// <param name="json">The data object containing the received tick</param> private void OnPricingDataReceived(string json) { var obj = (JObject)JsonConvert.DeserializeObject(json); var type = obj["type"].ToString(); switch (type) { case "HEARTBEAT": PricingConnectionHandler.KeepAlive(DateTime.UtcNow); break; case "PRICE": var data = obj.ToObject <Price>(); var securityType = SymbolMapper.GetBrokerageSecurityType(data.Instrument); var symbol = SymbolMapper.GetLeanSymbol(data.Instrument, securityType, Market.Oanda); var time = GetTickDateTimeFromString(data.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 = data.Bids.Last().Price.ConvertInvariant <decimal>(); var askPrice = data.Asks.Last().Price.ConvertInvariant <decimal>(); var tick = new Tick(time, symbol, bidPrice, askPrice); EmitTick(tick); break; } }
/// <summary> /// Converts an Oanda order into a LEAN order. /// </summary> private Order ConvertOrder(JToken order) { var type = order["type"].ToString(); Order qcOrder; var instrument = order["instrument"].ToString(); var id = order["id"].ToString(); var units = order["units"].ConvertInvariant <decimal>(); var createTime = order["createTime"].ToString(); var securityType = SymbolMapper.GetBrokerageSecurityType(instrument); var symbol = SymbolMapper.GetLeanSymbol(instrument, securityType, Market.Oanda); var time = GetTickDateTimeFromString(createTime); var quantity = units; switch (type) { case "MARKET_IF_TOUCHED": var stopOrder = order.ToObject <MarketIfTouchedOrder>(); qcOrder = new StopMarketOrder { StopPrice = stopOrder.Price.ToDecimal() }; break; case "LIMIT": var limitOrder = order.ToObject <OandaLimitOrder>(); qcOrder = new LimitOrder(symbol, quantity, limitOrder.Price.ToDecimal(), time); break; case "STOP": var stopLimitOrder = order.ToObject <StopOrder>(); var price = stopLimitOrder.Price.ConvertInvariant <decimal>(); var limitPrice = stopLimitOrder.PriceBound.ConvertInvariant <decimal>(); qcOrder = new StopLimitOrder(symbol, quantity, price, limitPrice, time); break; case "MARKET": qcOrder = new MarketOrder(); break; default: throw new NotSupportedException( "An existing " + type + " working order was found and is currently unsupported. Please manually cancel the order before restarting the algorithm."); } qcOrder.Status = OrderStatus.None; qcOrder.BrokerId.Add(id); var gtdTime = order["gtdTime"]; if (gtdTime != null) { var expiry = GetTickDateTimeFromString(gtdTime.ToString()); qcOrder.Properties.TimeInForce = TimeInForce.GoodTilDate(expiry); } return(qcOrder); }
/// <summary> /// Converts the Oanda position into a QuantConnect holding. /// </summary> /// <param name="position">The position.</param> /// <returns></returns> private Holding ConvertHolding(Position position) { var securityType = SymbolMapper.GetBrokerageSecurityType(position.instrument); return(new Holding { Symbol = SymbolMapper.GetLeanSymbol(position.instrument, securityType, Market.Oanda), Type = securityType, AveragePrice = (decimal)position.avgPrice, CurrencySymbol = "$", Quantity = position.side == "sell" ? -position.units : position.units }); }
/// <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()) { lock (LockerConnectionMonitor) { LastHeartbeatUtcTime = 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); lock (Ticks) { Ticks.Add(tick); } }
/// <summary> /// Converts an Oanda order into a LEAN order. /// </summary> private Order ConvertOrder(JToken order) { var type = order["type"].ToString(); Order qcOrder; switch (type) { case "MARKET_IF_TOUCHED": var stopOrder = order.ToObject <MarketIfTouchedOrder>(); qcOrder = new StopMarketOrder { StopPrice = stopOrder.Price.ToDecimal() }; break; case "LIMIT": var limitOrder = order.ToObject <OandaLimitOrder>(); qcOrder = new LimitOrder { LimitPrice = limitOrder.Price.ToDecimal() }; break; case "STOP": var stopLimitOrder = order.ToObject <StopOrder>(); qcOrder = new StopLimitOrder { Price = Convert.ToDecimal(stopLimitOrder.Price), LimitPrice = Convert.ToDecimal(stopLimitOrder.PriceBound) }; break; case "MARKET": qcOrder = new MarketOrder(); break; default: throw new NotSupportedException( "An existing " + type + " working order was found and is currently unsupported. Please manually cancel the order before restarting the algorithm."); } var instrument = order["instrument"].ToString(); var id = order["id"].ToString(); var units = Convert.ToInt32(order["units"]); var createTime = order["createTime"].ToString(); var securityType = SymbolMapper.GetBrokerageSecurityType(instrument); qcOrder.Symbol = SymbolMapper.GetLeanSymbol(instrument, securityType, Market.Oanda); qcOrder.Time = GetTickDateTimeFromString(createTime); qcOrder.Quantity = units; qcOrder.Status = OrderStatus.None; qcOrder.BrokerId.Add(id); var orderByBrokerageId = OrderProvider.GetOrderByBrokerageId(id); if (orderByBrokerageId != null) { qcOrder.Id = orderByBrokerageId.Id; } var gtdTime = order["gtdTime"]; if (gtdTime != null) { qcOrder.Duration = OrderDuration.Custom; qcOrder.DurationValue = GetTickDateTimeFromString(gtdTime.ToString()); } return(qcOrder); }
/// <summary> /// Converts the specified Oanda order into a qc order. /// The 'task' will have a value if we needed to issue a rest call for the stop price, otherwise it will be null /// </summary> private Order ConvertOrder(RestV1.DataType.Order order) { Order qcOrder; switch (order.type) { case "limit": qcOrder = new LimitOrder(); if (order.side == "buy") { ((LimitOrder)qcOrder).LimitPrice = Convert.ToDecimal(order.lowerBound); } if (order.side == "sell") { ((LimitOrder)qcOrder).LimitPrice = Convert.ToDecimal(order.upperBound); } break; case "stop": qcOrder = new StopLimitOrder(); if (order.side == "buy") { ((StopLimitOrder)qcOrder).LimitPrice = Convert.ToDecimal(order.lowerBound); } if (order.side == "sell") { ((StopLimitOrder)qcOrder).LimitPrice = Convert.ToDecimal(order.upperBound); } break; case "marketIfTouched": //when market reaches the price sell at market. qcOrder = new StopMarketOrder { Price = Convert.ToDecimal(order.price), StopPrice = Convert.ToDecimal(order.price) }; break; case "market": qcOrder = new MarketOrder(); break; default: throw new NotSupportedException("The Oanda order type " + order.type + " is not supported."); } var securityType = SymbolMapper.GetBrokerageSecurityType(order.instrument); qcOrder.Symbol = SymbolMapper.GetLeanSymbol(order.instrument, securityType, Market.Oanda); qcOrder.Quantity = ConvertQuantity(order); qcOrder.Status = OrderStatus.None; qcOrder.BrokerId.Add(order.id.ToString()); var orderByBrokerageId = OrderProvider.GetOrderByBrokerageId(order.id); if (orderByBrokerageId != null) { qcOrder.Id = orderByBrokerageId.Id; } var expiry = XmlConvert.ToDateTime(order.expiry, XmlDateTimeSerializationMode.Utc); qcOrder.Properties.TimeInForce = TimeInForce.GoodTilDate(expiry); qcOrder.Time = XmlConvert.ToDateTime(order.time, XmlDateTimeSerializationMode.Utc); return(qcOrder); }