This file contains hidden or 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
/* | |
* PEG.js grammar for evaluating numbers | |
* Modified from Majda's JSON parser example | |
*/ | |
number | |
= minus? int frac? exp? {return parseFloat(text());} | |
decimal_point = "." | |
digit1_9 = [1-9] |
This file contains hidden or 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
// PEG parser combinators | |
const lookup = x => typeof x == 'string' ? eval(x) : x | |
const match = (x, y, z) => x ? { c:y, v:z } : { e: true } | |
const eof = s => match(s.length, 0, '') | |
const char = s => match(s.length, 1, s[0]) | |
const not = g => s => match(g(s).e, 0, '') | |
const has = g => s => match(!g(s).e, 0, '') | |
const oneof = t => s => match(t.indexOf(s[0]) >= 0, 1, s[0]) | |
const lit = t => s => match(!s.indexOf(t), t.length, t) | |
const option = g => choose(g, lit('')) |
This file contains hidden or 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
// AST version: returns an Abstract Syntax Tree. | |
// Refactors subtraction into adding negatives. | |
// e.g. 1-2-3 is treated as 1+(-2)+(-3). | |
// | |
// Refactors division into multiplying by a reciprocal. | |
// e.g. 1024/2/2 is treated as 1024 * 1/2 * 1/2. | |
// | |
// Author: Benjamin J. Kruger <[email protected] |
This file contains hidden or 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
Scenario Outline: Decrease top outstanding order partially and then fill it completely | |
When the following orders are added to the "<Side>" book: | |
| Broker | Qty | Price | | |
| A | 100 | 10.5 | | |
| B | 100 | 10.5 | | |
Then the "<Side>" order book looks like: | |
| Broker | Qty | Price | | |
| A | 100 | 10.5 | | |
| B | 100 | 10.5 | | |
When the top order of the "<Side>" book is filled by "20" |
This file contains hidden or 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
Feature: Core matching logic for limit orders | |
Background: Submit initial non-crossing orders to work with | |
Given the following orders are submitted in this order: | |
| Broker | Side | Qty | Price | | |
| A | Buy | 100 | 10.4 | | |
| B | Buy | 200 | 10.3 | | |
| C | Sell | 100 | 10.7 | | |
| D | Sell | 200 | 10.8 | | |
Then no trades are generated |
This file contains hidden or 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
Feature: Core Market Order Functionality for Price and Time Priority | |
Scenario Outline: Price and time priority of market orders over limit orders | |
When the following orders are added to the "<Side>" book: | |
| Broker | Qty | Price | | |
| A | 100 | 10.5 | | |
Then the "<Side>" order book looks like: | |
| Broker | Qty | Price | | |
| A | 100 | 10.5 | | |
When the following orders are added to the "<Side>" book: |
This file contains hidden or 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
class OrderBook(side: Side, orderTypes: (Order => OrderType)) { | |
private var marketBook: List[Order] = Nil | |
private var limitBook: List[(Double, List[Order])] = Nil | |
private val priceOrdering = if (side == Sell) Ordering[Double] else Ordering[Double].reverse | |
def add(order: Order) { | |
orderTypes(order).price match { |
This file contains hidden or 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
Feature: Core matching logic for market orders | |
Scenario: Matching a large Buy market order against multiple limit orders | |
The order is large enough to fill the entire opposite book | |
The remainder of the market order is expected to rest in its book | |
When the following orders are submitted in this order: | |
| Broker | Side | Qty | Price | | |
| A | Buy | 100 | 10.7 | | |
| B | Buy | 200 | 10.6 | | |
| C | Buy | 300 | 10.5 | |
This file contains hidden or 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
Feature: Maintaining best limit in the order book | |
Scenario Outline: Various life cycles of the order book best limit | |
# When are no orders in the book, the best limit is not defined | |
Then the best limit for "<Side>" order book is "None" | |
# If a market order enters the book, the best limit is still undefined | |
When the following orders are added to the "<Side>" book: | |
| Broker | Qty | Price | | |
| A | 100 | MO | | |
Then the "<Side>" order book looks like: |
This file contains hidden or 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
Scenario: Matching incoming Buy limit order against a single outstanding Sell market order | |
When the following orders are submitted in this order: | |
| Broker | Side | Qty | Price | | |
| A | Sell | 100 | MO | | |
| B | Buy | 120 | 10.5 | | |
Then the following trades are generated: | |
| Buying broker | Selling broker | Qty | Price | | |
| B | A | 100 | 10.5 | | |
And market order book looks like: | |
| Broker | Qty | Price | Price | Qty | Broker | |