- [Fetch First Ohlcv Timestamp](./examples/py/) ```python import os import sys # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN: # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code # 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 def fetch_first_bar_timestamp(exchange, symbol, use_minute_timeframe=False): # set some constants milliseconds_per_day = 86400000 minutes_per_day = 1440 minimum_timestamp = 1230768000000 # 2009-01-01 (bitcoin created year) # get market features market = exchange.market(symbol) market_type = exchange.safe_string(market, 'type') features = exchange.safe_dict(exchange.features, market_type, {}) if market['subType'] is not None: features = exchange.safe_dict(features, market['subType'], {}) ohlcv = exchange.safe_dict(features, 'fetchOHLCV') if ohlcv is None: return None limit = exchange.safe_integer(ohlcv, 'limit') fetch_params = { 'maxRetriesOnFailure': 3, } # start loop current_since = exchange.milliseconds() - milliseconds_per_day * (limit - 1) found_start_time = 0 # eslint-disable-next-line while True: current_since = max(current_since, minimum_timestamp) daily_bars = await exchange.fetch_ohlcv(symbol, '1d', current_since, limit, fetch_params) if len(daily_bars) <= 0: break # if no days returned, then probably start date was passed first_ts = daily_bars[0][0] if first_ts == found_start_time: # 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 found_start_time = first_ts current_since = found_start_time - milliseconds_per_day * (limit - 1) # shift 'since' one step back if len(daily_bars) == 1: # in some cases, some exchanges might still return first bar of chart when endtime overlaps previous day break # if minute resolution needed if use_minute_timeframe: max_iteration = int(math.ceil(minutes_per_day / limit)) * 2 all_promises = [] for i in range(0, max_iteration): current_since = found_start_time - milliseconds_per_day + 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 all_promises.append(exchange.fetch_ohlcv(symbol, '1m', current_since, limit, fetch_params)) all_responses = await asyncio.gather(*all_promises) # find earliest bar for i in range(0, len(all_responses)): response = all_responses[i] if len(response) > 0: found_start_time = response[0][0] break return found_start_time # ###### Usage ###### run_example = False # set to true to run example if run_example: my_ex = ccxt.binance() await my_ex.load_markets() symbol = 'TRUMP/USDT' earliest_timestamp = asyncio.run(fetch_first_bar_timestamp(my_ex, symbol, True)) print('- Earliest bar timestamp:', earliest_timestamp, ', readable: ', my_ex.iso8601(earliest_timestamp)) print('- market.created value:', my_ex.market(symbol)['created']) ```