Esempio n. 1
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() }
            };

            const int orderFee = 0;
            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);
        }
        /// <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);
        }
Esempio n. 3
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 orderFee = OrderFee.Zero;
            var marketOrderFillQuantity      = 0;
            var marketOrderFillPrice         = 0m;
            var marketOrderRemainingQuantity = 0;
            var marketOrderStatus            = OrderStatus.Filled;
            var request = GenerateOrderRequest(order);

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

            lock (Locker)
            {
                var response = _apiRest.CreateOrder(Authorization, AccountId, request);
                order.BrokerId.Add(response.Data.OrderCreateTransaction.Id);

                // Market orders are special, due to the callback not being triggered always,
                // if the order was Filled/PartiallyFilled, find fill quantity and price and inform the user
                if (order.Type == OrderType.Market)
                {
                    var fill = response.Data.OrderFillTransaction;
                    marketOrderFillPrice = fill.Price.ConvertInvariant <decimal>();

                    if (fill.TradeOpened != null && fill.TradeOpened.TradeID.Length > 0)
                    {
                        marketOrderFillQuantity = fill.TradeOpened.Units.ConvertInvariant <int>();
                    }

                    if (fill.TradeReduced != null && fill.TradeReduced.TradeID.Length > 0)
                    {
                        marketOrderFillQuantity = fill.TradeReduced.Units.ConvertInvariant <int>();
                    }

                    if (fill.TradesClosed != null && fill.TradesClosed.Count > 0)
                    {
                        marketOrderFillQuantity += fill.TradesClosed.Sum(trade => trade.Units.ConvertInvariant <int>());
                    }

                    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, "Oanda Fill Event")
                {
                    Status       = marketOrderStatus,
                    FillPrice    = marketOrderFillPrice,
                    FillQuantity = marketOrderFillQuantity
                });
            }

            return(true);
        }