Beispiel #1
0
        OrderState UpdateOrder(string origOrderID, OrderOpID op, OrderUpdate update, out Fill fill)
        {
            // Match by OrderID happens on fills.
            // Match by OrigOrderID happens on moves.
            // Match by OrderOpID happens on order creation and when we are trying to cancel/move an
            // order with unknown ID (Order Cancel Reject <9>).
            IOrder order = _orders.FindByOrderID(update.OrderID) ?? _orders.FindByOrderID(origOrderID) ?? _orders.FindByOpID(op);

            if (order == null)
            {
                fill = null;
                return(null);
            }
            OrderStatus oldStatus = order.Status;
            OrderState  res       = order.Update(update, out fill);

            // If the order has transitioned to status TearingDown, schedule a check in RequestTimeout.
            // If it's still TearingDown by then, we'll mark it as Finished.
            if (order.Status == OrderStatus.TearingDown && order.Status != oldStatus && _cfg.RequestTimeout > TimeSpan.Zero)
            {
                _scheduler.Schedule(() => TryTearDown(order), DateTime.UtcNow + _cfg.RequestTimeout);
            }
            return(res);
        }
Beispiel #2
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;
 }
Beispiel #3
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);
        }