Coingecko feature branch (#521)

* Added pycoingecko_helpers.py and pycoingecko_model.py, added some methods that scrapes the data from coingecko and some helper methods that handles mostly dataframe operations.

* More methods added for CoinGecko

* Started adding views, and adding them into controller.

* Add stablecoins, yield_farms, recently_added views

* Add more views for Coingecko, + add them to Controller

* remove retry from dependencies, and gecko model

* Add more views for coingecko, seperate coin menu from overview menu, fix imports

* Add some description for coin methods

* Add TA into seperate coin gecko controller

* fix mock path in coingecko tests

* Now if ta is sperate mode, and load doesn't return data frame, change test in the way that ta with Coin object returns data frame

* add seperate ta controller for crypto

* update readme

* small fix in REDME

* Add screenshots for coingecko menu

* fix ta menu for gecko

* Update Gecko Coin menu readme, add screenshots

* Update README with screenshots pt2

* Finish updating readme with screenshots

* remove not needed print statement from gecko view

* Typo

* fix ta crypto controller

* refactor some of views, remove url, add additional argparser params, remove columns which in most cases doesn't bring any value to end user

* Add additional parameters like sortby, descend, top, links for most of coingecko methods. Improve description of commands

* Split cmc, and binance into seperate menus

* add readme for cmc and binance

* Update REDME

* Update README pt2

* Fix news issue with sorting by rank, fix issue with period time parameter for top gainers and top losers view (changed from 1d - 24h)

* Add check for binance menu. If coin is not loaded, do not fail with candles and books commands. Remove new line in candle view. Update print help in crypto menu
This commit is contained in:
jp
2021-07-04 08:03:32 +02:00
committed by GitHub
parent e1612f905d
commit 099ca7cd1d
24 changed files with 5925 additions and 466 deletions

View File

@@ -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

View File

@@ -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 <a name="COINGECKO"></a>
## load <a name="load"></a>
````
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 <a name="view"></a>
````
usage: view
````
Plot the loaded crypto data.
![crypto_view](https://user-images.githubusercontent.com/25267873/115787452-20889a80-a3ba-11eb-9216-f7fd1ffc98cf.png)
## trend <a name="trend"></a>
````
usage: trend
````
Print the top 7 trending coins from coingecko.
<img width="1004" alt="Captura de ecrã 2021-05-03, às 15 07 15" src="https://user-images.githubusercontent.com/25267873/116886674-45cea180-ac21-11eb-9951-ff10271df370.png">
# COINMARKETCAP <a name="COINMARKETCAP"></a>
## top <a name="top"></a>
````
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).
<img width="990" alt="crypto" src="https://user-images.githubusercontent.com/25267873/115787544-4746d100-a3ba-11eb-9433-b7cb9142404a.png">
# BINANCE <a name="BINANCE"></a>
## select <a name="select"></a>
````
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 <a name="book"></a>
````
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.
![orderbook](https://user-images.githubusercontent.com/25267873/116886857-84fcf280-ac21-11eb-9803-5baa8bceca05.png)
## candle <a name="candle"></a>
````
usage: candle
````
Show candle chart for loaded coin/currency.
![candle](https://user-images.githubusercontent.com/25267873/116886993-abbb2900-ac21-11eb-9ff8-b6a8131fdac5.png)
## balance <a name="balance"></a>
````
usage: balance
````
Shows the current holding balance in your account.
[BINANCE standalone menu](/gamestonk_terminal/cryptocurrency/coinmarketcap/)

View File

@@ -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 <a name="load"></a>
````
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 <a name="book"></a>
````
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.
![orderbook](https://user-images.githubusercontent.com/25267873/116886857-84fcf280-ac21-11eb-9803-5baa8bceca05.png)
## candle <a name="candle"></a>
````
usage: candle
````
Show candle chart for loaded coin/currency.
![candle](https://user-images.githubusercontent.com/25267873/116886993-abbb2900-ac21-11eb-9ff8-b6a8131fdac5.png)
## balance <a name="balance"></a>
````
usage: balance
````
Shows the current holding balance in your account.
## ta <a name="ta"></a>
````
usage: ta
````
Open Technical Analysis menu for loaded coin. [technical analysis](/gamestonk_terminal/cryptocurrency/coinmarketcap/)

View File

@@ -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 <coin>"
)
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

View File

@@ -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):

View File

@@ -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 <a name="COIN"></a>
## load <a name="load"></a>
````
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 <a name="chart"></a>
````
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".
![crypto_view](https://user-images.githubusercontent.com/25267873/115787452-20889a80-a3ba-11eb-9216-f7fd1ffc98cf.png)
## ta <a name="ta"></a>
````
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 <a name="info"></a>
````
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
![image](https://user-images.githubusercontent.com/275820/123523774-48e88a00-d6c6-11eb-97cf-71529fb209ca.png)
## market <a name="market"></a>
````
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
![image](https://user-images.githubusercontent.com/275820/123523943-708c2200-d6c7-11eb-97f4-6fb4f7e12c04.png)
## ath <a name="ath"></a>
````
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
![image](https://user-images.githubusercontent.com/275820/123523988-b648ea80-d6c7-11eb-9b08-7d8afecf9231.png)
## atl <a name="atl"></a>
````
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
![image](https://user-images.githubusercontent.com/275820/123523993-c4970680-d6c7-11eb-89ab-3637155e00a9.png)
## score <a name="score"></a>
````
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
![image](https://user-images.githubusercontent.com/275820/123524080-3707e680-d6c8-11eb-96e0-106b7a9c00c2.png)
## dev <a name="dev"></a>
````
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.
![image](https://user-images.githubusercontent.com/275820/123524107-60c10d80-d6c8-11eb-8217-cc767f82d7d9.png)
## web <a name="web"></a>
````
usage: web
````
Websites found for given Coin. You can find there urls to homepage, forum, announcement site and others.
![image](https://user-images.githubusercontent.com/275820/123524127-720a1a00-d6c8-11eb-9a63-ec4cef42c43f.png)
## social <a name="social"></a>
````
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.
![image](https://user-images.githubusercontent.com/275820/123524140-949c3300-d6c8-11eb-9fb7-1d7a3a084c88.png)
## bc <a name="bc"></a>
````
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...
![image](https://user-images.githubusercontent.com/275820/123524154-b5fd1f00-d6c8-11eb-9ec0-1fd1803db422.png)
## clear <a name="clear"></a>
````
usage: clear
````
Just remove previously loaded coin. (set coin = None)
## find <a name="find"></a>
````
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.
![image](https://user-images.githubusercontent.com/275820/124304806-8a64b380-db64-11eb-8df1-71d8032b0345.png)
# OVERVIEW <a name="OVERVIEW"></a>
## global <a name="global"></a>
````
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
![image](https://user-images.githubusercontent.com/275820/123538175-d1514400-d733-11eb-9634-09c341f63cb9.png)
## news <a name="news"></a>
````
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
![image](https://user-images.githubusercontent.com/275820/124304537-1e824b00-db64-11eb-946d-4eb28a37bd18.png)
## coins <a name="coins"></a>
````
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`
![image](https://user-images.githubusercontent.com/275820/123538885-26428980-d737-11eb-9418-e3f80511786d.png)
## defi <a name="defi"></a>
````
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
![image](https://user-images.githubusercontent.com/275820/123538414-188c0480-d735-11eb-8395-f9bd2f1ef96c.png)
## trending <a name="trending"></a>
````
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`
![image](https://user-images.githubusercontent.com/275820/124305015-c8fa6e00-db64-11eb-81de-4e8b943c6c0d.png)
## most_voted <a name="most_voted"></a>
````
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`
![image](https://user-images.githubusercontent.com/275820/123538516-8cc6a800-d735-11eb-85ee-e3f2141a54fb.png)
## most_visited <a name="most_visited"></a>
````
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`
![image](https://user-images.githubusercontent.com/275820/123538524-9cde8780-d735-11eb-9827-c02ea8bd5db7.png)
## sentiment <a name="sentiment"></a>
````
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`
![image](https://user-images.githubusercontent.com/275820/123538553-c5ff1800-d735-11eb-9fef-ef490184c6d8.png)
## recently <a name="recently"></a>
````
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`
![image](https://user-images.githubusercontent.com/275820/124305122-f47d5880-db64-11eb-9048-b495248723d3.png)
## top_volume <a name="top_volume"></a>
````
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)
![image](https://user-images.githubusercontent.com/275820/124305188-0a8b1900-db65-11eb-953f-febc32500ff9.png)
## gainers <a name="gainers"></a>
````
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`
![image](https://user-images.githubusercontent.com/275820/124305218-137bea80-db65-11eb-914c-865b56cf33ea.png)
## losers <a name="losers"></a>
````
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`
![image](https://user-images.githubusercontent.com/275820/124305327-3ad2b780-db65-11eb-9922-7783b740312c.png))
## stables <a name="stables"></a>
````
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.
![image](https://user-images.githubusercontent.com/275820/124305427-62298480-db65-11eb-9216-02cf9690c958.png)
## yfarms <a name="yfarms"></a>
````
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)
![image](https://user-images.githubusercontent.com/275820/124305461-6ce41980-db65-11eb-9c82-648f4ff905e8.png)
## top_defi <a name="top_defi"></a>
````
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`.
![image](https://user-images.githubusercontent.com/275820/124305508-7c636280-db65-11eb-8ae7-38389ac72770.png)
## top_dex <a name="top_dex"></a>
````
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)
![image](https://user-images.githubusercontent.com/275820/124305536-84230700-db65-11eb-82bf-ad2d0878135c.png)
## top_nft <a name="top_nft"></a>
````
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`.
![image](https://user-images.githubusercontent.com/275820/124305553-8be2ab80-db65-11eb-92a8-86485d2b7ef8.png)
## nft_today <a name="nft_today"></a>
````
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
![image](https://user-images.githubusercontent.com/275820/123539455-2abc7180-d73a-11eb-9b58-160f11d99b44.png)
## nft_market <a name="nft_market"></a>
````
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
![image](https://user-images.githubusercontent.com/275820/123539514-7838de80-d73a-11eb-8e22-ef3f250d3003.png)
## exchanges <a name="exchanges"></a>
````
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
![image](https://user-images.githubusercontent.com/275820/123539542-98689d80-d73a-11eb-9561-2de524d329d0.png)
## ex_rates <a name="ex_rates"></a>
````
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)
![image](https://user-images.githubusercontent.com/275820/124305586-969d4080-db65-11eb-8cc9-7024ae06758a.png)
## platforms <a name="platforms"></a>
````
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)
![image](https://user-images.githubusercontent.com/275820/123539607-e1205680-d73a-11eb-9ab4-b8998ef37731.png)
## products <a name="products"></a>
````
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)
![image](https://user-images.githubusercontent.com/275820/124305624-a583f300-db65-11eb-819d-4bd9961d2a08.png)
## indexes <a name="indexes"></a>
````
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)
![image](https://user-images.githubusercontent.com/275820/124305656-afa5f180-db65-11eb-91fc-a9b57e99e690.png)
## derivatives <a name="derivatives"></a>
````
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)
![image](https://user-images.githubusercontent.com/275820/124305694-b896c300-db65-11eb-9a15-dfd2d1e5832f.png)
## categories <a name="categories"></a>
````
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
![image](https://user-images.githubusercontent.com/275820/124305739-c51b1b80-db65-11eb-9f35-6dd1fceb731d.png)
## hold <a name="hold"></a>
````
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`
![image](https://user-images.githubusercontent.com/275820/123539842-f77ae200-d73b-11eb-9d6c-feb2fbd98c01.png)
## hold_comp <a name="hold_comp"></a>
````
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
![image](https://user-images.githubusercontent.com/275820/124305825-e419ad80-db65-11eb-85b4-35f2e163f3fd.png)

View File

@@ -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

View File

@@ -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 <coin>"
)
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

View File

@@ -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

View File

@@ -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()

File diff suppressed because it is too large Load Diff

View File

@@ -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 <a name="top"></a>
````
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).
<img width="990" alt="crypto" src="https://user-images.githubusercontent.com/25267873/115787544-4746d100-a3ba-11eb-9433-b7cb9142404a.png">

View File

@@ -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

View File

@@ -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():

View File

@@ -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)

View File

@@ -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("")

View File

@@ -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

65
poetry.lock generated
View File

@@ -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"},

View File

@@ -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"""