import { Exchange , Trade , Order } from 'ccxt' ; import { coinbasepro , binance , chaos } from './adapters' ; import { ExchangeAdapter } from './adapters/base' ; import { OrderWithTrades } from '@lib' ; import Bottleneck from 'bottleneck' ; import { logger } from '@util' ; const adapters = { binance , coinbasepro , chaos } ; export class ExchangeWrapper { public scan : 'back' | 'forward' ; private adapter : ExchangeAdapter ; private exchangeConnection : Exchange ; private bottleneck : Bottleneck ; constructor ( exchange , exchangeConnectionFn ) { if ( ! ( exchange in adapters ) ) throw new Error ( `No adapter for ${ exchange }.` ) ; this . adapter = adapters [ exchange ] ; this . exchangeConnection = exchangeConnectionFn ( this . adapter . options || { } ) ; this . scan = this . adapter . scan ; this . bottleneck = new Bottleneck ( { minTime : this . adapter . ratelimit } ) ; } public getTradeCursor ( trade ) { return this . adapter . getTradeCursor ( trade ) ; } public async getSymbols ( ) { const symbols = this . exchangeConnection . symbols ; if ( symbols ) return symbols ; await this . exchangeConnection . loadMarkets ( ) ; return this . exchangeConnection . symbols ; } public async fetchTrades ( symbol , start ) { const params = this . adapter . mapTradeParams ( start ) ; const fn = ( ) => this . exchangeConnection . fetchTrades ( symbol , undefined , undefined , params ) ; const res = await this . bottleneck . schedule ( fn ) ; return res ; } public async fetchMyTrades ( symbol ) { const fn = ( ) => this . exchangeConnection . fetchMyTrades ( symbol ) ; const res = await this . bottleneck . schedule ( fn ) ; const debug = { name : 'fetchMyTrades' , req : { } , res } ; logger . silly ( JSON . stringify ( debug ) ) ; return res ; } public async fetchBalance ( ) { const fn = ( ) => this . exchangeConnection . fetchBalance ( ) ; const res = await this . bottleneck . schedule ( fn ) ; const debug = { name : 'fetchBalance' , req : { } , res } ; logger . silly ( JSON . stringify ( debug ) ) ; return res ; } public async fetchOrderBook ( symbol ) { const fn = ( ) => this . exchangeConnection . fetchOrderBook ( symbol ) ; const res = await this . bottleneck . schedule ( fn ) ; const debug = { name : 'fetchOrderBook' , req : { symbol } , res } ; logger . silly ( JSON . stringify ( debug ) ) ; return res ; } public async createOrder ( symbol , type , side , amount , price ) { const params = { newOrderRespType : 'FULL' } ; const fn = ( ) => this . exchangeConnection . createOrder ( symbol , type , side , amount , price , params ) ; const res = await this . bottleneck . schedule ( fn ) ; const debug = { name : 'createOrder' , req : { symbol , type , side , amount , price } , res } ; logger . silly ( JSON . stringify ( debug ) ) ; return res ; } public async checkOrder ( orderId , symbol ) { const fn = ( ) => this . exchangeConnection . fetchOrder ( orderId , symbol ) ; const res = await this . bottleneck . schedule ( fn ) ; const debug = { name : 'checkOrder' , req : { orderId } , res } ; logger . silly ( JSON . stringify ( debug ) ) ; return res ; } public async cancelOrder ( orderId , symbol ) { const fn = ( ) => this . exchangeConnection . cancelOrder ( orderId , symbol ) ; const res = await this . bottleneck . schedule ( fn ) ; const debug = { name : 'cancelOrder' , req : { orderId } , res } ; logger . silly ( JSON . stringify ( debug ) ) ; return res ; } public async fetchTicker ( symbol ) { const fn = ( ) => this . exchangeConnection . fetchTicker ( symbol ) ; const res = await this . bottleneck . schedule ( fn ) ; const debug = { name : 'fetchTicker' , req : { symbol } , res } ; logger . silly ( JSON . stringify ( debug ) ) ; return res ; } public priceToPrecision ( symbol , amount ) { return Number ( this . exchangeConnection . priceToPrecision ( symbol , amount ) ) ; } public getLimits ( symbol ) { return this . exchangeConnection . market ( symbol ) . limits ; } }