UNPKG

tlab-trading-toolkit

Version:

A trading toolkit for building advanced trading bots on the GDAX platform

123 lines (115 loc) 5.98 kB
/*************************************************************************************************************************** * @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 * as GTT from '..'; import { TradeMessage } from '../src/core'; import { GDAXFeed } from '../src/exchanges/gdax/GDAXFeed'; import { SkippedMessageEvent } from '../src/core/LiveOrderbook'; import { Ticker } from '../src/exchanges/PublicExchangeAPI'; import { RedisBook, RedisBookConfig } from '../src/lib/RedisBook'; import { Writable } from 'stream' import { getRedisct, getEmitter } from '../src/core/RedisConnector' import { getIntervalTimeStamp } from 'tlab-util'; var redisct = getRedisct(); var io = getEmitter(); const EXCHANGE:string = process.env.Exchange || "GDAX"; let orderBooks = new Map<string, RedisBook>(); class SocketStream extends Writable { write(msg: any, callback: any): boolean { msg.exchange = EXCHANGE; let room = `${msg.exchange}:${msg.productId}`; let orderBookRoom = `${room}:book`; let tickerRoom = `${room}:ticker`; let type = 'book'; let toRoom = ''; switch(msg.type) { case 'ticker': toRoom = tickerRoom; type = 'ticker'; break; case 'snapshot': type = 'snapshot'; toRoom = orderBookRoom; break; case 'trade': var ltt = new Date(msg.time).getTime(); const ticker = { type: 'trade', ltt : ltt, scrip : msg.productId, exchange: msg.exchange, ltp: msg.price, volume: msg.size }; io.of('/api/quotes').to(tickerRoom).emit('ticker', Object.assign({}, ticker, {productId : room})); var quote = {ts:getIntervalTimeStamp(ltt, 60, 0), o : msg.price, h : msg.price, l:msg.price, c:msg.price, v:msg.size, exchange:msg.exchange, scrip:msg.productId} redisct.saveQuotes(quote, getIntervalTimeStamp(ltt, 86400, 0)); case 'level': toRoom = orderBookRoom; type ='book'; break; } io.of('/api/quotes').to(toRoom).emit(type, Object.assign({}, msg, {productId : room})); return true; } } const logger = GTT.utils.ConsoleLoggerFactory({ level: 'debug' }); async function start() { let tradeVolume: number = 0; console.log('Configuring Exchange ', EXCHANGE); await GTT.Exchanges.ProductMap.configureExchange(EXCHANGE); let products = await GTT.Exchanges.ProductMap.ExchangeMap.get(EXCHANGE).getAvailableProducts(); console.log('Total available products', products.length); let factories:any = GTT.Factories; let socketStream = new SocketStream(); factories[EXCHANGE].FeedFactory(logger, products).then((feed: GDAXFeed) => { // Configure the live book object console.log('Feed started for exchange ', EXCHANGE); products.forEach((product:any)=> { const config: RedisBookConfig = { product: product, logger: logger, exchange : EXCHANGE, }; const book = new RedisBook(config); book.on('LiveOrderbook.snapshot', () => { // logger.log('info', 'Snapshot received by LiveOrderbook Demo for '+product); }); book.on('LiveOrderbook.ticker', (ticker: Ticker) => { // console.log(printTicker(ticker)); }); book.on('LiveOrderbook.trade', (trade: TradeMessage) => { tradeVolume += +(trade.size); }); book.on('LiveOrderbook.skippedMessage', (details: SkippedMessageEvent) => { // On GDAX, this event should never be emitted, but we put it here for completeness console.log('SKIPPED MESSAGE', details); console.log('Reconnecting to feed'); feed.reconnect(0); }); book.on('end', () => { console.log('Orderbook closed'); }); book.on('error', (err) => { console.log('Livebook errored: ', err); feed.pipe(book); }); feed.pipe(book); orderBooks.set(product, book); }) feed.pipe(socketStream); }).catch((err:any) => { logger.error(err); }); } start();