示例#1
0
        /// <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()));
            }
        }
示例#2
0
        /// <summary>
        /// Updates the order with the same id
        /// </summary>
        /// <param name="order">The new order information</param>
        /// <returns>True if the request was made for the order to be updated, false otherwise</returns>
        public override bool UpdateOrder(Order order)
        {
            Log.Trace("OandaBrokerage.UpdateOrder(): " + order);

            if (!order.BrokerId.Any())
            {
                // we need the brokerage order id in order to perform an update
                Log.Trace("OandaBrokerage.UpdateOrder(): Unable to update order without BrokerId.");
                return(false);
            }

            var requestParams = new Dictionary <string, string>
            {
                { "instrument", SymbolMapper.GetBrokerageSymbol(order.Symbol) },
                { "units", order.AbsoluteQuantity.ConvertInvariant <int>().ToStringInvariant() },
            };

            // we need the brokerage order id in order to perform an update
            PopulateOrderRequestParameters(order, requestParams);

            if (UpdateOrder(Parse.Long(order.BrokerId.First()), requestParams))
            {
                OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, OrderFee.Zero)
                {
                    Status = OrderStatus.UpdateSubmitted
                });
            }

            return(true);
        }
示例#3
0
        /// <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.ToStringInvariant("yyyy-MM-ddTHH:mm:ssZ");
            var endUtc      = endTimeUtc.ToStringInvariant("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 response = _apiRest.GetInstrumentCandles(Authorization, oandaSymbol, null, "M", ToGranularity(resolution).ToString(), null, startUtc, endUtc);

            foreach (var candle in response.Candles)
            {
                var time = GetTickDateTimeFromString(candle.Time);
                if (time > endTimeUtc)
                {
                    break;
                }

                yield return(new TradeBar(
                                 time.ConvertFromUtc(requestedTimeZone),
                                 symbol,
                                 candle.Bid.O.ToDecimal(),
                                 candle.Bid.H.ToDecimal(),
                                 candle.Bid.L.ToDecimal(),
                                 candle.Bid.C.ToDecimal(),
                                 0,
                                 period));
            }
        }
示例#4
0
        /// <summary>
        /// Converts an Oanda position into a LEAN holding.
        /// </summary>
        private Holding ConvertHolding(Position position)
        {
            var securityType = SymbolMapper.GetBrokerageSecurityType(position.Instrument);
            var symbol       = SymbolMapper.GetLeanSymbol(position.Instrument, securityType, Market.Oanda);

            var longUnits  = position._Long.Units.ConvertInvariant <int>();
            var shortUnits = position._Short.Units.ConvertInvariant <int>();

            decimal averagePrice = 0;
            var     quantity     = 0;

            if (longUnits > 0)
            {
                averagePrice = position._Long.AveragePrice.ToDecimal();
                quantity     = longUnits;
            }
            else if (shortUnits < 0)
            {
                averagePrice = position._Short.AveragePrice.ToDecimal();
                quantity     = shortUnits;
            }

            return(new Holding
            {
                Symbol = symbol,
                Type = securityType,
                AveragePrice = averagePrice,
                CurrencySymbol = "$",
                Quantity = quantity
            });
        }
示例#5
0
        /// <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);
        }
示例#6
0
        /// <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;
            }
        }
示例#7
0
        /// <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);
        }
示例#8
0
        /// <summary>
        /// Generates an Oanda order request
        /// </summary>
        /// <param name="order">The LEAN order</param>
        /// <returns>The request in JSON format</returns>
        private string GenerateOrderRequest(Order order)
        {
            var instrument = SymbolMapper.GetBrokerageSymbol(order.Symbol);

            string request;

            switch (order.Type)
            {
            case OrderType.Market:
                var marketOrderRequest = new MarketOrderRequest
                {
                    Type       = MarketOrderRequest.TypeEnum.MARKET,
                    Instrument = instrument,
                    Units      = order.Quantity.ToStringInvariant()
                };
                request = JsonConvert.SerializeObject(new { order = marketOrderRequest });
                break;

            case OrderType.Limit:
                var limitOrderRequest = new LimitOrderRequest
                {
                    Type       = LimitOrderRequest.TypeEnum.LIMIT,
                    Instrument = instrument,
                    Units      = order.Quantity.ToStringInvariant(),
                    Price      = ((LimitOrder)order).LimitPrice.ToString(CultureInfo.InvariantCulture)
                };
                request = JsonConvert.SerializeObject(new { order = limitOrderRequest });
                break;

            case OrderType.StopMarket:
                var marketIfTouchedOrderRequest = new MarketIfTouchedOrderRequest
                {
                    Type       = MarketIfTouchedOrderRequest.TypeEnum.MARKETIFTOUCHED,
                    Instrument = instrument,
                    Units      = order.Quantity.ToStringInvariant(),
                    Price      = ((StopMarketOrder)order).StopPrice.ToString(CultureInfo.InvariantCulture)
                };
                request = JsonConvert.SerializeObject(new { order = marketIfTouchedOrderRequest });
                break;

            case OrderType.StopLimit:
                var stopOrderRequest = new StopOrderRequest
                {
                    Type       = StopOrderRequest.TypeEnum.STOP,
                    Instrument = instrument,
                    Units      = order.Quantity.ToStringInvariant(),
                    Price      = ((StopLimitOrder)order).StopPrice.ToString(CultureInfo.InvariantCulture),
                    PriceBound = ((StopLimitOrder)order).LimitPrice.ToString(CultureInfo.InvariantCulture)
                };
                request = JsonConvert.SerializeObject(new { order = stopOrderRequest });
                break;

            default:
                throw new NotSupportedException("The order type " + order.Type + " is not supported.");
            }

            return(request);
        }
示例#9
0
        /// <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
            });
        }
示例#10
0
        /// <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));
            }
        }
示例#11
0
        /// <summary>
        /// Updates the order with the same id
        /// </summary>
        /// <param name="order">The new order information</param>
        /// <returns>True if the request was made for the order to be updated, false otherwise</returns>
        public override bool UpdateOrder(Order order)
        {
            Log.Trace("OandaBrokerage.UpdateOrder(): " + order);

            if (!order.BrokerId.Any())
            {
                // we need the brokerage order id in order to perform an update
                Log.Trace("OandaBrokerage.UpdateOrder(): Unable to update order without BrokerId.");
                return(false);
            }

            var requestParams = new Dictionary <string, string>
            {
                { "instrument", SymbolMapper.GetBrokerageSymbol(order.Symbol) },
                { "units", Convert.ToInt32(order.AbsoluteQuantity).ToString() },
            };

            // we need the brokerage order id in order to perform an update
            PopulateOrderRequestParameters(order, requestParams);

            UpdateOrder(long.Parse(order.BrokerId.First()), requestParams);

            return(true);
        }
示例#12
0
 public EtradeParser()
 {
     m_SymbolMapper = new SymbolMapper();
 }
