예제 #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)
        {
            const int orderFee = 0;
            ApiResponse <InlineResponse201> response;

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

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

            // if market order, find fill quantity and price
            var fill = response.Data.OrderFillTransaction;
            var marketOrderFillPrice    = 0m;
            var marketOrderFillQuantity = 0;

            if (order.Type == OrderType.Market)
            {
                marketOrderFillPrice = Convert.ToDecimal(fill.Price);

                if (fill.TradeOpened != null && fill.TradeOpened.TradeID.Length > 0)
                {
                    marketOrderFillQuantity = Convert.ToInt32(fill.TradeOpened.Units);
                }

                if (fill.TradeReduced != null && fill.TradeReduced.TradeID.Length > 0)
                {
                    marketOrderFillQuantity = Convert.ToInt32(fill.TradeReduced.Units);
                }

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

            if (order.Type == OrderType.Market && order.Status != OrderStatus.Filled)
            {
                order.Status = OrderStatus.Filled;

                // if market order, also send Filled order event
                OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, orderFee, "Oanda Fill Event")
                {
                    Status       = OrderStatus.Filled,
                    FillPrice    = marketOrderFillPrice,
                    FillQuantity = marketOrderFillQuantity
                });
            }

            return(true);
        }
예제 #2
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);
        }