Merge pull request #283 from jmaslek/gecko_crypt

Add a crypto menu
This commit is contained in:
DidierRLopes
2021-03-27 00:16:07 +00:00
committed by GitHub
15 changed files with 300 additions and 2 deletions

View File

@@ -328,6 +328,7 @@ Distributed under the MIT License. See [LICENSE](https://github.com/DidierRLopes
[Artem Veremy](https://www.linkedin.com/in/veremey/) - artem@veremey.net
[James Maslek](https://www.linkedin.com/in/james-maslek-b6810186/) - jmaslek11@gmail.com
## Acknowledgments
* [VICE article](https://www.vice.com/en/article/qjp9vp/gamestonk-terminal-is-a-diy-meme-stock-version-of-bloomberg-terminal)

View File

@@ -202,7 +202,7 @@
### Short term
- [ ] Add Coingecko
- [x] Add Coingecko (@jmaslek) - [PR #283](#https://github.com/DidierRLopes/GamestonkTerminal/pulls)
- [ ] Add [Coinpaprika](https://coinpaprika.com/api/)
- [ ] Add crypto charts

View File

@@ -0,0 +1,42 @@
# Cryptocurrency
This page gives an overview of the ability to load cryptocurrency data.
Current crypto data is [Powered by CoinGecko API](#https://www.coingecko.com/en).
This is an awesome service that currently requires no API Key!
Current functionality is aimed to be similar to loading a stock ticker.
* [load](#load)
* [view](#view)
* [clear](#clear)
## load <a name="load"></a>
Load a given coin vs a given currency:
````
usage: load [-c --coin] [-d --days] [--vs]
````
* -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".
Currently only retrieves price, not volume or MarketCap.
Example doge/eur for the past day:
````
load -c doge -d 1 --vs eur
````
## view <a name="view"></a>
Plot the loaded crypto data.
````
usage: view
````
After loading the above 1 day dogecoin/eur. Running view plots the data:
![doge](https://user-images.githubusercontent.com/18151143/112690617-7832f500-8e52-11eb-84c4-253ab222a918.png)

View File

@@ -0,0 +1,115 @@
import argparse
import pandas as pd
from pandas.plotting import register_matplotlib_converters
import matplotlib.pyplot as plt
from pycoingecko import CoinGeckoAPI
from gamestonk_terminal.helper_funcs import parse_known_args_and_warn, plot_autoscale
from gamestonk_terminal.cryptocurrency.crypto_helper import coin_symbol_to_id, coin_ids
from gamestonk_terminal.config_plot import PLOT_DPI
register_matplotlib_converters()
# pylint: disable=inconsistent-return-statements
def load(l_args):
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 l_args:
if "-" not in l_args[0]:
l_args.insert(0, "-c")
ns_parser = parse_known_args_and_warn(parser, l_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, prices, l_args):
parser = argparse.ArgumentParser(
add_help=False,
prog="Crypto",
description="""
Cryptocurrencies
""",
)
try:
ns_parser = parse_known_args_and_warn(parser, l_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("")

View File

@@ -0,0 +1,103 @@
__docformat__ = "numpy"
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 coin_api
class CryptoController:
CHOICES = ["help", "q", "quit", "load", "view"]
def __init__(self):
""" CONSTRUCTOR """
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_df = pd.DataFrame()
@staticmethod
def print_help(current_coin):
""" Print help """
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 : {current_coin}")
print("")
print(" load load cryptocurrency data")
print(" view load and view cryptocurrency data")
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.crypto_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(self.current_coin)
def call_q(self, _):
"""Process Q command - quit the menu"""
return False
def call_quit(self, _):
"""Process Quit command - quit the program"""
return True
def call_load(self, other_args):
self.current_coin, self.current_df = coin_api.load(other_args)
def call_view(self, other_args):
if self.current_coin:
coin_api.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 menu():
crypto_controller = CryptoController()
crypto_controller.print_help(crypto_controller.current_coin)
plt.close("all")
while True:
# Get input command from user
if session and gtff.USE_PROMPT_TOOLKIT:
completer = NestedCompleter.from_nested_dict(
{c: None for c in crypto_controller.CHOICES}
)
an_input = session.prompt(
f"{get_flair()} (crypto)> ",
completer=completer,
)
else:
an_input = input(f"{get_flair()} (crypto)> ")
try:
process_input = crypto_controller.switch(an_input)
if process_input is not None:
return process_input
except SystemExit:
print("The command selected doesn't exist\n")
continue

View File

@@ -0,0 +1,11 @@
from pycoingecko import CoinGeckoAPI
cg = CoinGeckoAPI()
coins = cg.get_coins()
coin_symbol_to_id = {}
coin_ids = []
for coin in coins:
coin_symbol_to_id[coin["symbol"]] = coin["id"]
coin_ids.append(coin["id"])

View File

@@ -54,6 +54,7 @@ def print_help(s_ticker, s_start, s_interval, b_is_market_open):
" fred economic data, \t\t\t from: Federal Reserve Bank of St. Louis "
)
print(" pa portfolio analysis, \t\t Currently Supported: Robinhood ")
print(" crypto cryptocurrencies, \t\t coingecko api")
if s_ticker:
print(

17
poetry.lock generated
View File

@@ -1799,6 +1799,17 @@ category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]]
name = "pycoingecko"
version = "1.4.0"
description = "Python wrapper around the CoinGecko API"
category = "main"
optional = false
python-versions = "*"
[package.dependencies]
requests = "*"
[[package]]
name = "pycparser"
version = "2.20"
@@ -2767,7 +2778,7 @@ prediction = ["fbprophet", "tensorflow", "pmdarima", "transformers", "flair", "t
[metadata]
lock-version = "1.1"
python-versions = "^3.6.8"
content-hash = "ab13d87e3da8dcb61024c74340e528554cea71b5ccab8637e3c75ab88550fcd1"
content-hash = "b05035fef8aa3a5dacf6c4713579493f1104296ea25305049466fc47e0c35401"
[metadata.files]
absl-py = [
@@ -3940,6 +3951,10 @@ pycodestyle = [
{file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"},
{file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"},
]
pycoingecko = [
{file = "pycoingecko-1.4.0-py3-none-any.whl", hash = "sha256:bc6e2d87a59bda88bd01a241b37d49c30104842534fdf65ba96616c90419d756"},
{file = "pycoingecko-1.4.0.tar.gz", hash = "sha256:082949e83b49ab89090d19b88b6177c9458679dc4a98323db950bd4cef7afa2e"},
]
pycparser = [
{file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"},
{file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"},

View File

@@ -49,6 +49,7 @@ robin-stocks = "^2.0.3"
termcolor = "^1.1.0"
alpaca-trade-api = "^1.0.1"
pyally = "^1.1.2"
pycoingecko = "^1.4.0"
[tool.poetry.dev-dependencies]
pytest = "^6.2.2"

View File

@@ -126,6 +126,7 @@ py==1.10.0; python_version >= "3.6" and python_full_version < "3.0.0" and implem
pyally==1.1.2
pyasn1-modules==0.2.8; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0"
pyasn1==0.4.8; python_version >= "3.5" and python_full_version < "3.0.0" and python_version < "4" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6") or python_version >= "3.5" and python_version < "4" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6") and python_full_version >= "3.6.0"
pycoingecko==1.4.0
pycparser==2.20; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.5"
pygments==2.8.1; python_version >= "3.6"
pymeeus==0.5.9; python_version >= "3.5"

View File

@@ -86,6 +86,7 @@ psaw==0.0.12; python_version >= "3"
pyally==1.1.2
pyasn1-modules==0.2.8; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0"
pyasn1==0.4.8; python_version >= "3.5" and python_full_version < "3.0.0" and python_version < "4" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6") or python_version >= "3.5" and python_version < "4" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6") and python_full_version >= "3.6.0"
pycoingecko==1.4.0
pymeeus==0.4.3; python_version >= "3.5"
pyparsing==2.4.7; python_full_version >= "3.6.0" and python_version >= "3.6"
pysocks==1.7.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"

View File

@@ -87,6 +87,7 @@ psaw==0.0.12; python_version >= "3"
pyally==1.1.2
pyasn1-modules==0.2.8; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.6.0"
pyasn1==0.4.8; python_version >= "3.5" and python_full_version < "3.0.0" and python_version < "4" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6") or python_version >= "3.5" and python_version < "4" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.6") and python_full_version >= "3.6.0"
pycoingecko==1.4.0
pymeeus==0.4.3; python_version >= "3.5"
pyparsing==2.4.7; python_full_version >= "3.6.0" and python_version >= "3.6"
pysocks==1.7.1; python_version >= "2.7" and python_full_version < "3.0.0" or python_full_version >= "3.5.0"

View File

@@ -85,6 +85,7 @@ psaw==0.0.12; python_version >= "3"
ptyprocess==0.7.0; os_name != "nt" and python_version >= "3.6" and sys_platform != "win32"
py==1.10.0; python_version >= "3.6" and python_full_version < "3.0.0" and implementation_name == "pypy" or implementation_name == "pypy" and python_version >= "3.6" and python_full_version >= "3.4.0"
pyally==1.1.2
pycoingecko==1.4.0
pycparser==2.20; python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.5"
pygments==2.8.1; python_version >= "3.6"
pymeeus==0.5.9; python_version >= "3.5"

View File

@@ -26,6 +26,7 @@ from gamestonk_terminal.comparison_analysis import ca_controller
from gamestonk_terminal.options import op_controller
from gamestonk_terminal.fred import fred_menu as fm
from gamestonk_terminal.portfolio import port_controller
from gamestonk_terminal.cryptocurrency import crypto_controller
# import warnings
# warnings.simplefilter("always")
@@ -79,6 +80,7 @@ def main():
"op",
"fred",
"pa",
"crypto",
]
menu_parser.add_argument("opt", choices=choices)
completer = NestedCompleter.from_nested_dict({c: None for c in choices})
@@ -209,6 +211,9 @@ def main():
elif ns_known_args.opt == "pa":
b_quit = port_controller.menu()
elif ns_known_args.opt == "crypto":
b_quit = crypto_controller.menu()
elif ns_known_args.opt == "pred":
if not gtff.ENABLE_PREDICT: