Files
strategy-lab/research/ext_lib/util.py
David Brazda 7188b2d003 updates
2024-10-02 13:54:29 +02:00

50 lines
2.0 KiB
Python

import logging
from datetime import datetime, timedelta
from ccxt.base.errors import ExchangeNotAvailable
from vectorbtpro import pd, tp, vbt
log = logging.getLogger(__name__)
def find_earliest_date(symbol: str, exchange: str, **kwargs) -> tp.Optional[pd.Timestamp]:
"""Wrapper around CCXTData.find_earliest_date to handle ExchangeNotAvailable error with binary search
Args:
symbol: The trading symbol to query
exchange: The exchange to query
**kwargs: Additional arguments to pass to the find_earliest_date method
Returns:
tp.Optional[pd.Timestamp]: The earliest available date if found, otherwise None
"""
log.info("Searching for earliest date for %s", symbol)
start_date = pd.Timestamp(kwargs.pop("start", datetime(2010, 1, 1))).floor("D")
end_date = pd.Timestamp(kwargs.pop("end", datetime.now())).floor("D")
while start_date < end_date:
log.info("Trying %s to %s range", start_date, end_date)
mid_date = (start_date + (end_date - start_date) // 2).floor("D")
try:
found_date = vbt.CCXTData.find_earliest_date(
symbol, exchange=exchange, start=mid_date, end=end_date, limit=10, **kwargs
)
if found_date:
# Move the end date to mid_date to search the earlier half
end_date = mid_date
else:
# Move the start date to mid_date + 1 to search the later half
start_date = mid_date + timedelta(days=1)
except ExchangeNotAvailable:
# Move the start date to mid_date + 1 to search the later half
start_date = mid_date + timedelta(days=1)
# After the loop, start_date should be the earliest date with data
try:
found_date = vbt.CCXTData.find_earliest_date(
symbol, exchange=exchange, start=start_date, end=end_date, **kwargs
)
return found_date
except ExchangeNotAvailable as e:
log.error("ExchangeNotAvailable error encountered at final step... Error: %s", e)
return None