tlab-trading-toolkit
Version:
A trading toolkit for building advanced trading bots on the GDAX platform
105 lines (104 loc) • 5.57 kB
TypeScript
/// <reference types="node" />
/***************************************************************************************************************************
* @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. *
***************************************************************************************************************************/
import { Logger } from '../utils/Logger';
import { OrderbookMessage } from './Messages';
import { Duplex } from 'stream';
/**
* Configuration interface for A MessageQueue
*
* @param logger {Logger} An optional logging interface
*
* @param product {string} A product to filter for. A single feed might be producing messages form multiple products (each with their own
* sequence numbers). This selects for the product so that all messages can be emitted in strictly increasing sequence number.
*
* @param targetQueueLength {number} Tries to maintain the queue length at this value. Default is zero, but you can increase to
* small number like 2 or 3 if messages frequently arrive out of order. This will impose small lag on your feed, but will
* reduce the risk of messages arriving out of order
*
* @param waitForSnapshot If true, messages are queued up until a snapshot message is received. If false, messages are
* emitted in the order they are received without waiting for a snapshot.
*/
export interface MessageQueueConfig {
product: string;
logger?: Logger;
targetQueueLength?: number;
waitForSnapshot: boolean;
}
/**
* The MessageQueue does two things:
* i) Filters input messages for a specific product
* ii) Queues messages, sorts them and emits them in a strictly increasing order.
*
* The source feed can contain multiple product streams. This class will filter out any products that don't match the configured
* product feed. This means you can create a single websocket feed that subscribes to all of, say GDAX's products and then
* create multiple `MessageStreams` without much overhead.
*
* There are three different ways of using the stream:
*
* 1. Push mode: You attach a `data` listener to this stream and each each message will be emitted more/less instantaneously,
* as it is received from the feed. In this case one might still get messages arriving out of order, since the queue is usually
* going to be empty.
* 2. Create the stream in 'paused' mode (the default when you create it) and call `read` when you want the
* next message (perhaps every n ms).
* 3. Pipe the stream to another stream that performs some other function (like filter out HFT trades, or apply an exchange rate)
*
* You can always track out-of-order messages by subscribing to the `messageOutOfSequence` event.
*
* ## Events
*
* ### data(msg)
* Emitted for each message that gets sent out
*
* ### messageOutOfSequence (msg, expectedSequence)
* Emitted if a message is about to be sent out, out of sequence and waiting would violate the `targetQueueLength` constraint
*/
export declare class MessageQueue extends Duplex {
private logger;
private messages;
private targetQueueLength;
private lastSequence;
private productId;
private messageListener;
private waitForSnapshot;
constructor(options: MessageQueueConfig);
readonly product: string;
readonly queueLength: number;
readonly sequence: number;
read(size?: number): OrderbookMessage;
/**
* Close the stream. No more reads will be possible after calling this method
*/
end(): void;
/**
* Add the message to the queue
* @param message
*/
addMessage(message: OrderbookMessage): void;
clearQueue(): void;
/**
* Will provide the next message, in the correct order
* @private
*/
protected _read(): void;
/**
* Returns the next message off the queue, and removes it from the queue. pop() tries to keep the queue at
* `targetQueueLength` if releasing a message would result in messages being out of order, so its possible for
* pop() to return null
* @returns {OrderbookMessage || null}
*/
protected pop(): OrderbookMessage;
protected _write(inputMessage: any, encoding: string, callback: (err: Error) => void): void;
private defaultMessageHandler(msg);
}