mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-30 14:02:06 +00:00
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:
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||

|
||||
|
||||
|
||||
## 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.
|
||||
|
||||

|
||||
|
||||
|
||||
## candle <a name="candle"></a>
|
||||
````
|
||||
usage: candle
|
||||
````
|
||||
|
||||
Show candle chart for loaded coin/currency.
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
## balance <a name="balance"></a>
|
||||
````
|
||||
usage: balance
|
||||
````
|
||||
|
||||
Shows the current holding balance in your account.
|
||||
[BINANCE standalone menu](/gamestonk_terminal/cryptocurrency/coinmarketcap/)
|
||||
|
||||
52
gamestonk_terminal/cryptocurrency/binance/README.md
Normal file
52
gamestonk_terminal/cryptocurrency/binance/README.md
Normal 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.
|
||||
|
||||

|
||||
|
||||
|
||||
## candle <a name="candle"></a>
|
||||
````
|
||||
usage: candle
|
||||
````
|
||||
|
||||
Show candle chart for loaded coin/currency.
|
||||
|
||||

|
||||
|
||||
|
||||
## 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/)
|
||||
171
gamestonk_terminal/cryptocurrency/binance/binance_controller.py
Normal file
171
gamestonk_terminal/cryptocurrency/binance/binance_controller.py
Normal 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
|
||||
@@ -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):
|
||||
784
gamestonk_terminal/cryptocurrency/coingecko/README.md
Normal file
784
gamestonk_terminal/cryptocurrency/coingecko/README.md
Normal 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".
|
||||
|
||||

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

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

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

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

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

|
||||
|
||||
## 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.
|
||||
|
||||

|
||||
|
||||
## web <a name="web"></a>
|
||||
|
||||
````
|
||||
usage: web
|
||||
````
|
||||
|
||||
Websites found for given Coin. You can find there urls to homepage, forum, announcement site and others.
|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
|
||||

|
||||
|
||||
## 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...
|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
|
||||

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

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

|
||||
|
||||
## 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`
|
||||
|
||||

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

|
||||
|
||||
|
||||
## 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`
|
||||
|
||||

|
||||
|
||||
## 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`
|
||||
|
||||

|
||||
|
||||
## 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`
|
||||
|
||||
|
||||

|
||||
|
||||
## 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`
|
||||
|
||||
|
||||

|
||||
|
||||
## 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`
|
||||
|
||||

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

|
||||
|
||||
|
||||
## 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`
|
||||
|
||||

|
||||
|
||||
## 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`
|
||||
|
||||
)
|
||||
|
||||
## 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.
|
||||
|
||||

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

|
||||
|
||||
## 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`.
|
||||
|
||||
|
||||
|
||||

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

|
||||
|
||||
## 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`.
|
||||
|
||||
|
||||

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

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

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

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

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

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

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

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

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

|
||||
|
||||
|
||||
## 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`
|
||||
|
||||

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

|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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()
|
||||
2623
gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_view.py
Normal file
2623
gamestonk_terminal/cryptocurrency/coingecko/pycoingecko_view.py
Normal file
File diff suppressed because it is too large
Load Diff
17
gamestonk_terminal/cryptocurrency/coinmarketcap/README.md
Normal file
17
gamestonk_terminal/cryptocurrency/coinmarketcap/README.md
Normal 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">
|
||||
@@ -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
|
||||
@@ -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():
|
||||
|
||||
49
gamestonk_terminal/cryptocurrency/cryptocurrency_helpers.py
Normal file
49
gamestonk_terminal/cryptocurrency/cryptocurrency_helpers.py
Normal 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)
|
||||
@@ -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("")
|
||||
@@ -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
65
poetry.lock
generated
@@ -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"},
|
||||
|
||||
@@ -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"""
|
||||
|
||||
Reference in New Issue
Block a user