public void FinishPending() { Assert.True(IsPending); Assert.True(Status != OrderStatus.Finished); _orders.RemoveOp(_pending); _pending = null; }
public void SetPending(OrderOpID id) { Assert.True(!IsPending); Assert.True(Status != OrderStatus.Finished); _orders.AddOp(id, this); _pending = id; }
public void AddOp(OrderOpID id, IOrder order) { Assert.NotNull(id); Assert.NotNull(id.SeqNum); Assert.NotNull(id.ClOrdID); Assert.NotNull(order); Assert.True(!_orders._bySeqNum.ContainsKey(id.SeqNum), "Duplicate SeqNum: {0}", id.SeqNum); Assert.True(!_orders._byClOrdID.ContainsKey(id.ClOrdID), "Duplicate ClOrdID: {0}", id.ClOrdID); _log.Info("Issued OrderOP {0} for order {1}", id, order); _orders._bySeqNum.Add(id.SeqNum, order); _orders._byClOrdID.Add(id.ClOrdID, order); }
void Finish() { _log.Info("Order has finished: {0}", this); if (_pending != null) { _orders.RemoveOp(_pending); _pending = null; } if (_orderID != null) { _orders.RemoveOrder(_orderID); } _state.Status = OrderStatus.Finished; }
public void RemoveOp(OrderOpID id) { Assert.NotNull(id); Assert.NotNull(id.SeqNum); Assert.NotNull(id.ClOrdID); _log.Info("OrderOp {0} has finished", id); IOrder bySeqNum = null; IOrder byClOrdID = null; Assert.True(_orders._bySeqNum.TryGetValue(id.SeqNum, out bySeqNum), "Unknown SeqNum: {0}", id.SeqNum); Assert.True(_orders._byClOrdID.TryGetValue(id.ClOrdID, out byClOrdID), "Unknown ClOrdID: {0}", id.ClOrdID); Assert.True(bySeqNum == byClOrdID, "Ambiguous OrderOpID: {0}", id); Assert.True(_orders._bySeqNum.Remove(id.SeqNum)); Assert.True(_orders._byClOrdID.Remove(id.ClOrdID)); }
bool StoreOp(IOrder order, string clOrdID, DurableSeqNum seqNum, OrderStatus?statusOnTimeout) { Assert.NotNull(order); Assert.NotNull(clOrdID); if (seqNum == null) { return(false); // Didn't sent the request to the exchange. } var id = new OrderOpID() { SeqNum = seqNum, ClOrdID = clOrdID }; order.SetPending(id); if (_cfg.RequestTimeout > TimeSpan.Zero) { _scheduler.Schedule(() => TryTimeout(id, statusOnTimeout), DateTime.UtcNow + _cfg.RequestTimeout); } return(true); }
void TryTimeout(OrderOpID id, OrderStatus?statusOnTimeout) { IOrder order = _orders.FindByOpID(id); if (order == null) { return; } _log.Warn("OrderOp {0} timed out for order {1}", id, order); Fill dummy; RaiseOrderEvent(state: order.Update(new OrderUpdate() { Status = statusOnTimeout }, out dummy)); // The previus call to Update may have finished the Op, so we need to check // whether it's still pending. if (order.IsPending) { order.FinishPending(); } }
// If id.SeqNum is specified, tries to find the associated order. // The same for id.ClOrdID. If both are specified, verifies that the result is the same. public IOrder FindByOpID(OrderOpID id) { if (id == null) { return(null); } IOrder bySeqNum = null; IOrder byClOrdID = null; if (id.SeqNum != null) { _bySeqNum.TryGetValue(id.SeqNum, out bySeqNum); } if (id.ClOrdID != null) { _byClOrdID.TryGetValue(id.ClOrdID, out byClOrdID); } if (bySeqNum != null && byClOrdID != null && bySeqNum != byClOrdID) { _log.Warn("Ambiguous OrderOpID: {0}", id); return(null); } return(bySeqNum != null ? bySeqNum : byClOrdID); }
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); }
// If id.SeqNum is specified, tries to find the associated order. // The same for id.ClOrdID. If both are specified, verifies that the result is the same. public IOrder FindByOpID(OrderOpID id) { if (id == null) return null; IOrder bySeqNum = null; IOrder byClOrdID = null; if (id.SeqNum != null) _bySeqNum.TryGetValue(id.SeqNum, out bySeqNum); if (id.ClOrdID != null) _byClOrdID.TryGetValue(id.ClOrdID, out byClOrdID); if (bySeqNum != null && byClOrdID != null && bySeqNum != byClOrdID) { _log.Warn("Ambiguous OrderOpID: {0}", id); return null; } return bySeqNum != null ? bySeqNum : byClOrdID; }
void Finish() { _log.Info("Order has finished: {0}", this); if (_pending != null) { _orders.RemoveOp(_pending); _pending = null; } if (_orderID != null) _orders.RemoveOrder(_orderID); _state.Status = OrderStatus.Finished; }