"""Cryptocurrency helpers"""
# pylint: disable=too-many-lines,too-many-return-statements
from __future__ import annotations
import os
import json
from datetime import datetime, timedelta
import difflib
import logging
import pandas as pd
import numpy as np
import ccxt
import matplotlib.pyplot as plt
from matplotlib.ticker import LogLocator, ScalarFormatter
import yfinance as yf
import mplfinance as mpf
from pycoingecko import CoinGeckoAPI
from openbb_terminal.helper_funcs import (
lambda_long_number_format,
plot_autoscale,
export_data,
print_rich_table,
lambda_long_number_format_y_axis,
is_valid_axes_count,
)
from openbb_terminal.config_plot import PLOT_DPI
from openbb_terminal.config_terminal import theme
from openbb_terminal.rich_config import console
from openbb_terminal.cryptocurrency.due_diligence import coinpaprika_model
from openbb_terminal.cryptocurrency.discovery import pycoingecko_model
from openbb_terminal.cryptocurrency.due_diligence.pycoingecko_model import (
get_ohlc,
get_coin_tokenomics,
)
logger = logging.getLogger(__name__)
__docformat__ = "numpy"
INTERVALS = ["1H", "3H", "6H", "1D"]
CCXT_INTERVAL_MAP = {
"1": "1m",
"15": "15m",
"30": "30m",
"60": "1h",
"240": "4h",
"1440": "1d",
"10080": "1w",
"43200": "1M",
}
SOURCES_INTERVALS = {
"Binance": [
"1day",
"3day",
"1hour",
"2hour",
"4hour",
"6hour",
"8hour",
"12hour",
"1week",
"1min",
"3min",
"5min",
"15min",
"30min",
"1month",
],
"Coinbase": [
"1min",
"5min",
"15min",
"1hour",
"6hour",
"24hour",
"1day",
],
"YahooFinance": [
"1min",
"2min",
"5min",
"15min",
"30min",
"60min",
"90min",
"1hour",
"1day",
"5day",
"1week",
"1month",
"3month",
],
}
YF_CURRENCY = [
"CAD",
"CNY",
"ETH",
"EUR",
"GBP",
"INR",
"JPY",
"KRW",
"RUB",
"USD",
"AUD",
"BTC",
]
def check_datetime(
ck_date: datetime | str | None = None, start: bool = True
) -> datetime:
"""Checks if given argument is string and attempts to convert to datetime.
Parameters
----------
ck_date : Optional[Union[datetime, str]], optional
Date to check, by default None
start : bool, optional
If True and string is invalid, will return 1100 days ago
If False and string is invalid, will return today, by default True
Returns
-------
datetime
Datetime object
"""
error_catch = (datetime.now() - timedelta(days=1100)) if start else datetime.now()
try:
if ck_date is None:
return error_catch
if isinstance(ck_date, datetime):
return ck_date
if isinstance(ck_date, str):
return datetime.