Skip to content
This repository has been archived by the owner on Sep 9, 2023. It is now read-only.

Added book ticker to BinanceClient. #324

Open
wants to merge 38 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
92a57b7
Merge pull request #1 from karimhossenbux/master
jargote May 11, 2021
15afe1f
Ignoring vscode history
jargote May 11, 2021
83e2727
Defined BookTicker class for representing an orderbook ticker event
jargote May 11, 2021
008c904
Added generic functions for subscribing to orderbook ticker in basic …
jargote May 11, 2021
e98d31a
Implementing concrete subscribe and unsubscribe functions for binance…
jargote May 11, 2021
6845ef1
Added bookTicker enum value
jargote May 12, 2021
ed27d5b
Marking ws alive when bookTicker events are received
jargote May 12, 2021
514c1ba
Removed non-existent property
jargote May 12, 2021
0360fd9
resubscribe to bookTicker on reconnection
jargote May 12, 2021
16aa412
Added handlers for bookTicker on MultiClient
jargote May 12, 2021
d2f1e77
Better matching of bookTicker stream messages
jargote May 12, 2021
9e9e15d
Overriding _onConnected for binance client to limit to maximum 5 subs…
jargote May 23, 2021
3c8d2f6
Generalised throttled subscriptions
jargote May 23, 2021
c72adf6
Bug fix
jargote May 23, 2021
b1c4b35
Not clearing subscription map on closing
jargote May 23, 2021
ccbbeea
Fixes to binance _onConnected handler
jargote May 23, 2021
f862669
Batching subscriptions for ticker and orderbook. [WIP] Adding support…
jargote Aug 2, 2021
94bf23d
Fixed @bookTicker and !bookTicker streams
jargote Aug 3, 2021
53bf940
Connect client after initialization
jargote Apr 15, 2022
0f32581
Bumping version
jargote Apr 15, 2022
5f12ae8
Added yarn lock
jargote Apr 15, 2022
0171094
Merge branch 'master' of https://github.com/altangent/ccxws into develop
jargote Apr 18, 2022
0157a1e
Added BookTicker to TS ccxws version
jargote Apr 18, 2022
81b3e41
fixes
jargote Apr 18, 2022
ae32aa6
ts fixes
jargote Apr 18, 2022
58d962f
Batching Binance subscriptions/unsubscriptions
jargote Apr 19, 2022
a012a26
Removing left-over .js files
jargote Apr 19, 2022
293724f
Removing .js files
jargote Apr 19, 2022
f24fdee
Do not output declarations
jargote Jun 23, 2022
3ef7408
Added ping - pong envents to SmartWSS to avoid disconnections
jargote Jul 3, 2022
aa37287
Adding timestamp to ws messages. Using timestamp on BookTicker
jargote Oct 3, 2022
760872c
Fixing syntax error
jargote Oct 3, 2022
c05f8c1
Checking for null message
jargote Oct 3, 2022
4e5a017
Replaced timestamp for hrtime
jargote Nov 5, 2022
123f508
Added hrtime to BookTicker. Removed timestamp
jargote Nov 5, 2022
a455d43
Updated BookTicker definition
jargote Nov 5, 2022
46d35b2
Error fix
jargote Nov 5, 2022
1c447fa
Added uId to BookTicker
jargote Dec 1, 2022
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
Prev Previous commit
Next Next commit
Added BookTicker to TS ccxws version
  • Loading branch information
