tlab-trading-toolkit
Version:
A trading toolkit for building advanced trading bots on the GDAX platform
111 lines (110 loc) • 5.54 kB
JavaScript
;
/***************************************************************************************************************************
* @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. *
***************************************************************************************************************************/
Object.defineProperty(exports, "__esModule", { value: true });
const request = require("superagent");
const FXProvider_1 = require("../FXProvider");
const Big = require("bignumber.js");
const URL = 'https://api.coinmarketcap.com/v1/ticker/';
let CODE_MAP = null;
let REVERSE_MAP = null;
const SUPPORTED_QUOTE_CURRENCIES = ['BTC', 'USD', 'AUD', 'BRL', 'CAD', 'CHF', 'CNY', 'EUR', 'GBP', 'HKD', 'IDR', 'INR', 'JPY', 'KRW', 'MXN', 'RUB'];
const SUPPORTED_BASE_CURRENCIES = [];
const FIVE_MIN = 5 * 60 * 1000;
class CoinMarketCapProvider extends FXProvider_1.FXProvider {
constructor(config) {
super(config);
this.lastUpdate = {};
this.initializing = null;
}
get name() {
return 'Coinmarketcap.com';
}
downloadCurrentRate(pair) {
const id = CODE_MAP[pair.from];
if (!id) {
const error = new FXProvider_1.EFXRateUnavailable(`Invalid CoinMarketCap currency symbol: ${pair.from}`, this.name);
return Promise.reject(error);
}
const rate = {
time: null,
from: pair.from,
to: pair.to,
rate: null
};
// The endpoints are only updated every 5 minutes, so return cached value if we're inside that window
const lastUpdate = this.lastUpdate[FXProvider_1.pairAsString(pair)];
if (lastUpdate && Date.now() - lastUpdate.timestamp < FIVE_MIN) {
rate.time = new Date(lastUpdate.timestamp);
rate.rate = lastUpdate.value;
return Promise.resolve(rate);
}
const query = ['BTC', 'USD'].includes(pair.to) ? null : { convert: pair.to };
const req = request.get(`${URL}/${id}`).accept('application/json');
if (query) {
req.query(query);
}
return req.then((res) => {
const result = res.body[0];
rate.time = new Date((+result.last_updated) * 1000);
if (pair.to === 'BTC') {
rate.rate = new Big(result.price_btc);
}
else {
const key = `price_${pair.to.toLowerCase()}`;
rate.rate = new Big(result[key]);
}
if (!rate.rate.isFinite()) {
const error = new FXProvider_1.EFXRateUnavailable('We got a response, but the FX rates weren\'t present', this.name);
return Promise.reject(error);
}
// Update cache
this.lastUpdate[FXProvider_1.pairAsString(pair)] = {
timestamp: +(result.last_updated) * 1000,
value: rate.rate
};
return Promise.resolve(rate);
});
}
/**
* Valid quote currencies are USD, BTC, or one of the valid fiat currencies given in [[SUPPORTED_QUOTE_CURRENCIES]]
* The list of currently supported base currencies will be constructed when this is first called.
*/
supportsPair(pair) {
if (!SUPPORTED_QUOTE_CURRENCIES.includes(pair.to)) {
return Promise.resolve(false);
}
let initCodeMap = this.initializing;
if (!this.initializing) {
CODE_MAP = {};
REVERSE_MAP = {};
initCodeMap = request.get(URL)
.accept('application/json')
.then((res) => {
const result = res.body;
result.forEach((currency) => {
CODE_MAP[currency.symbol] = currency.id;
REVERSE_MAP[currency.id] = currency.symbol;
SUPPORTED_BASE_CURRENCIES.push(currency.symbol);
});
return Promise.resolve();
});
this.initializing = initCodeMap;
}
return initCodeMap.then(() => {
return Promise.resolve(SUPPORTED_BASE_CURRENCIES.includes(pair.from));
});
}
}
exports.default = CoinMarketCapProvider;