Fix 2099 - add crypto funding rate (#2159)

* added funding rate feature to dd menu

* didier changes

* tests
This commit is contained in:
jose-donato
2022-07-26 00:23:34 +01:00
committed by GitHub
parent 9d6292c7fe
commit 9d0bf694f6
11 changed files with 154 additions and 8 deletions

3
i18n/en.yml vendored
View File

@@ -251,7 +251,7 @@ en:
stocks/ins/stats: insider stats of the company
stocks/ins/act: insider activity over time
stocks/ins/lins: last insider trading of the company
stocks/ins/lcb: latest cluster boys
stocks/ins/lcb: latest cluster buys
stocks/ins/lpsb: latest penny stock buys
stocks/ins/lit: latest insider trading (all filings)
stocks/ins/lip: latest insider purchases
@@ -612,6 +612,7 @@ en:
crypto/dd/change: 30d change of supply held on exchange wallets
crypto/dd/eb: total balance held on exchanges (in percentage and units)
crypto/dd/oi: open interest per exchange
crypto/dd/fundrate: funding rate per exchange
crypto/dd/basic: basic information about loaded coin
crypto/dd/ps: price and supply related metrics for loaded coin
crypto/dd/mkt: all markets for loaded coin

View File

@@ -16,6 +16,68 @@ api_url = "https://open-api.coinglass.com/api/pro/v1/"
INTERVALS = [0, 1, 2, 4]
@log_start_end(log=logger)
def get_funding_rate(symbol: str) -> pd.DataFrame:
"""Returns open interest by exchange for a certain symbol
[Source: https://coinglass.github.io/API-Reference/]
Parameters
----------
symbol : str
Crypto Symbol to search open interest futures (e.g., BTC)
Returns
-------
pd.DataFrame
funding rate per exchange
"""
url = api_url + f"futures/funding_rates_chart?symbol={symbol.upper()}&type=C"
headers = {"coinglassSecret": cfg.API_COINGLASS_KEY}
response = requests.request("GET", url, headers=headers)
df = pd.DataFrame()
if response.status_code == 200:
res_json = json.loads(response.text)
if res_json["success"]:
if "data" in res_json:
data = res_json["data"]
time = data["dateList"]
time_new = []
for elem in time:
time_actual = dt.datetime.utcfromtimestamp(elem / 1000)
time_new.append(time_actual)
df = pd.DataFrame(
data={
"date": time_new,
"price": data["priceList"],
**data["dataMap"],
}
)
df = df.set_index("date")
else:
console.print(f"No data found for {symbol}.\n")
else:
if "secret invalid" in res_json["msg"]:
console.print("[red]Invalid API Key[/red]\n")
else:
console.print(res_json["msg"])
elif response.status_code == 429:
console.print("[red]Exceeded number of calls per minute[/red]\n")
elif response.status_code == 429:
console.print(
"[red]IP address autobanned for exceeding calls limit multiple times.[/red]\n"
)
return df
@log_start_end(log=logger)
def get_open_interest_per_exchange(symbol: str, interval: int) -> pd.DataFrame:
"""Returns open interest by exchange for a certain symbol
@@ -36,7 +98,7 @@ def get_open_interest_per_exchange(symbol: str, interval: int) -> pd.DataFrame:
url = (
api_url
+ f"futures/openInterest/chart?&symbol={symbol.upper()}&interval={interval}"
+ f"futures/openInterest/chart?symbol={symbol.upper()}&interval={interval}"
)
headers = {"coinglassSecret": cfg.API_COINGLASS_KEY}

View File

@@ -9,6 +9,7 @@ from matplotlib import ticker
from openbb_terminal.config_terminal import theme
from openbb_terminal import config_plot as cfgPlot
from openbb_terminal.cryptocurrency.due_diligence.coinglass_model import (
get_funding_rate,
get_open_interest_per_exchange,
)
from openbb_terminal.decorators import check_api_key
@@ -24,6 +25,33 @@ from openbb_terminal.rich_config import console
logger = logging.getLogger(__name__)
@log_start_end(log=logger)
@check_api_key(["API_COINGLASS_KEY"])
def display_funding_rate(symbol: str, export: str = "") -> None:
"""Displays funding rate by exchange for a certain cryptocurrency
[Source: https://coinglass.github.io/API-Reference/]
Parameters
----------
symbol : str
Crypto symbol to search funding rate (e.g., BTC)
export : str
Export dataframe data to csv,json,xlsx file"""
df = get_funding_rate(symbol)
if df.empty:
return
plot_data(df, symbol, f"Exchange {symbol} Funding Rate", "Funding Rate [%]")
console.print("")
export_data(
export,
os.path.dirname(os.path.abspath(__file__)),
"fundrate",
df,
)
@log_start_end(log=logger)
@check_api_key(["API_COINGLASS_KEY"])
def display_open_interest(symbol: str, interval: int = 0, export: str = "") -> None:
@@ -42,7 +70,12 @@ def display_open_interest(symbol: str, interval: int = 0, export: str = "") -> N
if df.empty:
return
plot_data(df, symbol)
plot_data(
df,
symbol,
f"Exchange {symbol} Futures Open Interest",
"Open futures value [$B]",
)
console.print("")
export_data(
@@ -57,6 +90,8 @@ def display_open_interest(symbol: str, interval: int = 0, export: str = "") -> N
def plot_data(
df: pd.DataFrame,
symbol: str,
title: str,
ylabel: str,
external_axes: Optional[List[plt.Axes]] = None,
):
@@ -84,8 +119,8 @@ def plot_data(
ticker.FuncFormatter(lambda x, _: lambda_long_number_format(x))
)
ax1.legend(df_without_price.columns, fontsize="x-small", ncol=2)
ax1.set_title(f"Exchange {symbol} Futures Open Interest")
ax1.set_ylabel("Open futures value[$B]")
ax1.set_title(title)
ax1.set_ylabel(ylabel)
ax2.plot(df_price.index, df_price)
ax2.legend([f"{symbol} price"])

View File

@@ -55,7 +55,7 @@ def check_cg_id(symbol: str):
class DueDiligenceController(CryptoBaseController):
"""Due Diligence Controller class"""
CHOICES_COMMANDS = ["load", "oi", "active", "change", "nonzero", "eb"]
CHOICES_COMMANDS = ["load", "fundrate", "oi", "active", "change", "nonzero", "eb"]
SPECIFIC_CHOICES = {
"cp": [
@@ -183,6 +183,7 @@ class DueDiligenceController(CryptoBaseController):
mt.add_cmd("trades", "Coinbase")
mt.add_cmd("ex", "CoinPaprika")
mt.add_cmd("oi", "Coinglass")
mt.add_cmd("fundrate", "Coinglass")
mt.add_cmd("eb", "Glassnode")
mt.add_info("_metrics_")
@@ -499,6 +500,30 @@ class DueDiligenceController(CryptoBaseController):
export=ns_parser.export,
)
@log_start_end(log=logger)
def call_fundrate(self, other_args):
"""Process fundrate command"""
assert isinstance(self.symbol, str)
parser = argparse.ArgumentParser(
add_help=False,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
prog="fundrate",
description="""
Displays funding rate by exchange for a certain asset
[Source: https://coinglass.github.io/API-Reference/]
""",
)
ns_parser = self.parse_known_args_and_warn(
parser, other_args, EXPORT_BOTH_RAW_DATA_AND_FIGURES
)
if ns_parser:
coinglass_view.display_funding_rate(
symbol=self.symbol.upper(),
export=ns_parser.export,
)
@log_start_end(log=logger)
def call_info(self, other_args):
"""Process info command"""

View File

@@ -1,6 +1,8 @@
crypto
load btc
dd
fundrate
oi
nonzero
info
market

View File

@@ -302,6 +302,13 @@ def test_call_func_expect_queue(expected_queue, func, queue, mocker):
[],
dict(),
),
(
"call_fundrate",
[],
"coinglass_view.display_funding_rate",
[],
dict(),
),
(
"call_oi",
[],

View File

@@ -22,6 +22,7 @@ Market:
trades last trades [Coinbase]
ex all exchanges where loaded coin is listed [CoinPaprika]
oi open interest per exchange [Coinglass]
fundrate funding rate per exchange [Coinglass]
eb total balance held on exchanges (in percentage and units) [Glassnode]
Metrics:
mcapdom market cap dominance [Messari]

View File

@@ -13,7 +13,7 @@ Ticker:
[unvl] lins last insider trading of the company[/unvl] [Finviz]
Last Insiders:
lcb latest cluster boys [Open Insider]
lcb latest cluster buys [Open Insider]
lpsb latest penny stock buys [Open Insider]
lit latest insider trading (all filings) [Open Insider]
lip latest insider purchases [Open Insider]

View File

@@ -0,0 +1,11 @@
```
usage: fundrate [-h] [--export EXPORT]
```
Displays funding rate by exchange for a certain asset [Source: https://coinglass.github.io/API-Reference/]
```
optional arguments:
-h, --help show this help message (default: False)
--export EXPORT Export raw data into csv, json, xlsx and figure into png, jpg, pdf, svg (default: )
```

View File

@@ -3,7 +3,7 @@ usage: oi [-i {0, 1, 2, 4}]
[--export {csv,json,xlsx}] [-h]
```
Display the open interest per exchange for a certain cryptocurrency. [Source: https://bybt.gitbook.io]
Display the open interest per exchange for a certain cryptocurrency. [Source: https://coinglass.github.io/API-Reference/]
Crypto must be loaded (e.g., `load btc`) before running this feature.
The total Bitcoin futures open interest across cryptocurrency exchanges, where open interest is calculated as the estimated notional value of all open futures positions, or the aggregate dollar value of outstanding contract specified BTC deliverables. Includes the largest exchanges with trustworthy reporting of exchange volume metrics.

View File

@@ -748,6 +748,8 @@ main:
ref: "/terminal/crypto/dd/change"
- name: eb
ref: "/terminal/crypto/dd/eb"
- name: fundrate
ref: "/terminal/crypto/dd/fundrate"
- name: oi
ref: "/terminal/crypto/dd/oi"
- name: info