diff --git a/docs/make.bat b/docs/make.bat
index 2119f51099b..922152e96a0 100644
--- a/docs/make.bat
+++ b/docs/make.bat
@@ -1,35 +1,35 @@
-@ECHO OFF
-
-pushd %~dp0
-
-REM Command file for Sphinx documentation
-
-if "%SPHINXBUILD%" == "" (
- set SPHINXBUILD=sphinx-build
-)
-set SOURCEDIR=.
-set BUILDDIR=_build
-
-if "%1" == "" goto help
-
-%SPHINXBUILD% >NUL 2>NUL
-if errorlevel 9009 (
- echo.
- echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
- echo.installed, then set the SPHINXBUILD environment variable to point
- echo.to the full path of the 'sphinx-build' executable. Alternatively you
- echo.may add the Sphinx directory to PATH.
- echo.
- echo.If you don't have Sphinx installed, grab it from
- echo.http://sphinx-doc.org/
- exit /b 1
-)
-
-%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
-goto end
-
-:help
-%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
-
-:end
-popd
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=.
+set BUILDDIR=_build
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.http://sphinx-doc.org/
+ exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+
+:end
+popd
diff --git a/gamestonk_terminal/cryptocurrency/README.md b/gamestonk_terminal/cryptocurrency/README.md
index e92f658f783..d1cecbe15d6 100644
--- a/gamestonk_terminal/cryptocurrency/README.md
+++ b/gamestonk_terminal/cryptocurrency/README.md
@@ -5,123 +5,8 @@ This menu aims to explore crypto world, and the usage of the following commands
Note that we have added the ability to look at technical analysis in the ta menu. Data loaded from CoinGecko has no candle data,
so indicators that rely on anything other than close will fail with an error.
-[COINGECKO](#COINGECKO)
-* [load](#load)
- * load a given coin vs a given currency [CoinGecko]
-* [view](#view)
- * plot the loaded crypto data
-* [trend](#trend)
- * show top 7 trending coins
+[COINGECKO standalone menu](/gamestonk_terminal/cryptocurrency/coingecko/)
-[COINMARKETCAP](#COINMARKETCAP)
-* [top](#top)
- * view top coins from coinmarketcap [coinmarketcap.com]
+[COINMARKETCAP standalone menu](/gamestonk_terminal/cryptocurrency/coinmarketcap/)
-[BINANCE](#BINANCE)
-* [select](#select)
- * select coin/currency to use
-* [book](#book)
- * show order book
-* [candle](#candle)
- * get klines/candles and plot
-* [balance](#balance)
- * show coin balance
-
-[MENUS](#Menu)
-* [> ta](technical_analysis/README.md)
- * **technical analysis for selected tickers**
-
-# COINGECKO
-## load
-
-````
-usage: load [-c --coin] [-d --days] [--vs]
-````
-
-Load a given coin vs a given currency. Currently only retrieves price, not volume or MarketCap. The current crypto data is [Powered by CoinGecko API](#https://www.coingecko.com/en), which is an awesome service that currently requires no API Key!
-
-* -c/--coin The coin you wish to load. This can either be the symbol or the name. `load -c btc` and `load -c bitcoin`
- will load. The -c flag is optional, the above is equivalent to `load btc`.
-* -d/--days The number of days to look. Defaults to 30 days. As per the API: Minutely data will be used for duration within 1 day,
- Hourly data will be used for duration between 1 day and 90 days, Daily data will be used for duration above 90 days.
-* --vs The currency to look against. Defaults to "usd".
-
-
-## view
-
-````
-usage: view
-````
-
-Plot the loaded crypto data.
-
-
-
-
-## trend
-````
-usage: trend
-````
-Print the top 7 trending coins from coingecko.
-
-
-
-
-# COINMARKETCAP
-
-## top
-
-````
-top [-n] [-s --sort SORTBY] [--descend]
-````
-
-This command displays the top n cryptocurrencies from coinmarketcap.com.
-
-* -n: Number of coins to look at (after sort). Defaults to 10.
-* -s/--sort : Column to sort by. One of {Symbol,CMC_Rank,LastPrice,DayPctChange,MarketCap}. Defaults to sorting by the CMC rank.
-* --descend : Flag to change the sorting order. Sorts in ascending order (since default order is the Rank which starts at 1).
-
-
-
-# BINANCE
-
-## select
-````
-usage: select [-c --coin] [-q --quote] [-i --interval] [-l --limit]
-````
-
-Select a coin/currency to the current object and load in the price dataframe. Note that in binance, the exchange "ticker" is usually COINCURR, such as BTCEUR for BTC to EURO. There is no USD, but it uses a coin tethered to the USD (USDT), which is the default. Some symbols are a combination of coins, as `ETHBTC` is a valid symbol
-* -c/--coin Coin to load. If not specified, BTC will be loaded to prevent errors later.
-* -q/--quote Quote currency. Defaults to `USDT` (which is 1-to-1 with USD)
-* -i/--interval. Interval for candles. One of [1day,3day,1hour,2hour,4hour,6hour,8hour,12hour,1week,1min,3min,5min,15min,30min,1month]. Defaults to 1day.
-* -l/--limit. Number of candles to get. Defaults to 100.
-
-## book
-````
-usage: book -l/--limit
-````
-
-Gets and shows the order book for the given coin/currency. Shows the cumulative amount of orders.
-
-* -l/--limit Number of orders to get on each side. One of [5,10,20,50,100,500,1000,5000]. Defaults to 100.
-
-
-
-
-## candle
-````
-usage: candle
-````
-
-Show candle chart for loaded coin/currency.
-
-
-
-
-
-## balance
-````
-usage: balance
-````
-
-Shows the current holding balance in your account.
+[BINANCE standalone menu](/gamestonk_terminal/cryptocurrency/coinmarketcap/)
diff --git a/gamestonk_terminal/cryptocurrency/binance/README.md b/gamestonk_terminal/cryptocurrency/binance/README.md
new file mode 100644
index 00000000000..347b9c39c81
--- /dev/null
+++ b/gamestonk_terminal/cryptocurrency/binance/README.md
@@ -0,0 +1,52 @@
+# BINANCE
+
+Binance is the largest cryptocurrency exchange in the world in terms of trading volume.
+This menu aims to explore Binance API and display data like order book, candles chart, account balance.
+
+## load
+````
+usage: load [-c --coin] [-q --quote] [-i --interval] [-l --limit]
+````
+
+Select a coin/currency to the current object and load in the price dataframe. Note that in binance, the exchange "ticker" is usually COINCURR, such as BTCEUR for BTC to EURO. There is no USD, but it uses a coin tethered to the USD (USDT), which is the default. Some symbols are a combination of coins, as `ETHBTC` is a valid symbol
+* -c/--coin Coin to load. If not specified, BTC will be loaded to prevent errors later.
+* -q/--quote Quote currency. Defaults to `USDT` (which is 1-to-1 with USD)
+* -i/--interval. Interval for candles. One of [1day,3day,1hour,2hour,4hour,6hour,8hour,12hour,1week,1min,3min,5min,15min,30min,1month]. Defaults to 1day.
+* -l/--limit. Number of candles to get. Defaults to 100.
+
+## book
+````
+usage: book -l/--limit
+````
+
+Gets and shows the order book for the given coin/currency. Shows the cumulative amount of orders.
+
+* -l/--limit Number of orders to get on each side. One of [5,10,20,50,100,500,1000,5000]. Defaults to 100.
+
+
+
+
+## candle
+````
+usage: candle
+````
+
+Show candle chart for loaded coin/currency.
+
+
+
+
+## balance
+````
+usage: balance
+````
+
+Shows the current holding balance in your account.
+
+## ta
+
+````
+usage: ta
+````
+
+Open Technical Analysis menu for loaded coin. [technical analysis](/gamestonk_terminal/cryptocurrency/coinmarketcap/)
diff --git a/gamestonk_terminal/cryptocurrency/binance/__init__.py b/gamestonk_terminal/cryptocurrency/binance/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/gamestonk_terminal/cryptocurrency/binance/binance_controller.py b/gamestonk_terminal/cryptocurrency/binance/binance_controller.py
new file mode 100644
index 00000000000..c7892674768
--- /dev/null
+++ b/gamestonk_terminal/cryptocurrency/binance/binance_controller.py
@@ -0,0 +1,171 @@
+"""Cryptocurrency Controller"""
+__docformat__ = "numpy"
+# pylint: disable=R0904, C0302, W0622
+import argparse
+import pandas as pd
+from prompt_toolkit.completion import NestedCompleter
+from gamestonk_terminal import feature_flags as gtff
+from gamestonk_terminal.helper_funcs import get_flair
+from gamestonk_terminal.menu import session
+from gamestonk_terminal.cryptocurrency.binance import binance_model
+from gamestonk_terminal.technical_analysis import ta_controller
+
+
+class BinanceController:
+
+ CHOICES = ["help", "q", "quit", "book", "candle", "balance", "load", "ta", "clear"]
+
+ def __init__(self):
+ """CONSTRUCTOR"""
+
+ self._binance_parser = argparse.ArgumentParser(add_help=False, prog="bin")
+ self._binance_parser.add_argument("cmd", choices=self.CHOICES)
+ self.current_coin = None
+ self.current_currency = None
+ self.current_df = pd.DataFrame()
+ self.source = ""
+
+ def print_help(self):
+ """Print help"""
+ print("\nBinance:")
+ print(" help show this menu again")
+ print(" q quit this menu, and shows back to main menu")
+ print(" quit quit to abandon program")
+ print("")
+ print(f"Loaded coin: {self.current_coin}")
+ print("")
+ print(" load load coin/currency to use and load candle data")
+ print(" clear clear loaded coin")
+ print(" book show order book")
+ print(" candle show candles")
+ print(" balance show coin balance")
+ print(" ta open technical analysis menu")
+ print("")
+
+ def switch(self, an_input: str):
+ """Process and dispatch input
+
+ Returns
+ -------
+ True, False or None
+ False - quit the menu
+ True - quit the program
+ None - continue in the menu
+ """
+ (known_args, other_args) = self._binance_parser.parse_known_args(
+ an_input.split()
+ )
+
+ return getattr(
+ self, "call_" + known_args.cmd, lambda: "Command not recognized!"
+ )(other_args)
+
+ def call_help(self, _):
+ """Process Help command"""
+ self.print_help()
+
+ def call_q(self, _):
+ """Process Q command - quit the menu."""
+ print("Moving back to (crypto) menu")
+ return False
+
+ def call_quit(self, _):
+ """Process Quit command - quit the program."""
+ return True
+
+ def call_book(self, other_args):
+ """Process book command"""
+ binance_model.order_book(other_args, self.current_coin, self.current_currency)
+
+ def call_candle(self, _):
+ """Process candle command"""
+ if self.current_coin is None and self.current_df.empty:
+ print("No coin selected. Use 'load' to load the coin you want to look at.")
+ print("")
+ else:
+ binance_model.show_candles(
+ self.current_df, self.current_coin, self.current_currency
+ )
+
+ def call_balance(self, _):
+ """Process balance command"""
+ binance_model.balance(self.current_coin)
+
+ def call_load(self, other_args):
+ """Process select command"""
+ (
+ self.current_coin,
+ self.current_currency,
+ self.current_df,
+ ) = binance_model.select_binance_coin(other_args)
+ self.source = "BIN"
+ print("")
+
+ def call_clear(self, _):
+ """Process clear command"""
+ if self.current_coin:
+ print(
+ f"Current coin {self.current_coin} was removed. You can load new coin with load -c "
+ )
+ print("")
+ self.current_coin = None
+ self.current_currency = None
+ self.current_df = pd.DataFrame()
+ else:
+ print("No coin selected. Use 'load' to load the coin you want to look at.")
+ print("")
+
+ # pylint: disable=inconsistent-return-statements
+ def call_ta(self, _):
+ """Process ta command"""
+ if not self.current_coin:
+ print("Please load a coin through either load -c ", "\n")
+
+ elif self.current_df.empty:
+ print("Price dataframe is empty")
+
+ else:
+
+ try:
+ quit = ta_controller.menu(
+ stock=self.current_df,
+ ticker=self.current_coin,
+ start=self.current_df.index[0],
+ interval="",
+ context="(crypto)>(bin)",
+ )
+ print("")
+ if quit is not None:
+ if quit is True:
+ return quit
+
+ except (ValueError, KeyError) as e:
+ print(e)
+
+
+def menu():
+ binance_controller = BinanceController()
+ binance_controller.print_help()
+
+ while True:
+ # Get input command from user
+ if session and gtff.USE_PROMPT_TOOLKIT:
+ completer = NestedCompleter.from_nested_dict(
+ {c: None for c in binance_controller.CHOICES}
+ )
+ an_input = session.prompt(
+ f"{get_flair()} (crypto)>(bin)> ",
+ completer=completer,
+ )
+ else:
+ an_input = input(f"{get_flair()} (crypto)>(bin)> ")
+
+ try:
+ process_input = binance_controller.switch(an_input)
+
+ if process_input is not None:
+ return process_input
+
+ except SystemExit:
+ print("The command selected doesn't exist\n")
+ continue
diff --git a/gamestonk_terminal/cryptocurrency/binance_model.py b/gamestonk_terminal/cryptocurrency/binance/binance_model.py
similarity index 98%
rename from gamestonk_terminal/cryptocurrency/binance_model.py
rename to gamestonk_terminal/cryptocurrency/binance/binance_model.py
index 2e183ab1d45..aad648e6a04 100644
--- a/gamestonk_terminal/cryptocurrency/binance_model.py
+++ b/gamestonk_terminal/cryptocurrency/binance/binance_model.py
@@ -10,7 +10,10 @@ from binance.exceptions import BinanceAPIException
from tabulate import tabulate
from gamestonk_terminal.main_helper import parse_known_args_and_warn
import gamestonk_terminal.config_terminal as cfg
-from gamestonk_terminal.cryptocurrency.binance_view import plot_order_book, plot_candles
+from gamestonk_terminal.cryptocurrency.binance.binance_view import (
+ plot_order_book,
+ plot_candles,
+)
def check_valid_binance_str(symbol: str) -> str:
@@ -43,7 +46,7 @@ def select_binance_coin(other_args: List[str]):
"""
client = Client(cfg.API_BINANCE_KEY, cfg.API_BINANCE_SECRET)
parser = argparse.ArgumentParser(
- prog="select",
+ prog="load",
add_help=False,
description="Define the coin to be used from binance and get data",
)
@@ -196,7 +199,6 @@ def show_candles(candles_df: pd.DataFrame, coin: str, currency: str):
f"{coin+currency} from {candles_df.index[0].strftime('%Y/%m/%d')} to "
f"{candles_df.index[-1].strftime('%Y/%m/%d')}",
)
- print("")
def balance(coin: str):
diff --git a/gamestonk_terminal/cryptocurrency/binance_view.py b/gamestonk_terminal/cryptocurrency/binance/binance_view.py
similarity index 100%
rename from gamestonk_terminal/cryptocurrency/binance_view.py
rename to gamestonk_terminal/cryptocurrency/binance/binance_view.py
diff --git a/gamestonk_terminal/cryptocurrency/coingecko/README.md b/gamestonk_terminal/cryptocurrency/coingecko/README.md
new file mode 100644
index 00000000000..f3d292c3435
--- /dev/null
+++ b/gamestonk_terminal/cryptocurrency/coingecko/README.md
@@ -0,0 +1,784 @@
+# CoinGecko
+
+This menu aims to explore crypto world with [CoinGecko](#https://www.coingecko.com/en)
+The usage of the following commands along with an example will be exploited below.
+
+Note that we have added the ability to look at technical analysis in the ta menu. Data loaded from CoinGecko has no candle data,
+so indicators that rely on anything other than close will fail with an error.
+
+[coin](#coin)
+* [load](#load)
+ * load a given coin, you can use either coin symbol or coin id
+* [find](#find)
+ * find similar coin by coin name,symbol or id
+* [clear](#clear)
+ * clear loaded coin
+* [chart](#chart)
+ * plot the loaded crypto chart
+* [ta](technical_analysis/README.md)
+ * open technical analysis menu
+* [info](#info)
+ * show coin base information
+* [market](#market)
+ * show market data
+* [ath](#ath)
+ * show all time high related metrics
+* [atl](#atl)
+ * show all time low related metrics
+* [score](#score)
+ * show different scores related to loaded coin
+* [web](#web)
+ * show websites related to loaded coin
+* [social](#social)
+ * show social media urls for loaded coin
+* [bc](#bc)
+ * show block-chain explorers urls for loaded coins
+* [dev](#dev)
+ * show developers data for loaded coins
+
+[overview](#overview)
+* [global](#global)
+ * show global crypto market info
+* [coins](#coins)
+ * show coins available on CoinGecko
+* [defi](#defi)
+ * show global DeFi market info
+* [trending](#trending)
+ * show trending coins on CoinGecko
+* [most_voted](#most_voted)
+ * show most voted coins on CoinGecko
+* [top_volume](#top_volume)
+ * show coins with highest volume on CoinGecko
+* [recently](#recently)
+ * show recently added on CoinGecko
+* [sentiment](#sentiment)
+ * show coins with most positive sentiment
+* [gainers](#gainers)
+ * show top gainers - coins which price gained the most in given period
+* [losers](#losers)
+ * show top losers - coins which price dropped the most in given period
+* [stables](#stables)
+ * show Stable Coins
+* [yfarms](#yfarms)
+ * show top Yield Farms
+* [top_defi](#top_defi)
+ * show top DeFi Protocols
+* [top_dex](#top_dex)
+ * show top Decentralized Exchanges
+* [top_nft](#top_nft)
+ * show top Non Fungible Tokens
+* [nft_today](#nft_today)
+ * show NFT Of The Day
+* [nft_market](#nft_market)
+ * show NFT Market Status
+* [exchanges](#exchanges)
+ * show Top Crypto Exchanges
+* [ex_rates](#ex_rates)
+ * show Coin Exchange Rates
+* [platforms](#platforms)
+ * show Crypto Financial Platforms
+* [products](#products)
+ * show Crypto Financial Products
+* [indexes](#indexes)
+ * show Crypto Indexes
+* [derivatives](#derivatives)
+ * show Crypto Derivatives
+* [categories](#categories)
+ * show Crypto Categories
+* [hold](#hold)
+ * show eth, btc holdings overview statistics
+* [hold_comp](#hold_comp)
+ * show eth, btc holdings by public companies
+
+
+
+# COIN
+## load
+
+````
+usage: load [-c --coin]
+````
+
+Load a given coin vs a given currency. Currently only retrieves price, not volume or MarketCap. The current crypto data is [Powered by CoinGecko API](#https://www.coingecko.com/en), which is an awesome service that currently requires no API Key!
+By loading a coin you will have access to a lot of statistics on that coin like price data, coin development stats, social media and many others. Loading coin also will open access to technical analysis menu
+
+
+* -c/--coin The coin you wish to load. This can either be the symbol or the name. `load -c btc` and `load -c bitcoin`
+ will load. The -c flag is optional, the above is equivalent to `load btc`.
+
+
+## chart
+
+````
+usage: chart [-d --days] [--vs]
+````
+
+Display chart for loaded coin. You can specify currency vs which you want to show chart and also number of days to get data for.
+By default currency: usd and days: 30. E.g. if you loaded in previous step Bitcoin and you want to see it's price vs ethereum in last 90 days range use `chart --vs eth --days 90`
+
+
+* -d/--days The number of days to look. Defaults to 30 days. As per the API: Minutely data will be used for duration within 1 day,
+ Hourly data will be used for duration between 1 day and 90 days, Daily data will be used for duration above 90 days.
+* --vs The currency to look against. Defaults to "usd".
+
+
+
+
+## ta
+
+````
+usage: ta [-d --days] [--vs]
+````
+
+Open Technical Analysis menu for loaded coin
+Loads data for technical analysis. You can specify currency vs which you want to show chart and also number of days to get data for.
+E.g. if you loaded in previous step Bitcoin and you want to see it's price vs ethereum in last 90 days range use `ta --vs eth --days 90`
+
+
+* -d/--days The number of days to look. Defaults to 30 days. As per the API: Minutely data will be used for duration within 1 day,
+ Hourly data will be used for duration between 1 day and 90 days, Daily data will be used for duration above 90 days.
+* --vs The currency to look against. Defaults to "usd".
+
+## info
+
+````
+usage: info
+````
+
+Shows basic information about loaded coin like:
+* id,
+* name,
+* symbol,
+* asset_platform,
+* description,
+* contract_address,
+* market_cap_rank,
+* public_interest_score,
+* total_supply,
+* max_supply,
+* price_change_percentage_24h,
+* price_change_percentage_7d,
+* price_change_percentage_30d,
+* current_price_btc,
+* current_price_eth,
+* current_price_usd
+
+
+
+## market
+
+````
+usage: market
+````
+
+Market data for loaded coin. There you find metrics like:
+* market_cap_rank,
+* total_supply,
+* max_supply,
+* circulating_supply,
+* price_change_percentage_24h,
+* price_change_percentage_7d,
+* price_change_percentage_30d,
+* price_change_percentage_60d,
+* price_change_percentage_1y,
+* market_cap_change_24h,
+* market_cap_btc,
+* market_cap_eth,
+* market_cap_usd,
+* total_volume_btc,
+* total_volume_eth,
+* total_volume_usd,
+* high_24h_btc,
+* high_24h_eth,
+* high_24h_usd,
+* low_24h_btc,
+* low_24h_eth,
+* low_24h_usd
+
+
+
+## ath
+
+````
+usage: ath
+````
+
+All time high data for loaded coin. You can find there most important metrics regarding ath of coin price like:
+* current_price_btc,
+* current_price_eth,
+* current_price_usd,
+* ath_btc,
+* ath_eth,
+* ath_usd,
+* ath_date_btc,
+* ath_date_eth,
+* ath_date_usd,
+* ath_change_percentage_btc,
+* ath_change_percentage_btc,
+* ath_change_percentage_eth,
+* ath_change_percentage_usd
+
+
+
+## atl
+
+````
+usage: atl
+````
+
+All time low data for loaded coin. You can find there most important metrics regarding atl of coin price like:
+* current_price_btc,
+* current_price_eth,
+* current_price_usd,
+* atl_btc,
+* atl_eth,
+* atl_usd,
+* atl_date_btc,
+* atl_date_eth,
+* atl_date_usd,
+* atl_change_percentage_btc,
+* atl_change_percentage_btc,
+* atl_change_percentage_eth,
+* atl_change_percentage_usd
+
+
+
+
+## score
+
+````
+usage: score
+````
+
+In this view you can find different kind of scores for loaded coin. Those scores represents different rankings, sentiment metrics, some user stats and others.
+* coingecko_rank,
+* coingecko_score,
+* developer_score,
+* community_score,
+* liquidity_score,
+* sentiment_votes_up_percentage,
+* sentiment_votes_down_percentage,
+* public_interest_score,
+* facebook_likes,
+* twitter_followers,
+* reddit_average_posts_48h,
+* reddit_average_comments_48h,
+* reddit_subscribers,
+* reddit_accounts_active_48h,
+* telegram_channel_user_count,
+* alexa_rank,
+ * bing_matches
+
+
+
+## dev
+
+````
+usage: dev
+````
+
+Developers data for loaded coin. If the development data is available you can see how the code development of given coin is going on.
+There are some statistics that shows number of stars, forks, subscribers, pull requests, commits, merges, contributors on github.
+
+
+
+## web
+
+````
+usage: web
+````
+
+Websites found for given Coin. You can find there urls to homepage, forum, announcement site and others.
+
+
+
+## social
+
+````
+usage: social
+````
+
+Display social media corresponding to loaded coin. You can find there name of telegram channel, urls to twitter, reddit, bitcointalk, facebook and discord.
+
+
+
+## bc
+
+````
+usage: bc
+````
+
+Blockchain explorers URLs for loaded coin. Those are sites like etherescan.io or polkascan.io in which you can see all blockchain data e.g. all txs, all tokens, all contracts...
+
+
+
+## clear
+
+````
+usage: clear
+````
+
+Just remove previously loaded coin. (set coin = None)
+
+## find
+
+````
+usage: find [-c --coin] [-t --top] [-k --key]
+````
+
+Find similar coin by coin name,symbol or id. If you don't remember exact name or id of the Coin at CoinGecko, you can use this command to display coins with similar name, symbol or id to your search query.
+Example of usage: coin name is something like "polka". So you can try: `find -c polka -k name -t 25`
+It will search for coin that has similar name to polka and display top 25 matches.
+* -c, --coin stands for coin - you provide here your search query
+* -k, --key it's a searching key. You can search by symbol, id or name of coin
+* -t, --top it displays top N number of records.
+
+
+
+
+# OVERVIEW
+## global
+
+````
+usage: global
+````
+
+Display global statistics about Crypto Market like:
+* active_cryptocurrencies,
+* upcoming_icos,
+* ongoing_icos,
+* ended_icos,
+* markets,
+* market_cap_change_percentage_24h,
+* eth_market_cap_in_pct,
+* btc_market_cap_in_pct,
+* altcoin_market_cap_in_pct
+
+
+
+## news
+
+````
+usage: news [-t --top] [-s --sortby] [--descend] [-l --links]
+````
+
+Shows latest news from https://www.coingecko.com/en/news
+Display columns: index, title, author, posted columns. You can sort by each of column above, using `--sort` parameter and also do it descending with `--descend` flag
+It's also possible to display urls to news with `--links` flag. If you want to display top 75 news, sorted by author use `news -t 75 -s author` if you want to see urls to source of the news use `news -t 75 -l`
+
+
+* -t/--top - number of news to display. One page of news contains 25 news, so to get 250 news script needs to scrape 10 pages (it can take some time). Default 100. E.g `news --top 150`
+* -s/--sortby - sort by given column. You can chose on from `index, title, author, posted`
+* --descend - flag to sort in descending order (lowest first)
+* -l/--links - flag to show urls. Using this flag will add additional column with urls and display only `index, url` columns
+
+
+
+## coins
+
+````
+usage: coins [-s --skip] [-t --top] [-l --letter] [-k --key]
+````
+
+Display all available coins in coingecko. You can search with pagination mechanism with `news --skip [num] --top [num]` or you can just search by letter like
+`news --letter d --key name --top 10` it will display top 10 matches for coins which name starts with letter `d` and search will be done in column `name`
+
+* -s/--skip - number of records to skip. Default is 0. There are thousands of coins, so there is mechanism to paginate through them.
+e.q if you want to see only records from 500-750 you should use `coins --skip 500 --top 250` or if you want to see 1200-1880 you should use `coins --skip 1200 --top 680`.
+* -t/--top - number of news to display. One page of news contains 25 news, so to get 250 news script needs to scrape 10 pages (it can take some time). Default 100. E.g `news --top 150`
+* -l/--letter - first letters of coin by which you want to search
+* -k/--key - search key. With this parameter you can specify in which column you would like to search. Choose on from `name, id, symbol`
+
+
+
+
+## defi
+
+````
+usage: defi
+````
+
+Shows global DeFi statistics. DeFi or Decentralized Finance refers to financial services that are built on top of distributed networks with no central intermediaries.
+Displays metrics like:
+* defi_market_cap,
+* eth_market_cap,
+* defi_to_eth_ratio,
+* trading_volume_24h,
+* defi_dominance,
+* top_coin_name,
+* top_coin_defi_dominance
+
+
+
+
+## trending
+
+````
+usage: trending [-t --top] [-s --sortby] [--descend] [-l --links]
+````
+
+Shows most trending coins on CoinGecko.
+
+* -t/--top - number of coins to display. To display top 10 coins: `trending --top 10`
+* -s/--sortby - sort by given column. You can chose on from `rank, name, price_usd, price_btc`
+* --descend - flag to sort in descending order (lowest first)
+* -l/--links - flag to show urls. Using this flag will add additional column with urls e.g. `trending --top 10 --links`
+
+
+
+## most_voted
+
+````
+usage: most_voted [-t --top] [-s --sortby] [--descend] [-l --links]
+````
+
+Shows most voted coins on CoinGecko.
+
+* -t/--top - number of coins to display. To display top 10 coins: `most_voted --top 10`
+* -s/--sortby - sort by given column. You can chose on from `rank, name, price_usd, price_btc`
+* --descend - flag to sort in descending order (lowest first)
+* -l/--links - flag to show urls. Using this flag will add additional column with urls e.g. `most_voted --top 10 --links`
+
+
+
+## most_visited
+
+````
+usage: most_visited [-t --top] [-s --sortby] [--descend] [-l --links]
+````
+
+Shows most visited coins on CoinGecko.
+
+* -t/--top - number of coins to display. To display top 10 coins: `most_visited --top 10`
+* -s/--sortby - sort by given column. You can chose on from `rank, name, price_usd, price_btc`
+* --descend - flag to sort in descending order (lowest first)
+* -l/--links - flag to show urls. Using this flag will add additional column with urls e.g. `most_visited --top 10 --links`
+
+
+
+
+## sentiment
+
+````
+usage: sentiment [-t --top] [-s --sortby] [--descend] [-l --links]
+````
+
+Shows coins with the most positive sentiment on CoinGecko
+
+* -t/--top - number of coins to display. To display top 10 coins: `sentiment --top 10`
+* -s/--sortby - sort by given column. You can chose on from `rank, name, price_usd, price_btc`
+* --descend - flag to sort in descending order (lowest first)
+* -l/--links - flag to show urls. Using this flag will add additional column with urls e.g. `sentiment --top 10 --links`
+
+
+
+
+## recently
+
+````
+usage: recently [-t --top] [-s --sortby] [--descend] [-l --links]
+````
+
+Shows coins which were recently added on CoinGecko
+
+* -t/--top - number of coins to display. To display top 10 coins: `recently --top 10 --sortby rank`
+* -s/--sortby - sort by given column. You can chose on from `rank, name, symbol, price, change_24h, change_1h, added`
+* --descend - flag to sort in descending order (lowest first)
+* -l/--links - flag to show urls. Using this flag will add additional column with urls e.g. `recently --top 10 --links`
+
+
+
+## top_volume
+
+````
+usage: top_volume [-t --top] [-s --sortby] [--descend]
+````
+
+Shows coins with the highest transactions volume on CoinGecko
+
+* -t/--top - number of coins to display. To display top 10 coins: `top_volume --top 10 --sortby rank`
+* -s/--sortby - sort by given column. You can chose on from `rank, name, symbol, price, change_1h, change_24h, change_7d , volume_24h`
+* --descend - flag to sort in descending order (lowest first)
+
+
+
+
+## gainers
+
+````
+usage: gainers [-p --period] [-t --top] [-s --sortby] [--descend] [-l --links]
+````
+
+Shows largest gainers - coins which gain the most in given period.
+
+* -p/--period - time period in which coins gained the most in price. One from `1h, 24h, 7d, 14d, 30d, 60d, 1y`. If you want to see top gainers in last 24h `gainers -p 24h` or top gainers in last 60days `gainers -p 60d`
+* -t/--top - number of coins to display. To display top 10 coins: `gainers --top 10 --sortby rank`
+* -s/--sortby - sort by given column. You can chose on from `rank, name, symbol, price, change, volume`.
+* --descend - flag to sort in descending order (lowest first)
+* -l/--links - flag to show urls. Using this flag will add additional column with urls e.g. `gainers --period 24h --links`
+
+
+
+## losers
+
+````
+usage: losers [-p --period] [-t --top] [-s --sortby] [--descend] [-l --links]
+````
+
+Shows largest losers - coins which lost the most in given period.
+
+* -p/--period - time period in which coins lost the most in price. One from `1h, 24h, 7d, 14d, 30d, 60d, 1y`. If you want to see top losers in last 24h `losers -p 24h` or top losers in last 60days `losers -p 60d`
+* -t/--top - number of coins to display. To display top 10 coins: `losers --top 10 --sortby rank`
+* -s/--sortby - sort by given column. You can chose on from `rank, name, symbol, price, change, volume`.
+* --descend - flag to sort in descending order (lowest first)
+* -l/--links - flag to show urls. Using this flag will add additional column with urls e.g. `losers --period 24h --links`
+
+)
+
+## stables
+
+````
+usage: stables [-t --top] [-s --sortby] [--descend] [-l --links]
+````
+
+Shows stablecoins by market capitalization. Stablecoins are cryptocurrencies that attempt to peg their market value to some external reference
+like the U.S. dollar or to a commodity's price such as gold.
+
+* -t/--top - number of coins to display. To display top 10 coins: `stables --top 10 --sortby rank`
+* -s/--sortby - sort by given column. You can sort data by `rank, name, symbol, price, change_24h, exchanges, market_cap, change_30d`
+* --descend - flag to sort in descending order (lowest first)
+* -l/--links - flag to show urls. Using this flag will add additional column with urls e.g. `stables --links`. If you will use this flag `rank, name, symbol, url` columns will be displayed.
+
+
+
+
+## yfarms
+
+````
+usage: yfarms [-t --top] [-s --sortby] [--descend]
+````
+
+Shows Top Yield Farming Pools by Value Locked from https://www.coingecko.com/en/yield-farming
+Yield farming, also referred to as liquidity mining, is a way to generate rewards with cryptocurrency holdings.
+In simple terms, it means locking up cryptocurrencies and getting rewards.
+
+* -t/--top - number of yield farms to display. To display top 10 yield farms: `yfarms --top 10 --sortby rank`
+* -s/--sortby - sort by given column. You can sort data by `rank, name, value_locked, return_year`
+* --descend - flag to sort in descending order (lowest first)
+
+
+
+
+## top_defi
+
+````
+usage: top_defi [-t --top] [-s --sortby] [--descend] [-l --links]
+````
+
+Shows Top DeFi Coins by Market Capitalization from https://www.coingecko.com/en/defi
+DeFi or Decentralized Finance refers to financial services that are built on top of distributed networks with no central intermediaries.
+
+* -t/--top - number of defi coins to display. To display top 10 defi coins: `top_defi --top 10 --sortby rank`
+* -s/--sortby - sort by given column. You can sort data by `rank, name, symbol, price, change_24h, change_1h, change_7d`
+* --descend - flag to sort in descending order (lowest first)
+* -l/--links - flag to show urls. Using this flag will add additional column with urls e.g. `top_defi --links`.
+
+
+
+
+
+## top_dex
+
+````
+usage: top_dex [-t --top] [-s --sortby] [--descend]
+````
+
+Shows Top Decentralized Exchanges on CoinGecko by Trading Volume from https://www.coingecko.com/en/dex
+Decentralized exchanges or DEXs are autonomous decentralized applications (DApps) that allow cryptocurrency buyers or
+sellers to trade without having to give up control over their funds to any intermediary or custodian. Source: [coinmarketcap](#https://coinmarketcap.com/alexandria/article/what-are-decentralized-exchanges-dex)
+
+* -t/--top - number of Decentralized Exchanges to display. To display top 10 DEX: `top_dex --top 10 --sortby rank`
+* -s/--sortby - sort by given column. You can sort data by `rank, name, volume_24h, n_coins, n_pairs, visits, most_traded, market_share_by_vol most_traded_pairs, market_share_by_volume`
+* --descend - flag to sort in descending order (lowest first)
+
+
+
+## top_nft
+
+````
+usage: top_nft [-t --top] [-s --sortby] [--descend] [-l --links]
+````
+
+Shows Top 100 NFT Coins by Market Capitalization from https://www.coingecko.com/en/nft
+NFT (Non-fungible Token) refers to digital assets with unique characteristics.
+Examples of NFT include crypto artwork, collectibles, game items, financial products, and more.
+
+* -t/--top - number of NFT to display. To display top 10 NFT Coins: `top_nft --top 10 --sortby rank`
+* -s/--sortby - sort by given column. You can sort data by `rank, name, symbol, price, change_24h, change_1h, change_7d, volume_24h, market_cap`
+* --descend - flag to sort in descending order (lowest first)
+* -l/--links - flag to show urls. Using this flag will add additional column with urls e.g. `top_nft --links`.
+
+
+
+
+## nft_today
+
+````
+usage: nft_today
+````
+Get Non-fungible Token of the Day. Everyday on CoinGecko there is chosen new NFT.
+NFT (Non-fungible Token) refers to digital assets with unique characteristics.
+Examples of NFT include crypto artwork, collectibles, game items, financial products, and more.
+`nft_today` command you will display:
+* author,
+* description,
+* url,
+* img url
+
+
+
+## nft_market
+
+````
+usage: nft_market
+````
+Get current state of NFTs market. NFT (Non-fungible Token) refers to digital assets with unique characteristics.
+Examples of NFT include crypto artwork, collectibles, game items, financial products, and more.
+`nft_market` will display:
+* NFT Market Cap,
+* 24h Trading Volume,
+* NFT Dominance vs Global market,
+* Theta Network NFT Dominance
+
+
+
+
+## exchanges
+
+````
+usage: exchanges [-t --top] [-s --sortby] [--descend] [-l --links]
+````
+Shows top crypto exchanges base on trust score.
+
+* -t/--top - number of exchanges to display. To display top 10 exchanges by trust_score: `exchanges --top 10 --sortby trust_score --descend`
+* -s/--sortby - sort by given column. You can sort data by `rank, trust_score, id, name, country, established, trade_volume_24h_btc`
+* --descend - flag to sort in descending order (lowest first)
+* -l/--links - flag to show urls. Using this flag will add additional column with urls e.g. `exchanges --links`. Using `links` parameter will display only `rank, name, url` columns
+
+
+
+## ex_rates
+
+````
+usage: ex_rates [-t --top] [-s --sortby] [--descend]
+````
+
+Shows list of crypto, fiats, commodity exchange rates from CoinGecko
+* -t/--top - number of exchanges to display. To display top 10 exchanges by trust_score: `ex_rates --top 10 --sortby name --descend`
+* -s/--sortby - sort by given column. You can sort by `index,name,unit, value, type`
+* --descend - flag to sort in descending order (lowest first)
+
+
+
+## platforms
+
+````
+usage: platforms [-t --top] [-s --sortby] [--descend]
+````
+Shows Top Crypto Financial Platforms in which you can borrow or lend your crypto e.g. Celsius, Nexo, Crypto.com, Aave and others.
+
+* -t/--top - number of crypto platforms to display. To display top 10 platforms: `platforms --top 10 --sortby name`
+* -s/--sortby - sort by given column. You can sort data by `rank, name, category, centralized`
+* --descend - flag to sort in descending order (lowest first)
+
+
+
+
+
+## products
+
+````
+usage: products [-t --top] [-s --sortby] [--descend]
+````
+Shows Top Crypto Financial Products with which you can earn yield, borrow or lend your crypto.
+
+* -t/--top - number of crypto products to display. To display top 10 products: `products --top 10 --sortby name`
+* -s/--sortby - sort by given column. You can sort data by `rank, platform, identifier, supply_rate_percentage, borrow_rate_percentage`
+* --descend - flag to sort in descending order (lowest first)
+
+
+
+## indexes
+
+````
+usage: indexes [-t --top] [-s --sortby] [--descend]
+````
+
+Shows list of crypto indexes from CoinGecko.Each crypto index is made up of a selection of cryptocurrencies, grouped together and weighted by market cap.
+* -t/--top - number of crypto indexes to display. To display top 10 indexes: `indexes --top 10 --sortby name`
+* -s/--sortby - sort by given column. You can sort data by `rank, name, id, market, last, is_multi_asset_composite`
+* --descend - flag to sort in descending order (lowest first)
+
+
+
+## derivatives
+
+````
+usage: derivatives [-t --top] [-s --sortby] [--descend]
+````
+Shows list of crypto derivatives from CoinGecko. Crypto derivatives are secondary contracts or financial tools that derive their value from a primary
+underlying asset. In this case, the primary asset would be a cryptocurrency such as Bitcoin. The most popular crypto derivatives are crypto futures, crypto options, and perpetual contracts.
+* -t/--top - number of crypto derivatives to display. To display top 10 derivatives: `derivatives --top 10 --sortby symbol`
+* -s/--sortby - sort by given column. You can sort by `rank, market, symbol, price, pct_change_24h, contract_type, basis, spread, funding_rate, volume_24h`
+* --descend - flag to sort in descending order (lowest first)
+
+
+
+
+## categories
+
+````
+usage: categories [-t --top] [-s --sortby] [--descend] [-l --links]
+````
+Shows top cryptocurrency categories by market capitalization from https://www.coingecko.com/en/categories
+It includes categories like: stablecoins, defi, solana ecosystem, polkadot ecosystem and many others.
+
+* -t/--top - number of crypto categories to display. To display top 10 crypto categories: `categories --top 10 --sortby rank`
+* -s/--sortby - sort by given column. You can sort by `rank, name, change_1h, change_24h, change_7d, market_cap, volume_24h, n_of_coins`
+* --descend - flag to sort in descending order (lowest first)
+* -l/--links - flag to show urls. Using this flag will add additional column with urls e.g. `categories --links`. Using `links` parameter will display only `rank, name, url` columns
+
+
+
+
+## hold
+
+````
+usage: hold [-c --coin]
+````
+
+Shows overview of public companies that holds ethereum or bitcoin
+Displays most important metrics like:
+* Total Bitcoin/Ethereum Holdings,
+* Total Value (USD),
+* Public Companies Bitcoin/Ethereum Dominance,
+* Companies
+
+* -c/--coin - chose a coin. Only available for ethereum or bitcoin. If you want to see overview of public companies that holds ethereum use `hold --coin ethereum` for bitcoin `hold --coin bitcoin`
+
+
+
+
+## hold_comp
+
+````
+usage: hold_comp [-c --coin] [- --links]
+````
+
+Shows Ethereum/Bitcoin Holdings by Public Companies. Track publicly traded companies around the world that are buying ethereum as part of corporate treasury
+
+* -c/--coin - chose a coin. Only available for ethereum or bitcoin. List of public companies that holds ethereum `hold_comp --coin ethereum` for bitcoin `hold_comp --coin bitcoin`
+* -l/--links - You can use additional flag `--links` to see urls to announcement about buying btc or eth by given company. In this case of usage `links` only columns `rank, company, url` will be displayed
+
+
+
diff --git a/gamestonk_terminal/cryptocurrency/coingecko/__init__.py b/gamestonk_terminal/cryptocurrency/coingecko/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_coin_model.py b/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_coin_model.py
new file mode 100644
index 00000000000..dff6a679046
--- /dev/null
+++ b/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_coin_model.py
@@ -0,0 +1,419 @@
+import pandas as pd
+from pycoingecko import CoinGeckoAPI
+from gamestonk_terminal.cryptocurrency.coingecko.pycoingecko_helpers import (
+ remove_keys,
+ filter_list,
+ find_discord,
+ rename_columns_in_dct,
+ create_dictionary_with_prefixes,
+)
+
+CHANNELS = {
+ "telegram_channel_identifier": "telegram",
+ "twitter_screen_name": "twitter",
+ "subreddit_url": "subreddit",
+ "bitcointalk_thread_identifier": "bitcointalk",
+ "facebook_username": "facebook",
+ "discord": "discord",
+}
+
+BASE_INFO = [
+ "id",
+ "name",
+ "symbol",
+ "asset_platform_id",
+ "description",
+ "contract_address",
+ "market_cap_rank",
+ "public_interest_score",
+]
+
+DENOMINATION = ("usd", "btc", "eth")
+
+
+class Coin:
+ """Coin class, it holds loaded coin"""
+
+ def __init__(self, symbol):
+ self.client = CoinGeckoAPI()
+ self._coin_list = self.client.get_coins_list()
+ self.coin_symbol = self._validate_coin(symbol)
+
+ if self.coin_symbol:
+ self.coin = self._get_coin_info()
+
+ def __str__(self):
+ return f"{self.coin_symbol}"
+
+ def _validate_coin(self, symbol):
+ """Validate if given coin symbol or id exists in list of available coins on CoinGecko.
+ If yes it returns coin id.
+
+ Parameters
+ ----------
+ symbol: str
+ Either coin symbol or coin id
+
+ Returns
+ -------
+ id of the coin on CoinGecko service.
+
+ """
+ coin = None
+ for dct in self._coin_list:
+ if symbol.lower() in list(dct.values()):
+ coin = dct.get("id")
+ if not coin:
+ raise ValueError(f"Could not find coin with the given id: {symbol}\n")
+ return coin
+
+ def coin_list(self):
+ """
+ Returns
+ -------
+ list of all available coin ids
+ """
+ return [token.get("id") for token in self._coin_list]
+
+ def _get_coin_info(self):
+ """Helper method which fetch the coin information by id from CoinGecko API like:
+ (name, price, market, ... including exchange tickers)
+
+ Returns
+ -------
+ dict
+ """
+ params = dict(localization="false", tickers="false", sparkline=True)
+ return self.client.get_coin_by_id(self.coin_symbol, **params)
+
+ def _get_links(self):
+ """Helper method that extracts links from coin
+
+ Returns
+ -------
+ dict
+ """
+ return self.coin.get("links")
+
+ @property
+ def repositories(self):
+ """Get list of all repositories for given coin
+
+ Returns
+ -------
+ list with repositories
+ """
+ return self._get_links().get("repos_url")
+
+ @property
+ def developers_data(self):
+ """Get coin development data from GitHub or BitBucket like:
+ number of pull requests, contributor etc
+
+ Returns
+ -------
+ pandas.DataFrame
+ Metric, Value
+ """
+ dev = self.coin.get("developer_data")
+ useless_keys = (
+ "code_additions_deletions_4_weeks",
+ "last_4_weeks_commit_activity_series",
+ )
+ remove_keys(useless_keys, dev)
+ df = pd.Series(dev).to_frame().reset_index()
+ df.columns = ["Metric", "Value"]
+ return df
+
+ @property
+ def blockchain_explorers(self):
+ """Get list of URLs to blockchain explorers for given coin:
+
+ Returns
+ -------
+ pandas.DataFrame
+ Metric, Value
+ """
+ blockchain = self._get_links().get("blockchain_site")
+ if blockchain:
+ dct = filter_list(blockchain)
+ df = pd.Series(dct).to_frame().reset_index()
+ df.columns = ["Metric", "Value"]
+ return df
+ return None
+
+ @property
+ def social_media(self):
+ """Get list of URLs to social media like twitter, facebook, reddit...
+
+ Returns
+ -------
+ pandas.DataFrame
+ Metric, Value
+ """
+ social_dct = {}
+ links = self._get_links()
+ for (
+ channel
+ ) in CHANNELS.keys(): # pylint: disable=consider-iterating-dictionary)
+ if channel in links:
+ value = links.get(channel)
+ if channel == "twitter_screen_name":
+ value = "https://twitter.com/" + value
+ elif channel == "bitcointalk_thread_identifier" and value is not None:
+ value = f"https://bitcointalk.org/index.php?topic={value}"
+ social_dct[channel] = value
+ social_dct["discord"] = find_discord(links.get("chat_url"))
+ dct = rename_columns_in_dct(social_dct, CHANNELS)
+ df = pd.Series(dct).to_frame().reset_index()
+ df.columns = ["Metric", "Value"]
+ return df
+
+ @property
+ def websites(self):
+ """Get list of URLs to websites like homepage of coin, forum,
+
+ Returns
+ -------
+ pandas.DataFrame
+ Metric, Value
+ """
+ websites_dct = {}
+ links = self._get_links()
+ sites = ["homepage", "official_forum_url", "announcement_url"]
+ for site in sites:
+ websites_dct[site] = filter_list(links.get(site))
+ df = pd.Series(websites_dct).to_frame().reset_index()
+ df.columns = ["Metric", "Value"]
+ df["Value"] = df["Value"].apply(lambda x: ",".join(x))
+ return df
+
+ @property
+ def categories(self):
+ """Coins categories
+ Returns
+ -------
+ list/dict
+ """
+ return self.coin.get("categories")
+
+ def _get_base_market_data_info(self):
+ """Helper method that fetches all the base market/price information about given coin
+
+ Returns
+ -------
+ dict
+ """
+ market_dct = {}
+ market_data = self.coin.get("market_data")
+ for stat in [
+ "total_supply",
+ "max_supply",
+ "circulating_supply",
+ "price_change_percentage_24h",
+ "price_change_percentage_7d",
+ "price_change_percentage_30d",
+ ]:
+ market_dct[stat] = market_data.get(stat)
+ prices = create_dictionary_with_prefixes(
+ ["current_price"], market_data, DENOMINATION
+ )
+ market_dct.update(prices)
+ return market_dct
+
+ @property
+ def base_info(self):
+ """Get all the base information about given coin
+
+ Returns
+ -------
+ pandas.DataFrame
+ """
+ results = {}
+ for attr in BASE_INFO:
+ info_obj = self.coin.get(attr)
+ if attr == "description":
+ info_obj = info_obj.get("en")
+ results[attr] = info_obj
+ results.update(self._get_base_market_data_info())
+ return pd.Series(results).to_frame().reset_index()
+
+ @property
+ def market_data(self):
+ """Get all the base market information about given coin
+
+ Returns
+ -------
+ pandas.DataFrame
+ Metric,Value
+ """
+ market_data = self.coin.get("market_data")
+ market_columns_denominated = [
+ "market_cap",
+ "fully_diluted_valuation",
+ "total_volume",
+ "high_24h",
+ "low_24h",
+ ]
+ denominated_data = create_dictionary_with_prefixes(
+ market_columns_denominated, market_data, DENOMINATION
+ )
+
+ market_single_columns = [
+ "market_cap_rank",
+ "total_supply",
+ "max_supply",
+ "circulating_supply",
+ "price_change_percentage_24h",
+ "price_change_percentage_7d",
+ "price_change_percentage_30d",
+ "price_change_percentage_60d",
+ "price_change_percentage_1y",
+ "market_cap_change_24h",
+ ]
+ single_stats = {}
+ for col in market_single_columns:
+ single_stats[col] = market_data.get(col)
+ single_stats.update(denominated_data)
+
+ try:
+ single_stats["circulating_supply_to_total_supply_ratio"] = (
+ single_stats["circulating_supply"] / single_stats["total_supply"]
+ )
+ except (ZeroDivisionError, TypeError) as e:
+ print(e)
+ df = pd.Series(single_stats).to_frame().reset_index()
+ df.columns = ["Metric", "Value"]
+ return df
+
+ @property
+ def all_time_high(self):
+ """Get all time high data for given coin
+
+ Returns
+ -------
+ pandas.DataFrame
+ Metric,Value
+ """
+ market_data = self.coin.get("market_data")
+ ath_columns = [
+ "current_price",
+ "ath",
+ "ath_date",
+ "ath_change_percentage",
+ ]
+ results = create_dictionary_with_prefixes(
+ ath_columns, market_data, DENOMINATION
+ )
+ df = pd.Series(results).to_frame().reset_index()
+ df.columns = ["Metric", "Value"]
+ return df
+
+ @property
+ def all_time_low(self):
+ """Get all time low data for given coin
+
+ Returns
+ -------
+ pandas.DataFrame
+ Metric,Value
+ """
+ market_data = self.coin.get("market_data")
+ ath_columns = [
+ "current_price",
+ "atl",
+ "atl_date",
+ "atl_change_percentage",
+ ]
+ results = create_dictionary_with_prefixes(
+ ath_columns, market_data, DENOMINATION
+ )
+ df = pd.Series(results).to_frame().reset_index()
+ df.columns = ["Metric", "Value"]
+ return df
+
+ @property
+ def scores(self):
+ """Get different kind of scores for given coin
+
+ Returns
+ -------
+ pandas.DataFrame
+ Metric,Value
+ """
+ score_columns = [
+ "coingecko_rank",
+ "coingecko_score",
+ "developer_score",
+ "community_score",
+ "liquidity_score",
+ "sentiment_votes_up_percentage",
+ "sentiment_votes_down_percentage",
+ "public_interest_score",
+ "community_data",
+ "public_interest_stats",
+ ]
+
+ single_stats = {col: self.coin.get(col) for col in score_columns[:-2]}
+ nested_stats = {}
+ for col in score_columns[-2:]:
+ _dct = self.coin.get(col)
+ for k, _ in _dct.items():
+ nested_stats[k] = _dct.get(k)
+
+ single_stats.update(nested_stats)
+ df = pd.Series(single_stats).reset_index()
+ df.replace({0: ""}, inplace=True)
+ df = df.fillna("")
+ df.columns = ["Metric", "Value"]
+ return df
+
+ def get_coin_market_chart(self, vs_currency="usd", days=30, **kwargs):
+ """Get prices for given coin
+
+ Parameters
+ ----------
+ vs_currency: str
+ currency vs which display data
+ days: int
+ number of days to display the data
+ kwargs
+
+ Returns
+ -------
+ pandas.DataFrame
+ time, price, currency
+ """
+ prices = self.client.get_coin_market_chart_by_id(
+ self.coin_symbol, vs_currency, days, **kwargs
+ )
+ prices = prices["prices"]
+ df = pd.DataFrame(data=prices, columns=["time", "price"])
+ df["time"] = pd.to_datetime(df.time, unit="ms")
+ df = df.set_index("time")
+ df["currency"] = vs_currency
+ return df
+
+ def get_ohlc(self, vs_currency="usd", days=90):
+ """Get Open, High, Low, Close prices for given coin
+
+ Parameters
+ ----------
+ vs_currency: str
+ currency vs which display data
+ days: int
+ number of days to display the data
+ on from (1/7/14/30/90/180/365, max)
+
+ Returns
+ -------
+ pandas.DataFrame
+ time, price, currency
+ """
+
+ prices = self.client.get_coin_ohlc_by_id(self.coin_symbol, vs_currency, days)
+ df = pd.DataFrame(data=prices, columns=["time", "open", "high", "low", "close"])
+ df["time"] = pd.to_datetime(df.time, unit="ms")
+ df = df.set_index("time")
+ df["currency"] = vs_currency
+ return df
diff --git a/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_controller.py b/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_controller.py
new file mode 100644
index 00000000000..314858e68c0
--- /dev/null
+++ b/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_controller.py
@@ -0,0 +1,437 @@
+"""Cryptocurrency Controller"""
+__docformat__ = "numpy"
+# pylint: disable=R0904, C0302, W0622
+import argparse
+import pandas as pd
+from prompt_toolkit.completion import NestedCompleter
+from gamestonk_terminal import feature_flags as gtff
+from gamestonk_terminal.helper_funcs import get_flair
+from gamestonk_terminal.menu import session
+from gamestonk_terminal.cryptocurrency.coingecko import pycoingecko_view
+from gamestonk_terminal.technical_analysis import ta_controller
+
+
+class GeckoController:
+
+ CHOICES = [
+ "help",
+ "q",
+ "quit",
+ "global",
+ "find",
+ "coins",
+ "defi",
+ "news",
+ "trending",
+ "most_voted",
+ "most_visited",
+ "top_volume",
+ "recently",
+ "sentiment",
+ "gainers",
+ "losers",
+ "stables",
+ "yfarms",
+ "top_defi",
+ "top_dex",
+ "top_nft",
+ "nft_today",
+ "nft_market",
+ "exchanges",
+ "ex_rates",
+ "platforms",
+ "products",
+ "indexes",
+ "derivatives",
+ "categories",
+ "hold",
+ "hold_comp",
+ "load",
+ "clear",
+ "chart",
+ "ta",
+ "info",
+ "market",
+ "ath",
+ "atl",
+ "score",
+ "web",
+ "social",
+ "bc",
+ "dev",
+ ]
+
+ def __init__(self):
+ """CONSTRUCTOR"""
+
+ self._gecko_parser = argparse.ArgumentParser(add_help=False, prog="cg")
+ self._gecko_parser.add_argument("cmd", choices=self.CHOICES)
+ self.current_coin = None
+ self.current_currency = None
+ self.current_df = pd.DataFrame()
+ self.source = ""
+
+ def print_help(self):
+ """Print help"""
+ print("\nCoinGecko:")
+ print(" help show this menu again")
+ print(" q quit this menu, and shows back to main menu")
+ print(" quit quit to abandon program")
+ print("")
+ print("Coin")
+ print(" find find coin by name, symbol or id")
+ print(" load load cryptocurrency data")
+ print(" clear remove loaded coin")
+ print("")
+ print(f"Loaded coin: {self.current_coin}")
+ print("")
+ print(" chart price chart for loaded coin")
+ print(" ta yechnical analysis menu for loaded coin")
+ print(" info nasic information about loaded coin")
+ print(" market market stats about loaded coin")
+ print(" ath all time high related stats for loaded coin")
+ print(" atl all time low related stats for loaded coin")
+ print(" web found websites for loaded coin e.g forum, homepage")
+ print(
+ " social social portals urls for loaded coin, e.g reddit, twitter"
+ )
+ print(
+ " score different kind of scores for loaded coin, e.g developer score, sentiment score"
+ )
+ print(" dev github, bitbucket coin development statistics")
+ print(" bc links to blockchain explorers for loaded coin")
+ print("")
+ print("Overview:")
+ print(" global global crypto market info")
+ print(" coins coins available on CoinGecko")
+ print(" defi global DeFi market info")
+ print(" trending trending coins on CoinGecko")
+ print(" most_voted most voted coins on CoinGecko")
+ print(" most_visited most visited coins on CoinGecko")
+ print(" top_volume coins with highest volume on CoinGecko")
+ print(" recently recently added on CoinGecko")
+ print(" sentiment coins with most positive sentiment")
+ print(
+ " gainers top gainers - coins which price gained the most in given period "
+ )
+ print(
+ " losers top losers - coins which price dropped the most in given period "
+ )
+ print(" stables stablecoins")
+ print(" yfarms top yield farms")
+ print(" top_defi top defi protocols")
+ print(" top_dex top decentralized exchanges")
+ print(" top_nft top non fungible tokens")
+ print(" nft_today non fungible token of the day")
+ print(" nft_market non fungible token market status")
+ print(" exchanges top crypto exchanges")
+ print(" ex_rates coin exchange rates")
+ print(" platforms crypto financial platforms")
+ print(" products crypto financial products")
+ print(" indexes crypto indexes")
+ print(" derivatives crypto derivatives")
+ print(" categories crypto categories")
+ print(" hold ethereum, bitcoin holdings overview statistics")
+ print(" hold_comp ethereum, bitcoin holdings by public companies")
+ print("")
+
+ def switch(self, an_input: str):
+ """Process and dispatch input
+
+ Returns
+ -------
+ True, False or None
+ False - quit the menu
+ True - quit the program
+ None - continue in the menu
+ """
+ (known_args, other_args) = self._gecko_parser.parse_known_args(an_input.split())
+
+ return getattr(
+ self, "call_" + known_args.cmd, lambda: "Command not recognized!"
+ )(other_args)
+
+ def call_help(self, _):
+ """Process Help command"""
+ self.print_help()
+
+ def call_q(self, _):
+ """Process Q command - quit the menu."""
+ print("Moving back to (crypto) menu")
+ return False
+
+ def call_quit(self, _):
+ """Process Quit command - quit the program."""
+ return True
+
+ def call_find(self, other_args):
+ """Process find command"""
+ pycoingecko_view.find(other_args=other_args)
+
+ def call_load(self, other_args):
+ """Process load command"""
+ self.current_coin = pycoingecko_view.load(other_args)
+
+ def call_chart(self, other_args):
+ """Process chart command"""
+ if self.current_coin:
+ pycoingecko_view.chart(self.current_coin, other_args)
+ else:
+ print("No coin selected. Use 'load' to load the coin you want to look at.")
+ print("")
+
+ def call_info(self, other_args):
+ """Process info command"""
+ if self.current_coin:
+ pycoingecko_view.info(self.current_coin, other_args)
+ else:
+ print("No coin selected. Use 'load' to load the coin you want to look at.")
+ print("")
+
+ def call_market(self, other_args):
+ """Process market command"""
+ if self.current_coin:
+ pycoingecko_view.market(self.current_coin, other_args)
+ else:
+ print("No coin selected. Use 'load' to load the coin you want to look at.")
+ print("")
+
+ def call_web(self, other_args):
+ """Process web command"""
+ if self.current_coin:
+ pycoingecko_view.web(self.current_coin, other_args)
+ else:
+ print("No coin selected. Use 'load' to load the coin you want to look at.")
+ print("")
+
+ def call_social(self, other_args):
+ """Process social command"""
+ if self.current_coin:
+ pycoingecko_view.social(self.current_coin, other_args)
+ else:
+ print("No coin selected. Use 'load' to load the coin you want to look at.")
+ print("")
+
+ def call_dev(self, other_args):
+ """Process dev command"""
+ if self.current_coin:
+ pycoingecko_view.dev(self.current_coin, other_args)
+ else:
+ print("No coin selected. Use 'load' to load the coin you want to look at.")
+ print("")
+
+ def call_ath(self, other_args):
+ """Process ath command"""
+ if self.current_coin:
+ pycoingecko_view.ath(self.current_coin, other_args)
+ else:
+ print("No coin selected. Use 'load' to load the coin you want to look at.")
+ print("")
+
+ def call_atl(self, other_args):
+ """Process atl command"""
+ if self.current_coin:
+ pycoingecko_view.atl(self.current_coin, other_args)
+ else:
+ print("No coin selected. Use 'load' to load the coin you want to look at.")
+ print("")
+
+ def call_score(self, other_args):
+ """Process score command"""
+ if self.current_coin:
+ pycoingecko_view.score(self.current_coin, other_args)
+ else:
+ print("No coin selected. Use 'load' to load the coin you want to look at.")
+ print("")
+
+ def call_bc(self, other_args):
+ """Process bc command"""
+ if self.current_coin:
+ pycoingecko_view.bc(self.current_coin, other_args)
+ else:
+ print("No coin selected. Use 'load' to load the coin you want to look at.")
+ print("")
+
+ def call_clear(self, _):
+ """Process clear command"""
+ if self.current_coin:
+ print(
+ f"Current coin {self.current_coin.coin_symbol} was removed. You can load new coin with load -c "
+ )
+ self.current_coin = None
+ else:
+ print("No coin selected. Use 'load' to load the coin you want to look at.")
+ print("")
+
+ # pylint: disable=inconsistent-return-statements
+ def call_ta(self, other_args):
+ """Process ta command"""
+ if self.current_coin:
+ self.current_df, self.current_currency = pycoingecko_view.ta(
+ self.current_coin, other_args
+ )
+ if self.current_df is not None:
+ try:
+ self.current_df = self.current_df[["price"]].rename(
+ columns={"price": "Close"}
+ )
+ self.current_df.index.name = "date"
+ quit = ta_controller.menu(
+ stock=self.current_df,
+ ticker=self.current_coin.coin_symbol,
+ start=self.current_df.index[0],
+ interval="",
+ context="(crypto)>(cg)",
+ )
+ print("")
+ if quit is not None:
+ if quit is True:
+ return quit
+
+ except (ValueError, KeyError) as e:
+ print(e)
+ else:
+ return
+ else:
+ print("Please load a coin through either load - coin", "\n")
+ return
+
+ def call_hold(self, other_args):
+ """Process hold command"""
+ pycoingecko_view.holdings_overview(other_args)
+
+ def call_hold_comp(self, other_args):
+ """Process hold_comp command"""
+ pycoingecko_view.holdings_companies_list(other_args)
+
+ def call_gainers(self, other_args):
+ """Process hold_comp command"""
+ pycoingecko_view.gainers(other_args)
+
+ def call_losers(self, other_args):
+ """Process hold_comp command"""
+ pycoingecko_view.losers(other_args)
+
+ def call_trending(self, other_args):
+ """Process trending command"""
+ pycoingecko_view.discover(category="trending", other_args=other_args)
+
+ def call_most_voted(self, other_args):
+ """Process most_voted command"""
+ pycoingecko_view.discover(category="most_voted", other_args=other_args)
+
+ def call_recently(self, other_args):
+ """Process recently command"""
+ pycoingecko_view.recently_added(other_args=other_args)
+
+ def call_most_visited(self, other_args):
+ """Process most_voted command"""
+ pycoingecko_view.discover(category="most_visited", other_args=other_args)
+
+ def call_sentiment(self, other_args):
+ """Process sentiment command"""
+ pycoingecko_view.discover(category="positive_sentiment", other_args=other_args)
+
+ def call_news(self, other_args):
+ """Process news command"""
+ pycoingecko_view.news(other_args=other_args)
+
+ def call_categories(self, other_args):
+ """Process top_categories command"""
+ pycoingecko_view.categories(other_args=other_args)
+
+ def call_stables(self, other_args):
+ """Process stables command"""
+ pycoingecko_view.stablecoins(other_args=other_args)
+
+ def call_yfarms(self, other_args):
+ """Process yield_farms command"""
+ pycoingecko_view.yfarms(other_args=other_args)
+
+ def call_top_volume(self, other_args):
+ """Process top_volume command"""
+ pycoingecko_view.top_volume_coins(other_args=other_args)
+
+ def call_top_defi(self, other_args):
+ """Process top_volume command"""
+ pycoingecko_view.top_defi_coins(other_args=other_args)
+
+ def call_top_dex(self, other_args):
+ """Process top_volume command"""
+ pycoingecko_view.top_dex(other_args=other_args)
+
+ def call_top_nft(self, other_args):
+ """Process top_volume command"""
+ pycoingecko_view.top_dex(other_args=other_args)
+
+ def call_nft_market(self, other_args):
+ """Process top_volume command"""
+ pycoingecko_view.nft_market_status(other_args=other_args)
+
+ def call_nft_today(self, other_args):
+ """Process nft_today command"""
+ pycoingecko_view.nft_of_the_day(other_args=other_args)
+
+ def call_products(self, other_args):
+ """Process products command"""
+ pycoingecko_view.products(other_args=other_args)
+
+ def call_platforms(self, other_args):
+ """Process platforms command"""
+ pycoingecko_view.platforms(other_args=other_args)
+
+ def call_exchanges(self, other_args):
+ """Process exchanges command"""
+ pycoingecko_view.exchanges(other_args=other_args)
+
+ def call_ex_rates(self, other_args):
+ """Process exchange_rates command"""
+ pycoingecko_view.exchange_rates(other_args=other_args)
+
+ def call_indexes(self, other_args):
+ """Process indexes command"""
+ pycoingecko_view.indexes(other_args=other_args)
+
+ def call_derivatives(self, other_args):
+ """Process derivatives command"""
+ pycoingecko_view.derivatives(other_args=other_args)
+
+ def call_global(self, other_args):
+ """Process global command"""
+ pycoingecko_view.global_market_info(other_args=other_args)
+
+ def call_defi(self, other_args):
+ """Process defi command"""
+ pycoingecko_view.global_defi_info(other_args=other_args)
+
+ def call_coins(self, other_args):
+ """Process coins command"""
+ pycoingecko_view.coin_list(other_args=other_args)
+
+
+def menu():
+ gecko_controller = GeckoController()
+ gecko_controller.print_help()
+
+ while True:
+ # Get input command from user
+ if session and gtff.USE_PROMPT_TOOLKIT:
+ completer = NestedCompleter.from_nested_dict(
+ {c: None for c in gecko_controller.CHOICES}
+ )
+ an_input = session.prompt(
+ f"{get_flair()} (crypto)>(cg)> ",
+ completer=completer,
+ )
+ else:
+ an_input = input(f"{get_flair()} (crypto)>(cg)> ")
+
+ try:
+ process_input = gecko_controller.switch(an_input)
+
+ if process_input is not None:
+ return process_input
+
+ except SystemExit:
+ print("The command selected doesn't exist\n")
+ continue
diff --git a/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_helpers.py b/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_helpers.py
new file mode 100644
index 00000000000..761e0878990
--- /dev/null
+++ b/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_helpers.py
@@ -0,0 +1,155 @@
+import json
+import datetime as dt
+from datetime import timezone
+from typing import Sequence, Optional, Any, Dict, Tuple
+import textwrap
+import pandas as pd
+from dateutil import parser
+
+
+def replace_underscores_to_newlines(cols: list, line: int = 13):
+ """Helper method that replace underscores to white space and breaks it to new line
+
+ Parameters
+ ----------
+ cols
+ - list of columns names
+ line
+ - line length
+ Returns
+ -------
+ list of column names with replaced underscores
+ """
+ return [
+ textwrap.fill(c.replace("_", " "), line, break_long_words=False)
+ for c in list(cols)
+ ]
+
+
+def find_discord(item: list):
+ if isinstance(item, list) and len(item) > 0:
+ discord = [chat for chat in item if "discord" in chat]
+ if len(discord) > 0:
+ return discord[0]
+ return None
+
+
+def join_list_elements(elem):
+ if isinstance(elem, dict):
+ return ", ".join(k for k, v in elem.items())
+ if isinstance(elem, list):
+ return ", ".join(k for k in elem)
+ return None
+
+
+def filter_list(lst: list) -> list:
+ if isinstance(lst, list) and len(lst) > 0:
+ return [i for i in lst if i != ""]
+ return lst
+
+
+def calculate_time_delta(date: dt.datetime):
+ now = dt.datetime.now(timezone.utc)
+ if not isinstance(date, dt.datetime):
+ date = parser.parse(date)
+ return (now - date).days
+
+
+def get_eth_addresses_for_cg_coins(file): # pragma: no cover
+ with open(file) as f:
+ data = json.load(f)
+ df = pd.DataFrame(data)
+ df["ethereum"] = df["platforms"].apply(
+ lambda x: x.get("ethereum") if "ethereum" in x else None
+ )
+ return df
+
+
+def clean_question_marks(dct: dict):
+ if isinstance(dct, dict):
+ for k, v in dct.items():
+ if v == "?":
+ dct[k] = None
+
+
+def replace_qm(df):
+ df.replace({"?": None, " ?": None}, inplace=True)
+ return df
+
+
+def get_url(url, elem): # pragma: no cover
+ return url + elem.find("a")["href"]
+
+
+def clean_row(row):
+ """Helper method that cleans whitespaces and newlines in text returned from BeautifulSoup
+ Parameters
+ ----------
+ row
+ text returned from BeautifulSoup find method
+ Returns
+ -------
+ list of elements
+
+ """
+ return [r for r in row.text.strip().split("\n") if r not in ["", " "]]
+
+
+def convert(word):
+ return "".join(x.capitalize() or "_" for x in word.split("_") if word.isalpha())
+
+
+def collateral_auditors_parse(args): # pragma: no cover
+ try:
+ if args and args[0] == "N/A":
+ collateral = args[1:]
+ auditors = []
+ else:
+ n_elem = int(args[0])
+ auditors = args[1 : n_elem + 1]
+ collateral = args[n_elem + 1 :]
+
+ return auditors, collateral
+ except ValueError:
+ return [], []
+
+
+def swap_columns(df):
+ cols = list(df.columns)
+ cols = [cols[-1]] + cols[:-1]
+ df = df[cols]
+ return df
+
+
+def changes_parser(changes):
+ if isinstance(changes, list) and len(changes) < 3:
+ for _ in range(3 - len(changes)):
+ changes.append(None)
+ else:
+ changes = [None for _ in range(3)]
+ return changes
+
+
+def remove_keys(entries, the_dict):
+ for key in entries:
+ if key in the_dict:
+ del the_dict[key]
+
+
+def rename_columns_in_dct(dct, mapper):
+ return {mapper.get(k, v): v for k, v in dct.items()}
+
+
+def create_dictionary_with_prefixes(
+ columns: Sequence[Any], dct: Dict[Any, Any], constrains: Optional[Tuple] = None
+): # type: ignore
+ results = {}
+ for column in columns:
+ ath_data = dct.get(column)
+ for element in ath_data: # type: ignore
+ if constrains: # type: ignore
+ if element in constrains: # type: ignore
+ results[f"{column}_" + element] = ath_data.get(element) # type: ignore
+ else:
+ results[f"{column}_" + element] = ath_data.get(element) # type: ignore
+ return results
diff --git a/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_overview_model.py b/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_overview_model.py
new file mode 100644
index 00000000000..76e3448ca87
--- /dev/null
+++ b/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_overview_model.py
@@ -0,0 +1,972 @@
+import math
+import requests
+import pandas as pd
+import numpy as np
+from bs4 import BeautifulSoup
+from pycoingecko import CoinGeckoAPI
+from gamestonk_terminal.cryptocurrency.cryptocurrency_helpers import (
+ wrap_text_in_df,
+ percent_to_float,
+ create_df_index,
+)
+from gamestonk_terminal.cryptocurrency.coingecko.pycoingecko_helpers import (
+ changes_parser,
+ replace_qm,
+ clean_row,
+ collateral_auditors_parse,
+ swap_columns,
+)
+
+PERIODS = {
+ "1h": "?time=h1",
+ "24h": "?time=h24",
+ "7d": "?time=d7",
+ "14d": "?time=d14",
+ "30d": "?time=d30",
+ "60d": "?time=d60",
+ "1y": "?time=y1",
+}
+
+CATEGORIES = {
+ "trending": 0,
+ "most_voted": 1,
+ "positive_sentiment": 2,
+ "recently_added": 3,
+ "most_visited": 4,
+}
+
+COLUMNS = {
+ "id": "id",
+ "rank": "rank",
+ "name": "name",
+ "symbol": "symbol",
+ "price": "price",
+ "change_1h": "change_1h",
+ "change_24h": "change_24h",
+ "change_7d": "change_7d",
+ "volume_24h": "volume_24h",
+ "market_cap": "market_cap",
+ "country": "country",
+ "total_market_cap": "total_market_cap",
+ "total_volume": "total_volume",
+ "market_cap_percentage": "market_cap_percentage",
+ "company": "company",
+ "ticker": "ticker",
+ "last_added": "added",
+ "title": "title",
+ "author": "author",
+ "posted": "posted",
+ "article": "article",
+ "url": "url",
+ "price_btc": "price_btc",
+ "price_usd": "price_usd",
+ "n_of_coins": "n_of_coins",
+ "exchanges": "exchanges",
+ "change_30d": "change_30d",
+}
+
+CHANNELS = {
+ "telegram_channel_identifier": "telegram",
+ "twitter_screen_name": "twitter",
+ "subreddit_url": "subreddit",
+ "bitcointalk_thread_identifier": "bitcointalk",
+ "facebook_username": "facebook",
+ "discord": "discord",
+}
+
+BASE_INFO = [
+ "id",
+ "name",
+ "symbol",
+ "asset_platform_id",
+ "description",
+ "contract_address",
+ "market_cap_rank",
+ "public_interest_score",
+]
+
+DENOMINATION = ("usd", "btc", "eth")
+
+client = CoinGeckoAPI()
+
+GECKO_BASE_URL = "https://www.coingecko.com"
+
+
+def scrape_gecko_data(url: str) -> BeautifulSoup:
+ """Helper method that scrape Coin Gecko site.
+
+ Parameters
+ ----------
+ url : str
+ coin gecko url to scrape e.g: "https://www.coingecko.com/en/discover"
+
+ Returns
+ -------
+ BeautifulSoup object
+ """
+
+ req = requests.get(url)
+ return BeautifulSoup(req.text, features="lxml")
+
+
+def get_holdings_overview(endpoint: str = "bitcoin"):
+ """Scrapes overview of public companies that holds ethereum or bitcoin
+ from "https://www.coingecko.com/en/public-companies-{bitcoin/ethereum}"
+
+ Parameters
+ ----------
+ endpoint : str
+ "bitcoin" or "ethereum"
+
+ Returns
+ -------
+ pandas.DataFrame
+ Metric, Value
+ """
+ url = f"https://www.coingecko.com/en/public-companies-{endpoint}"
+ rows = scrape_gecko_data(url).find_all(
+ "span", class_="overview-box d-inline-block p-3 mr-2"
+ )
+ kpis = {}
+ for row in rows:
+ row_cleaned = clean_row(row)
+ if row_cleaned:
+ value, *kpi = row_cleaned
+ name = " ".join(kpi)
+ kpis[name] = value
+
+ df = pd.Series(kpis).to_frame().reset_index()
+ df.columns = ["Metric", "Value"]
+ return df
+
+
+def get_companies_assets(endpoint="bitcoin"):
+ """Scrapes list of companies that holds ethereum or bitcoin
+ from "https://www.coingecko.com/en/public-companies-{bitcoin/ethereum}"
+
+ Parameters
+ ----------
+ endpoint : str
+ "bitcoin" or "ethereum"
+
+ Returns
+ -------
+ pandas.DataFrame
+ rank, company, ticker, country, total_btc, entry_value, today_value, pct_of_supply, url
+ """
+ url = f"https://www.coingecko.com/en/public-companies-{endpoint}"
+ rows = scrape_gecko_data(url).find("tbody").find_all("tr")
+ results = []
+ for row in rows:
+ link = row.find("a")["href"]
+ row_cleaned = clean_row(row)
+ row_cleaned.append(link)
+ results.append(row_cleaned)
+ df = pd.DataFrame(
+ results,
+ columns=[
+ COLUMNS["rank"],
+ COLUMNS["company"],
+ COLUMNS["ticker"],
+ COLUMNS["country"],
+ "total_btc",
+ "entry_value",
+ "today_value",
+ "pct_of_supply",
+ COLUMNS["url"],
+ ],
+ )
+ return df
+
+
+def get_gainers_or_losers(period="1h", typ="gainers"):
+ """Scrape data about top gainers - coins which gain the most in given period and
+ top losers - coins that lost the most in given period of time.
+
+ Parameters
+ ----------
+ period: str
+ One from [1h, 24h, 7d, 14d, 30d, 60d, 1y]
+ typ: str
+ Either "gainers" or "losers"
+ Returns
+ -------
+ pandas.DataFrame
+ symbol, name, volume, price, change_{period}, url
+ """
+ category = {
+ "gainers": 0,
+ "losers": 1,
+ }
+
+ if period not in PERIODS:
+ raise ValueError(
+ f"Wrong time period\nPlease chose one from list: {PERIODS.keys()}"
+ )
+
+ url = f"https://www.coingecko.com/en/coins/trending{PERIODS.get(period)}"
+ rows = scrape_gecko_data(url).find_all("tbody")[category.get(typ)].find_all("tr")
+ results = []
+ for row in rows:
+ url = GECKO_BASE_URL + row.find("a")["href"]
+ symbol, name, *_, volume, price, change = clean_row(row)
+ try:
+ change = percent_to_float(change)
+ except (ValueError, TypeError):
+ ...
+ results.append([symbol, name, volume, price, change, url])
+ df = pd.DataFrame(
+ results,
+ columns=[
+ COLUMNS["symbol"],
+ COLUMNS["name"],
+ "volume",
+ COLUMNS["price"],
+ f"%change_{period}",
+ COLUMNS["url"],
+ ],
+ )
+ df.index = df.index + 1
+ df.reset_index(inplace=True)
+ df = df.rename(columns={"index": "rank"})
+ return df
+
+
+def get_btc_price():
+ """Get BTC/USD price from CoinGecko API
+
+ Returns
+ -------
+ str
+ latest bitcoin price in usd.
+ """
+ req = requests.get(
+ "https://api.coingecko.com/api/v3/simple/"
+ "price?ids=bitcoin&vs_currencies=usd&include_market_cap"
+ "=false&include_24hr_vol"
+ "=false&include_24hr_change=false&include_last_updated_at=false"
+ )
+ return req.json()["bitcoin"]["usd"]
+
+
+def discover_coins(category: str = "trending") -> pd.DataFrame:
+ """Scrapes data from "https://www.coingecko.com/en/discover"
+ - Most voted coins
+ - Most popular coins
+ - Recently added coins
+ - Most positive sentiment coins
+ Parameters
+ ----------
+ category: str
+ - one from list: [trending, most_voted, positive_sentiment,recently_added, most_visited]
+ Returns
+ -------
+ pandas.DataFrame:
+ name, price_btc, price_usd, url
+ """
+ if category not in CATEGORIES:
+ raise ValueError(
+ f"Wrong category name\nPlease chose one from list: {CATEGORIES.keys()}"
+ )
+ url = "https://www.coingecko.com/en/discover"
+ popular = scrape_gecko_data(url).find_all(
+ "div", class_="col-12 col-sm-6 col-md-6 col-lg-4"
+ )[CATEGORIES[category]]
+ rows = popular.find_all("a")
+ results = []
+ btc_price = get_btc_price()
+
+ for row in rows:
+ name, *_, price = clean_row(row)
+ url = GECKO_BASE_URL + row["href"]
+ if price.startswith("BTC"):
+ price = price.replace("BTC", "").replace(",", ".")
+
+ price_usd = (int(btc_price) * float(price)) if btc_price else None
+ results.append([name, price, price_usd, url])
+ return pd.DataFrame(
+ results,
+ columns=[
+ COLUMNS["name"],
+ COLUMNS["price_btc"],
+ COLUMNS["price_usd"],
+ COLUMNS["url"],
+ ],
+ )
+
+
+def get_news(n: int = 100) -> pd.DataFrame:
+ """Scrapes news from "https://www.coingecko.com/en/news?page={}"
+
+ Parameters
+ ----------
+ n: int
+ Number of news, by default n=100, one page has 25 news, so 4 pages are scraped.
+ Returns
+ -------
+ pandas.DataFrame:
+ title, author, posted, article
+ """
+
+ n_of_pages = (math.ceil(n / 25) + 1) if n else 2
+ dfs = []
+ for page in range(1, n_of_pages):
+ url = f"https://www.coingecko.com/en/news?page={page}"
+ rows = scrape_gecko_data(url).find_all(COLUMNS["article"])
+ results = []
+ for row in rows:
+ header = row.find("header")
+ link = header.find("a")["href"]
+ text = [t for t in header.text.strip().split("\n") if t not in ["", " "]]
+ article = row.find("div", class_="post-body").text.strip()
+ title, *by_who = text
+ author, posted = " ".join(by_who).split("(")
+ posted = posted.strip().replace(")", "")
+ results.append([title, author.strip(), posted, article, link])
+ dfs.append(
+ pd.DataFrame(
+ results,
+ columns=[
+ COLUMNS["title"],
+ COLUMNS["author"],
+ COLUMNS["posted"],
+ COLUMNS["article"],
+ COLUMNS["url"],
+ ],
+ )
+ )
+ df = pd.concat(dfs, ignore_index=True).head(n)
+ df.drop("article", axis=1, inplace=True)
+ df.index = df.index + 1
+ df.reset_index(inplace=True)
+ return df
+
+
+def get_top_crypto_categories():
+ """Scrapes top crypto categories from "https://www.coingecko.com/en/categories"
+
+ Returns
+ -------
+ pandas.DataFrame
+ rank, name, change_1h, change_7d, market_cap, volume_24h, n_of_coins, url
+ """
+ columns = [
+ COLUMNS["rank"],
+ COLUMNS["name"],
+ COLUMNS["change_1h"],
+ COLUMNS["change_24h"],
+ COLUMNS["change_7d"],
+ COLUMNS["market_cap"],
+ COLUMNS["volume_24h"],
+ COLUMNS["n_of_coins"],
+ COLUMNS["url"],
+ ]
+ url = "https://www.coingecko.com/en/categories"
+ rows = scrape_gecko_data(url).find("tbody").find_all("tr")
+ results = []
+ for row in rows:
+ url = GECKO_BASE_URL + row.find("a")["href"]
+ (
+ rank,
+ *names,
+ change_1h,
+ change_24h,
+ change_7d,
+ market_cap,
+ volume,
+ n_of_coins,
+ ) = row.text.strip().split()
+ results.append(
+ [
+ rank,
+ " ".join(names),
+ change_1h,
+ change_24h,
+ change_7d,
+ market_cap,
+ volume,
+ n_of_coins,
+ url,
+ ]
+ )
+
+ df = pd.DataFrame(results, columns=columns)
+ df["rank"] = df["rank"].astype(int)
+ return df
+
+
+def get_recently_added_coins():
+ """Scrape recently added coins on CoinGecko from "https://www.coingecko.com/en/coins/recently_added"
+
+ Returns
+ -------
+ pandas.DataFrame
+ name, symbol, price, change_1h, change_24h, last_added
+ """
+ columns = [
+ COLUMNS["name"],
+ COLUMNS["symbol"],
+ COLUMNS["price"],
+ COLUMNS["change_1h"],
+ COLUMNS["change_24h"],
+ COLUMNS["last_added"],
+ COLUMNS["url"],
+ ]
+
+ url = "https://www.coingecko.com/en/coins/recently_added"
+ rows = scrape_gecko_data(url).find("tbody").find_all("tr")
+ results = []
+
+ for row in rows:
+ url = GECKO_BASE_URL + row.find("a")["href"]
+ row_cleaned = clean_row(row)
+ (
+ name,
+ symbol,
+ _,
+ price,
+ *changes,
+ _,
+ _volume,
+ last_added,
+ ) = row_cleaned
+ change_1h, change_24h, _ = changes_parser(changes)
+ results.append([name, symbol, price, change_1h, change_24h, last_added, url])
+ df = replace_qm(pd.DataFrame(results, columns=columns))
+ df.index = df.index + 1
+ df.reset_index(inplace=True)
+ df.rename(columns={"index": "rank"}, inplace=True)
+ return df
+
+
+def get_stable_coins():
+ """Scrapes stable coins data from "https://www.coingecko.com/en/stablecoins"
+
+ Returns
+ -------
+ pandas.DataFrame
+ rank, name, symbol, price, change_24h, exchanges, market_cap, change_30, url
+ """
+ columns = [
+ COLUMNS["rank"],
+ COLUMNS["name"],
+ COLUMNS["symbol"],
+ COLUMNS["price"],
+ COLUMNS["change_24h"],
+ COLUMNS["exchanges"],
+ COLUMNS["market_cap"],
+ COLUMNS["change_30d"],
+ COLUMNS["url"],
+ ]
+ url = "https://www.coingecko.com/en/stablecoins"
+ rows = scrape_gecko_data(url).find("tbody").find_all("tr")
+ results = []
+ for row in rows:
+ link = GECKO_BASE_URL + row.find("a")["href"]
+ row_cleaned = clean_row(row)
+ if len(row_cleaned) == 8:
+ row_cleaned.append(None)
+
+ (
+ rank,
+ name,
+ *symbols,
+ price,
+ volume_24h,
+ exchanges,
+ market_cap,
+ change_30d,
+ ) = row_cleaned
+ symbol = symbols[0] if symbols else symbols
+ results.append(
+ [
+ rank,
+ name,
+ symbol,
+ price,
+ volume_24h,
+ exchanges,
+ market_cap,
+ change_30d,
+ link,
+ ]
+ )
+ df = replace_qm(pd.DataFrame(results, columns=columns))
+ df.drop("rank", axis=1, inplace=True)
+ create_df_index(df, "rank")
+ return df
+
+
+def get_yield_farms():
+ """Scrapes yield farms data from "https://www.coingecko.com/en/yield-farming"
+
+ Returns
+ -------
+ pandas.DataFrame
+ rank, name, pool, audits, collateral,value_locked, returns_year, returns_hour
+ """
+ columns = [
+ COLUMNS["rank"],
+ COLUMNS["name"],
+ "pool",
+ "audits",
+ "collateral",
+ "value_locked",
+ "return_year",
+ ]
+ url = "https://www.coingecko.com/en/yield-farming"
+ rows = scrape_gecko_data(url).find("tbody").find_all("tr")
+ results = []
+ for row in rows:
+ row_cleaned = clean_row(row)[:-2]
+ if " New" in row_cleaned: # find better way to fix it in future
+ row_cleaned.remove(" New")
+
+ if len(row_cleaned) == 7:
+ row_cleaned.insert(2, None)
+ (
+ rank,
+ name,
+ pool,
+ *others,
+ _,
+ value_locked,
+ apy1,
+ _, # hourly removed for most cases it's 0.00 so it doesn't bring any value for user
+ ) = row_cleaned
+ auditors, collateral = collateral_auditors_parse(others)
+ auditors = ", ".join(aud.strip() for aud in auditors)
+ collateral = ", ".join(coll.strip() for coll in collateral)
+ results.append(
+ [
+ rank,
+ name,
+ pool,
+ auditors,
+ collateral,
+ value_locked,
+ apy1,
+ ]
+ )
+ df = pd.DataFrame(results, columns=columns).replace({"": None})
+ for col in ["return_year"]:
+ df[col] = df[col].apply(
+ lambda x: x.replace(" Yearly", "") if isinstance(x, str) else x
+ )
+ df["rank"] = df["rank"].astype(int)
+ df = wrap_text_in_df(df, w=30)
+ return df
+
+
+def get_top_volume_coins():
+ """Scrapes top coins by trading volume "https://www.coingecko.com/en/coins/high_volume"
+
+ Returns
+ -------
+ pandas.DataFrame
+ rank, name, symbol, price, change_1h, change_24h, change_7d, volume_24h, market_cap
+ """
+ columns = [
+ COLUMNS["rank"],
+ COLUMNS["name"],
+ COLUMNS["symbol"],
+ COLUMNS["price"],
+ COLUMNS["change_1h"],
+ COLUMNS["change_24h"],
+ COLUMNS["change_7d"],
+ COLUMNS["volume_24h"],
+ COLUMNS["market_cap"],
+ ]
+ url = "https://www.coingecko.com/en/coins/high_volume"
+ rows = scrape_gecko_data(url).find("tbody").find_all("tr")
+ results = []
+ for row in rows:
+ row_cleaned = clean_row(row)
+ if len(row_cleaned) == 9:
+ row_cleaned.insert(0, "?")
+ row_cleaned.pop(3)
+ results.append(row_cleaned)
+ df = replace_qm(pd.DataFrame(results, columns=columns))
+ df.drop("rank", axis=1, inplace=True)
+ create_df_index(df, "rank")
+ return df
+
+
+def get_top_defi_coins():
+ """Scrapes top decentralized finance coins "https://www.coingecko.com/en/defi"
+
+ Returns
+ -------
+ pandas.DataFrame
+ rank, name, symbol, price, change_1h, change_24h, change_7d, volume_24h, market_cap, url
+ """
+ url = "https://www.coingecko.com/en/defi"
+ rows = scrape_gecko_data(url).find("tbody").find_all("tr")
+ results = []
+ for row in rows:
+
+ row_cleaned = clean_row(row)
+ row_cleaned.pop(2)
+ url = GECKO_BASE_URL + row.find("a")["href"]
+ row_cleaned.append(url)
+ if len(row_cleaned) == 11:
+ row_cleaned.insert(4, "?")
+ results.append(row_cleaned)
+
+ df = pd.DataFrame(
+ results,
+ columns=[
+ COLUMNS["rank"],
+ COLUMNS["name"],
+ COLUMNS["symbol"],
+ COLUMNS["price"],
+ COLUMNS["change_1h"],
+ COLUMNS["change_24h"],
+ COLUMNS["change_7d"],
+ COLUMNS["volume_24h"],
+ COLUMNS["market_cap"],
+ "fully_diluted_market_cap",
+ "market_cap_to_tvl_ratio",
+ COLUMNS["url"],
+ ],
+ )
+ df.drop(
+ ["fully_diluted_market_cap", "market_cap_to_tvl_ratio"],
+ axis=1,
+ inplace=True,
+ )
+ df["rank"] = df["rank"].astype(int)
+ return df
+
+
+def get_top_dexes():
+ """Scrapes top decentralized exchanges from "https://www.coingecko.com/en/dex"
+
+ Returns
+ -------
+ pandas.DataFrame
+ name, rank, volume_24h, n_coins, n_pairs, visits, most_traded, market_share_by_vol
+ """
+ columns = [
+ COLUMNS["name"],
+ COLUMNS["rank"],
+ COLUMNS["volume_24h"],
+ "n_coins",
+ "n_pairs",
+ "visits",
+ "most_traded",
+ "market_share_by_vol",
+ ]
+ url = "https://www.coingecko.com/en/dex"
+ rows = scrape_gecko_data(url).find("tbody").find_all("tr")
+ results = []
+ for row in rows:
+ row_cleaned = clean_row(row)
+ if " Trading Incentives" in row_cleaned:
+ row_cleaned.remove(" Trading Incentives")
+ if len(row_cleaned) == 8:
+ row_cleaned.insert(-3, "N/A")
+ results.append(row_cleaned)
+ df = pd.DataFrame(results)
+ df[COLUMNS["name"]] = df.iloc[:, 1] + " " + df.iloc[:, 2].replace("N/A", "")
+ df.drop(df.columns[1:3], axis=1, inplace=True)
+ df = swap_columns(df)
+ df.columns = columns
+ df["most_traded"] = (
+ df["most_traded"]
+ .apply(lambda x: x.split("$")[0])
+ .str.replace(",", "", regex=True)
+ .str.replace(".", "", regex=True)
+ )
+ df["most_traded"] = df["most_traded"].apply(lambda x: None if x.isdigit() else x)
+ df["rank"] = df["rank"].astype(int)
+ df.set_index("rank", inplace=True)
+ return df.reset_index()
+
+
+def get_top_nfts():
+ """Scrapes top nfts from "https://www.coingecko.com/en/nft"
+
+ Returns
+ -------
+ pandas.DataFrame
+ rank, name, symbol, price, change_1d, change_24h, change_7d, market_cap, url
+ """
+ url = "https://www.coingecko.com/en/nft"
+ rows = scrape_gecko_data(url).find("tbody").find_all("tr")
+ results = []
+ for row in rows:
+ link = GECKO_BASE_URL + row.find("a")["href"]
+ row_cleaned = clean_row(row)
+ if len(row_cleaned) == 9:
+ row_cleaned.insert(5, "N/A")
+ row_cleaned.append(link)
+ row_cleaned.pop(3)
+ results.append(row_cleaned)
+ df = pd.DataFrame(
+ results,
+ columns=[
+ COLUMNS["rank"],
+ COLUMNS["name"],
+ COLUMNS["symbol"],
+ COLUMNS["price"],
+ COLUMNS["change_1h"],
+ COLUMNS["change_24h"],
+ COLUMNS["change_7d"],
+ COLUMNS["volume_24h"],
+ COLUMNS["market_cap"],
+ COLUMNS["url"],
+ ],
+ )
+ df["rank"] = df["rank"].astype(int)
+ return df
+
+
+def get_nft_of_the_day():
+ """Scrapes data about nft of the day.
+
+ Returns
+ -------
+ pandas.DataFrame
+ metric, value
+ """
+ url = "https://www.coingecko.com/en/nft"
+ soup = scrape_gecko_data(url)
+ row = soup.find("div", class_="tw-px-4 tw-py-5 sm:tw-p-6")
+ try:
+ *author, description, _ = clean_row(row)
+ if len(author) > 3:
+ author, description = author[:3], author[3]
+ except (ValueError, IndexError):
+ return {}
+ df = (
+ pd.Series(
+ {
+ COLUMNS["author"]: " ".join(author),
+ "desc": description,
+ COLUMNS["url"]: GECKO_BASE_URL + row.find("a")["href"],
+ "img": row.find("img")["src"],
+ }
+ )
+ .to_frame()
+ .reset_index()
+ )
+ df.columns = ["Metric", "Value"]
+ df = wrap_text_in_df(df, w=100)
+ return df
+
+
+def get_nft_market_status():
+ """Scrapes overview data of nft markets from "https://www.coingecko.com/en/nft"
+
+ Returns
+ -------
+ pandas.DataFrame
+ Metric, Value
+ """
+ url = "https://www.coingecko.com/en/nft"
+ rows = scrape_gecko_data(url).find_all(
+ "span", class_="overview-box d-inline-block p-3 mr-2"
+ )
+ kpis = {}
+ for row in rows:
+ value, *kpi = clean_row(row)
+ name = " ".join(kpi)
+ kpis[name] = value
+ df = pd.Series(kpis).to_frame().reset_index()
+ df.columns = ["Metric", "Value"]
+ return df
+
+
+def get_exchanges():
+ """Get list of top exchanges from CoinGecko API
+
+ Returns
+ -------
+ pandas.DataFrame
+ trust_score, id, name, country, year_established, trade_volume_24h_btc, url
+ """
+ df = pd.DataFrame(client.get_exchanges_list(per_page=250))
+ df.replace({float(np.NaN): None}, inplace=True)
+ df = df[
+ [
+ "trust_score",
+ COLUMNS["id"],
+ COLUMNS["name"],
+ COLUMNS["country"],
+ "year_established",
+ "trade_volume_24h_btc",
+ COLUMNS["url"],
+ ]
+ ]
+ create_df_index(df, "rank")
+ return df
+
+
+def get_financial_platforms():
+ """Get list of financial platforms from CoinGecko API
+
+ Returns
+ -------
+ pandas.DataFrame
+ rank, name, category, centralized, website_url
+ """
+ df = pd.DataFrame(client.get_finance_platforms())
+ df.drop("facts", axis=1, inplace=True)
+ create_df_index(df, "rank")
+ return df
+
+
+def get_finance_products():
+ """Get list of financial products from CoinGecko API
+
+ Returns
+ -------
+ pandas.DataFrame
+ rank, platform, identifier, supply_rate_percentage, borrow_rate_percentage
+ """
+ df = pd.DataFrame(
+ client.get_finance_products(per_page=250),
+ columns=[
+ "platform",
+ "identifier",
+ "supply_rate_percentage",
+ "borrow_rate_percentage",
+ ],
+ )
+ create_df_index(df, "rank")
+ return df
+
+
+def get_indexes():
+ """Get list of crypto indexes from CoinGecko API
+
+ Returns
+ -------
+ pandas.DataFrame
+ name, id, market, last, is_multi_asset_composite
+ """
+ df = pd.DataFrame(client.get_indexes(per_page=250))
+ create_df_index(df, "rank")
+ return df
+
+
+def get_derivatives():
+ """Get list of crypto derivatives from CoinGecko API
+
+ Returns
+ -------
+ pandas.DataFrame
+ market, symbol, price, pct_change_24h, contract_type, basis, spread, funding_rate, volume_24h
+ """
+ df = pd.DataFrame(client.get_derivatives(include_tickers="unexpired"))
+ df.drop(
+ ["index", "last_traded_at", "expired_at", "index_id", "open_interest"],
+ axis=1,
+ inplace=True,
+ )
+
+ df.rename(columns={"price_percentage_change_24h": "pct_change_24h"}, inplace=True)
+ create_df_index(df, "rank")
+ return df
+
+
+def get_exchange_rates():
+ """Get list of crypto, fiats, commodity exchange rates from CoinGecko API
+
+ Returns
+ -------
+ pandas.DataFrame
+ index, name, unit, value, type
+ """
+ df = pd.DataFrame(client.get_exchange_rates()["rates"]).T.reset_index()
+ df.drop("index", axis=1, inplace=True)
+ create_df_index(df, "index")
+ return df
+
+
+def get_global_info():
+ """Get global statistics about crypto from CoinGecko API like:
+ - market cap change
+ - number of markets
+ - icos
+ - number of active crypto
+
+ Returns
+ -------
+ pandas.DataFrame
+ Metric, Value
+ """
+ results = client.get_global()
+
+ total_mcap = results.pop("market_cap_percentage")
+ eth, btc = total_mcap.get("btc"), total_mcap.get("eth")
+ for key in [COLUMNS["total_market_cap"], COLUMNS["total_volume"], "updated_at"]:
+ del results[key]
+ results["eth_market_cap_in_pct"] = eth
+ results["btc_market_cap_in_pct"] = btc
+ results["altcoin_market_cap_in_pct"] = 100 - (float(eth) + float(btc))
+ df = pd.Series(results).reset_index()
+ df.columns = ["Metric", "Value"]
+ return df
+
+
+def get_global_markets_info():
+ """Get global statistics about crypto markets from CoinGecko API like:
+ - total_market_cap
+ - total_volume
+ - market_cap_percentage
+
+ Returns
+ -------
+ pandas.DataFrame
+ total_market_cap, total_volume, market_cap_percentage
+ """
+ columns = [
+ COLUMNS["total_market_cap"],
+ COLUMNS["total_volume"],
+ COLUMNS["market_cap_percentage"],
+ ]
+ data = []
+ results = client.get_global()
+ for key in columns:
+ data.append(results.get(key))
+ df = pd.DataFrame(data).T
+ df.columns = columns
+ df.replace({float("nan"): None}, inplace=True)
+ return df.reset_index()
+
+
+def get_global_defi_info():
+ """Get global statistics about Decentralized Finances from CoinGecko API like:
+
+ Returns
+ -------
+ pandas.DataFrame
+ Metric, Value
+ """
+ results = client.get_global_decentralized_finance_defi()
+ for key, value in results.items():
+ try:
+ results[key] = round(float(value), 4)
+ except (ValueError, TypeError):
+ pass
+
+ df = pd.Series(results).reset_index()
+ df.columns = ["Metric", "Value"]
+ return df
+
+
+def get_coin_list():
+ """Get list of coins available on CoinGecko
+
+ Returns
+ -------
+ pandas.DataFrame
+ id, symbol, name
+ """
+
+ return pd.DataFrame(
+ client.get_coins_list(),
+ columns=[COLUMNS["id"], COLUMNS["symbol"], COLUMNS["name"]],
+ ).reset_index()
diff --git a/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_view.py b/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_view.py
new file mode 100644
index 00000000000..fc83b9c747b
--- /dev/null
+++ b/gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_view.py
@@ -0,0 +1,2623 @@
+""" pycoingecko_api """
+__docformat__ = "numpy"
+
+import argparse
+from typing import List
+import textwrap
+import difflib
+import pandas as pd
+from pandas.plotting import register_matplotlib_converters
+import matplotlib.pyplot as plt
+from tabulate import tabulate
+from pycoingecko import CoinGeckoAPI
+from gamestonk_terminal.helper_funcs import parse_known_args_and_warn, plot_autoscale
+from gamestonk_terminal.config_plot import PLOT_DPI
+import gamestonk_terminal.cryptocurrency.coingecko.pycoingecko_overview_model as gecko
+import gamestonk_terminal.cryptocurrency.coingecko.pycoingecko_coin_model as gecko_coin
+from gamestonk_terminal.cryptocurrency.cryptocurrency_helpers import wrap_text_in_df
+
+register_matplotlib_converters()
+
+# Generate a list of valid coins to be checked against later
+cg_api = CoinGeckoAPI()
+coins = cg_api.get_coins()
+
+# pylint: disable=inconsistent-return-statements
+# pylint: disable=R0904, C0302
+
+
+def load(other_args: List[str]):
+ """Load selected Cryptocurrency. You can pass either symbol of id of the coin
+
+ Parameters
+ ----------
+ other_args : List[str]
+ argparse arguments
+
+ """
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ prog="load",
+ description="""
+ Load cryptocurrency, from CoinGecko.
+ You will have access to a lot of statistics on that coin like price data,
+ coin development stats, social media and many others. Loading coin
+ also will open access to technical analysis menu.
+ """,
+ )
+
+ parser.add_argument(
+ "-c",
+ "--coin",
+ required=True,
+ type=str,
+ dest="coin",
+ help="Coin to load data for (symbol or coin id). You can use either symbol of the coin or coinId"
+ "You can find all coins using command `coins` or visit https://www.coingecko.com/en. "
+ "To use load a coin use command load -c [symbol or coinId]",
+ )
+
+ try:
+ if other_args:
+ if "-" not in other_args[0]:
+ other_args.insert(0, "-c")
+
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+
+ if not ns_parser:
+ return
+
+ try:
+ coin = gecko_coin.Coin(ns_parser.coin)
+ except KeyError:
+ print(f"Could not find coin with the id: {ns_parser.coin}")
+ print("")
+ return None
+
+ print("")
+ return coin
+
+ except SystemExit:
+ print("")
+ return None
+
+ except Exception as e:
+ print(e)
+ print("")
+ return None
+
+
+def chart(coin: gecko_coin.Coin, other_args: List[str]):
+ """Plots chart for loaded cryptocurrency
+
+ Parameters
+ ----------
+ coin : gecko_coin.Coin
+ Cryptocurrency
+ other_args : List[str]
+ argparse arguments
+
+ """
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ prog="chart",
+ description="""
+ Display chart for loaded coin. You can specify currency vs which you want
+ to show chart and also number of days to get data for.
+ By default currency: usd and days: 30.
+ E.g. if you loaded in previous step Bitcoin and you want to see it's price vs ethereum
+ in last 90 days range use `chart --vs eth --days 90`
+ """,
+ )
+
+ parser.add_argument(
+ "--vs", default="usd", dest="vs", help="Currency to display vs coin"
+ )
+
+ parser.add_argument(
+ "-d", "--days", default=30, dest="days", help="Number of days to get data for"
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+
+ if not ns_parser:
+ return
+
+ df = coin.get_coin_market_chart(ns_parser.vs, ns_parser.days)
+ plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)
+
+ plt.plot(df.index, df.price, "-ok", ms=2)
+ plt.xlabel("Time")
+ plt.xlim(df.index[0], df.index[-1])
+ plt.ylabel("Price")
+ plt.grid(b=True, which="major", color="#666666", linestyle="-")
+ plt.minorticks_on()
+ plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2)
+ plt.title(f"{coin.coin_symbol}/{df['currency'][0]}")
+ plt.show()
+ print("")
+
+ except SystemExit:
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def ta(coin: gecko_coin.Coin, other_args: List[str]):
+ """Load data for Technical Analysis
+
+ Parameters
+ ----------
+ coin : gecko_coin.Coin
+ Cryptocurrency
+ other_args : List[str]
+ argparse arguments
+
+ """
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ prog="ta",
+ description="""
+ Loads data for technical analysis. You can specify currency vs which you want
+ to show chart and also number of days to get data for.
+ By default currency: usd and days: 30.
+ E.g. if you loaded in previous step Bitcoin and you want to see it's price vs ethereum
+ in last 90 days range use `ta --vs eth --days 90`
+ """,
+ )
+
+ parser.add_argument(
+ "--vs", default="usd", dest="vs", help="Currency to display vs coin"
+ )
+
+ parser.add_argument(
+ "-d", "--days", default=30, dest="days", help="Number of days to get data for"
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+
+ if not ns_parser:
+ return None, None
+
+ df = coin.get_coin_market_chart(ns_parser.vs, ns_parser.days)
+ return df, ns_parser.vs
+
+ except SystemExit:
+ print("")
+ return None, None
+
+ except Exception as e:
+ print(e)
+ print("")
+ return None, None
+
+
+def info(coin: gecko_coin.Coin, other_args: List[str]):
+ """Shows basic information about loaded coin
+
+ Parameters
+ ----------
+ coin : gecko_coin.Coin
+ Cryptocurrency
+ other_args : List[str]
+ argparse arguments
+
+ """
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ prog="info",
+ description="""
+ Shows basic information about loaded coin like:
+ id, name, symbol, asset_platform, description, contract_address,
+ market_cap_rank, public_interest_score, total_supply, max_supply,
+ price_change_percentage_24h, price_change_percentage_7d, price_change_percentage_30d,
+ current_price_btc, current_price_eth, current_price_usd
+ """,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+
+ if not ns_parser:
+ return
+
+ df = wrap_text_in_df(coin.base_info, w=80)
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except SystemExit:
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def web(coin: gecko_coin.Coin, other_args: List[str]):
+ """Shows found websites corresponding to loaded coin
+
+ Parameters
+ ----------
+ coin : gecko_coin.Coin
+ Cryptocurrency
+ other_args : List[str]
+ argparse arguments
+
+ """
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ prog="web",
+ description="""
+ Websites found for given Coin. You can find there urls to
+ homepage, forum, announcement site and others.
+ """,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+
+ if not ns_parser:
+ return
+
+ df = coin.websites
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except SystemExit:
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def social(coin: gecko_coin.Coin, other_args: List[str]):
+ """Shows social media corresponding to loaded coin
+
+ Parameters
+ ----------
+ coin : gecko_coin.Coin
+ Cryptocurrency
+ other_args : List[str]
+ argparse arguments
+
+ """
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ prog="social",
+ description="""
+ Shows social media corresponding to loaded coin. You can find there name of
+ telegram channel, urls to twitter, reddit, bitcointalk, facebook and discord.
+ """,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+
+ if not ns_parser:
+ return
+
+ df = coin.social_media
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except SystemExit:
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def dev(coin: gecko_coin.Coin, other_args: List[str]):
+ """Shows developers data for loaded coin
+
+ Parameters
+ ----------
+ coin : gecko_coin.Coin
+ Cryptocurrency
+ other_args : List[str]
+ argparse arguments
+
+ """
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ prog="dev",
+ description="""
+ Developers data for loaded coin. If the development data is available you can see
+ how the code development of given coin is going on.
+ There are some statistics that shows number of stars, forks, subscribers, pull requests,
+ commits, merges, contributors on github.
+ """,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+
+ if not ns_parser:
+ return
+
+ df = coin.developers_data
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except SystemExit:
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def ath(coin: gecko_coin.Coin, other_args: List[str]):
+ """Shows all time high data for loaded coin
+
+ Parameters
+ ----------
+ coin : gecko_coin.Coin
+ Cryptocurrency
+ other_args : List[str]
+ argparse arguments
+
+ """
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ prog="ath",
+ description="""
+ All time high data for loaded coin. You can find there most important metrics regarding
+ ath of coin price like:
+ current_price_btc, ,current_price_eth, current_price_usd, ath_btc, ath_eth, ath_usd,
+ ath_date_btc, ath_date_eth, ath_date_usd, ath_change_percentage_btc, ath_change_percentage_btc,
+ ath_change_percentage_eth, ath_change_percentage_usd
+ """,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+
+ if not ns_parser:
+ return
+
+ df = coin.all_time_high
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except SystemExit:
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def atl(coin: gecko_coin.Coin, other_args: List[str]):
+ """Shows all time low data for loaded coin
+
+ Parameters
+ ----------
+ coin : gecko_coin.Coin
+ Cryptocurrency
+ other_args : List[str]
+ argparse arguments
+
+ """
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ prog="atl",
+ description="""
+ All time low data for loaded coin. You can find there most important metrics regarding
+ atl of coin price like:
+ current_price_btc, ,current_price_eth, current_price_usd, atl_btc, atl_eth, atl_usd,
+ atl_date_btc, atl_date_eth, atl_date_usd, atl_change_percentage_btc, atl_change_percentage_btc,
+ atl_change_percentage_eth, atl_change_percentage_usd
+ """,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+
+ if not ns_parser:
+ return
+
+ df = coin.all_time_low
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except SystemExit:
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def score(coin: gecko_coin.Coin, other_args: List[str]):
+ """Shows different kind of scores for loaded coin
+
+ Parameters
+ ----------
+ coin : gecko_coin.Coin
+ Cryptocurrency
+ other_args : List[str]
+ argparse arguments
+
+ """
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ prog="score",
+ description="""
+ In this view you can find different kind of scores for loaded coin.
+ Those scores represents different rankings, sentiment metrics, some user stats and others.
+ coingecko_rank, coingecko_score, developer_score, community_score, liquidity_score,
+ sentiment_votes_up_percentage, sentiment_votes_down_percentage, public_interest_score,
+ facebook_likes, twitter_followers, reddit_average_posts_48h, reddit_average_comments_48h,
+ reddit_subscribers, reddit_accounts_active_48h, telegram_channel_user_count, alexa_rank,
+ bing_matches
+ """,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+
+ if not ns_parser:
+ return
+
+ df = coin.scores
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except SystemExit:
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def bc(coin: gecko_coin.Coin, other_args: List[str]):
+ """Shows urls to blockchain explorers
+
+ Parameters
+ ----------
+ coin : gecko_coin.Coin
+ Cryptocurrency
+ other_args : List[str]
+ argparse arguments
+
+ """
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ prog="bc",
+ description="""
+ Blockchain explorers URLs for loaded coin. Those are sites like etherescan.io or polkascan.io
+ in which you can see all blockchain data e.g. all txs, all tokens, all contracts...
+ """,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+
+ if not ns_parser:
+ return
+
+ df = coin.blockchain_explorers
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except SystemExit:
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def market(coin: gecko_coin.Coin, other_args: List[str]):
+ """Shows market data for loaded coin
+
+ Parameters
+ ----------
+ coin : gecko_coin.Coin
+ Cryptocurrency
+ other_args : List[str]
+ argparse arguments
+
+ """
+ parser = argparse.ArgumentParser(
+ add_help=False,
+ prog="market",
+ description="""
+ Market data for loaded coin. There you find metrics like:
+ market_cap_rank, total_supply, max_supply, circulating_supply,
+ price_change_percentage_24h, price_change_percentage_7d, 'price_change_percentage_30d',
+ price_change_percentage_60d', 'price_change_percentage_1y', 'market_cap_change_24h',
+ market_cap_btc', 'market_cap_eth', 'market_cap_usd', 'total_volume_btc', 'total_volume_eth',
+ total_volume_usd', 'high_24h_btc', 'high_24h_eth', 'high_24h_usd', 'low_24h_btc', 'low_24h_eth',
+ low_24h_usd'
+ """,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+
+ if not ns_parser:
+ return
+
+ df = coin.market_data
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except SystemExit:
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def holdings_overview(other_args: List[str]):
+ """
+ Shows overview of public companies that holds ethereum or bitcoin from www.coingecko.com
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="hold",
+ add_help=False,
+ description="""
+ Shows overview of public companies that holds ethereum or bitcoin.
+ You can find there most important metrics like:
+ Total Bitcoin Holdings, Total Value (USD), Public Companies Bitcoin Dominance, Companies
+ """,
+ )
+
+ parser.add_argument(
+ "-c",
+ "--coin",
+ dest="coin",
+ type=str,
+ help="companies with ethereum or bitcoin",
+ default="bitcoin",
+ choices=["ethereum", "bitcoin"],
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_holdings_overview(endpoint=ns_parser.coin)
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def holdings_companies_list(other_args: List[str]):
+ """Shows Ethereum/Bitcoin Holdings by Public Companies from www.coingecko.com
+ Track publicly traded companies around the world that are buying ethereum as part of corporate treasury
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="hold_comp",
+ add_help=False,
+ description="""Track publicly traded companies around the world that
+ are buying ethereum or bitcoin as part of corporate treasury:
+ rank, company, ticker, country, total_btc, entry_value, today_value, pct_of_supply
+ You can use additional flag --links to see urls to announcement about buying btc or eth by given company.
+ In this case you will see only columns like rank, company, url
+ """,
+ )
+
+ parser.add_argument(
+ "-c",
+ "--coin",
+ dest="coin",
+ type=str,
+ help="companies with ethereum or bitcoin",
+ default="bitcoin",
+ choices=["ethereum", "bitcoin"],
+ )
+
+ parser.add_argument(
+ "-l",
+ "--links",
+ dest="links",
+ action="store_true",
+ help="Flag to show urls. If you will use that flag you will see only rank, company, url columns",
+ default=False,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_companies_assets(endpoint=ns_parser.coin)
+
+ if ns_parser.links is True:
+ df = df[["rank", "company", "url"]]
+ else:
+ df.drop("url", axis=1, inplace=True)
+
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def gainers(other_args: List[str]):
+ """Shows Largest Gainers - coins which gain the most in given period from www.coingecko.com
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="gainers",
+ add_help=False,
+ description="""
+ Shows Largest Gainers - coins which gain the most in given period.
+ You can use parameter --period to set which timeframe are you interested in. eg. 1h, 24h, 7d, 14d, 30d, 60d, 1y
+ You can look on only top N number of records with --top,
+ You can sort by rank, symbol, name, volume, price, change with --sort and also with --descend flag to set it
+ to sort descending.
+ There is --links flag, which will display one additional column you all urls for coins.
+ """,
+ )
+
+ parser.add_argument(
+ "-p",
+ "--period",
+ dest="period",
+ type=str,
+ help="time period, one from [1h, 24h, 7d, 14d, 30d, 60d, 1y]",
+ default="1h",
+ choices=["1h", "24h", "7d", "14d", "30d", "60d", "1y"],
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="top N number records",
+ default=20,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: rank",
+ default="rank",
+ choices=["rank", "symbol", "name", "volume", "price", "change"],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+
+ parser.add_argument(
+ "-l",
+ "--links",
+ dest="links",
+ action="store_true",
+ help="Flag to show urls. If you will use that flag you will additional column with urls",
+ default=False,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ if ns_parser.sortby == "change":
+ sortby = f"%change_{ns_parser.period}"
+ else:
+ sortby = ns_parser.sortby
+
+ df = gecko.get_gainers_or_losers(
+ period=ns_parser.period, typ="gainers"
+ ).sort_values(by=sortby, ascending=ns_parser.descend)
+
+ if not ns_parser.links:
+ df.drop("url", axis=1, inplace=True)
+
+ print(
+ tabulate(
+ df.head(ns_parser.top),
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def losers(other_args: List[str]):
+ """Shows Largest Losers - coins which lost the most in given period of time from www.coingecko.com
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="losers",
+ add_help=False,
+ description="""
+ Shows Largest Losers - coins which price dropped the most in given period
+ You can use parameter --period to set which timeframe are you interested in. eg. 1h, 24h, 7d, 14d, 30d, 60d, 1y
+ You can look on only top N number of records with --top,
+ You can sort by rank, symbol, name, volume, price, change with --sort and also with --descend flag
+ to sort descending.
+ Flag --links will display one additional column with all coingecko urls for listed coins.
+ """,
+ )
+
+ parser.add_argument(
+ "-p",
+ "--period",
+ dest="period",
+ type=str,
+ help="time period, one from [1h, 24h, 7d, 14d, 30d, 60d, 1y]",
+ default="1h",
+ choices=["1h", "24h", "7d", "14d", "30d", "60d", "1y"],
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="top N number records",
+ default=20,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: change",
+ default="rank",
+ choices=["rank", "symbol", "name", "volume", "price", "change"],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+
+ parser.add_argument(
+ "-l",
+ "--links",
+ dest="links",
+ action="store_true",
+ help="Flag to show urls. If you will use that flag you will additional column with urls",
+ default=False,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ if ns_parser.sortby == "change":
+ sortby = f"%change_{ns_parser.period}"
+ else:
+ sortby = ns_parser.sortby
+
+ df = gecko.get_gainers_or_losers(
+ period=ns_parser.period, typ="losers"
+ ).sort_values(by=sortby, ascending=ns_parser.descend)
+
+ if not ns_parser.links:
+ df.drop("url", axis=1, inplace=True)
+
+ print(
+ tabulate(
+ df.head(ns_parser.top),
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def discover(category: str, other_args: List[str]):
+ """Discover coins by different categories
+ - Most voted coins
+ - Most popular coins
+ - Recently added coins
+ - Most positive sentiment coins
+
+ Parameters
+ ----------
+ category: str
+ one from list: [trending, most_voted, positive_sentiment, most_visited]
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog=f"{category}",
+ add_help=False,
+ description=f"""Discover {category} coins.
+ Use --top parameter to display only top N number of records,
+ You can sort by rank, name, price_btc, price_usd, using --sort parameter and also with --descend flag
+ to sort descending.
+ Flag --links will display one additional column with all coingecko urls for listed coins.
+ {category} will display: rank, name, price_usd, price_btc
+ """,
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="top N number records",
+ default=20,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: rank",
+ default="rank",
+ choices=["rank", "name", "price_usd", "price_btc"],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+
+ parser.add_argument(
+ "-l",
+ "--links",
+ dest="links",
+ action="store_true",
+ help="Flag to show urls. If you will use that flag you will additional column with urls",
+ default=False,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.discover_coins(category=category)
+ df.index = df.index + 1
+ df.reset_index(inplace=True)
+ df.rename(columns={"index": "rank"}, inplace=True)
+
+ df = df.sort_values(by=ns_parser.sortby, ascending=ns_parser.descend)
+
+ if not ns_parser.links:
+ df.drop("url", axis=1, inplace=True)
+
+ print(
+ tabulate(
+ df.head(ns_parser.top),
+ headers=df.columns,
+ floatfmt=".5f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def news(other_args: List[str]):
+ """Shows latest crypto news from www.coingecko.com
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="news",
+ add_help=False,
+ description="Shows latest crypto news from CoinGecko. "
+ "You will see index, title, author, posted columns. "
+ "You can sort by each of column above, using --sort parameter and also do it descending with --descend flag"
+ "To display urls to news use --links flag.",
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="top N number of news >=10",
+ default=50,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: index",
+ default="index",
+ choices=["index", "title", "author", "posted"],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+
+ parser.add_argument(
+ "-l",
+ "--links",
+ dest="links",
+ action="store_true",
+ help="Flag to show urls. If you will use that flag you will additional column with urls",
+ default=False,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_news(n=ns_parser.top).sort_values(
+ by=ns_parser.sortby, ascending=ns_parser.descend
+ )
+
+ df["title"] = df["title"].apply(
+ lambda x: "\n".join(textwrap.wrap(x, width=50)) if isinstance(x, str) else x
+ )
+
+ if not ns_parser.links:
+ df.drop("url", axis=1, inplace=True)
+ else:
+ df = df[["index", "url"]]
+
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".0f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def categories(other_args: List[str]):
+ """Shows top cryptocurrency categories by market capitalization from https://www.coingecko.com/en/categories
+ The cryptocurrency category ranking is based on market capitalization.
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="categories",
+ add_help=False,
+ description="""Shows top cryptocurrency categories by market capitalization. It includes categories like:
+ stablecoins, defi, solana ecosystem, polkadot ecosystem and many others.
+ "You can sort by each of column above, using --sort parameter and also do it descending with --descend flag"
+ "To display urls to news use --links flag.",
+ Displays: rank, name, change_1h, change_24h, change_7d, market_cap, volume_24h, n_of_coins
+
+ """,
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="top N number of news >=10",
+ default=20,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: rank",
+ default="rank",
+ choices=[
+ "rank",
+ "name",
+ "change_1h",
+ "change_24h",
+ "change_7d",
+ "market_cap",
+ "volume_24h",
+ "n_of_coins",
+ ],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+
+ parser.add_argument(
+ "-l",
+ "--links",
+ dest="links",
+ action="store_true",
+ help="Flag to show urls. If you will use that flag you will additional column with urls",
+ default=False,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_top_crypto_categories().sort_values(
+ by=ns_parser.sortby, ascending=ns_parser.descend
+ )
+
+ if not ns_parser.links:
+ df.drop("url", axis=1, inplace=True)
+ else:
+ df = df[["rank", "name", "url"]]
+
+ print(
+ tabulate(
+ df.head(ns_parser.top),
+ headers=df.columns,
+ floatfmt=".0f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def recently_added(other_args: List[str]):
+ """Shows recently added coins from "https://www.coingecko.com/en/coins/recently_added"
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="recently",
+ add_help=False,
+ description="""
+ Shows recently added coins on CoinGecko. You can display only top N number of coins with --top parameter.
+ You can sort data by rank, name, symbol, price, change_24h, change_1h, added with --sort
+ and also with --descend flag to sort descending.
+ Flag --links will display urls
+ """,
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="top N number records",
+ default=20,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: rank",
+ default="rank",
+ choices=["rank", "name", "symbol", "price", "change_24h", "change_1h", "added"],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+
+ parser.add_argument(
+ "-l",
+ "--links",
+ dest="links",
+ action="store_true",
+ help="Flag to show urls",
+ default=False,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_recently_added_coins().sort_values(
+ by=ns_parser.sortby, ascending=ns_parser.descend
+ )
+
+ if ns_parser.links is True:
+ df = df[["rank", "symbol", "added", "url"]]
+ else:
+ df.drop("url", axis=1, inplace=True)
+
+ print(
+ tabulate(
+ df.head(ns_parser.top),
+ headers=df.columns,
+ floatfmt=".0f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def stablecoins(other_args: List[str]):
+ """Shows stablecoins data from "https://www.coingecko.com/en/stablecoins"
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="stables",
+ add_help=False,
+ description="""Shows stablecoins by market capitalization.
+ Stablecoins are cryptocurrencies that attempt to peg their market value to some external reference
+ like the U.S. dollar or to a commodity's price such as gold.
+ You can display only top N number of coins with --top parameter.
+ You can sort data by rank, name, symbol, price, change_24h, exchanges, market_cap, change_30d with --sort
+ and also with --descend flag to sort descending.
+ Flag --links will display stablecoins urls
+ """,
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="top N number records",
+ default=20,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: rank",
+ default="rank",
+ choices=[
+ "rank",
+ "name",
+ "symbol",
+ "price",
+ "change_24h",
+ "exchanges",
+ "market_cap",
+ "change_30d",
+ ],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+
+ parser.add_argument(
+ "-l",
+ "--links",
+ dest="links",
+ action="store_true",
+ help="Flag to show urls",
+ default=False,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_stable_coins().sort_values(
+ by=ns_parser.sortby, ascending=ns_parser.descend
+ )
+
+ if ns_parser.links is True:
+ df = df[["rank", "name", "symbol", "url"]]
+ else:
+ df.drop("url", axis=1, inplace=True)
+
+ print(
+ tabulate(
+ df.head(ns_parser.top),
+ headers=df.columns,
+ floatfmt=".0f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def yfarms(other_args: List[str]):
+ """Shows Top Yield Farming Pools by Value Locked from "https://www.coingecko.com/en/yield-farming"
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="yfarms",
+ add_help=False,
+ description="""Shows Top Yield Farming Pools by Value Locked
+ Yield farming, also referred to as liquidity mining, is a way to generate rewards with cryptocurrency holdings.
+ In simple terms, it means locking up cryptocurrencies and getting rewards.
+ You can display only top N number of coins with --top parameter.
+ You can sort data by rank, name, value_locked, return_year with --sort parameter
+ and also with --descend flag to sort descending.
+ """,
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="Top N of records. Default 20",
+ default=20,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: rank",
+ default="rank",
+ choices=["rank", "name", "value_locked", "return_year"],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_yield_farms()
+ df = df.sort_values(by=ns_parser.sortby, ascending=ns_parser.descend)
+
+ print(
+ tabulate(
+ df.head(ns_parser.top),
+ headers=df.columns,
+ floatfmt=".0f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def top_volume_coins(other_args: List[str]):
+ """Shows Top 100 Coins by Trading Volume from "https://www.coingecko.com/en/yield-farming"
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="top_volume",
+ add_help=False,
+ description="""Shows Top Coins by Trading Volume.
+ You can display only top N number of coins with --top parameter.
+ You can sort data by on of columns rank, name, symbol, price, change_1h, change_24h, change_7d , volume_24h ,
+ market_cap with --sort parameter and also with --descend flag to sort descending.
+ Displays columns: rank, name, symbol, price, change_1h, change_24h, change_7d , volume_24h ,market_cap
+ """,
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="Top N of records. Default 20",
+ default=20,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: rank",
+ default="rank",
+ choices=[
+ "rank",
+ "name",
+ "symbol",
+ "price",
+ "change_1h",
+ "change_24h",
+ "change_7d",
+ "volume_24h",
+ "market_cap",
+ ],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_top_volume_coins().sort_values(
+ by=ns_parser.sortby, ascending=ns_parser.descend
+ )
+
+ print(
+ tabulate(
+ df.head(ns_parser.top),
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def top_defi_coins(other_args: List[str]):
+ """Shows Top 100 DeFi Coins by Market Capitalization from "https://www.coingecko.com/en/defi"
+ DeFi or Decentralized Finance refers to financial services that are built
+ on top of distributed networks with no central intermediaries.
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="top_defi",
+ add_help=False,
+ description="""Shows Top DeFi Coins by Market Capitalization
+ DeFi or Decentralized Finance refers to financial services that are built
+ on top of distributed networks with no central intermediaries.
+ You can display only top N number of coins with --top parameter.
+ You can sort data by rank, name, symbol, price, change_24h, change_1h, change_7d,
+ volume_24h, market_cap with --sort and also with --descend flag to sort descending.
+ Flag --links will display urls
+ """,
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="top N number records",
+ default=20,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: rank",
+ default="rank",
+ choices=[
+ "rank",
+ "name",
+ "symbol",
+ "price",
+ "change_1h",
+ "change_24h",
+ "change_7d",
+ "volume_24h",
+ "market_cap",
+ ],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+
+ parser.add_argument(
+ "-l",
+ "--links",
+ dest="links",
+ action="store_true",
+ help="Flag to show urls",
+ default=False,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_top_defi_coins().sort_values(
+ by=ns_parser.sortby, ascending=ns_parser.descend
+ )
+
+ if ns_parser.links is True:
+ df = df[["rank", "name", "symbol", "url"]]
+ else:
+ df.drop("url", axis=1, inplace=True)
+
+ print(
+ tabulate(
+ df.head(ns_parser.top),
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def top_dex(other_args: List[str]):
+ """Shows Top Decentralized Exchanges on CoinGecko by Trading Volume from "https://www.coingecko.com/en/dex"
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="top_dex",
+ add_help=False,
+ description="""
+ Shows Top Decentralized Exchanges on CoinGecko by Trading Volume
+ You can display only top N number of coins with --top parameter.
+ You can sort data by rank, name, volume_24h, n_coins, n_pairs, visits, most_traded, market_share_by_vol
+ most_traded_pairs, market_share_by_volume with --sort and also with --descend flag to sort descending.
+ Display columns:
+ rank, name, volume_24h, n_coins, n_pairs, visits, most_traded, market_share_by_vol
+ """,
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="top N number records",
+ default=20,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: rank",
+ default="rank",
+ choices=[
+ "rank",
+ "name",
+ "volume_24h",
+ "n_coins",
+ "visits",
+ "most_traded",
+ "market_share_by_vol",
+ "n_pairs",
+ ],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_top_dexes().sort_values(
+ by=ns_parser.sortby, ascending=ns_parser.descend
+ )
+
+ print(
+ tabulate(
+ df.head(ns_parser.top),
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def top_nft(other_args: List[str]):
+ """Shows Top 100 NFT Coins by Market Capitalization from "https://www.coingecko.com/en/nft"
+ Top 100 NFT Coins by Market Capitalization
+ NFT (Non-fungible Token) refers to digital assets with unique characteristics.
+ Examples of NFT include crypto artwork, collectibles, game items, financial products, and more.
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="top_nft",
+ add_help=False,
+ description="""Shows Top NFT Coins by Market Capitalization
+ NFT (Non-fungible Token) refers to digital assets with unique characteristics.
+ Examples of NFT include crypto artwork, collectibles, game items, financial products, and more.
+ You can display only top N number of coins with --top parameter.
+ You can sort data by rank, name, symbol, price, change_24h, change_1h, change_7d,
+ volume_24h, market_cap with --sort and also with --descend flag to sort descending.
+ Flag --links will display urls
+ Displays : rank, name, symbol, price, change_1h, change_24h, change_7d, market_cap, url
+
+ """,
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="top N number records",
+ default=20,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: rank",
+ default="rank",
+ choices=[
+ "rank",
+ "name",
+ "symbol",
+ "price",
+ "change_1h",
+ "change_24h",
+ "change_7d",
+ "volume_24h",
+ "market_cap",
+ ],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+
+ parser.add_argument(
+ "-l",
+ "--links",
+ dest="links",
+ action="store_true",
+ help="Flag to show urls",
+ default=False,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_top_nfts().sort_values(
+ by=ns_parser.sortby, ascending=ns_parser.descend
+ )
+
+ if ns_parser.links is True:
+ df = df[["rank", "name", "symbol", "url"]]
+ else:
+ df.drop("url", axis=1, inplace=True)
+
+ print(
+ tabulate(
+ df.head(ns_parser.top),
+ headers=df.columns,
+ floatfmt=".4f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def nft_of_the_day(other_args: List[str]):
+ """Shows NFT of the day "https://www.coingecko.com/en/nft"
+
+ NFT (Non-fungible Token) refers to digital assets with unique characteristics.
+ Examples of NFT include crypto artwork, collectibles, game items, financial products, and more.
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="nft_today",
+ add_help=False,
+ description="""Shows NFT of the day
+ NFT (Non-fungible Token) refers to digital assets with unique characteristics.
+ Examples of NFT include crypto artwork, collectibles, game items, financial products, and more.
+ With nft_today command you will display:
+ author, description, url, img url for NFT which was chosen on CoinGecko as a nft of the day.
+
+ """,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_nft_of_the_day()
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def nft_market_status(other_args: List[str]):
+ """Shows overview data of nft markets "https://www.coingecko.com/en/nft"
+
+ NFT (Non-fungible Token) refers to digital assets with unique characteristics.
+ Examples of NFT include crypto artwork, collectibles, game items, financial products, and more.
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="nft_market",
+ add_help=False,
+ description="""Shows NFT market status
+ NFT (Non-fungible Token) refers to digital assets with unique characteristics.
+ Examples of NFT include crypto artwork, collectibles, game items, financial products, and more.
+ Displays:
+ NFT Market Cap, 24h Trading Volume, NFT Dominance vs Global market, Theta Network NFT Dominance
+ """,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_nft_market_status()
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def exchanges(other_args: List[str]):
+ """Shows list of top exchanges from CoinGecko
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="exchanges",
+ add_help=False,
+ description="""Shows Top Crypto Exchanges
+ You can display only top N number of coins with --top parameter.
+ You can sort data by rank, trust_score, id, name, country, established, trade_volume_24h_btc with --sort
+ and also with --descend flag to sort descending.
+ Flag --links will display urls.
+ Displays: rank, trust_score, id, name, country, established, trade_volume_24h_btc
+ """,
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="top N number records",
+ default=20,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: rank",
+ default="rank",
+ choices=[
+ "rank",
+ "trust_score",
+ "id",
+ "name",
+ "country",
+ "year_established",
+ "trade_volume_24h_btc",
+ ],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+
+ parser.add_argument(
+ "-l",
+ "--links",
+ dest="links",
+ action="store_true",
+ help="Flag to show urls",
+ default=False,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_exchanges().sort_values(
+ by=ns_parser.sortby, ascending=ns_parser.descend
+ )
+
+ if ns_parser.links is True:
+ df = df[["rank", "name", "url"]]
+ else:
+ df.drop("url", axis=1, inplace=True)
+
+ print(
+ tabulate(
+ df.head(ns_parser.top),
+ headers=df.columns,
+ floatfmt=".1f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def platforms(other_args: List[str]):
+ """Shows list of financial platforms from CoinGecko
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="platforms",
+ add_help=False,
+ description="""Shows Top Crypto Financial Platforms in which you can borrow or lend your crypto.
+ e.g Celsius, Nexo, Crypto.com, Aave and others.
+ You can display only top N number of coins with --top parameter.
+ You can sort data by rank, name, category, centralized with --sort
+ and also with --descend flag to sort descending.
+ Displays: rank, name, category, centralized, website_url
+ """,
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="top N number records",
+ default=20,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: rank",
+ default="rank",
+ choices=["rank", "name", "category", "centralized"],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_financial_platforms().sort_values(
+ by=ns_parser.sortby, ascending=ns_parser.descend
+ )
+
+ print(
+ tabulate(
+ df.head(ns_parser.top),
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def products(other_args: List[str]):
+ """Shows list of financial products from CoinGecko
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="products",
+ add_help=False,
+ description="""Shows Top Crypto Financial Products with which you can earn yield, borrow or lend your crypto.
+ You can display only top N number of coins with --top parameter.
+ You can sort data by rank, platform, identifier, supply_rate_percentage, borrow_rate_percentage with --sort
+ and also with --descend flag to sort descending.
+ Displays: rank, platform, identifier, supply_rate_percentage, borrow_rate_percentage
+ """,
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="top N number records",
+ default=20,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: rank",
+ default="rank",
+ choices=[
+ "rank",
+ "platform",
+ "identifier",
+ "supply_rate_percentage",
+ "borrow_rate_percentage",
+ ],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_finance_products().sort_values(
+ by=ns_parser.sortby, ascending=ns_parser.descend
+ )
+ print(
+ tabulate(
+ df.head(ns_parser.top),
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def indexes(other_args: List[str]):
+ """Shows list of crypto indexes from CoinGecko
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="indexes",
+ add_help=False,
+ description="""Shows list of crypto indexes from CoinGecko.
+ Each crypto index is made up of a selection of cryptocurrencies, grouped together and weighted by market cap.
+ You can display only top N number of coins with --top parameter.
+ You can sort data by rank, name, id, market, last, is_multi_asset_composite with --sort
+ and also with --descend flag to sort descending.
+ Displays: rank, name, id, market, last, is_multi_asset_composite
+ """,
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="top N number records",
+ default=20,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: rank",
+ default="rank",
+ choices=["rank", "name", "id", "market", "last", "is_multi_asset_composite"],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_indexes().sort_values(
+ by=ns_parser.sortby, ascending=ns_parser.descend
+ )
+
+ print(
+ tabulate(
+ df.head(ns_parser.top),
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def derivatives(other_args: List[str]):
+ """Shows list of crypto derivatives from CoinGecko
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="derivatives",
+ add_help=False,
+ description="""Shows list of crypto derivatives from CoinGecko
+ Crypto derivatives are secondary contracts or financial tools that derive their value from a primary
+ underlying asset. In this case, the primary asset would be a cryptocurrency such as Bitcoin.
+ The most popular crypto derivatives are crypto futures, crypto options, and perpetual contracts.
+ You can look on only top N number of records with --top,
+ You can sort by rank, market, symbol, price, pct_change_24h, contract_type, basis, spread,
+ funding_rate, volume_24h with --sort and also with --descend flag to set it to sort descending.
+ Displays:
+ rank, market, symbol, price, pct_change_24h, contract_type, basis, spread, funding_rate, volume_24h
+
+ """,
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="top N number records",
+ default=20,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: rank",
+ default="rank",
+ choices=[
+ "rank",
+ "market",
+ "symbol",
+ "price",
+ "pct_change_24h",
+ "contract_type",
+ "basis",
+ "spread",
+ "funding_rate",
+ "volume_24h",
+ ],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_derivatives().sort_values(
+ by=ns_parser.sortby, ascending=ns_parser.descend
+ )
+
+ print(
+ tabulate(
+ df.head(ns_parser.top),
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def exchange_rates(other_args: List[str]):
+ """Shows list of crypto, fiats, commodity exchange rates from CoinGecko
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="ex_rates",
+ add_help=False,
+ description="""
+ Shows list of crypto, fiats, commodity exchange rates from CoinGecko
+ You can look on only top N number of records with --top,
+ You can sort by index,name,unit, value, type, and also use --descend flag to sort descending.
+ """,
+ )
+
+ parser.add_argument(
+ "-t",
+ "--top",
+ dest="top",
+ type=int,
+ help="top N number records",
+ default=20,
+ )
+
+ parser.add_argument(
+ "-s",
+ "--sort",
+ dest="sortby",
+ type=str,
+ help="Sort by given column. Default: index",
+ default="index",
+ choices=["index", "name", "unit", "value", "type"],
+ )
+
+ parser.add_argument(
+ "--descend",
+ action="store_false",
+ help="Flag to sort in descending order (lowest first)",
+ dest="descend",
+ default=True,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_exchange_rates().sort_values(
+ by=ns_parser.sortby, ascending=ns_parser.descend
+ )
+ print(
+ tabulate(
+ df.head(ns_parser.top),
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def global_market_info(other_args: List[str]):
+ """Shows global statistics about crypto from CoinGecko
+ - market cap change
+ - number of markets
+ - icos
+ - number of active crypto
+ - market_cap_pct
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="global",
+ add_help=False,
+ description="""Shows global statistics about Crypto Market like:
+ active_cryptocurrencies, upcoming_icos, ongoing_icos, ended_icos, markets, market_cap_change_percentage_24h,
+ eth_market_cap_in_pct, btc_market_cap_in_pct, altcoin_market_cap_in_pct
+ """,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_global_info()
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".2f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def global_defi_info(other_args: List[str]):
+ """Shows global statistics about Decentralized Finances from CoinGecko
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="defi",
+ add_help=False,
+ description="""Shows global DeFi statistics
+ DeFi or Decentralized Finance refers to financial services that are built
+ on top of distributed networks with no central intermediaries.
+ Displays metrics like:
+ defi_market_cap, eth_market_cap, defi_to_eth_ratio, trading_volume_24h, defi_dominance, top_coin_name,
+ top_coin_defi_dominance
+
+ """,
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_global_defi_info()
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".1f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def coin_list(other_args: List[str]):
+ """Shows list of coins available on CoinGecko
+
+ Parameters
+ ----------
+ other_args: List[str]
+ Arguments to pass to argparse
+
+ """
+ parser = argparse.ArgumentParser(
+ prog="coins",
+ add_help=False,
+ description="Shows list of coins available on CoinGecko",
+ )
+ parser.add_argument(
+ "-s", "--skip", default=0, dest="skip", help="Skip n of records", type=int
+ )
+ parser.add_argument(
+ "-t", "--top", default=100, dest="top", help="Limit of records", type=int
+ )
+
+ parser.add_argument("-l", "--letter", dest="letter", help="First letters", type=str)
+ parser.add_argument(
+ "-k",
+ "--key",
+ dest="key",
+ help="Search in column symbol, name, id",
+ type=str,
+ choices=["id", "symbol", "name"],
+ default="symbol",
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+
+ df = gecko.get_coin_list()
+
+ letter = ns_parser.letter
+ if letter and isinstance(letter, str):
+ if letter.isalpha():
+ letter = letter.lower()
+ df = df[df[ns_parser.key].str.startswith(letter)]
+
+ try:
+ df = df[ns_parser.skip : ns_parser.skip + ns_parser.top]
+ except Exception:
+ df = gecko.get_coin_list()
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".1f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+ except Exception as e:
+ print(e)
+ print("")
+
+
+def find(other_args: List[str]):
+ parser = argparse.ArgumentParser(
+ prog="find",
+ add_help=False,
+ description="""
+ Find similar coin by coin name,symbol or id. If you don't remember exact name or id of the Coin at CoinGecko,
+ you can use this command to display coins with similar name, symbol or id to your search query.
+ Example of usage: coin name is something like "polka". So I can try: find -c polka -k name -t 25
+ It will search for coin that has similar name to polka and display top 25 matches.
+ -c, --coin stands for coin - you provide here your search query
+ -k, --key it's a searching key. You can search by symbol, id or name of coin
+ -t, --top it displays top N number of records.
+ """,
+ )
+ parser.add_argument(
+ "-c",
+ "--coin",
+ help="Symbol Name or Id of Coin",
+ dest="coin",
+ required=True,
+ type=str,
+ )
+
+ parser.add_argument(
+ "-k",
+ "--key",
+ dest="key",
+ help="Specify by which column you would like to search: symbol, name, id",
+ type=str,
+ choices=["id", "symbol", "name"],
+ default="symbol",
+ )
+
+ parser.add_argument(
+ "-t", "--top", default=10, dest="top", help="Limit of records", type=int
+ )
+
+ try:
+ ns_parser = parse_known_args_and_warn(parser, other_args)
+ if not ns_parser:
+ return
+ coins_df = gecko.get_coin_list()
+ coins_list = coins_df[ns_parser.key].to_list()
+ sim = difflib.get_close_matches(ns_parser.coin, coins_list, ns_parser.top)
+ df = pd.Series(sim).to_frame().reset_index()
+ df.columns = ["index", ns_parser.key]
+ coins_df.drop("index", axis=1, inplace=True)
+ df = df.merge(coins_df, on=ns_parser.key)
+ print(
+ tabulate(
+ df,
+ headers=df.columns,
+ floatfmt=".1f",
+ showindex=False,
+ tablefmt="fancy_grid",
+ )
+ )
+ print("")
+ except Exception as e:
+ print(e)
+ print("")
diff --git a/gamestonk_terminal/cryptocurrency/coinmarketcap/README.md b/gamestonk_terminal/cryptocurrency/coinmarketcap/README.md
new file mode 100644
index 00000000000..0a0ad2b3c0e
--- /dev/null
+++ b/gamestonk_terminal/cryptocurrency/coinmarketcap/README.md
@@ -0,0 +1,17 @@
+# COINMARKETCAP
+
+This menu aims to explore CoinMarketCap API and provide to user meaningful crypto currency data and different kind of metrics.
+
+## top
+
+````
+top [-n] [-s --sort SORTBY] [--descend]
+````
+
+This command displays the top n cryptocurrencies from coinmarketcap.com.
+
+* -n: Number of coins to look at (after sort). Defaults to 10.
+* -s/--sort : Column to sort by. One of {Symbol,CMC_Rank,LastPrice,DayPctChange,MarketCap}. Defaults to sorting by the CMC rank.
+* --descend : Flag to change the sorting order. Sorts in ascending order (since default order is the Rank which starts at 1).
+
+
diff --git a/gamestonk_terminal/cryptocurrency/coinmarketcap/__init__.py b/gamestonk_terminal/cryptocurrency/coinmarketcap/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/gamestonk_terminal/cryptocurrency/coinmarketcap/coinmarketcap_controller.py b/gamestonk_terminal/cryptocurrency/coinmarketcap/coinmarketcap_controller.py
new file mode 100644
index 00000000000..b2d25dfd106
--- /dev/null
+++ b/gamestonk_terminal/cryptocurrency/coinmarketcap/coinmarketcap_controller.py
@@ -0,0 +1,102 @@
+"""Cryptocurrency Controller"""
+__docformat__ = "numpy"
+# pylint: disable=R0904, C0302, W0622
+import argparse
+import pandas as pd
+from prompt_toolkit.completion import NestedCompleter
+from gamestonk_terminal import feature_flags as gtff
+from gamestonk_terminal.helper_funcs import get_flair
+from gamestonk_terminal.menu import session
+from gamestonk_terminal.cryptocurrency.coinmarketcap import (
+ coinmarketcap_view as cmc_view,
+)
+
+
+class CMCController:
+
+ CHOICES = [
+ "help",
+ "q",
+ "quit",
+ "top",
+ ]
+
+ def __init__(self):
+ """CONSTRUCTOR"""
+
+ self._cmc_parser = argparse.ArgumentParser(add_help=False, prog="cmc")
+ self._cmc_parser.add_argument("cmd", choices=self.CHOICES)
+ self.current_coin = None
+ self.current_currency = None
+ self.current_df = pd.DataFrame()
+ self.source = ""
+
+ def print_help(self):
+ """Print help"""
+ print("\nCoinmarketcap:")
+ print(" help show this menu again")
+ print(" q quit this menu, and shows back to main menu")
+ print(" quit quit to abandon program")
+ print(" top view top coins from coinmarketcap")
+ print("")
+
+ def switch(self, an_input: str):
+ """Process and dispatch input
+
+ Returns
+ -------
+ True, False or None
+ False - quit the menu
+ True - quit the program
+ None - continue in the menu
+ """
+ (known_args, other_args) = self._cmc_parser.parse_known_args(an_input.split())
+
+ return getattr(
+ self, "call_" + known_args.cmd, lambda: "Command not recognized!"
+ )(other_args)
+
+ def call_help(self, _):
+ """Process Help command"""
+ self.print_help()
+
+ def call_q(self, _):
+ """Process Q command - quit the menu."""
+ print("Moving back to (crypto) menu")
+ return False
+
+ def call_quit(self, _):
+ """Process Quit command - quit the program."""
+ return True
+
+ def call_top(self, other_args):
+ """Process top command"""
+ cmc_view.get_cmc_top_n(other_args)
+
+
+def menu():
+ cmc_controller = CMCController()
+ cmc_controller.print_help()
+
+ while True:
+ # Get input command from user
+ if session and gtff.USE_PROMPT_TOOLKIT:
+ completer = NestedCompleter.from_nested_dict(
+ {c: None for c in cmc_controller.CHOICES}
+ )
+ an_input = session.prompt(
+ f"{get_flair()} (crypto)>(cmc)> ",
+ completer=completer,
+ )
+ else:
+ an_input = input(f"{get_flair()} (crypto)>(cmc)> ")
+
+ try:
+ process_input = cmc_controller.switch(an_input)
+
+ if process_input is not None:
+ return process_input
+
+ except SystemExit:
+ print("The command selected doesn't exist\n")
+ continue
diff --git a/gamestonk_terminal/cryptocurrency/coinmarketcap_view.py b/gamestonk_terminal/cryptocurrency/coinmarketcap/coinmarketcap_view.py
similarity index 100%
rename from gamestonk_terminal/cryptocurrency/coinmarketcap_view.py
rename to gamestonk_terminal/cryptocurrency/coinmarketcap/coinmarketcap_view.py
diff --git a/gamestonk_terminal/cryptocurrency/crypto_controller.py b/gamestonk_terminal/cryptocurrency/crypto_controller.py
index 631660760c8..66d8da787f8 100644
--- a/gamestonk_terminal/cryptocurrency/crypto_controller.py
+++ b/gamestonk_terminal/cryptocurrency/crypto_controller.py
@@ -1,19 +1,15 @@
"""Cryptocurrency Controller"""
__docformat__ = "numpy"
-
+# pylint: disable=R0904, C0302, R1710
import argparse
-import pandas as pd
import matplotlib.pyplot as plt
from prompt_toolkit.completion import NestedCompleter
from gamestonk_terminal import feature_flags as gtff
from gamestonk_terminal.helper_funcs import get_flair
from gamestonk_terminal.menu import session
-from gamestonk_terminal.cryptocurrency import (
- binance_model,
- pycoingecko_view,
- coinmarketcap_view as cmc_view,
-)
-from gamestonk_terminal.technical_analysis import ta_controller
+from gamestonk_terminal.cryptocurrency.coinmarketcap import coinmarketcap_controller
+from gamestonk_terminal.cryptocurrency.binance import binance_controller
+from gamestonk_terminal.cryptocurrency.coingecko import pycoingecko_controller
class CryptoController:
@@ -22,16 +18,9 @@ class CryptoController:
"help",
"q",
"quit",
- "load",
- "view",
- "top",
- "trend",
- "book",
- "trades",
- "candle",
- "balance",
- "select",
- "ta",
+ "cg",
+ "bin",
+ "cmc",
]
def __init__(self):
@@ -39,10 +28,6 @@ class CryptoController:
self.crypto_parser = argparse.ArgumentParser(add_help=False, prog="crypto")
self.crypto_parser.add_argument("cmd", choices=self.CHOICES)
- self.current_coin = None
- self.current_currency = None
- self.current_df = pd.DataFrame()
- self.source = ""
def print_help(self):
"""Print help"""
@@ -50,26 +35,13 @@ class CryptoController:
"https://github.com/GamestonkTerminal/GamestonkTerminal/tree/main/gamestonk_terminal/cryptocurrency"
)
print("\nCryptocurrency:")
- print(" help show this menu again")
- print(" q quit this menu, and shows back to main menu")
- print(" quit quit to abandon program")
- print(f"\nCurrent Coin: {self.current_coin}")
+ print(" help show this menu again")
+ print(" q quit this menu, and shows back to main menu")
+ print(" quit quit to abandon program")
print("")
- print("Coingecko:")
- print(" load load cryptocurrency data")
- print(" view load and view cryptocurrency data")
- print(" trend show top 7 trending coins")
- print("")
- print("CoinMarketCap:")
- print(" top view top coins from coinmarketcap")
- print("")
- print("Binance:")
- print(" select select coin/currency to use and load candle data")
- print(" book show order book")
- print(" candle show candles")
- print(" balance show coin balance")
- print("")
- print("> ta technical analysis menu for")
+ print("> cg CoinGecko overview (market statistics) and coin menu")
+ print("> cmc Coinmarketcap menu")
+ print("> bin Binance menu with order book, candles, ta.. ")
print("")
def switch(self, an_input: str):
@@ -100,79 +72,22 @@ class CryptoController:
"""Process Quit command - quit the program"""
return True
- def call_load(self, other_args):
- """Process load command"""
- self.current_coin, self.current_df = pycoingecko_view.load(other_args)
- self.source = "CG"
-
- def call_view(self, other_args):
- """Process view command"""
- if self.current_coin:
- pycoingecko_view.view(self.current_coin, self.current_df, other_args)
-
- else:
- print("No coin selected. Use 'load' to load the coin you want to look at.")
- print("")
-
- def call_trend(self, _):
- """Process trend command"""
- pycoingecko_view.trend()
-
- def call_top(self, other_args):
- """Process top command"""
- cmc_view.get_cmc_top_n(other_args)
-
- def call_book(self, other_args):
- """Process book command"""
- binance_model.order_book(other_args, self.current_coin, self.current_currency)
-
- def call_candle(self, _):
- """Process candle command"""
- binance_model.show_candles(
- self.current_df, self.current_coin, self.current_currency
- )
-
- def call_balance(self, _):
- """Process balance command"""
- binance_model.balance(self.current_coin)
-
- def call_select(self, other_args):
- """Process select command"""
- (
- self.current_coin,
- self.current_currency,
- self.current_df,
- ) = binance_model.select_binance_coin(other_args)
- self.source = "BIN"
+ def call_cg(self, _):
+ if pycoingecko_controller.menu():
+ return True
print("")
- # pylint: disable=inconsistent-return-statements
- def call_ta(self, _):
- """Process ta command"""
- if not self.current_coin:
- print("Please load a coin through either load or select", "\n")
+ def call_bin(self, _):
+ """Process bin command"""
+ if binance_controller.menu():
+ return True
+ print("")
- elif self.current_df.empty:
- print("Price dataframe is empty")
-
- else:
- # Coingecko does not provide candles so we can only provide close data.
- if self.source == "CG":
-
- self.current_df = self.current_df[["Price"]].rename(
- columns={"Price": "Close"}
- )
-
- self.current_df.index.name = "date"
-
- ta_controller.menu(
- self.current_coin,
- self.current_df.index[0],
- "",
- self.current_df,
- "crypto",
- )
- print("")
+ def call_cmc(self, _):
+ """Process top command"""
+ if coinmarketcap_controller.menu():
+ return True
+ print("")
def menu():
diff --git a/gamestonk_terminal/cryptocurrency/cryptocurrency_helpers.py b/gamestonk_terminal/cryptocurrency/cryptocurrency_helpers.py
new file mode 100644
index 00000000000..55fb65c8d0f
--- /dev/null
+++ b/gamestonk_terminal/cryptocurrency/cryptocurrency_helpers.py
@@ -0,0 +1,49 @@
+import textwrap
+import pandas as pd
+
+
+def wrap_text_in_df(df: pd.DataFrame, w=55): # pragma: no cover
+ """
+ Parameters
+ ----------
+ df: pd.DataFrame
+ Data Frame with some data
+ w: int
+ length of text in column after which text is wrapped into new line
+
+ Returns
+ -------
+
+ """
+ return df.applymap(
+ lambda x: "\n".join(textwrap.wrap(x, width=w)) if isinstance(x, str) else x
+ )
+
+
+def percent_to_float(s: str):
+ """Helper method to replace string pct like "123.56%" to float 1.2356
+ Parameters
+ ----------
+ s: string
+ string to replace
+ Returns
+ -------
+ float
+ """
+ s = str(float(s.rstrip("%")))
+ i = s.find(".")
+ if i == -1:
+ return int(s) / 100
+ if s.startswith("-"):
+ return -percent_to_float(s.lstrip("-"))
+ s = s.replace(".", "")
+ i -= 2
+ if i < 0:
+ return float("." + "0" * abs(i) + s)
+ return float(s[:i] + "." + s[i:])
+
+
+def create_df_index(df: pd.DataFrame, name="rank"):
+ df.index = df.index + 1
+ df.reset_index(inplace=True)
+ df.rename(columns={"index": name}, inplace=True)
diff --git a/gamestonk_terminal/cryptocurrency/pycoingecko_view.py b/gamestonk_terminal/cryptocurrency/pycoingecko_view.py
deleted file mode 100644
index c4f6fca5f3c..00000000000
--- a/gamestonk_terminal/cryptocurrency/pycoingecko_view.py
+++ /dev/null
@@ -1,178 +0,0 @@
-""" pycoingecko_api """
-__docformat__ = "numpy"
-
-import argparse
-from typing import List
-import pandas as pd
-from pandas.plotting import register_matplotlib_converters
-import matplotlib.pyplot as plt
-from tabulate import tabulate
-from pycoingecko import CoinGeckoAPI
-from gamestonk_terminal.helper_funcs import parse_known_args_and_warn, plot_autoscale
-from gamestonk_terminal.config_plot import PLOT_DPI
-
-register_matplotlib_converters()
-
-# Generate a list of valid coins to be checked against later
-cg_api = CoinGeckoAPI()
-coins = cg_api.get_coins()
-coin_symbol_to_id = {}
-coin_ids = []
-
-for single_coin in coins:
- coin_symbol_to_id[single_coin["symbol"]] = single_coin["id"]
- coin_ids.append(single_coin["id"])
-
-# pylint: disable=inconsistent-return-statements
-
-
-def load(other_args: List[str]):
- """Load selected Cryptocurrency
-
- Parameters
- ----------
- other_args : List[str]
- argparse arguments
-
- """
- cg = CoinGeckoAPI()
- parser = argparse.ArgumentParser(
- add_help=False,
- prog="Crypto",
- description="""
- Cryptocurrencies
- """,
- )
-
- parser.add_argument(
- "-c",
- "--coin",
- required=True,
- type=str,
- dest="coin",
- help="Coin to load data for",
- )
-
- parser.add_argument(
- "-d", "--days", default=30, dest="days", help="Number of days to get data for"
- )
-
- parser.add_argument(
- "--vs", default="usd", dest="vs", help="Currency to display vs coin"
- )
-
- try:
- if other_args:
- if "-" not in other_args[0]:
- other_args.insert(0, "-c")
-
- ns_parser = parse_known_args_and_warn(parser, other_args)
-
- if not ns_parser:
- return
-
- if ns_parser.coin in coin_ids:
- coin = ns_parser.coin
- else:
- try:
- coin = coin_symbol_to_id[ns_parser.coin]
- except KeyError:
- print(f"Could not find coin with the id: {ns_parser.coin}")
- print("")
- return [None, pd.DataFrame()]
-
- prices = cg.get_coin_market_chart_by_id(
- coin, vs_currency=ns_parser.vs, days=ns_parser.days
- )
- prices = prices["prices"]
- prices = pd.DataFrame(data=prices, columns=["Time", "Price"])
- prices["Time"] = pd.to_datetime(prices.Time, unit="ms")
- prices = prices.set_index("Time")
- prices["currency"] = ns_parser.vs
- print(f"{coin}/{ns_parser.vs} loaded")
- print("")
- return [coin, prices]
-
- except SystemExit:
- print("")
- return [None, pd.DataFrame()]
-
- except Exception as e:
- print(e)
- print("")
- return [None, pd.DataFrame()]
-
-
-def view(coin: str, prices: pd.DataFrame, other_args: List[str]):
- """Plots loaded cryptocurrency
-
- Parameters
- ----------
- coin : str
- Cryptocurrency
- prices : pandas.DataFrame
- Dataframe containing prices and dates for selected coin
- other_args : List[str]
- argparse arguments
-
- """
- parser = argparse.ArgumentParser(
- add_help=False,
- prog="Crypto",
- description="""
- Cryptocurrencies
- """,
- )
- try:
- ns_parser = parse_known_args_and_warn(parser, other_args)
-
- if not ns_parser:
- return
- plt.figure(figsize=plot_autoscale(), dpi=PLOT_DPI)
- plt.plot(prices.index, prices.Price, "-ok", ms=2)
- plt.xlabel("Time")
- plt.xlim(prices.index[0], prices.index[-1])
- plt.ylabel("Price")
- plt.grid(b=True, which="major", color="#666666", linestyle="-")
- plt.minorticks_on()
- plt.grid(b=True, which="minor", color="#999999", linestyle="-", alpha=0.2)
- plt.title(f"{coin}/{prices['currency'][0]}")
- plt.show()
- print("")
-
- except SystemExit:
- print("")
-
- except Exception as e:
- print(e)
- print("")
-
-
-def trend():
- """Prints top 7 coins from pycoingecko"""
-
- cg = CoinGeckoAPI()
- trending = cg.get_search_trending()["coins"]
- name, symbol, price, rank = [], [], [], []
- for coin in trending:
- name.append(coin["item"]["name"])
- symbol.append(coin["item"]["symbol"])
- coin_id = coin["item"]["id"]
- price.append(cg.get_price(coin_id, vs_currencies="USD")[coin_id]["usd"])
- rank.append(coin["item"]["market_cap_rank"])
-
- df = pd.DataFrame()
- df["name"] = name
- df["symbol"] = symbol
- df["last_price"] = price
- df["market_cap_rank"] = rank
- print(
- tabulate(
- df,
- headers=df.columns,
- floatfmt=".2f",
- showindex=False,
- tablefmt="fancy_grid",
- )
- )
- print("")
diff --git a/gamestonk_terminal/technical_analysis/ta_controller.py b/gamestonk_terminal/technical_analysis/ta_controller.py
index 212806fa5b6..fbeb3f63d11 100644
--- a/gamestonk_terminal/technical_analysis/ta_controller.py
+++ b/gamestonk_terminal/technical_analysis/ta_controller.py
@@ -219,7 +219,7 @@ def menu(
ta_controller.call_help(None)
if context:
- context = f"({context})>"
+ context = f"{context}>"
while True:
# Get input command from user
diff --git a/poetry.lock b/poetry.lock
index 53daf0de543..adea115fa48 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -574,7 +574,7 @@ dev = ["black (>=20.8b1)", "codecov", "coverage", "flake8", "flake8-black", "fut
[[package]]
name = "finviz"
-version = "1.4.1"
+version = "1.4.2"
description = "Unofficial API for FinViz.com"
category = "main"
optional = false
@@ -764,7 +764,7 @@ numpy = [
[[package]]
name = "hijri-converter"
-version = "2.1.2"
+version = "2.1.3"
description = "Accurate Hijri-Gregorian date converter based on the Umm al-Qura calendar"
category = "main"
optional = false
@@ -930,16 +930,17 @@ python-versions = "*"
[[package]]
name = "isort"
-version = "5.8.0"
+version = "5.9.1"
description = "A Python utility / library to sort Python imports."
category = "dev"
optional = false
-python-versions = ">=3.6,<4.0"
+python-versions = ">=3.6.1,<4.0"
[package.extras]
pipfile_deprecated_finder = ["pipreqs", "requirementslib"]
requirements_deprecated_finder = ["pipreqs", "pip-api"]
colors = ["colorama (>=0.4.3,<0.5.0)"]
+plugins = ["setuptools"]
[[package]]
name = "jedi"
@@ -2009,7 +2010,7 @@ six = ">=1.5"
[[package]]
name = "python-dotenv"
-version = "0.17.1"
+version = "0.18.0"
description = "Read key-value pairs from a .env file and set them as environment variables"
category = "main"
optional = false
@@ -2313,12 +2314,15 @@ urllib3 = "*"
[[package]]
name = "send2trash"
-version = "1.5.0"
+version = "1.7.1"
description = "Send file to trash natively under Mac OS X, Windows and Linux."
category = "main"
optional = false
python-versions = "*"
+[package.extras]
+win32 = ["pywin32"]
+
[[package]]
name = "six"
version = "1.15.0"
@@ -3018,6 +3022,10 @@ argon2-cffi = [
{file = "argon2_cffi-20.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:9dfd5197852530294ecb5795c97a823839258dfd5eb9420233c7cfedec2058f2"},
{file = "argon2_cffi-20.1.0-cp39-cp39-win32.whl", hash = "sha256:e2db6e85c057c16d0bd3b4d2b04f270a7467c147381e8fd73cbbe5bc719832be"},
{file = "argon2_cffi-20.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:8a84934bd818e14a17943de8099d41160da4a336bcc699bb4c394bbb9b94bd32"},
+ {file = "argon2_cffi-20.1.0-pp36-pypy36_pp73-macosx_10_7_x86_64.whl", hash = "sha256:b94042e5dcaa5d08cf104a54bfae614be502c6f44c9c89ad1535b2ebdaacbd4c"},
+ {file = "argon2_cffi-20.1.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:8282b84ceb46b5b75c3a882b28856b8cd7e647ac71995e71b6705ec06fc232c3"},
+ {file = "argon2_cffi-20.1.0-pp37-pypy37_pp73-macosx_10_7_x86_64.whl", hash = "sha256:3aa804c0e52f208973845e8b10c70d8957c9e5a666f702793256242e9167c4e0"},
+ {file = "argon2_cffi-20.1.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:36320372133a003374ef4275fbfce78b7ab581440dfca9f9471be3dd9a522428"},
]
astroid = [
{file = "astroid-2.5.6-py3-none-any.whl", hash = "sha256:4db03ab5fc3340cf619dbc25e42c2cc3755154ce6009469766d7143d1fc2ee4e"},
@@ -3107,24 +3115,36 @@ cffi = [
{file = "cffi-1.14.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:48e1c69bbacfc3d932221851b39d49e81567a4d4aac3b21258d9c24578280058"},
{file = "cffi-1.14.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:69e395c24fc60aad6bb4fa7e583698ea6cc684648e1ffb7fe85e3c1ca131a7d5"},
{file = "cffi-1.14.5-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:9e93e79c2551ff263400e1e4be085a1210e12073a31c2011dbbda14bda0c6132"},
+ {file = "cffi-1.14.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24ec4ff2c5c0c8f9c6b87d5bb53555bf267e1e6f70e52e5a9740d32861d36b6f"},
+ {file = "cffi-1.14.5-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3c3f39fa737542161d8b0d680df2ec249334cd70a8f420f71c9304bd83c3cbed"},
+ {file = "cffi-1.14.5-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:681d07b0d1e3c462dd15585ef5e33cb021321588bebd910124ef4f4fb71aef55"},
{file = "cffi-1.14.5-cp36-cp36m-win32.whl", hash = "sha256:58e3f59d583d413809d60779492342801d6e82fefb89c86a38e040c16883be53"},
{file = "cffi-1.14.5-cp36-cp36m-win_amd64.whl", hash = "sha256:005a36f41773e148deac64b08f233873a4d0c18b053d37da83f6af4d9087b813"},
{file = "cffi-1.14.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2894f2df484ff56d717bead0a5c2abb6b9d2bf26d6960c4604d5c48bbc30ee73"},
{file = "cffi-1.14.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0857f0ae312d855239a55c81ef453ee8fd24136eaba8e87a2eceba644c0d4c06"},
{file = "cffi-1.14.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:cd2868886d547469123fadc46eac7ea5253ea7fcb139f12e1dfc2bbd406427d1"},
{file = "cffi-1.14.5-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:35f27e6eb43380fa080dccf676dece30bef72e4a67617ffda586641cd4508d49"},
+ {file = "cffi-1.14.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06d7cd1abac2ffd92e65c0609661866709b4b2d82dd15f611e602b9b188b0b69"},
+ {file = "cffi-1.14.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f861a89e0043afec2a51fd177a567005847973be86f709bbb044d7f42fc4e05"},
+ {file = "cffi-1.14.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc5a8e069b9ebfa22e26d0e6b97d6f9781302fe7f4f2b8776c3e1daea35f1adc"},
{file = "cffi-1.14.5-cp37-cp37m-win32.whl", hash = "sha256:9ff227395193126d82e60319a673a037d5de84633f11279e336f9c0f189ecc62"},
{file = "cffi-1.14.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9cf8022fb8d07a97c178b02327b284521c7708d7c71a9c9c355c178ac4bbd3d4"},
{file = "cffi-1.14.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8b198cec6c72df5289c05b05b8b0969819783f9418e0409865dac47288d2a053"},
{file = "cffi-1.14.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:ad17025d226ee5beec591b52800c11680fca3df50b8b29fe51d882576e039ee0"},
{file = "cffi-1.14.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6c97d7350133666fbb5cf4abdc1178c812cb205dc6f41d174a7b0f18fb93337e"},
{file = "cffi-1.14.5-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8ae6299f6c68de06f136f1f9e69458eae58f1dacf10af5c17353eae03aa0d827"},
+ {file = "cffi-1.14.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04c468b622ed31d408fea2346bec5bbffba2cc44226302a0de1ade9f5ea3d373"},
+ {file = "cffi-1.14.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:06db6321b7a68b2bd6df96d08a5adadc1fa0e8f419226e25b2a5fbf6ccc7350f"},
+ {file = "cffi-1.14.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:293e7ea41280cb28c6fcaaa0b1aa1f533b8ce060b9e701d78511e1e6c4a1de76"},
{file = "cffi-1.14.5-cp38-cp38-win32.whl", hash = "sha256:b85eb46a81787c50650f2392b9b4ef23e1f126313b9e0e9013b35c15e4288e2e"},
{file = "cffi-1.14.5-cp38-cp38-win_amd64.whl", hash = "sha256:1f436816fc868b098b0d63b8920de7d208c90a67212546d02f84fe78a9c26396"},
{file = "cffi-1.14.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1071534bbbf8cbb31b498d5d9db0f274f2f7a865adca4ae429e147ba40f73dea"},
{file = "cffi-1.14.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9de2e279153a443c656f2defd67769e6d1e4163952b3c622dcea5b08a6405322"},
{file = "cffi-1.14.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:6e4714cc64f474e4d6e37cfff31a814b509a35cb17de4fb1999907575684479c"},
{file = "cffi-1.14.5-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:158d0d15119b4b7ff6b926536763dc0714313aa59e320ddf787502c70c4d4bee"},
+ {file = "cffi-1.14.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bf1ac1984eaa7675ca8d5745a8cb87ef7abecb5592178406e55858d411eadc0"},
+ {file = "cffi-1.14.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:df5052c5d867c1ea0b311fb7c3cd28b19df469c056f7fdcfe88c7473aa63e333"},
+ {file = "cffi-1.14.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:24a570cd11895b60829e941f2613a4f79df1a27344cbbb82164ef2e0116f09c7"},
{file = "cffi-1.14.5-cp39-cp39-win32.whl", hash = "sha256:afb29c1ba2e5a3736f1c301d9d0abe3ec8b86957d04ddfa9d7a6a42b9367e396"},
{file = "cffi-1.14.5-cp39-cp39-win_amd64.whl", hash = "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d"},
{file = "cffi-1.14.5.tar.gz", hash = "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c"},
@@ -3168,6 +3188,8 @@ cssselect = [
{file = "cssselect-1.1.0.tar.gz", hash = "sha256:f95f8dedd925fd8f54edb3d2dfb44c190d9d18512377d3c1e2388d16126879bc"},
]
cvxpy = [
+ {file = "cvxpy-1.1.12-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:48e9bae36a43453659ca5d0c85e78f1eb0dfe629b8aa0f023f65aa59d0ac04d7"},
+ {file = "cvxpy-1.1.12-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:fe0bcb7f83b5d4deb760bf033cb72ab97c8e0770b116e08d96e9726cb1a52c01"},
{file = "cvxpy-1.1.12-cp36-cp36m-win_amd64.whl", hash = "sha256:86f8e4aa1a79482431b89aa526249d9fda04c74e04a3ec224d1175d281643d71"},
{file = "cvxpy-1.1.12-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:90b09a7361b9c614166fa673e1fe9321317df6939135330e1621b9a0bf10e3a8"},
{file = "cvxpy-1.1.12-cp37-cp37m-win_amd64.whl", hash = "sha256:084e5292f2a13133a1cd28d68f5af1df33a5119b0f1aec7cecf834eea3e2d11d"},
@@ -3175,6 +3197,8 @@ cvxpy = [
{file = "cvxpy-1.1.12-cp38-cp38-win_amd64.whl", hash = "sha256:76d04444cb50ad2840bbc72a625ac246b5eeeeb580ee20c71bec057822667738"},
{file = "cvxpy-1.1.12-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2de5e0e75316839bc71b5df2c2db0131cee7ef06dac566c6c44dc852c091502b"},
{file = "cvxpy-1.1.12-cp39-cp39-win_amd64.whl", hash = "sha256:9fa4d033ab31855aea090e4b358017b36880390a7d0e6e97ecc5226c77eab489"},
+ {file = "cvxpy-1.1.12-py3.5-macosx-10.9-x86_64.egg", hash = "sha256:27ff263c80700b097d3714ba34161bd284f736f3029dfa89a95bf4c4a2801cb9"},
+ {file = "cvxpy-1.1.12-py3.6-macosx-10.7-x86_64.egg", hash = "sha256:7c1c5371dda78580f0892fba6776abb6e43bdb45589311c3179a057f1a984110"},
{file = "cvxpy-1.1.12-py3.6-win-amd64.egg", hash = "sha256:d2c28e0eea1b6dc70262c9ed8b63c5c1747d85c28b3ec24cbaab07583b3ad729"},
{file = "cvxpy-1.1.12-py3.7-win-amd64.egg", hash = "sha256:44d0e3d60693831ac70bdc9b2e23faf84401347bfcdef4eb5da5ae22ac57f5ff"},
{file = "cvxpy-1.1.12-py3.8-win-amd64.egg", hash = "sha256:c86f8de9a63ccbd45844a4482df8099824688b5329060f089aad1c3beb939190"},
@@ -3289,7 +3313,7 @@ ffn = [
{file = "ffn-0.3.6.tar.gz", hash = "sha256:4a79e72e06ff328e333ffe97010b1ce110bcd694fcd03be7351bf5065cd273e8"},
]
finviz = [
- {file = "finviz-1.4.1.tar.gz", hash = "sha256:7b1a2a730ce8e09dfe64aad30b499a3adaf0fdf2d52cba6dd3ef9813248182be"},
+ {file = "finviz-1.4.2.tar.gz", hash = "sha256:f921a2674ea16f5ee9320834ab80554872fdb32a2bc9e0fdf23542ea33094d24"},
]
finvizfinance = [
{file = "finvizfinance-0.9.8-py3-none-any.whl", hash = "sha256:b179ade3dfdd3df3a28928bfc53d415fcc39d35c166410b96275d804970e4aa3"},
@@ -3403,8 +3427,8 @@ h5py = [
{file = "h5py-3.1.0.tar.gz", hash = "sha256:1e2516f190652beedcb8c7acfa1c6fa92d99b42331cbef5e5c7ec2d65b0fc3c2"},
]
hijri-converter = [
- {file = "hijri-converter-2.1.2.tar.gz", hash = "sha256:43b5ac566e7a7deeab364a2397e94405a65fd24ea786073eb3d4c740ebda7b9b"},
- {file = "hijri_converter-2.1.2-py3-none-any.whl", hash = "sha256:b323d5f75b7e238d7e8760570d7ad8cabfc890af15c9f7945b6422d14603d33c"},
+ {file = "hijri-converter-2.1.3.tar.gz", hash = "sha256:7a22438be995f76d7ac78dcd8c5195261615069de2ddbb266aec4ce9c03e06b3"},
+ {file = "hijri_converter-2.1.3-py3-none-any.whl", hash = "sha256:61ee0260a1a3f97890cdfda432c96c1548e521e05fa0050e156c73781c3eb157"},
]
holidays = [
{file = "holidays-0.10.5.2-py3.7.egg", hash = "sha256:c704931e2e133ff1d591595d5f84cf6c9fd0e1230ea65e270e845769b27a5058"},
@@ -3456,8 +3480,8 @@ iso8601 = [
{file = "iso8601-0.1.14.tar.gz", hash = "sha256:8aafd56fa0290496c5edbb13c311f78fa3a241f0853540da09d9363eae3ebd79"},
]
isort = [
- {file = "isort-5.8.0-py3-none-any.whl", hash = "sha256:2bb1680aad211e3c9944dbce1d4ba09a989f04e238296c87fe2139faa26d655d"},
- {file = "isort-5.8.0.tar.gz", hash = "sha256:0a943902919f65c5684ac4e0154b1ad4fac6dcaa5d9f3426b732f1c8b5419be6"},
+ {file = "isort-5.9.1-py3-none-any.whl", hash = "sha256:8e2c107091cfec7286bc0f68a547d0ba4c094d460b732075b6fba674f1035c0c"},
+ {file = "isort-5.9.1.tar.gz", hash = "sha256:83510593e07e433b77bd5bff0f6f607dbafa06d1a89022616f02d8b699cfcd56"},
]
jedi = [
{file = "jedi-0.18.0-py2.py3-none-any.whl", hash = "sha256:18456d83f65f400ab0c2d3319e48520420ef43b23a086fdc05dff34132f0fb93"},
@@ -3579,30 +3603,40 @@ lxml = [
{file = "lxml-4.6.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:4bff24dfeea62f2e56f5bab929b4428ae6caba2d1eea0c2d6eb618e30a71e6d4"},
{file = "lxml-4.6.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:74f7d8d439b18fa4c385f3f5dfd11144bb87c1da034a466c5b5577d23a1d9b51"},
{file = "lxml-4.6.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f90ba11136bfdd25cae3951af8da2e95121c9b9b93727b1b896e3fa105b2f586"},
+ {file = "lxml-4.6.3-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:4c61b3a0db43a1607d6264166b230438f85bfed02e8cff20c22e564d0faff354"},
+ {file = "lxml-4.6.3-cp35-cp35m-manylinux2014_x86_64.whl", hash = "sha256:5c8c163396cc0df3fd151b927e74f6e4acd67160d6c33304e805b84293351d16"},
{file = "lxml-4.6.3-cp35-cp35m-win32.whl", hash = "sha256:f2380a6376dfa090227b663f9678150ef27543483055cc327555fb592c5967e2"},
{file = "lxml-4.6.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c4f05c5a7c49d2fb70223d0d5bcfbe474cf928310ac9fa6a7c6dddc831d0b1d4"},
{file = "lxml-4.6.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d2e35d7bf1c1ac8c538f88d26b396e73dd81440d59c1ef8522e1ea77b345ede4"},
{file = "lxml-4.6.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:289e9ca1a9287f08daaf796d96e06cb2bc2958891d7911ac7cae1c5f9e1e0ee3"},
{file = "lxml-4.6.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:bccbfc27563652de7dc9bdc595cb25e90b59c5f8e23e806ed0fd623755b6565d"},
+ {file = "lxml-4.6.3-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:d916d31fd85b2f78c76400d625076d9124de3e4bda8b016d25a050cc7d603f24"},
{file = "lxml-4.6.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:820628b7b3135403540202e60551e741f9b6d3304371712521be939470b454ec"},
+ {file = "lxml-4.6.3-cp36-cp36m-manylinux2014_x86_64.whl", hash = "sha256:c47ff7e0a36d4efac9fd692cfa33fbd0636674c102e9e8d9b26e1b93a94e7617"},
{file = "lxml-4.6.3-cp36-cp36m-win32.whl", hash = "sha256:5a0a14e264069c03e46f926be0d8919f4105c1623d620e7ec0e612a2e9bf1c04"},
{file = "lxml-4.6.3-cp36-cp36m-win_amd64.whl", hash = "sha256:92e821e43ad382332eade6812e298dc9701c75fe289f2a2d39c7960b43d1e92a"},
{file = "lxml-4.6.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:efd7a09678fd8b53117f6bae4fa3825e0a22b03ef0a932e070c0bdbb3a35e654"},
{file = "lxml-4.6.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:efac139c3f0bf4f0939f9375af4b02c5ad83a622de52d6dfa8e438e8e01d0eb0"},
{file = "lxml-4.6.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:0fbcf5565ac01dff87cbfc0ff323515c823081c5777a9fc7703ff58388c258c3"},
+ {file = "lxml-4.6.3-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:36108c73739985979bf302006527cf8a20515ce444ba916281d1c43938b8bb96"},
{file = "lxml-4.6.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:122fba10466c7bd4178b07dba427aa516286b846b2cbd6f6169141917283aae2"},
+ {file = "lxml-4.6.3-cp37-cp37m-manylinux2014_x86_64.whl", hash = "sha256:cdaf11d2bd275bf391b5308f86731e5194a21af45fbaaaf1d9e8147b9160ea92"},
{file = "lxml-4.6.3-cp37-cp37m-win32.whl", hash = "sha256:3439c71103ef0e904ea0a1901611863e51f50b5cd5e8654a151740fde5e1cade"},
{file = "lxml-4.6.3-cp37-cp37m-win_amd64.whl", hash = "sha256:4289728b5e2000a4ad4ab8da6e1db2e093c63c08bdc0414799ee776a3f78da4b"},
{file = "lxml-4.6.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b007cbb845b28db4fb8b6a5cdcbf65bacb16a8bd328b53cbc0698688a68e1caa"},
{file = "lxml-4.6.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:76fa7b1362d19f8fbd3e75fe2fb7c79359b0af8747e6f7141c338f0bee2f871a"},
{file = "lxml-4.6.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:26e761ab5b07adf5f555ee82fb4bfc35bf93750499c6c7614bd64d12aaa67927"},
+ {file = "lxml-4.6.3-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:e1cbd3f19a61e27e011e02f9600837b921ac661f0c40560eefb366e4e4fb275e"},
{file = "lxml-4.6.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:66e575c62792c3f9ca47cb8b6fab9e35bab91360c783d1606f758761810c9791"},
+ {file = "lxml-4.6.3-cp38-cp38-manylinux2014_x86_64.whl", hash = "sha256:1b38116b6e628118dea5b2186ee6820ab138dbb1e24a13e478490c7db2f326ae"},
{file = "lxml-4.6.3-cp38-cp38-win32.whl", hash = "sha256:89b8b22a5ff72d89d48d0e62abb14340d9e99fd637d046c27b8b257a01ffbe28"},
{file = "lxml-4.6.3-cp38-cp38-win_amd64.whl", hash = "sha256:2a9d50e69aac3ebee695424f7dbd7b8c6d6eb7de2a2eb6b0f6c7db6aa41e02b7"},
{file = "lxml-4.6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ce256aaa50f6cc9a649c51be3cd4ff142d67295bfc4f490c9134d0f9f6d58ef0"},
{file = "lxml-4.6.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:7610b8c31688f0b1be0ef882889817939490a36d0ee880ea562a4e1399c447a1"},
{file = "lxml-4.6.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f8380c03e45cf09f8557bdaa41e1fa7c81f3ae22828e1db470ab2a6c96d8bc23"},
+ {file = "lxml-4.6.3-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:3082c518be8e97324390614dacd041bb1358c882d77108ca1957ba47738d9d59"},
{file = "lxml-4.6.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:884ab9b29feaca361f7f88d811b1eea9bfca36cf3da27768d28ad45c3ee6f969"},
+ {file = "lxml-4.6.3-cp39-cp39-manylinux2014_x86_64.whl", hash = "sha256:6f12e1427285008fd32a6025e38e977d44d6382cf28e7201ed10d6c1698d2a9a"},
{file = "lxml-4.6.3-cp39-cp39-win32.whl", hash = "sha256:33bb934a044cf32157c12bfcfbb6649807da20aa92c062ef51903415c704704f"},
{file = "lxml-4.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:542d454665a3e277f76954418124d67516c5f88e51a900365ed54a9806122b83"},
{file = "lxml-4.6.3.tar.gz", hash = "sha256:39b78571b3b30645ac77b95f7c69d1bffc4cf8c3b157c435a34da72e78c82468"},
@@ -4012,6 +4046,7 @@ pillow = [
{file = "Pillow-8.2.0-pp37-pypy37_pp73-manylinux2010_i686.whl", hash = "sha256:aac00e4bc94d1b7813fe882c28990c1bc2f9d0e1aa765a5f2b516e8a6a16a9e4"},
{file = "Pillow-8.2.0-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:22fd0f42ad15dfdde6c581347eaa4adb9a6fc4b865f90b23378aa7914895e120"},
{file = "Pillow-8.2.0-pp37-pypy37_pp73-win32.whl", hash = "sha256:e98eca29a05913e82177b3ba3d198b1728e164869c613d76d0de4bde6768a50e"},
+ {file = "Pillow-8.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:8b56553c0345ad6dcb2e9b433ae47d67f95fc23fe28a0bde15a120f25257e291"},
{file = "Pillow-8.2.0.tar.gz", hash = "sha256:a787ab10d7bb5494e5f76536ac460741788f1fbce851068d73a87ca7c35fc3e1"},
]
plotly = [
@@ -4207,8 +4242,8 @@ python-dateutil = [
{file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"},
]
python-dotenv = [
- {file = "python-dotenv-0.17.1.tar.gz", hash = "sha256:b1ae5e9643d5ed987fc57cc2583021e38db531946518130777734f9589b3141f"},
- {file = "python_dotenv-0.17.1-py2.py3-none-any.whl", hash = "sha256:00aa34e92d992e9f8383730816359647f358f4a3be1ba45e5a5cefd27ee91544"},
+ {file = "python-dotenv-0.18.0.tar.gz", hash = "sha256:effaac3c1e58d89b3ccb4d04a40dc7ad6e0275fda25fd75ae9d323e2465e202d"},
+ {file = "python_dotenv-0.18.0-py2.py3-none-any.whl", hash = "sha256:dd8fe852847f4fbfadabf6183ddd4c824a9651f02d51714fa075c95561959c7d"},
]
pytrends = [
{file = "pytrends-4.7.3-py3-none-any.whl", hash = "sha256:88d92e398b9408c79fd92946ddc2b03fa622301233bc49f16804042eb2897328"},
@@ -4539,8 +4574,8 @@ selenium = [
{file = "selenium-3.141.0.tar.gz", hash = "sha256:deaf32b60ad91a4611b98d8002757f29e6f2c2d5fcaf202e1c9ad06d6772300d"},
]
send2trash = [
- {file = "Send2Trash-1.5.0-py3-none-any.whl", hash = "sha256:f1691922577b6fa12821234aeb57599d887c4900b9ca537948d2dac34aea888b"},
- {file = "Send2Trash-1.5.0.tar.gz", hash = "sha256:60001cc07d707fe247c94f74ca6ac0d3255aabcb930529690897ca2a39db28b2"},
+ {file = "Send2Trash-1.7.1-py3-none-any.whl", hash = "sha256:c20fee8c09378231b3907df9c215ec9766a84ee20053d99fbad854fe8bd42159"},
+ {file = "Send2Trash-1.7.1.tar.gz", hash = "sha256:17730aa0a33ab82ed6ca76be3bb25f0433d0014f1ccf63c979bab13a5b9db2b2"},
]
six = [
{file = "six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"},
diff --git a/tests/test_coingecko_crypto.py b/tests/test_coingecko_crypto.py
index e0eed2eed55..0367a297669 100644
--- a/tests/test_coingecko_crypto.py
+++ b/tests/test_coingecko_crypto.py
@@ -1,14 +1,15 @@
from unittest import mock, TestCase
import json
from pycoingecko import CoinGeckoAPI
-from gamestonk_terminal.cryptocurrency.pycoingecko_view import load
+from gamestonk_terminal.cryptocurrency.coingecko.pycoingecko_view import load, ta
+from gamestonk_terminal.cryptocurrency.coingecko.pycoingecko_coin_model import Coin
# pylint: disable=unused-import
class TestCoinGeckoAPI(TestCase):
@mock.patch(
- "gamestonk_terminal.cryptocurrency.pycoingecko_view.CoinGeckoAPI.get_coin_market_chart_by_id"
+ "gamestonk_terminal.cryptocurrency.coingecko.pycoingecko_view.CoinGeckoAPI.get_coin_market_chart_by_id"
)
def test_coin_api_load(self, mock_load):
"""
@@ -20,10 +21,28 @@ class TestCoinGeckoAPI(TestCase):
sample_return = json.load(f)
mock_load.return_value = sample_return
- coin, mock_return = load(["-c", "bitcoin"])
- self.assertEqual(coin, "bitcoin")
- self.assertTrue(mock_load.called)
+ coin = load(["-c", "bitcoin"])
+ self.assertEqual(coin.coin_symbol, "bitcoin")
+ self.assertIsInstance(coin, Coin)
+
+ @mock.patch(
+ "gamestonk_terminal.cryptocurrency.coingecko.pycoingecko_view.CoinGeckoAPI.get_coin_market_chart_by_id"
+ )
+ def test_coin_api_load_df_for_ta(self, mock_load):
+ """
+ Mock load function through get_coin_market_chart_by_id.
+ Mock returns a dict saved as .json
+
+ """
+
+ with open("tests/data/btc_usd_test_data.json") as f:
+ sample_return = json.load(f)
+
+ mock_load.return_value = sample_return
+ coin = load(["-c", "bitcoin"])
+ mock_return, vs = ta(coin, ["--vs", "usd"])
self.assertTrue(mock_return.shape == (722, 2))
+ self.assertTrue(vs == "usd")
def test_coin(self):
"""Test that pycoingecko retrieves the major coins"""