示例#13
0
        /// <summary>
        /// Places a new order and assigns a new broker ID to the order
        /// </summary>
        /// <param name="order">The order to be placed</param>
        /// <returns>True if the request for a new order has been placed, false otherwise</returns>
        public override bool PlaceOrder(Order order)
        {
            var requestParams = new Dictionary <string, string>
            {
                { "instrument", SymbolMapper.GetBrokerageSymbol(order.Symbol) },
                { "units", Convert.ToInt32(order.AbsoluteQuantity).ToString() }
            };

            PopulateOrderRequestParameters(order, requestParams);

            var postOrderResponse = PostOrderAsync(requestParams);

            if (postOrderResponse == null)
            {
                return(false);
            }

            // if market order, find fill quantity and price
            var marketOrderFillPrice = 0m;

            if (order.Type == OrderType.Market)
            {
                marketOrderFillPrice = Convert.ToDecimal(postOrderResponse.price);
            }

            var marketOrderFillQuantity = 0;

            if (postOrderResponse.tradeOpened != null && postOrderResponse.tradeOpened.id > 0)
            {
                if (order.Type == OrderType.Market)
                {
                    marketOrderFillQuantity = postOrderResponse.tradeOpened.units;
                }
                else
                {
                    order.BrokerId.Add(postOrderResponse.tradeOpened.id.ToString());
                }
            }

            if (postOrderResponse.tradeReduced != null && postOrderResponse.tradeReduced.id > 0)
            {
                if (order.Type == OrderType.Market)
                {
                    marketOrderFillQuantity = postOrderResponse.tradeReduced.units;
                }
                else
                {
                    order.BrokerId.Add(postOrderResponse.tradeReduced.id.ToString());
                }
            }

            if (postOrderResponse.orderOpened != null && postOrderResponse.orderOpened.id > 0)
            {
                if (order.Type != OrderType.Market)
                {
                    order.BrokerId.Add(postOrderResponse.orderOpened.id.ToString());
                }
            }

            if (postOrderResponse.tradesClosed != null && postOrderResponse.tradesClosed.Count > 0)
            {
                marketOrderFillQuantity += postOrderResponse.tradesClosed
                                           .Where(trade => order.Type == OrderType.Market)
                                           .Sum(trade => trade.units);
            }

            // send Submitted order event
            const int orderFee = 0;

            order.PriceCurrency = SecurityProvider.GetSecurity(order.Symbol).SymbolProperties.QuoteCurrency;
            OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, orderFee)
            {
                Status = OrderStatus.Submitted
            });

            if (order.Type == OrderType.Market)
            {
                // if market order, also send Filled order event
                OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, orderFee)
                {
                    Status       = OrderStatus.Filled,
                    FillPrice    = marketOrderFillPrice,
                    FillQuantity = marketOrderFillQuantity * Math.Sign(order.Quantity)
                });
            }

            return(true);
        }
示例#14
0
        /// <summary>
        /// Places a new order and assigns a new broker ID to the order
        /// </summary>
        /// <param name="order">The order to be placed</param>
        /// <returns>True if the request for a new order has been placed, false otherwise</returns>
        public override bool PlaceOrder(Order order)
        {
            var requestParams = new Dictionary <string, string>
            {
                { "instrument", SymbolMapper.GetBrokerageSymbol(order.Symbol) },
                { "units", Convert.ToInt32(order.AbsoluteQuantity).ToString() }
            };

            var     orderFee = OrderFee.Zero;
            var     marketOrderFillQuantity      = 0;
            var     marketOrderRemainingQuantity = 0;
            decimal marketOrderFillPrice;
            var     marketOrderStatus = OrderStatus.Filled;

            order.PriceCurrency = SecurityProvider.GetSecurity(order.Symbol).SymbolProperties.QuoteCurrency;
            PopulateOrderRequestParameters(order, requestParams);

            lock (Locker)
            {
                var postOrderResponse = PostOrderAsync(requestParams);
                if (postOrderResponse == null)
                {
                    return(false);
                }
                // Market orders are special, due to the callback not being triggered always, if the order was filled,
                // find fill quantity and price and inform the user
                if (postOrderResponse.tradeOpened != null && postOrderResponse.tradeOpened.id > 0)
                {
                    if (order.Type == OrderType.Market)
                    {
                        marketOrderFillQuantity = postOrderResponse.tradeOpened.units;
                    }
                    else
                    {
                        order.BrokerId.Add(postOrderResponse.tradeOpened.id.ToString());
                    }
                }

                if (postOrderResponse.tradeReduced != null && postOrderResponse.tradeReduced.id > 0)
                {
                    if (order.Type == OrderType.Market)
                    {
                        marketOrderFillQuantity = postOrderResponse.tradeReduced.units;
                    }
                    else
                    {
                        order.BrokerId.Add(postOrderResponse.tradeReduced.id.ToString());
                    }
                }

                if (postOrderResponse.orderOpened != null && postOrderResponse.orderOpened.id > 0)
                {
                    if (order.Type != OrderType.Market)
                    {
                        order.BrokerId.Add(postOrderResponse.orderOpened.id.ToString());
                    }
                }

                if (postOrderResponse.tradesClosed != null && postOrderResponse.tradesClosed.Count > 0)
                {
                    marketOrderFillQuantity += postOrderResponse.tradesClosed
                                               .Where(trade => order.Type == OrderType.Market)
                                               .Sum(trade => trade.units);
                }

                marketOrderFillPrice         = Convert.ToDecimal(postOrderResponse.price);
                marketOrderRemainingQuantity = Convert.ToInt32(order.AbsoluteQuantity - Math.Abs(marketOrderFillQuantity));
                if (marketOrderRemainingQuantity > 0)
                {
                    marketOrderStatus = OrderStatus.PartiallyFilled;
                    // The order was not fully filled lets save it so the callback can inform the user
                    PendingFilledMarketOrders[order.Id] = marketOrderStatus;
                }
            }
            OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, orderFee)
            {
                Status = OrderStatus.Submitted
            });

            // If 'marketOrderRemainingQuantity < order.AbsoluteQuantity' is false it means the order was not even PartiallyFilled, wait for callback
            if (order.Type == OrderType.Market && marketOrderRemainingQuantity < order.AbsoluteQuantity)
            {
                OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, orderFee)
                {
                    Status       = marketOrderStatus,
                    FillPrice    = marketOrderFillPrice,
                    FillQuantity = marketOrderFillQuantity * Math.Sign(order.Quantity)
                });
            }

            return(true);
        }
