public async Task <ExchangeOrder> CancelOrder(ExchangeOrder order) { var canceledOrder = order.WithUpdatedStatus(ExchangeOrderStatus.Canceled); _cancelledOrders.OnNext(canceledOrder); return(canceledOrder); }
public MockOrderBook CancelOrder(ExchangeOrder order) { if (order == null) { throw new ArgumentNullException("order"); } var orders = this.Orders; var bids = this.Bids; var asks = this.Asks; #region remove order from bids or asks if (order.OSide == OrderSide.Buy) { var bidsBuilder = bids.ToBuilder(); var orderToRemove = bidsBuilder.SingleOrDefault(o => o.ID == order.ID); if (orderToRemove != null) { bidsBuilder.Remove(orderToRemove); } bids = bidsBuilder.ToImmutableSortedSet(comparer: OrderComparer.DescBidComparer()); } else { var asksBuilder = asks.ToBuilder(); var orderToRemove = asksBuilder.SingleOrDefault(o => o.ID == order.ID); if (orderToRemove != null) { asksBuilder.Remove(orderToRemove); } asks = asksBuilder.ToImmutableSortedSet(comparer: OrderComparer.DescAskComparer()); } #endregion #region update the status of the order in the dictionnary containing all the orders var ordersBuilder = orders.ToBuilder(); ExchangeOrder changingOrder = null; ordersBuilder.TryGetValue(order.ID, out changingOrder); if (changingOrder != null) { changingOrder = changingOrder.WithUpdatedStatus(ExchangeOrderStatus.Canceled); } ordersBuilder[changingOrder.ID] = changingOrder; orders = ordersBuilder.ToImmutableDictionary(); #endregion MockOrderBook result = new MockOrderBook(this.ExchangeID, orders, bids, asks); return(result); }
public MockOrderBook PlaceOrder(ExchangeOrder pendingOrder) { if (pendingOrder == null) { throw new ArgumentNullException("pendingOrder"); } if (pendingOrder.Status != ExchangeOrderStatus.Pending) { throw new Exception(string.Format("Cannot insert order with '{0}' status in the OrderBook", pendingOrder.Status)); } //Now the order is opened var openOrder = pendingOrder.WithUpdatedStatus(ExchangeOrderStatus.Open); var orders = this.Orders; var bids = this.Bids; var asks = this.Asks; ImmutableSortedSet <ExchangeOrder> oppositeSideOrders = null; ImmutableSortedSet <ExchangeOrder> sameSideOrders = null; if (openOrder.OSide == OrderSide.Buy) { oppositeSideOrders = asks; sameSideOrders = bids; } else { oppositeSideOrders = bids; sameSideOrders = asks; } var matchOuput = MatchOrder(Tuple.Create(openOrder, oppositeSideOrders)); ExchangeOrder resultingOrder = matchOuput.Item1; ImmutableSortedSet <ExchangeOrder> resultingSameSideOrders = null; if (resultingOrder.RemainingVolume > 0) { resultingSameSideOrders = sameSideOrders.Add(resultingOrder); } else { resultingSameSideOrders = sameSideOrders; } ImmutableSortedSet <ExchangeOrder> resultingOppositeSideOrders = matchOuput.Item2; #region update orders var ordersBuilder = orders.ToBuilder(); ordersBuilder[resultingOrder.ID] = resultingOrder; var oppositeSideOrdersDiff = resultingOppositeSideOrders.SymmetricExcept(oppositeSideOrders). //contains all the elements which are NOT PRESENT IN BOTH sets. for updated orders, both the old and new one will be returned GroupBy(o => o.ID, (_, g) => g.OrderBy(o => o.RemainingVolume).FirstOrDefault()). //for changed orders, take only the latest one ToList(); foreach (var item in oppositeSideOrdersDiff) { //add or update the value in dictionary ordersBuilder[item.ID] = item; } #endregion #region reconstruct bids and asks ImmutableSortedSet <ExchangeOrder> resultingBids = null; ImmutableSortedSet <ExchangeOrder> resultingAsks = null; if (openOrder.OSide == OrderSide.Buy) { resultingBids = resultingSameSideOrders; resultingAsks = resultingOppositeSideOrders; } else { resultingBids = resultingOppositeSideOrders; resultingAsks = resultingSameSideOrders; } resultingBids = resultingBids.Where(o => o.Status == ExchangeOrderStatus.Open).ToImmutableSortedSet(OrderComparer.DescBidComparer()); resultingAsks = resultingAsks.Where(o => o.Status == ExchangeOrderStatus.Open).ToImmutableSortedSet(OrderComparer.DescAskComparer()); #endregion //return all orders + bids and asks from which completed orders are removed return(new MockOrderBook(this.ExchangeID, ordersBuilder.ToImmutable(), resultingBids, resultingAsks)); }