From 3e8112ac4a8569bf0d97407c393f0b704f13bb8c Mon Sep 17 00:00:00 2001 From: xworld2000 Date: Thu, 23 Jul 2020 18:14:10 -0400 Subject: [PATCH 1/5] 2 working need to refactor completely want to save progress --- orderBook.js | 42 ++++++++++++++++++++++++++++++++++++++++++ package-lock.json | 6 +++--- 2 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 orderBook.js diff --git a/orderBook.js b/orderBook.js new file mode 100644 index 0000000..66e3247 --- /dev/null +++ b/orderBook.js @@ -0,0 +1,42 @@ +const existingBook = [{ type: 'buy', quantity: 10, price: 6150 }, { type: 'sell', quantity: 12, price: 5950 }] +const incomingOrder = { type: 'sell', quantity: 15, price: 6150 } +reconcileOrder = (existingBook, incomingOrder) => { + const buyOrder = (order) => order.type === 'buy' && order.price <= incomingOrder.price; + + const sellOrder = (order) => order.type === 'sell' && order.quantity >= incomingOrder.quantity && order.price <= incomingOrder.price; + + if (incomingOrder.type === 'buy') { + let i = existingBook.findIndex(sellOrder) + if (i >= 0) { + existingBook[i].quantity -= incomingOrder.quantity + if (existingBook[i].quantity > 0) { + existingBook.push(existingBook.splice((i), 1)[0]) + } + existingBook = existingBook.filter(orders => orders.quantity > 0) + } + else { existingBook.push(incomingOrder) } + } + if (incomingOrder.type === 'sell') { + + let i = existingBook.findIndex(buyOrder) + + if (i >= 0) { + existingBook[i].quantity -= incomingOrder.quantity + if (incomingOrder.quantity > existingBook[i].quantity) { + incomingOrder.quantity = incomingOrder.quantity - existingBook[i].quantity + existingBook.push(incomingOrder) + } + if (existingBook[i].quantity > 0) { + existingBook.push(existingBook.splice((i), 1)[0]) + } + + existingBook = existingBook.filter(orders => orders.quantity > 0) + } + else { + existingBook.push(incomingOrder) + } + } + return existingBook +} +console.log(reconcileOrder(existingBook, incomingOrder)) +module.exports = reconcileOrder diff --git a/package-lock.json b/package-lock.json index 74a2b24..e937acb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -911,9 +911,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", "dev": true }, "log-symbols": { From ceed44b37ba69b4833e478af5792cd6a90f22fcc Mon Sep 17 00:00:00 2001 From: xworld2000 Date: Fri, 24 Jul 2020 12:42:14 -0400 Subject: [PATCH 2/5] 5 out of 9 progress save --- orderBook.js | 71 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/orderBook.js b/orderBook.js index 66e3247..0fc8f35 100644 --- a/orderBook.js +++ b/orderBook.js @@ -1,42 +1,57 @@ -const existingBook = [{ type: 'buy', quantity: 10, price: 6150 }, { type: 'sell', quantity: 12, price: 5950 }] -const incomingOrder = { type: 'sell', quantity: 15, price: 6150 } -reconcileOrder = (existingBook, incomingOrder) => { - const buyOrder = (order) => order.type === 'buy' && order.price <= incomingOrder.price; - const sellOrder = (order) => order.type === 'sell' && order.quantity >= incomingOrder.quantity && order.price <= incomingOrder.price; - if (incomingOrder.type === 'buy') { - let i = existingBook.findIndex(sellOrder) - if (i >= 0) { - existingBook[i].quantity -= incomingOrder.quantity - if (existingBook[i].quantity > 0) { - existingBook.push(existingBook.splice((i), 1)[0]) - } - existingBook = existingBook.filter(orders => orders.quantity > 0) +function reconcileOrder(existingBook, incomingOrder) { + let key = 'a' + let i = -1 + + const buyEqualOrder = order => order.type === 'buy' && + order.price >= incomingOrder.price + + const sellOrder = order => order.type === 'sell' && order.quantity >= incomingOrder.quantity && + order.price <= incomingOrder.price + + if (existingBook.length) { + if (incomingOrder.type === 'buy') { + i = existingBook.findIndex(sellOrder) + } + if (incomingOrder.type === 'sell') { + i = existingBook.findIndex(buyEqualOrder) } - else { existingBook.push(incomingOrder) } } - if (incomingOrder.type === 'sell') { + if (i >= 0 && incomingOrder.quantity <= existingBook[i].quantity) { key = 'b' } + //if (i >= 0 && incomingOrder.quantity < existingBook[i].quantity) { key = 'b' } - let i = existingBook.findIndex(buyOrder) - if (i >= 0) { - existingBook[i].quantity -= incomingOrder.quantity - if (incomingOrder.quantity > existingBook[i].quantity) { - incomingOrder.quantity = incomingOrder.quantity - existingBook[i].quantity - existingBook.push(incomingOrder) - } + switch (key) { + // adds an order to the book when the book is empty and thus cannot fulfill the order + // adds an order to the book when the book has no orders of the corresponding type (i.e. a sell with + // no buys) + // adds an order to the book when the book has a corresponding order type but it does not match' + case 'a': existingBook.push(incomingOrder) + + return existingBook + // fulfills an order and removes the matching order when the book contains a matching order of the + // same quantity + // fulfills an order and reduces the matching order when the book contains a matching order of + // a larger quantity + case 'b': existingBook[i].quantity -= incomingOrder.quantity if (existingBook[i].quantity > 0) { existingBook.push(existingBook.splice((i), 1)[0]) } - existingBook = existingBook.filter(orders => orders.quantity > 0) - } - else { + + return existingBook + // partially fulfills an order, removes the matching order and adds the remainder of the order + // to the book when the book contains a matching order of a smaller quantity + case 'c': incomingOrder.quantity = incomingOrder.quantity - existingBook[i].quantity existingBook.push(incomingOrder) - } + existingBook = existingBook.filter(orders => orders.quantity > 0) + + return existingBook + + default: + break } - return existingBook } -console.log(reconcileOrder(existingBook, incomingOrder)) +// console.log(reconcileOrder(existingBook, incomingOrder)) module.exports = reconcileOrder From c5d08c8643244992c951b573710845f276a8e6a8 Mon Sep 17 00:00:00 2001 From: xworld2000 Date: Fri, 24 Jul 2020 13:16:54 -0400 Subject: [PATCH 3/5] Winning got all 9 to pass need to refactor, condense and comment! --- orderBook.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/orderBook.js b/orderBook.js index 0fc8f35..30a07ef 100644 --- a/orderBook.js +++ b/orderBook.js @@ -1,11 +1,10 @@ - function reconcileOrder(existingBook, incomingOrder) { let key = 'a' let i = -1 const buyEqualOrder = order => order.type === 'buy' && - order.price >= incomingOrder.price + order.price === incomingOrder.price const sellOrder = order => order.type === 'sell' && order.quantity >= incomingOrder.quantity && order.price <= incomingOrder.price @@ -19,8 +18,7 @@ function reconcileOrder(existingBook, incomingOrder) { } } if (i >= 0 && incomingOrder.quantity <= existingBook[i].quantity) { key = 'b' } - //if (i >= 0 && incomingOrder.quantity < existingBook[i].quantity) { key = 'b' } - + if (i >= 0 && incomingOrder.quantity > existingBook[i].quantity) { key = 'c' } switch (key) { // adds an order to the book when the book is empty and thus cannot fulfill the order @@ -44,14 +42,18 @@ function reconcileOrder(existingBook, incomingOrder) { // partially fulfills an order, removes the matching order and adds the remainder of the order // to the book when the book contains a matching order of a smaller quantity case 'c': incomingOrder.quantity = incomingOrder.quantity - existingBook[i].quantity - existingBook.push(incomingOrder) + existingBook[i].quantity = 0 existingBook = existingBook.filter(orders => orders.quantity > 0) + if (existingBook.findIndex(buyEqualOrder) >= 0) { + existingBook = reconcileOrder(existingBook, incomingOrder) + } + else { + existingBook.push(incomingOrder) + } return existingBook - default: - break } } -// console.log(reconcileOrder(existingBook, incomingOrder)) +//console.log(reconcileOrder(existingBook, incomingOrder)) module.exports = reconcileOrder From 15f9f3cafd337985a026f977ce3663c32311cc2d Mon Sep 17 00:00:00 2001 From: xworld2000 Date: Sat, 25 Jul 2020 08:41:38 -0400 Subject: [PATCH 4/5] Commented everything finished extra credit --- orderBook.js | 24 ++++++++++-------------- tests.js | 4 ++-- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/orderBook.js b/orderBook.js index 30a07ef..d95204c 100644 --- a/orderBook.js +++ b/orderBook.js @@ -1,13 +1,16 @@ function reconcileOrder(existingBook, incomingOrder) { + // default switch case key let key = 'a' + // matching order index variable let i = -1 - + // callback function for findIndex method which sets conditions for matching orders in existing book const buyEqualOrder = order => order.type === 'buy' && - order.price === incomingOrder.price + order.price >= incomingOrder.price const sellOrder = order => order.type === 'sell' && order.quantity >= incomingOrder.quantity && order.price <= incomingOrder.price + // Finds matching order index in existing book if (existingBook.length) { if (incomingOrder.type === 'buy') { @@ -17,21 +20,16 @@ function reconcileOrder(existingBook, incomingOrder) { i = existingBook.findIndex(buyEqualOrder) } } + // switches handling of orders in special scenarios if (i >= 0 && incomingOrder.quantity <= existingBook[i].quantity) { key = 'b' } if (i >= 0 && incomingOrder.quantity > existingBook[i].quantity) { key = 'c' } switch (key) { - // adds an order to the book when the book is empty and thus cannot fulfill the order - // adds an order to the book when the book has no orders of the corresponding type (i.e. a sell with - // no buys) - // adds an order to the book when the book has a corresponding order type but it does not match' + // adds an order to the book when the book is empty, or no matching order case 'a': existingBook.push(incomingOrder) return existingBook - // fulfills an order and removes the matching order when the book contains a matching order of the - // same quantity - // fulfills an order and reduces the matching order when the book contains a matching order of - // a larger quantity + // fulfills an order and removes matching order with same quantity, or reduces when larger quantity case 'b': existingBook[i].quantity -= incomingOrder.quantity if (existingBook[i].quantity > 0) { existingBook.push(existingBook.splice((i), 1)[0]) @@ -39,8 +37,7 @@ function reconcileOrder(existingBook, incomingOrder) { existingBook = existingBook.filter(orders => orders.quantity > 0) return existingBook - // partially fulfills an order, removes the matching order and adds the remainder of the order - // to the book when the book contains a matching order of a smaller quantity + // all the rest of the special cases (uses recursion to fullfill order with to existing orders) case 'c': incomingOrder.quantity = incomingOrder.quantity - existingBook[i].quantity existingBook[i].quantity = 0 existingBook = existingBook.filter(orders => orders.quantity > 0) @@ -52,8 +49,7 @@ function reconcileOrder(existingBook, incomingOrder) { } return existingBook - } } -//console.log(reconcileOrder(existingBook, incomingOrder)) +// console.log(reconcileOrder(existingBook, incomingOrder)) module.exports = reconcileOrder diff --git a/tests.js b/tests.js index 4926c8a..d7432a4 100644 --- a/tests.js +++ b/tests.js @@ -91,7 +91,7 @@ describe('Order Book', () => { expect(updatedBook).to.deep.equal([{ type: 'sell', quantity: 12, price: 6950 }, { type: 'sell', quantity: 5, price: 6150 }]) }) - it.skip('Extra Credit: it fulfills a mismatched order when both parties benefit', () => { + it('Extra Credit: it fulfills a mismatched order when both parties benefit', () => { const existingBook = [{ type: 'buy', quantity: 15, price: 6000 }, { type: 'sell', quantity: 12, price: 6950 }] const incomingOrder = { type: 'sell', quantity: 15, price: 5900 } @@ -100,7 +100,7 @@ describe('Order Book', () => { expect(updatedBook).to.deep.equal([{ type: 'sell', quantity: 12, price: 6950 }]) }) - it.skip('Extra Credit: it does not fulfill a mismatched order when it does not benefit both parties', () => { + it('Extra Credit: it does not fulfill a mismatched order when it does not benefit both parties', () => { const existingBook = [{ type: 'buy', quantity: 15, price: 5900 }, { type: 'sell', quantity: 12, price: 6950 }] const incomingOrder = { type: 'sell', quantity: 15, price: 6000 } From a0b9307823bf37349452bee0abd99d8dd5b5111a Mon Sep 17 00:00:00 2001 From: xworld2000 Date: Sat, 25 Jul 2020 09:17:21 -0400 Subject: [PATCH 5/5] Less code got rid of code for reversed buy/sell scenario. --- orderBook.js | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) diff --git a/orderBook.js b/orderBook.js index d95204c..2ddd338 100644 --- a/orderBook.js +++ b/orderBook.js @@ -5,40 +5,34 @@ function reconcileOrder(existingBook, incomingOrder) { // matching order index variable let i = -1 // callback function for findIndex method which sets conditions for matching orders in existing book - const buyEqualOrder = order => order.type === 'buy' && - order.price >= incomingOrder.price - const sellOrder = order => order.type === 'sell' && order.quantity >= incomingOrder.quantity && - order.price <= incomingOrder.price + const buyEqualOrder = order => order.type === 'buy' && order.price >= incomingOrder.price + // Finds matching order index in existing book - if (existingBook.length) { - if (incomingOrder.type === 'buy') { - i = existingBook.findIndex(sellOrder) - } - if (incomingOrder.type === 'sell') { - i = existingBook.findIndex(buyEqualOrder) - } - } + if (existingBook.length) { i = existingBook.findIndex(buyEqualOrder) } + // switches handling of orders in special scenarios + if (i >= 0 && incomingOrder.quantity <= existingBook[i].quantity) { key = 'b' } if (i >= 0 && incomingOrder.quantity > existingBook[i].quantity) { key = 'c' } switch (key) { // adds an order to the book when the book is empty, or no matching order - case 'a': existingBook.push(incomingOrder) + case 'a': + existingBook.push(incomingOrder) return existingBook // fulfills an order and removes matching order with same quantity, or reduces when larger quantity - case 'b': existingBook[i].quantity -= incomingOrder.quantity - if (existingBook[i].quantity > 0) { - existingBook.push(existingBook.splice((i), 1)[0]) - } + case 'b': + existingBook[i].quantity -= incomingOrder.quantity + if (existingBook[i].quantity > 0) { existingBook.push(existingBook.splice((i), 1)[0]) } existingBook = existingBook.filter(orders => orders.quantity > 0) return existingBook // all the rest of the special cases (uses recursion to fullfill order with to existing orders) - case 'c': incomingOrder.quantity = incomingOrder.quantity - existingBook[i].quantity + case 'c': + incomingOrder.quantity -= existingBook[i].quantity existingBook[i].quantity = 0 existingBook = existingBook.filter(orders => orders.quantity > 0) if (existingBook.findIndex(buyEqualOrder) >= 0) { @@ -51,5 +45,4 @@ function reconcileOrder(existingBook, incomingOrder) { return existingBook } } -// console.log(reconcileOrder(existingBook, incomingOrder)) module.exports = reconcileOrder