"""Cryptocurrency helpers"""
# pylint: disable=too-many-lines,too-many-return-statements
import difflib
import json
import logging
import os
from datetime import datetime, timedelta
from typing import Union
import ccxt
import matplotlib.pyplot as plt
import mplfinance as mpf
import numpy as np
import pandas as pd
import yfinance as yf
from matplotlib.ticker import LogLocator, ScalarFormatter
from pycoingecko import CoinGeckoAPI
from openbb_terminal.config_plot import PLOT_DPI
from openbb_terminal.config_terminal import theme
from openbb_terminal.cryptocurrency.discovery import pycoingecko_model
from openbb_terminal.cryptocurrency.due_diligence import coinpaprika_model
from openbb_terminal.cryptocurrency.due_diligence.pycoingecko_model import (
get_coin_tokenomics,
get_ohlc,
)
from openbb_terminal.helper_funcs import (
export_data,
is_valid_axes_count,
lambda_long_number_format,
lambda_long_number_format_y_axis,
plot_autoscale,
print_rich_table,
)
from openbb_terminal.rich_config import console
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: Union[datetime, Union[str, None]] = None, start: bool = True
) -> datetime:
"""Checks if given argument is string and attempts to convert to datetime.
Parameters
----------
ck_date : Union[datetime, Union[str, None]], 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):