Back to Ccxt

Fetch First Ohlcv Timestamp

wiki/examples/js/fetch-first-ohlcv-timestamp.md

4.5.523.9 KB
Original Source
javascript
// eslint-disable-next-line no-unused-vars
import ccxt from '../../js/ccxt.js';
// AUTO-TRANSPILE //
// ###### Description ######
//
// This function tries to fetch the "listing time" of a symbol by fetching the earliest available bar in daily resolution.
// Top-tier exchanges also support fetching smaller timeframes (eg. 1 minute) even several years back, so for those exchanges you can also use `useMinuteTimeframe = true` argument to get the timestamp rounded to the earliest minute bar (instead of daily bar timestamp).
// See usage in the end of this file
async function fetchFirstBarTimestamp(exchange, symbol, useMinuteTimeframe = false) {
   // set some constants
   const millisecondsPerDay = 86400000;
   const minutesPerDay = 1440;
   const minimumTimestamp = 1230768000000; // 2009-01-01 (bitcoin created year)
   // get market features
   const market = exchange.market(symbol);
   const marketType = exchange.safeString(market, 'type');
   let features = exchange.safeDict(exchange.features, marketType, {});
   if (market['subType'] !== undefined) {
       features = exchange.safeDict(features, market['subType'], {});
   }
   const ohlcv = exchange.safeDict(features, 'fetchOHLCV');
   if (ohlcv === undefined) {
       return undefined;
   }
   const limit = exchange.safeInteger(ohlcv, 'limit');
   const fetchParams = { 'maxRetriesOnFailure': 3 };
   // start loop
   let currentSince = exchange.milliseconds() - millisecondsPerDay * (limit - 1);
   let foundStartTime = 0;
   // eslint-disable-next-line
   while (true) {
       currentSince = Math.max(currentSince, minimumTimestamp);
       const dailyBars = await exchange.fetchOHLCV(symbol, '1d', currentSince, limit, fetchParams);
       if (dailyBars.length <= 0) {
           break; // if no days returned, then probably start date was passed
       }
       const firstTs = dailyBars[0][0];
       if (firstTs === foundStartTime) {
           // if the first timestamp is equal to the last-fetched timestamp, then break here, because some exchanges still return initial bar even if since is much ahead to listing time
           break;
       }
       foundStartTime = firstTs;
       currentSince = foundStartTime - millisecondsPerDay * (limit - 1); // shift 'since' one step back
       if (dailyBars.length === 1) {
           // in some cases, some exchanges might still return first bar of chart when endtime overlaps previous day
           break;
       }
   }
   // if minute resolution needed
   if (useMinuteTimeframe) {
       const maxIteration = Math.ceil(minutesPerDay / limit) * 2;
       const allPromises = [];
       for (let i = 0; i < maxIteration; i++) {
           currentSince = foundStartTime - millisecondsPerDay + i * limit * 60 * 1000; // shift one-duration back for more accuracy for different kind of exchanges, like OKX, where first daily bar is offset by one day, but minute bars present
           allPromises.push(exchange.fetchOHLCV(symbol, '1m', currentSince, limit, fetchParams));
       }
       const allResponses = await Promise.all(allPromises);
       // find earliest bar
       for (let i = 0; i < allResponses.length; i++) {
           const response = allResponses[i];
           if (response.length > 0) {
               foundStartTime = response[0][0];
               break;
           }
       }
   }
   return foundStartTime;
}
// ###### Usage ######
const runExample = false; // set to true to run example
if (runExample) {
   const myEx = new ccxt.binance();
   await myEx.loadMarkets();
   const symbol = 'TRUMP/USDT';
   const earliest_timestamp = await fetchFirstBarTimestamp(myEx, symbol, true);
   console.log('- Earliest bar timestamp:', earliest_timestamp, ', readable: ', myEx.iso8601(earliest_timestamp));
   console.log('- market.created value:', myEx.market(symbol)['created']);
}
export default fetchFirstBarTimestamp;