mirror of
https://github.com/discountry/ritmex-bot.git
synced 2026-09-09 08:18:07 +00:00
80 lines
3.8 KiB
JavaScript
80 lines
3.8 KiB
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;
|