private void HandlerOrder(Order order, Action onSuccess, Action <string> onFailure) { var validation = ValidateOrder(order); if (!validation.IsValid) { onFailure?.Invoke(validation.Reason); return; } var bestBidPrice = _orderStore.BestBid; var bestAskPrice = _orderStore.BestAsk; // Accept bid (buy) and ask (sell) orders of a specified quantity and price for 1 stock var tradingOrder = TradingOrder.New(order); _orderStore.Add(tradingOrder); onSuccess?.Invoke(); // Publishes an event when an order has been accepted (not necessarily matched) NotifyOrderPlaced(order); // Find if any matched, Publishes an event when a bid order has been settled with a matching ask order, partially or otherwise ResolveMatching(tradingOrder); // Publishes an event when the best bid and ask price changes if (IsPriceChanging(bestBidPrice, bestAskPrice)) { NotifyPriceChanged(); } }
private void ResolveMatching(TradingOrder tradingOrder) { if (tradingOrder.IsBid) { ResolveBidMatching(tradingOrder); } else { ResolveAskMatching(tradingOrder); } }
private static void ResolveMatching(TradingOrder tradingOrder, IEnumerable <TradingOrder> matchingOrders, Action <TradingOrder, int> onFound) { foreach (var matchingBid in matchingOrders) { if (tradingOrder.FullFilled) { break; } var shareToTrade = Math.Min(tradingOrder.TradableUnits, matchingBid.TradableUnits); matchingBid.TradableUnits -= shareToTrade; tradingOrder.TradableUnits -= shareToTrade; onFound?.Invoke(matchingBid, shareToTrade); } }
private void ResolveAskMatching(TradingOrder tradingOrder) { var matchingBids = _orderStore .Bids .Where(a => a.Price >= tradingOrder.Price) .OrderByDescending(_ => _.Price) // best price comes first .ToList(); ResolveMatching(tradingOrder, matchingBids, (matchingBid, shareToTrade) => { var trade = new TradeSettled { Price = tradingOrder.Price, Units = shareToTrade, AskOrderId = tradingOrder.OrderId, StockId = _stockId, BidOrderId = matchingBid.OrderId }; _tradeSettled.Add(trade); }); }
private void ResolveBidMatching(TradingOrder tradingOrder) { var matchingAsks = _orderStore .Asks .Where(a => a.Price <= tradingOrder.Price) .OrderBy(_ => _.Price) .ToList(); // best price comes first ResolveMatching(tradingOrder, matchingAsks, (matchingAsk, shareToTrade) => { var trade = new TradeSettled { Price = tradingOrder.Price, Units = shareToTrade, AskOrderId = matchingAsk.OrderId, StockId = _stockId, BidOrderId = tradingOrder.OrderId }; _tradeSettled.Add(trade); }); }