Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions orderBook.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
function reconcileOrder(existingBook, incomingOrder) {
// first thing we do is try to find a deal, if we find one
// return the index of that order, if not then just combine
// our orders together
let dealFoundIndex = findDeal(existingBook, incomingOrder)

// let's check our index, if it's less than 0 then we didnt find a deal
// so simply concat our lists
if (dealFoundIndex < 0) {
// no deal found, concat our order into our book and return it
return existingBook.concat({ ...incomingOrder })
}

// now let's make our deal using our indexed order and generate a new pending order
const newOrder = makeDeal(existingBook[dealFoundIndex], incomingOrder)

// now let's trim our existing order from the book, if the quantity isn't 0
// it will be reinserted on the next recursion
existingBook.splice(dealFoundIndex, 1)

// now let's check if our order has any quantity, if it doesnt then we are done
if (newOrder.quantity > 0) {
// we still have some quantity left, so let's recall the function using our
// new data causing a recursion that wont be stopped until the quantity is 0
// or no deal is found on line 11
return reconcileOrder(existingBook, newOrder)
} else {
// quantity is 0, we are done! no need to concat because it's not a valid order
// just return our book which has been spliced of the order that was processed
return existingBook
}
}


// our function which first finds a deal, and returns the index of that deal
function findDeal(existingBook, incomingOrder) {
// we want to return the index of a deal by making a callback function
// find index will cycle through each order until it finds one
return existingBook.findIndex((existingOrder) => {
// if our existingOrder type isn't the same
// as our incoming order, then its a match
// we also need to make sure the prices work
// if both are true, return this order
// this will then make the function return the index
// if no order is found it will return -1
return existingOrder.type !== incomingOrder.type && goodDeal(existingOrder, incomingOrder) === true
})
}

// this function checks the prices to see if both sides benefit
function goodDeal(existingOrder, incomingOrder) {
// let's check if the incoming order is a buy, if not then its a sell
if (incomingOrder.type === 'buy') {
// if the incoming order is a buy, we need to check if the price
// of the existing order is >= to it
return incomingOrder.price >= existingOrder.price
} else {
// if it's not a buy, it must be a sell, so now we want to check if
// the existing order is <= to incoming order
return incomingOrder.price <= existingOrder.price
}
}

// this function makes a deal and returns our newOrder
function makeDeal(existingOrder, incomingOrder) {
// let's see which order will be sent back depending on the quantity
if (incomingOrder.quantity >= existingOrder.quantity) {
// our incoming order has more quantity, so subtract the existing order from it
// then return it as our newest order to be fulfilled
incomingOrder.quantity -= existingOrder.quantity

return { ...incomingOrder }
} else {
// now our incoming order has less quantity, so let's take its quantity from
// our existing order then return it to be processed through
existingOrder.quantity -= incomingOrder.quantity

return { ...existingOrder }
}
}

// export our module to tests and the front end
module.exports = reconcileOrder
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"main": ".eslintrc.js",
"scripts": {
"lint": "./node_modules/.bin/eslint --format codeframe .",
"test": "./node_modules/.bin/mocha ./tests.js"
"test": "./node_modules/.bin/mocha ./tests/*.js"
},
"repository": {
"type": "git",
Expand Down
6 changes: 3 additions & 3 deletions tests.js → tests/orderBook.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable max-len */
const { expect } = require('chai')
const reconcileOrder = require('./orderBook')
const reconcileOrder = require('../orderBook')

describe('Order Book', () => {
describe('reconcileOrder', () => {
Expand Down Expand Up @@ -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 }

Expand All @@ -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 }

Expand Down