From 2814b3eff4dea8fe8e4bd76107aec78f27993dad Mon Sep 17 00:00:00 2001 From: fasenderos Date: Mon, 8 May 2023 02:39:07 +0200 Subject: [PATCH] fix: check if sell FOK order can be filled --- src/orderbook.ts | 21 ++++++++++++------ test/orderbook.test.ts | 49 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/src/orderbook.ts b/src/orderbook.ts index 1652d0a..a3a732d 100644 --- a/src/orderbook.ts +++ b/src/orderbook.ts @@ -469,13 +469,20 @@ export class OrderBook { } let cumulativeSize = 0 - orderSide.priceTree().forEach((_key, priceLevel) => { - if (price <= priceLevel.price() && cumulativeSize < size) { - cumulativeSize += priceLevel.volume() - } else { - return true // break the loop - } - }) + let iterator = orderSide.priceTree().end + let continueLoop = true + while (continueLoop) { + if (iterator?.node) { + if (price <= iterator.node.key) { + cumulativeSize += iterator.node.value.volume() + if (cumulativeSize < size && iterator.hasPrev) { + iterator = orderSide.priceTree().at(iterator.index - 1) + } else { + continueLoop = false + } + } else continueLoop = false + } else continueLoop = false + } return cumulativeSize >= size } } diff --git a/test/orderbook.test.ts b/test/orderbook.test.ts index deda313..7cbadec 100644 --- a/test/orderbook.test.ts +++ b/test/orderbook.test.ts @@ -153,8 +153,57 @@ describe('OrderBook', () => { ) expect(process2.err?.message).toBe(ERROR.ErrLimitFOKNotFillable) + const process3 = ob.limit( + Side.BUY, + 'buy-order-size-greather-than-order-side-volume', + 30, + 100, + TimeInForce.FOK + ) + expect(process3.err?.message).toBe(ERROR.ErrLimitFOKNotFillable) + + const process4 = ob.limit( + Side.SELL, + 'sell-order-size-greather-than-order-side-volume', + 30, + 90, + TimeInForce.FOK + ) + expect(process4.err?.message).toBe(ERROR.ErrLimitFOKNotFillable) + ob.limit(Side.BUY, 'order-ioc-b100', 3, 100, TimeInForce.IOC) expect(ob.order('order-ioc-b100')).toBeUndefined() + + const processIOC = ob.limit( + Side.SELL, + 'order-ioc-s90', + 3, + 90, + TimeInForce.IOC + ) + expect(ob.order('order-ioc-s90')).toBeUndefined() + expect(processIOC.partial?.id).toBe('order-ioc-s90') + + const processFOKBuy = ob.limit( + Side.BUY, + 'order-fok-b110', + 2, + 120, + TimeInForce.FOK + ) + + expect(processFOKBuy.err).toBeNull() + expect(processFOKBuy.quantityLeft).toBe(0) + + const processFOKSell = ob.limit( + Side.SELL, + 'order-fok-s80', + 4, + 70, + TimeInForce.FOK + ) + expect(processFOKSell.err).toBeNull() + expect(processFOKSell.quantityLeft).toBe(0) }) test('test market', () => {