mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-29 13:32:08 +00:00
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
42
gamestonk_terminal/cryptocurrency/README.md
Normal file
42
gamestonk_terminal/cryptocurrency/README.md
Normal 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:
|
||||
|
||||

|
||||
0
gamestonk_terminal/cryptocurrency/__init__.py
Normal file
0
gamestonk_terminal/cryptocurrency/__init__.py
Normal file
115
gamestonk_terminal/cryptocurrency/coin_api.py
Normal file
115
gamestonk_terminal/cryptocurrency/coin_api.py
Normal 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("")
|
||||
103
gamestonk_terminal/cryptocurrency/crypto_controller.py
Normal file
103
gamestonk_terminal/cryptocurrency/crypto_controller.py
Normal 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
|
||||
11
gamestonk_terminal/cryptocurrency/crypto_helper.py
Normal file
11
gamestonk_terminal/cryptocurrency/crypto_helper.py
Normal 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"])
|
||||
@@ -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
17
poetry.lock
generated
@@ -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"},
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user