@melonproject/ea-bitfinex
Version:
Integration for the Bitfinex API.
87 lines (86 loc) • 3.41 kB
JavaScript
;
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
result["default"] = mod;
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const Rx = __importStar(require("rxjs"));
const book_1 = require("../../api/public/websocket/book");
const operators_1 = require("rxjs/operators");
const defaults = {
length: 25,
};
exports.observe = options => new Rx.Observable(subscriber => {
const state = {
base: options.base,
quote: options.quote,
asks: [],
bids: [],
};
const opts = Object.assign(Object.assign({}, defaults), (options.length && { length: options.length }));
const messages$ = book_1.watchAssetPair(`${options.base}/${options.quote}`, opts).pipe(operators_1.share());
const updates$ = messages$.pipe(operators_1.filter(message => !Array.isArray(message)));
const snapshots$ = messages$.pipe(operators_1.filter(message => Array.isArray(message)));
const updates = updates$.subscribe((event) => {
const volume = event.count.isZero() ? event.count : event.amount.abs();
const value = {
price: event.price,
volume,
};
const bids = event.amount.isPositive() ? [value] : [];
const asks = event.amount.isNegative() ? [value] : [];
state.asks = asks
.reduce((carry, current) => {
// Temporarily remove the updated price level from the state.
const out = carry.filter(item => !item.price.isEqualTo(current.price));
// Only (re-)add the price level if it's not zero.
return current.volume.isZero() ? out : out.concat(current);
}, state.asks)
.sort((a, b) => a.price.comparedTo(b.price))
.slice(0, options.length);
state.bids = bids
.reduce((carry, current) => {
// Temporarily remove the updated price level from the state.
const out = carry.filter(item => !item.price.isEqualTo(current.price));
// Only (re-)add the price level if it's not zero.
return current.volume.isZero() ? out : out.concat(current);
}, state.bids)
.sort((a, b) => b.price.comparedTo(a.price))
.slice(0, options.length);
subscriber.next({
quote: state.quote,
base: state.base,
asks: state.asks.slice(),
bids: state.bids.slice(),
});
});
const snapshots = snapshots$.subscribe((event) => {
state.bids = event
.filter(item => item.amount.isPositive())
.map(item => ({
price: item.price,
volume: item.amount,
}))
.slice(0, opts.length);
state.asks = event
.filter(item => item.amount.isNegative())
.map(item => ({
price: item.price,
volume: item.amount.abs(),
}))
.slice(0, opts.length);
subscriber.next({
quote: state.quote,
base: state.base,
asks: state.asks.slice(),
bids: state.bids.slice(),
});
});
return () => {
updates.unsubscribe();
snapshots.unsubscribe();
};
});