UNPKG

taapi-cache

Version:

TAAPI.IO Cache Package. A convenient way to fetch candles, store them and reuse them.

152 lines (115 loc) 5.16 kB
const moment = require('moment'); const mongodb = require("mongodb"); const database = require("../utilities/Database"); const config = require("../config/config"); const chalk = require("chalk"); const nodeSchedule = require("node-schedule"); const taapi = require("taapi"); const { Sema } = require('async-sema'); class Scheduler { constructor() { this.exchangeData = taapi.exchangeData(); this.exchangeDataLocks = {}; } async sleep(time) { return await new Promise(resolve => setTimeout(resolve, time)); } startMonitor() { if (config.dataProviders) { // Set up CCXT schedulers for (let exchangeId in config.dataProviders.ccxt) { let dataProvider = config.dataProviders.ccxt[exchangeId]; for (let interval in dataProvider.schedulers) { let schedule = config.dataProviders.ccxt[exchangeId].schedulers[interval]; if (schedule.enabled) { this.exchangeDataLocks[exchangeId] = new Sema(1); nodeSchedule.scheduleJob(schedule.cron, async date => { const cacheTickers = await database.getCacheTickers("ccxt", exchangeId, null, interval); for (let cacheTickerKey in cacheTickers) { const cacheTicker = cacheTickers[cacheTickerKey]; this.fetchAndCacheCandles(exchangeId, "ccxt", null, cacheTicker); await this.sleep(schedule.rateLimit); } }); } } } // Set up AlphaVantage schedulers for (let interval in config.dataProviders.alphaVantage.schedulers) { let dataProvider = config.dataProviders.alphaVantage; let schedule = dataProvider.schedulers[interval]; if (schedule.enabled) { this.exchangeDataLocks["alphavantage"] = new Sema(1); nodeSchedule.scheduleJob(schedule.cron, async date => { const cacheTickers = await database.getCacheTickers("alphavantage", null, null, interval); for (let cacheTickerKey in cacheTickers) { const cacheTicker = cacheTickers[cacheTickerKey]; this.fetchAndCacheCandles("alphavantage", "alphavantage", config.dataProviders.alphaVantage.secret, cacheTicker); await this.sleep(dataProvider.rateLimit); } }); } } // Set up FinnHub schedulers for (let interval in config.dataProviders.finnHub.schedulers) { let dataProvider = config.dataProviders.finnHub; let schedule = dataProvider.schedulers[interval]; if (schedule.enabled) { this.exchangeDataLocks["finnhub"] = new Sema(1); nodeSchedule.scheduleJob(schedule.cron, async date => { const cacheTickers = await database.getCacheTickers("finnhub", null, null, interval); for (let cacheTickerKey in cacheTickers) { const cacheTicker = cacheTickers[cacheTickerKey]; this.fetchAndCacheCandles("finnhub", "finnhub", config.dataProviders.finnHub.secret, cacheTicker); await this.sleep(dataProvider.rateLimit); } }); } } } } async fetchAndCacheCandles(exchangeDataLockName, providerName, providerSecret, cacheTicker) { const self = this; await this.exchangeDataLocks[exchangeDataLockName].acquire(); let execTime = new Date().getTime(); if (config.server.debugMode) { console.log(`Exec ${execTime}: ${providerName}:${cacheTicker.source} - ${cacheTicker.symbol}:${cacheTicker.interval}`); } // Get data provider secret this.exchangeData.setDataProvider(providerName, providerSecret); let candleCount = 5; if (cacheTicker.reset === true) { candleCount = -1; } this.exchangeData.getCandles(cacheTicker.source, cacheTicker.symbol, cacheTicker.interval, 0, candleCount).then(async candles => { const database = require("../utilities/Database"); // Add the ticker and interval data to each candle candles.filter(candle => { candle.symbol = cacheTicker.symbol; candle.interval = cacheTicker.interval; }); if (config.server.debugMode) { console.log("Latest candle: ", candles[candles.length - 1]); } /** * If the cache ticker is set to reset, then * delete all candles and restore them. If not * then upsert the 5 candles received. */ if (cacheTicker.reset === true) { //await database.deleteCandles(providerName, cacheTicker.source, cacheTicker.symbol, cacheTicker.interval); await database.insertCandles(providerName, cacheTicker.source, candles); } else { await database.upsertCandles(providerName, cacheTicker.source, cacheTicker.symbol, cacheTicker.interval, candles); } await database.updateCacheTicker(cacheTicker._id, { reset: false }); if (config.server.debugMode) { console.log("Fetched CandlesCount: ", candles.length); } self.exchangeDataLocks[exchangeDataLockName].release(); }).catch(function (error) { console.error(error); }); } } module.exports = new Scheduler();