示例#1
0
        public OrderState Update(OrderUpdate update, out Fill fill)
        {
            Assert.True(Status != OrderStatus.Finished);
            Assert.True(update.Status != OrderStatus.Created, "Invalid update {0} for order {1}", update, this);
            fill = null;
            bool changed = false;

            // Do we have a new OrderID assigned by the exchange?
            if (update.OrderID != null && update.OrderID != _orderID)
            {
                _log.Info("Updating OrderID from {0} to {1} for order {2}", _orderID ?? "null", update.OrderID, _state);
                // This will throw if we already have an order with the same ID. The update will be ignored.
                _orders.AddOrder(update.OrderID, this);
                if (_orderID != null)
                {
                    _orders.RemoveOrder(_orderID);
                }
                _orderID = update.OrderID;
            }
            // Have the status changed?
            if (update.Status.HasValue && update.Status != Status)
            {
                _state.Status = update.Status.Value;
                changed       = true;
                if (Status == OrderStatus.Finished)
                {
                    Finish();
                }
            }
            // Orders that aren't Created or Finished must have OrderID.
            if (Status != OrderStatus.Finished && Status != OrderStatus.Created && _orderID == null)
            {
                // This can happen if we sent a New Order Request to the exchange and the
                // reply doesn't contain OrderID.
                _log.Warn("Removing order with unknown ID: ", this);
                changed = true;
                Finish();
            }
            // Orders in state Created can't have OrderID.
            if (Status == OrderStatus.Created && _orderID != null)
            {
                // This can happen if we sent a New Order Request to the exchange and the
                // reply doesn't contain order status.
                _log.Warn("Removing order in unknown status: ", this);
                changed = true;
                Finish();
            }
            if (update.Price.HasValue && update.Price != _state.Price)
            {
                _state.Price = update.Price;
                changed      = true;
            }
            if (update.LeftQuantity.HasValue && update.LeftQuantity != _state.LeftQuantity)
            {
                _state.LeftQuantity = update.LeftQuantity.Value;
                changed             = true;
            }
            if (update.FillQuantity.HasValue && update.FillQuantity.Value > _state.FillQuantity)
            {
                // This is a so called "similated" fill. It's used only if ClientConfig.SimulateFills
                // is true.
                fill = new Fill()
                {
                    Side     = _state.Side,
                    Symbol   = _state.Symbol,
                    Quantity = update.FillQuantity.Value - _state.FillQuantity,
                    Price    = update.AverageFillPrice.HasValue ? update.AverageFillPrice.Value :
                               _state.Price.HasValue ? _state.Price.Value : 0m
                };
                _state.FillQuantity = update.FillQuantity.Value;
                changed             = true;
            }
            // TODO: update FillQuantity.
            return(changed ? (OrderState)_state.Clone() : null);
        }