示例#15
0
        /// <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);
        }
示例#16
0
        /// <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);
        }
示例#17
0
        public bool TryGenerate(IPContext context, string input, out IFilterParticle <TEntity> particle)
        {
            input = input.Trim();

            // Attempt to capture field name from filter string.
            var nameMatch = Regex.Match(input, "^([A-Za-z0-9_]*)");

            if (!nameMatch.Success || nameMatch.Length == 0)
            {
                particle = null;
                return(false);
            }

            // Validate the property by name
            if (!TryGetPropertyByAlias(nameMatch.Value, out PropertyInfo property))
            {
                particle = null;
                return(false);
            }

            // Remove the name out of the filter string.
            var remaining = input.Substring(nameMatch.Length).TrimStart();

            // Attempt to capture operator from filter string.
            // Keys are ordered by descending length to always match the longest one possible first. (eg, "!=" instead "=")
            var operatorKey = SymbolMapper.Symbols.FirstOrDefault(o => remaining.StartsWith(o));

            if (operatorKey is null)
            {
                particle = null;
                return(false);
            }

            var op = SymbolMapper.Map(operatorKey);

            // Remove the operator out of the remaining filter string.
            var value = remaining.Substring(operatorKey.Length).Trim();

            // If encased in double quotes, we remove them.
            if (value.StartsWith("\"") && value.EndsWith("\""))
            {
                value = value.Substring(1, value.Length - 2);
            }

            try
            {
                // Attempt to convert/cast the value to the type of the property.
                var converter = TypeDescriptor.GetConverter(property.PropertyType);

                dynamic typedValue = converter.CanConvertFrom(value.GetType())
                    ? converter.ConvertFrom(value)
                    : Convert.ChangeType(value, property.PropertyType);

                // We generate our particle
                Type[] typeArgs = { typeof(TEntity), property.PropertyType };
                Type   byPropertyParticleType = typeof(ByPropertyParticle <,>).MakeGenericType(typeArgs);
                particle = (IFilterParticle <TEntity>)Activator.CreateInstance(byPropertyParticleType, property, op, typedValue);

                return(true);
            }
            catch
            {
                particle = null;
                return(false);
            }
        }