Files
OpenBB/gamestonk_terminal/cryptocurrency/due_diligence/coinpaprika_model.py
Theodore Aptekarev 79bacf3f51 Fix mypy hook and Resolve documentation errors (#1008)
* Make mypy pre-commit check non-strict

* Fix mypy pre-commit hook

* Update docstrings to be compliant with sphinx-readthedocs commonmark

* Change report path to be relative to the module and not the terminal.py

* Update class library documentation
2021-12-01 23:19:50 +00:00

393 lines
12 KiB
Python

"""CoinPaprika model"""
__docformat__ = "numpy"
from typing import Tuple, Optional, Any
from datetime import datetime, timedelta
import textwrap
import pandas as pd
from dateutil import parser
from gamestonk_terminal.cryptocurrency.coinpaprika_helpers import PaprikaSession
def get_coin(coin_id: str = "eth-ethereum") -> dict:
"""Get coin by id [Source: CoinPaprika]
Parameters
----------
coin_id: str
id of coin from coinpaprika e.g. Ethereum - > 'eth-ethereum'
Returns
-------
dict
Coin response
"""
session = PaprikaSession()
coin = session.make_request(session.ENDPOINTS["coin"].format(coin_id))
return coin
def get_coin_twitter_timeline(coin_id: str = "eth-ethereum") -> pd.DataFrame:
"""Get twitter timeline for given coin id. Not more than last 50 tweets [Source: CoinPaprika]
Parameters
----------
coin_id: str
id of coin from coinpaprika e.g. Ethereum - > 'eth-ethereum'
Returns
-------
pandas.DataFrame
Twitter timeline for given coin.
Columns: date, user_name, status, retweet_count, like_count
"""
session = PaprikaSession()
res = session.make_request(session.ENDPOINTS["coin_tweeter"].format(coin_id))
if "error" in res:
print(res)
return pd.DataFrame()
if isinstance(res, list) and len(res) == 0:
return pd.DataFrame()
df = pd.DataFrame(res)[
["date", "user_name", "status", "retweet_count", "like_count"]
]
df = df.applymap(
lambda x: "\n".join(textwrap.wrap(x, width=80)) if isinstance(x, str) else x
)
df["status"] = df["status"].apply(lambda x: x.replace(" ", ""))
df["date"] = df["date"].apply(lambda x: x.replace("T", "\n"))
df["date"] = df["date"].apply(lambda x: x.replace("Z", ""))
return df
def get_coin_events_by_id(coin_id: str = "eth-ethereum") -> pd.DataFrame:
"""Get all events related to given coin like conferences, start date of futures trading etc. [Source: CoinPaprika]
Example of response from API:
.. code-block:: json
{
"id": "17398-cme-april-first-trade",
"date": "2018-04-02T00:00:00Z",
"date_to": "string",
"name": "CME: April First Trade",
"description": "First trade of Bitcoin futures contract for April 2018.",
"is_conference": false,
"link": "http://www.cmegroup.com/trading/equity-index/us-index/bitcoin_product_calendar_futures.html",
"proof_image_link": "https://static.coinpaprika.com/storage/cdn/event_images/16635.jpg"
}
.
Parameters
----------
coin_id: str
id of coin from coinpaprika e.g. Ethereum - > 'eth-ethereum'
Returns
-------
pandas.DataFrame
Events found for given coin
Columns: id, date , date_to, name, description, is_conference, link, proof_image_link
"""
session = PaprikaSession()
res = session.make_request(session.ENDPOINTS["coin_events"].format(coin_id))
if not res:
return pd.DataFrame()
data = pd.DataFrame(res)
data["description"] = data["description"].apply(
lambda x: "\n".join(textwrap.wrap(x, width=40)) if isinstance(x, str) else x
)
data.drop(["id", "proof_image_link"], axis=1, inplace=True)
for col in ["date", "date_to"]:
data[col] = data[col].apply(
lambda x: x.replace("T", "\n") if isinstance(x, str) else x
)
data[col] = data[col].apply(
lambda x: x.replace("Z", "") if isinstance(x, str) else x
)
return data
def get_coin_exchanges_by_id(coin_id: str = "eth-ethereum") -> pd.DataFrame:
"""Get all exchanges for given coin id. [Source: CoinPaprika]
Parameters
----------
coin_id: str
Identifier of Coin from CoinPaprika
Returns
-------
pandas.DataFrame
All exchanges for given coin
Columns: id, name, adjusted_volume_24h_share, fiats
"""
session = PaprikaSession()
res = session.make_request(session.ENDPOINTS["coin_exchanges"].format(coin_id))
df = pd.DataFrame(res)
df["fiats"] = df["fiats"].copy().apply(lambda x: len([i["symbol"] for i in x if x]))
return df
def get_coin_markets_by_id(
coin_id: str = "eth-ethereum", quotes: str = "USD"
) -> pd.DataFrame:
"""All markets for given coin and currency [Source: CoinPaprika]
Parameters
----------
coin_id: str
Coin Parpika identifier of coin e.g. eth-ethereum
quotes: str
Comma separated list of quotes to return.
Example: quotes=USD,BTC
Allowed values:
BTC, ETH, USD, EUR, PLN, KRW, GBP, CAD, JPY, RUB, TRY, NZD, AUD, CHF, UAH, HKD, SGD, NGN, PHP, MXN, BRL,
THB, CLP, CNY, CZK, DKK, HUF, IDR, ILS, INR, MYR, NOK, PKR, SEK, TWD, ZAR, VND, BOB, COP, PEN, ARS, ISK
Returns
-------
pandas.DataFrame
All markets for given coin and currency
"""
session = PaprikaSession()
markets = session.make_request(
session.ENDPOINTS["coin_markets"].format(coin_id), quotes=quotes
)
if "error" in markets:
print(markets)
return pd.DataFrame()
data = []
for r in markets:
dct = {
"exchange": r.get("exchange_name"),
"pair": r.get("pair"),
"trust_score": r.get("trust_score"),
"pct_volume_share": r.get("adjusted_volume_24h_share"),
}
_quotes: dict = r.get("quotes")
for k, v in _quotes.items():
dct[f"{k.lower()}_price"] = v.get("price")
dct[f"{k.lower()}_volume"] = v.get("volume_24h")
dct["market_url"] = r.get("market_url")
data.append(dct)
return pd.DataFrame(data)
def get_ohlc_historical(
coin_id: str = "eth-ethereum", quotes: str = "USD", days: int = 90
) -> pd.DataFrame:
"""
Open/High/Low/Close values with volume and market_cap. [Source: CoinPaprika]
Request example: https://api.coinpaprika.com/v1/coins/btc-bitcoin/ohlcv/historical?start=2019-01-01&end=2019-01-20
if the last day is current day it can an change with every request until actual close of the day at 23:59:59
Parameters
----------
coin_id: str
Paprika coin identifier e.g. eth-ethereum
quotes: str
returned data quote (available values: usd btc)
days: int
time range for chart in days. Maximum 365
Returns
-------
pandas.DataFrame
Open/High/Low/Close values with volume and market_cap.
"""
if quotes.lower() not in ["usd", "btc"]:
quotes = "USD"
if abs(int(days)) > 365:
days = 365
end = datetime.now().strftime("%Y-%m-%d")
start = (datetime.now() - timedelta(days=days)).strftime("%Y-%m-%d")
session = PaprikaSession()
data = session.make_request(
session.ENDPOINTS["ohlcv_hist"].format(coin_id),
quotes=quotes,
start=start,
end=end,
)
if "error" in data:
print(data)
return pd.DataFrame()
return pd.DataFrame(data)
def get_tickers_info_for_coin(
coin_id: str = "btc-bitcoin", quotes: str = "USD"
) -> pd.DataFrame:
"""Get all most important ticker related information for given coin id [Source: CoinPaprika]
.. code-block:: json
{
"id": "btc-bitcoin",
"name": "Bitcoin",
"symbol": "BTC",
"rank": 1,
"circulating_supply": 17007062,
"total_supply": 17007062,
"max_supply": 21000000,
"beta_value": 0.735327,
"first_data_at": "2010-11-14T07:20:41Z",
"last_updated": "2018-11-14T07:20:41Z",
"quotes": {
"USD": {
"price": 5162.15941296,
"volume_24h": 7304207651.1585,
"volume_24h_change_24h": -2.5,
"market_cap": 91094433242,
"market_cap_change_24h": 1.6,
"percent_change_15m": 0,
"percent_change_30m": 0,
"percent_change_1h": 0,
"percent_change_6h": 0,
"percent_change_12h": -0.09,
"percent_change_24h": 1.59,
"percent_change_7d": 0.28,
"percent_change_30d": 27.39,
"percent_change_1y": -37.99,
"ath_price": 20089,
"ath_date": "2017-12-17T12:19:00Z",
"percent_from_price_ath": -74.3
}
}
}
Parameters
----------
coin_id: str
Id of coin from CoinPaprika
quotes: str
Comma separated quotes to return e.g quotes = USD, BTC
Returns
-------
pandas.DataFrame
Most important ticker related information
Columns: Metric, Value
"""
session = PaprikaSession()
tickers = session.make_request(
session.ENDPOINTS["ticker_info"].format(coin_id), quotes=quotes
)
for key, date in tickers.items():
if "date" in key or "data" in key:
try:
tickers[key] = parser.parse(date).strftime("%Y-%m-%d %H:%M:%S")
except (KeyError, ValueError, TypeError) as e:
print(e)
if key == "quotes":
try:
tickers[key][quotes]["ath_date"] = parser.parse(
tickers[key][quotes]["ath_date"]
).strftime("%Y-%m-%d %H:%M:%S")
except (KeyError, ValueError, TypeError) as e:
print(e)
df = pd.json_normalize(tickers)
try:
df.columns = [col.replace("quotes.", "") for col in list(df.columns)]
df.columns = [col.replace(".", "_").lower() for col in list(df.columns)]
except KeyError as e:
print(e)
df = df.T.reset_index()
df.columns = ["Metric", "Value"]
return df
def validate_coin(coin: str, coins_dct: dict) -> Tuple[str, Optional[Any]]:
"""Helper method that validates if proper coin id or symbol was provided [Source: CoinPaprika]
Parameters
----------
coin: str
id or symbol of coin for CoinPaprika
coins_dct: dict
dictionary of coins
Returns
-------
Tuple[str,str]
coin id, coin symbol
"""
coin_found, symbol = None, None
if coin in coins_dct:
coin_found = coin
symbol = coins_dct.get(coin_found)
else:
for key, value in coins_dct.items():
if coin.upper() == value:
coin_found = key
symbol = value
if not coin_found:
raise ValueError(f"Could not find coin with given id: {coin}\n")
print(f"Coin found : {coin_found} with symbol {symbol}\n")
return coin_found, symbol
def basic_coin_info(coin_id: str) -> pd.DataFrame:
"""Basic coin information [Source: CoinPaprika]
Parameters
----------
coin_id: str
Coin id
Returns
-------
pd.DataFrame
Metric, Value
"""
coin = get_coin(coin_id)
tags = coin.get("tags") or []
keys = [
"id",
"name",
"symbol",
"rank",
"type",
"description",
"platform",
"proof_type",
"contract",
]
results = {}
for key in keys:
results[key] = coin.get(key)
try:
tags = ", ".join(t.get("name") for t in tags)
parent = coin.get("parent") or {}
except (KeyError, IndexError):
tags, parent = [], {}
results["tags"] = tags
results["parent"] = parent.get("id")
df = pd.Series(results).reset_index()
df.columns = ["Metric", "Value"]
df["Value"] = df["Value"].apply(
lambda x: "\n".join(textwrap.wrap(x, width=80)) if isinstance(x, str) else x
)
df.dropna(subset=["Value"], inplace=True)
return df