Last active
October 12, 2020 07:38
-
-
Save Gerst20051/45ef0657fc782d96bcb5d89b85214921 to your computer and use it in GitHub Desktop.
Order Book Matching Engine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function order_book(orders) { | |
return orders.reduce((executedQuantity, currentOrder, currentOrderIndex) => { | |
if (currentOrderIndex === 0) return executedQuantity; | |
const matchingOrders = find_matching_orders(orders.slice(0, currentOrderIndex), currentOrder); | |
if (!matchingOrders.length) return executedQuantity; | |
for (let matchingOrderIndex = 0; matchingOrderIndex < matchingOrders.length; matchingOrderIndex++) { | |
const currentOrderQuantity = parseInt(currentOrder[1], 0); | |
if (currentOrderQuantity === 0) break; | |
const matchingOrder = orders[matchingOrders[matchingOrderIndex].i]; | |
const matchingOrderQuantity = parseInt(matchingOrder[1], 0); | |
if (matchingOrderQuantity === currentOrderQuantity) { | |
executedQuantity += matchingOrderQuantity; | |
matchingOrder[1] = 0; | |
currentOrder[1] = 0; | |
} else if (matchingOrderQuantity < currentOrderQuantity) { | |
executedQuantity += matchingOrderQuantity; | |
matchingOrder[1] = 0; | |
currentOrder[1] -= matchingOrderQuantity; | |
} else if (matchingOrderQuantity > currentOrderQuantity) { | |
executedQuantity += currentOrderQuantity; | |
matchingOrder[1] -= currentOrderQuantity; | |
currentOrder[1] = 0; | |
} | |
} | |
return executedQuantity; | |
}, 0); | |
} | |
function find_matching_orders(orders, order) { | |
const orderType = order[2]; | |
const orderPrice = parseInt(order[0], 0); | |
return orders.reduce((matchingOrders, currentOrder, currentOrderIndex) => { | |
const counterPartyOrderQuantity = parseInt(currentOrder[1], 0); | |
if (counterPartyOrderQuantity === 0) return matchingOrders; | |
const counterPartyOrderType = currentOrder[2]; | |
if (orderType === counterPartyOrderType) return matchingOrders; | |
const counterPartyOrderPrice = parseInt(currentOrder[0], 0); | |
if ( | |
orderType === 'buy' && orderPrice >= counterPartyOrderPrice || | |
orderType === 'sell' && orderPrice <= counterPartyOrderPrice | |
) { | |
matchingOrders.push({ | |
i: currentOrderIndex, | |
order: currentOrder, | |
}); | |
} | |
return matchingOrders; | |
}, []).sort((matchingOrderA, matchingOrderB) => { | |
const matchingOrderAPrice = parseInt(matchingOrderA.order[0], 0); | |
const matchingOrderBPrice = parseInt(matchingOrderB.order[0], 0); | |
return orderType === 'buy' ? matchingOrderAPrice - matchingOrderBPrice : matchingOrderBPrice - matchingOrderAPrice; | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment