tlab-trading-toolkit
Version:
A trading toolkit for building advanced trading bots on the GDAX platform
279 lines (278 loc) • 14.8 kB
JavaScript
;
/***************************************************************************************************************************
* @license *
* Copyright 2017 Coinbase, Inc. *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on *
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the *
* License for the specific language governing permissions and limitations under the License. *
***************************************************************************************************************************/
Object.defineProperty(exports, "__esModule", { value: true });
const types_1 = require("../../src/lib/types");
const createOrderbookUtils_1 = require("./createOrderbookUtils");
const assert = require("assert");
describe('An OrderbookUtils object', () => {
let obu = null;
beforeEach(() => {
const bids = [[100, 10, 1], [99, 5, 1], [98, 1, 1]];
const asks = [[110, 2, 1], [115, 1, 1], [120, 4, 10]];
obu = createOrderbookUtils_1.default(bids, asks);
});
it('can calculate buy side stats when pre-cached', () => {
const stats = obu.calculateMarketOrderStats('buy', 4, types_1.ZERO);
assert(stats);
assert.equal(stats.total_cost.toFixed(1), '455.0');
assert.equal(stats.ave_price.toFixed(2), '113.75');
assert.equal(stats.slippage.toFixed(4), '0.0341');
assert.equal(stats.unfilled.toFixed(4), '0.0000');
assert.equal(stats.first_price.toFixed(2), '110.00');
assert.equal(stats.last_price.toFixed(2), '120.00');
});
it('can calculate sell side stats when pre-cached', () => {
const stats = obu.calculateMarketOrderStats('sell', 15.5);
assert(stats);
assert.equal(stats.total_cost.toFixed(1), '1544.0');
assert.equal(stats.ave_price.toFixed(2), '99.61');
assert.equal(stats.slippage.toFixed(5), '0.00387');
assert.equal(stats.unfilled.toFixed(4), '0.0000');
assert.equal(stats.first_price.toFixed(2), '100.00');
assert.equal(stats.last_price.toFixed(2), '98.00');
});
it('perfect fill case when pre-cached', () => {
const stats = obu.calculateMarketOrderStats('sell', 15.0);
assert(stats);
assert.equal(stats.total_cost.toFixed(1), '1495.0');
assert.equal(stats.ave_price.toFixed(2), '99.67');
assert.equal(stats.slippage.toFixed(5), '0.00333');
assert.equal(stats.unfilled.toFixed(4), '0.0000');
assert.equal(stats.first_price.toFixed(2), '100.00');
assert.equal(stats.last_price.toFixed(2), '99.00');
});
it('can handle too-large orders when pre-cached', () => {
const stats = obu.calculateMarketOrderStats('buy', 8);
assert(stats);
assert.equal(stats.total_cost.toFixed(1), '815.0');
assert.equal(stats.total_size.toFixed(1), '7.0');
assert.equal(stats.ave_price.toFixed(2), '116.43');
assert.equal(stats.slippage.toFixed(4), '0.0584');
assert.equal(stats.unfilled.toFixed(4), '1.0000');
assert.equal(stats.fees.toFixed(2), '0.00');
});
it('can handle zero-size orders when pre-cached', () => {
const stats = obu.calculateMarketOrderStats('buy', 0);
assert(stats);
assert.equal(stats.total_cost.toFixed(1), '0.0');
assert.equal(stats.total_size.toFixed(1), '0.0');
assert.equal(stats.ave_price.toFixed(2), '110.00');
assert.equal(stats.slippage.toFixed(4), '0.0000');
assert.equal(stats.unfilled.toFixed(4), '0.0000');
assert.equal(stats.fees.toFixed(2), '0.00');
});
it('can determine fees when pre-cached', () => {
const stats = obu.calculateMarketOrderStats('buy', 4, types_1.Big(0.001));
assert(stats);
assert.equal(stats.total_cost.toFixed(3), '455.455');
assert.equal(stats.fees.toFixed(3), '0.455');
assert.equal(stats.ave_price.toFixed(3), '113.864');
assert.equal(stats.slippage.toFixed(6), '0.035125');
});
it('can calculate sum of order sizes up to index n', () => {
assert.equal(+obu.getCumulativeSize(1, true), 3);
assert.equal(+obu.getCumulativeSize(1, false), 15);
assert.equal(+obu.getCumulativeSize(0, true), 2);
assert.equal(+obu.getCumulativeSize(0, false), 10);
assert.equal(+obu.getCumulativeSize(2, true), 7);
assert.equal(+obu.getCumulativeSize(3, false), 16);
});
it('can calculate sum of costs up to index n', () => {
assert.equal(+obu.getCumulativeCost(1, true), 335);
assert.equal(+obu.getCumulativeCost(1, false), 1495);
assert.equal(+obu.getCumulativeCost(0, true), 220);
assert.equal(+obu.getCumulativeCost(0, false), 1000);
assert.equal(+obu.getCumulativeCost(2, true), 815);
assert.equal(+obu.getCumulativeCost(3, false), 1593);
});
});
describe('Partial sums of orderbooks', () => {
let obu = null;
beforeEach(() => {
const bids = [[100, 10, 1], [99, 5, 1], [98, 1, 1], [97, 3, 1]];
const asks = [[110, 2, 1], [115, 1, 1], [120, 4, 10], [125, 2, 3]];
obu = createOrderbookUtils_1.default(bids, asks);
});
it('calculates sell stats between 10 and 15 BTC', () => {
const stats = obu.integrateBetween(types_1.Big(10), types_1.Big(15), false, types_1.Big(0));
assert.equal(+stats.total_size, 5);
assert.equal(+stats.first_price, 99);
assert.equal(+stats.last_price, 99);
assert.equal(+stats.total_cost, 495);
assert.equal(+stats.unfilled, 0);
});
it('calculates sell stats between 3 and 15.5 BTC', () => {
const stats = obu.integrateBetween(types_1.Big(3), types_1.Big(15.5), false, types_1.Big(0));
assert.equal(+stats.total_size, 12.5);
assert.equal(+stats.first_price, 100);
assert.equal(+stats.last_price, 98);
assert.equal(+stats.total_cost, 700 + 495 + 49);
assert.equal(+stats.unfilled, 0);
});
it('calculates sell stats between 10 and 10.1 BTC', () => {
const stats = obu.integrateBetween(types_1.Big(10), types_1.Big(10.1), false, types_1.Big(0));
assert.equal(+stats.total_size, 0.1);
assert.equal(+stats.first_price, 99);
assert.equal(+stats.last_price, 99);
assert.equal(+stats.total_cost, 9.9);
assert.equal(+stats.unfilled, 0);
});
it('calculates sell stats between 11 and 17 BTC', () => {
const stats = obu.integrateBetween(types_1.Big(11), types_1.Big(17), false, types_1.Big(0));
assert.equal(+stats.total_size, 6);
assert.equal(+stats.first_price, 99);
assert.equal(+stats.last_price, 97);
assert.equal(+stats.total_cost, 4 * 99 + 98 + 97);
assert.equal(+stats.unfilled, 0);
});
it('calculates sell stats between 11 and 17 BTC with fees', () => {
const stats = obu.integrateBetween(types_1.Big(11), types_1.Big(17), false, types_1.Big(0.01));
assert.equal(+stats.total_size, 6);
assert.equal(+stats.first_price, 99);
assert.equal(+stats.last_price, 97);
assert.equal(+stats.total_cost, (4 * 99 + 98 + 97) * 1.01);
assert.equal(+stats.fees, (4 * 99 + 98 + 97) * 0.01);
assert.equal(+stats.unfilled, 0);
});
it('calculates sell stats between 16 and 20 BTC', () => {
const stats = obu.integrateBetween(types_1.Big(16), types_1.Big(20), false, types_1.Big(0));
assert.equal(+stats.total_size, 3);
assert.equal(+stats.first_price, 97);
assert.equal(+stats.last_price, 97);
assert.equal(+stats.total_cost, 3 * 97);
assert.equal(+stats.unfilled, 1);
});
it('calculates buy stats between 1 and 3 BTC', () => {
const stats = obu.integrateBetween(types_1.Big(1), types_1.Big(3), true, types_1.Big(0));
assert.equal(+stats.total_size, 2);
assert.equal(+stats.first_price, 110);
assert.equal(+stats.last_price, 115);
assert.equal(+stats.total_cost, 110 + 115);
assert.equal(+stats.unfilled, 0);
});
it('calculates buy stats between 2 and 7 BTC', () => {
const stats = obu.integrateBetween(types_1.Big(2), types_1.Big(7), true, types_1.Big(0));
assert.equal(+stats.total_size, 5);
assert.equal(+stats.first_price, 115);
assert.equal(+stats.last_price, 120);
assert.equal(+stats.total_cost, 115 + 4 * 120);
assert.equal(+stats.unfilled, 0);
});
it('calculates buy stats between 2 and 2 BTC', () => {
const stats = obu.integrateBetween(types_1.Big(2), types_1.Big(2), true, types_1.Big(0));
assert.equal(+stats.total_size, 0);
assert.equal(+stats.first_price, 115);
assert.equal(+stats.last_price, 115);
assert.equal(+stats.total_cost, 0);
assert.equal(+stats.unfilled, 0);
});
it('calculates buy stats between 2.5 and 2.5 BTC', () => {
const stats = obu.integrateBetween(types_1.Big(2.5), types_1.Big(2.5), true, types_1.Big(0));
assert.equal(+stats.total_size, 0);
assert.equal(+stats.first_price, 115);
assert.equal(+stats.last_price, 115);
assert.equal(+stats.total_cost, 0);
assert.equal(+stats.unfilled, 0);
});
});
describe('Sums using quote currency', () => {
let obu = null;
beforeEach(() => {
const bids = [[100, 10, 1], [95, 50, 1], [90, 10, 1], [85, 20, 1]];
const asks = [[110, 2, 1], [115, 1, 1], [120, 4, 10], [125, 100, 1]];
obu = createOrderbookUtils_1.default(bids, asks);
});
it('calculates sell stats for $550', () => {
const stats = obu.getSizeFromCost(types_1.Big(0), types_1.Big(550), false, types_1.Big(0));
assert.equal(+stats.total_size, 5.5);
assert.equal(+stats.first_price, 100);
assert.equal(+stats.last_price, 100);
assert.equal(+stats.total_cost, 550);
assert.equal(+stats.unfilled, 0);
});
it('calculates buy stats for $165', () => {
const stats = obu.getSizeFromCost(types_1.Big(0), types_1.Big(165), true, types_1.Big(0));
assert.equal(+stats.total_size, 1.5);
assert.equal(+stats.first_price, 110);
assert.equal(+stats.last_price, 110);
assert.equal(+stats.total_cost, 165);
assert.equal(+stats.unfilled, 0);
});
it('calculates sell stats for $1095', () => {
const stats = obu.getSizeFromCost(types_1.Big(0), types_1.Big(1095), false, types_1.Big(0));
assert.equal(+stats.total_size, 11);
assert.equal(+stats.first_price, 100);
assert.equal(+stats.last_price, 95);
assert.equal(+stats.total_cost, 1095);
assert.equal(+stats.unfilled, 0);
});
it('calculates buy stats for $8,000', () => {
const stats = obu.getSizeFromCost(types_1.Big(0), types_1.Big(8000), true, types_1.Big(0));
assert.equal(+stats.total_size, 64.48);
assert.equal(+stats.first_price, 110);
assert.equal(+stats.last_price, 125);
assert.equal(+stats.total_cost, 8000);
assert.equal(+stats.unfilled, 0);
});
it('calculates sell stats for $1000 starting from $500', () => {
const stats = obu.getSizeFromCost(types_1.Big(500), types_1.Big(1000), false, types_1.Big(0));
assert.equal(+stats.total_size, 5 + 500 / 95); // 10.26315789
assert.equal(+stats.first_price, 100);
assert.equal(+stats.last_price, 95);
assert.equal(+stats.total_cost, 1000);
assert.equal(+stats.unfilled, 0);
});
it('calculates buy stats for $2000 starting from $1000', () => {
const stats = obu.getSizeFromCost(types_1.Big(1000), types_1.Big(2000), true, types_1.Big(0));
assert.equal(+stats.total_size.toFixed(6), 16);
assert.equal(+stats.first_price, 125);
assert.equal(+stats.last_price, 125);
assert.equal(+stats.total_cost, 2000);
assert.equal(+stats.unfilled, 0);
});
it('calculates sell stats for $0 starting from $1200', () => {
const stats = obu.getSizeFromCost(types_1.Big(5000), types_1.Big(0), false, types_1.Big(0));
assert.equal(+stats.total_size, 0);
assert.equal(+stats.first_price, 95);
assert.equal(+stats.last_price, 95);
assert.equal(+stats.total_cost, 0);
assert.equal(+stats.unfilled, 0);
});
it('calculates buy stats for $0 starting from $2500', () => {
const stats = obu.getSizeFromCost(types_1.Big(2500), types_1.Big(0), true, types_1.Big(0));
assert.equal(+stats.total_size, 0);
assert.equal(+stats.first_price, 125);
assert.equal(+stats.last_price, 125);
assert.equal(+stats.total_cost, 0);
assert.equal(+stats.unfilled, 0);
});
it('calculates sell stats for $1000 starting from $500, including fees', () => {
const stats = obu.getSizeFromCost(types_1.Big(500), types_1.Big(1000), false, types_1.Big(0.01));
assert.equal(+stats.total_size.toFixed(6), 10.158937);
assert.equal(+stats.first_price, 100);
assert.equal(+stats.last_price, 95);
assert.equal(+stats.total_cost, 1000);
assert.equal(+stats.unfilled, 0);
});
it('calculates buy stats for $15,000 starting from $750, including fees', () => {
const stats = obu.getSizeFromCost(types_1.Big(750), types_1.Big(15000), true, types_1.Big(0.01));
assert.equal(+stats.total_size.toFixed(3), 100.542);
assert.equal(+stats.first_price, 120);
assert.equal(+stats.last_price, 125);
assert.equal(+stats.total_cost, 12690.65);
assert.equal(+stats.fees, 125.65);
assert.equal(+stats.unfilled, 2309.35);
});
});