jargote committed Apr 18, 2022
commit 0157a1e048ba556bbbeec162457f7c3b0515e03f
49 changes: 49 additions & 0 deletions __tests__/BasicClient.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import { BasicClient } from "../src/BasicClient";
class TestClient extends BasicClient {
protected _onMessage = sinon.stub();
protected _sendSubTicker = sinon.stub();
protected _sendSubBookTicker = sinon.stub();
protected _sendSubCandles = sinon.stub();
protected _sendUnsubCandles = sinon.stub();
protected _sendUnsubTicker = sinon.stub();
protected _sendUnsubBookTicker = sinon.stub();
protected _sendSubTrades = sinon.stub();
protected _sendUnsubTrades = sinon.stub();
protected _sendSubLevel2Snapshots = sinon.stub();
Expand All @@ -26,6 +28,7 @@ class TestClient extends BasicClient {
function buildInstance() {
const instance = new TestClient("wss:https://localhost/test", "test", mockSmartWss);
instance.hasTickers = true;
instance.hasBookTickers = true;
instance.hasTrades = true;
instance.hasCandles = true;
instance.hasLevel2Snapshots = true;
Expand Down Expand Up @@ -398,6 +401,52 @@ describe("BasicClient", () => {
// });
});

describe("bookTicker", () => {
let instance;

before(() => {
instance = buildInstance();
instance._connect();
});

describe("on first subscribe", () => {
it("should open a connection", () => {
instance.subscribeBookTicker({ id: "BTCUSD" });
expect(instance._wss).to.not.be.undefined;
expect(instance._wss.connect.callCount).to.equal(1);
});
it("should send subscribe to the socket", () => {
instance._wss.mockEmit("connected");
expect(instance._sendSubBookTicker.callCount).to.equal(1);
expect(instance._sendSubBookTicker.args[0][0]).to.equal("BTCUSD");
expect(instance._sendSubBookTicker.args[0][1]).to.be.an("object");
});
it("should start the reconnectChecker", () => {
expect(instance._watcher.start.callCount).to.equal(1);
});
});

describe("on subsequent subscribes", () => {
it("should not connect again", () => {
instance.subscribeBookTicker({ id: "LTCBTC" });
expect(instance._wss.connect.callCount).to.equal(1);
});
it("should send subscribe to the socket", () => {
expect(instance._sendSubBookTicker.callCount).to.equal(2);
expect(instance._sendSubBookTicker.args[1][0]).to.equal("LTCBTC");
expect(instance._sendSubBookTicker.args[1][1]).to.be.an("object");
});
});

// describe("on unsubscribe", () => {
// it("should send unsubscribe to socket", () => {
// instance.unsubscribeTicker({ id: "LTCBTC" });
// expect(instance._sendUnsubTicker.callCount).to.equal(1);
// expect(instance._sendUnsubTicker.args[0][0]).to.equal("LTCBTC");
// });
// });
});

describe("candle", () => {
let instance;

Expand Down
4 changes: 0 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
{
"name": "ccxws",
<<<<<<< HEAD
"version": "0.43.2",
=======
"version": "0.47.0",
>>>>>>> 50ec03d4900ee9027a05678869ba05adb4d02fa3
"description": "Websocket client for 37 cryptocurrency exchanges",
"keywords": [
"bitmex",
Expand Down
21 changes: 21 additions & 0 deletions src/BasicClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export type SendFn = (remoteId: string, market: Market) => void;
*/
export abstract class BasicClient extends EventEmitter implements IClient {
public hasTickers: boolean;
public hasBookTickers: boolean;
public hasTrades: boolean;
public hasCandles: boolean;
public hasLevel2Snapshots: boolean;
Expand All @@ -28,6 +29,7 @@ export abstract class BasicClient extends EventEmitter implements IClient {

protected _wssFactory: WssFactoryFn;
protected _tickerSubs: MarketMap;
protected _bookTickerSubs: MarketMap;
protected _tradeSubs: MarketMap;
protected _candleSubs: MarketMap;
protected _level2SnapshotSubs: MarketMap;
Expand All @@ -45,6 +47,7 @@ export abstract class BasicClient extends EventEmitter implements IClient {
) {
super();
this._tickerSubs = new Map();
this._bookTickerSubs = new Map();
this._tradeSubs = new Map();
this._candleSubs = new Map();
this._level2SnapshotSubs = new Map();
Expand All @@ -55,6 +58,7 @@ export abstract class BasicClient extends EventEmitter implements IClient {
this._watcher = new Watcher(this, watcherMs);

this.hasTickers = false;
this.hasBookTickers = false;
this.hasTrades = true;
this.hasCandles = false;
this.hasLevel2Snapshots = false;
Expand Down Expand Up @@ -97,6 +101,16 @@ export abstract class BasicClient extends EventEmitter implements IClient {
this._unsubscribe(market, this._tickerSubs, this._sendUnsubTicker.bind(this));
}

public subscribeBookTicker(market: Market) {
if (!this.hasBookTickers) return;
return this._subscribe(market, this._bookTickerSubs, this._sendSubBookTicker.bind(this));
}

public unsubscribeBookTicker(market: Market): Promise<void> {
if (!this.hasBookTickers) return;
this._unsubscribe(market, this._bookTickerSubs, this._sendUnsubBookTicker.bind(this));
}

public subscribeCandles(market: Market) {
if (!this.hasCandles) return;
return this._subscribe(market, this._candleSubs, this._sendSubCandles.bind(this));
Expand Down Expand Up @@ -277,6 +291,9 @@ export abstract class BasicClient extends EventEmitter implements IClient {
for (const [marketSymbol, market] of this._tickerSubs) {
this._sendSubTicker(marketSymbol, market);
}
for (const [marketSymbol, market] of this._bookTickerSubs) {
this._sendSubBookTicker(marketSymbol, market);
}
for (const [marketSymbol, market] of this._candleSubs) {
this._sendSubCandles(marketSymbol, market);
}
Expand Down Expand Up @@ -339,12 +356,16 @@ export abstract class BasicClient extends EventEmitter implements IClient {

protected abstract _sendSubTicker(remoteId: string, market: Market);

protected abstract _sendSubBookTicker(remoteId: string, market: Market);

protected abstract _sendSubCandles(remoteId: string, market: Market);

protected abstract _sendUnsubCandles(remoteId: string, market: Market);

protected abstract _sendUnsubTicker(remoteId: string, market: Market);

protected abstract _sendUnsubBookTicker(remoteId: string, market: Market);

protected abstract _sendSubTrades(remoteId: string, market: Market);

protected abstract _sendUnsubTrades(remoteId: string, market: Market);
Expand Down
24 changes: 24 additions & 0 deletions src/BasicMultiClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { NotImplementedFn } from "./NotImplementedFn";
export abstract class BasicMultiClient extends EventEmitter {
public name: string;
public hasTickers: boolean;
public hasBookTickers: boolean;
public hasTrades: boolean;
public hasCandles: boolean;
public hasLevel2Snapshots: boolean;
Expand All @@ -33,6 +34,7 @@ export abstract class BasicMultiClient extends EventEmitter {
this._clients = new Map();

this.hasTickers = false;
this.hasBookTickers = false;
this.hasTrades = false;
this.hasCandles = false;
this.hasLevel2Snapshots = false;
Expand Down Expand Up @@ -74,6 +76,19 @@ export abstract class BasicMultiClient extends EventEmitter {
}
}

public subscribeBookTicker(market: Market) {
if (!this.hasBookTickers) return;
this._subscribe(market, this._clients, SubscriptionType.bookTicker);
}

public async unsubscribeBookTicker(market: Market) {
if (!this.hasBookTickers) return;
if (this._clients.has(market.id)) {
const client = await this._clients.get(market.id);
client.unsubscribeBookTicker(market);
}
}

public subscribeCandles(market: Market) {
if (!this.hasCandles) return;
this._subscribe(market, this._clients, SubscriptionType.candle);
Expand Down Expand Up @@ -184,6 +199,15 @@ export abstract class BasicMultiClient extends EventEmitter {
}
}

if (subscriptionType === SubscriptionType.bookTicker) {
const subscribed = client.subscribeBookTicker(market);
if (subscribed) {
client.on("bookTicker", (ticker, market) => {
this.emit("bookTicker", ticker, market);
});
}
}

if (subscriptionType === SubscriptionType.candle) {
const subscribed = client.subscribeCandles(market);
if (subscribed) {
Expand Down
38 changes: 38 additions & 0 deletions src/BookTicker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* {
* "u":400900217, // order book updateId
* "s":"BNBUSDT", // symbol
* "b":"25.35190000", // best bid price
* "B":"31.21000000", // best bid qty
* "a":"25.36520000", // best ask price
* "A":"40.66000000" // best ask qty
* }
*
* @class BookTicker
*/
export class BookTicker {
public exchange: string;
public base: string;
public quote: string;
public bid: string;
public bidVolume: string;
public ask: string;
public askVolume: string;

constructor({ exchange, base, quote, bid, bidVolume, ask, askVolume }) {
this.exchange = exchange;
this.base = base;
this.quote = quote;
this.bid = bid;
this.bidVolume = bidVolume;
this.ask = ask;
this.askVolume = askVolume;
}

/**
* @deprecated use Market object (second argument to each event) to determine exchange and trade pair
*/
get fullId() {
return `${this.exchange}:${this.base}/${this.quote}`;
}
}
3 changes: 3 additions & 0 deletions src/IClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Market } from "./Market";

export interface IClient extends EventEmitter {
hasTickers: boolean;
hasBookTickers: boolean;
hasTrades: boolean;
hasCandles: boolean;
hasLevel2Snapshots: boolean;
Expand All @@ -15,6 +16,8 @@ export interface IClient extends EventEmitter {

subscribeTicker(market: Market): void;
unsubscribeTicker(market: Market): Promise<void>;
subscribeBookTicker(market: Market): void;
unsubscribeBookTicker(market: Market): Promise<void>;
subscribeCandles(market: Market): void;
unsubscribeCandles(market: Market): Promise<void>;
subscribeTrades(market: Market): void;
Expand Down
1 change: 1 addition & 0 deletions src/SubscriptionType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ export enum SubscriptionType {
level3snapshot = 5,
level3update = 6,
candle = 7,
bookTicker = 8,
}
1 change: 1 addition & 0 deletions src/Watcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export class Watcher {
this._lastMessage = undefined;

client.on("ticker", this.markAlive.bind(this));
client.on("bookTicker", this.markAlive.bind(this));
client.on("candle", this.markAlive.bind(this));
client.on("trade", this.markAlive.bind(this));
client.on("l2snapshot", this.markAlive.bind(this));
Expand Down
4 changes: 2 additions & 2 deletions src/basic-auth-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class BasicAuthTradeClient extends BasicClient {
for (let marketSymbol of this._bookTickerSubs.keys()) {
this._sendSubBookTicker(marketSymbol);
}
if(this._allBookTickerSubs) {
if (this._allBookTickerSubs) {
this._sendSubAllBookTicker();
}
for (let marketSymbol of this._candleSubs.keys()) {
Expand All @@ -80,7 +80,7 @@ class BasicAuthTradeClient extends BasicClient {
JSON.stringify({
e: "auth",
auth: this.createAuthToken(),
})
}),
);
}
}
Expand Down
8 changes: 6 additions & 2 deletions src/basic-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@ class BasicTradeClient extends EventEmitter {

unsubscribeAllBookTicker(market) {
if (!this.hasAllBookTicker) return;
return this._unsubscribe(market, this._allBookTickerSubs, this._sendUnsubAllBookTicker.bind(this));
return this._unsubscribe(
market,
this._allBookTickerSubs,
this._sendUnsubAllBookTicker.bind(this),
);
}

subscribeCandles(market) {
Expand Down Expand Up @@ -117,7 +121,7 @@ class BasicTradeClient extends EventEmitter {
return this._subscribe(
market,
this._level2SnapshotSubs,
this._sendSubLevel2Snapshots.bind(this)
this._sendSubLevel2Snapshots.bind(this),
);
}

Expand Down
40 changes: 0 additions & 40 deletions src/bookTicker.js

This file was deleted.

2 changes: 1 addition & 1 deletion src/enums.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const MarketObjectTypes = Object.freeze({
level3snapshot: 5,
level3update: 6,
candle: 7,
bookTicker: 8
bookTicker: 8,
});

const CandlePeriod = Object.freeze({
Expand Down
5 changes: 5 additions & 0 deletions src/exchanges/BiboxClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export class BiboxClient extends EventEmitter implements IClient {
public readonly options: any;

public readonly hasTickers: boolean;
public readonly hasBookTickers: boolean;
public readonly hasTrades: boolean;
public readonly hasCandles: boolean;
public readonly hasLevel2Snapshots: boolean;
Expand All @@ -49,6 +50,8 @@ export class BiboxClient extends EventEmitter implements IClient {
protected _clients: BiboxBasicClient[];
protected _subscribe: CancelableFn;

public subscribeBookTicker = NotImplementedFn
public unsubscribeBookTicker = NotImplementedFn
public subscribeLevel2Updates = NotImplementedFn;
public unsubscribeLevel2Updates = NotImplementedAsyncFn;
public subscribeLevel3Snapshots = NotImplementedFn;
Expand Down Expand Up @@ -248,6 +251,8 @@ export class BiboxBasicClient extends BasicClient {
public subCount: number;
public parent: BiboxClient;

protected _sendSubBookTicker = NotImplementedFn;
protected _sendUnsubBookTicker = NotImplementedFn;
protected _sendSubLevel2Updates = NotImplementedFn;
protected _sendUnsubLevel2Updates = NotImplementedAsyncFn;
protected _sendSubLevel3Snapshots = NotImplementedFn;
Expand Down
Loading