Add option to go to ta menu from crypto

This commit is contained in:
Jamie
2021-05-20 14:39:47 -04:00
parent 4698ce3530
commit 8b3c396d83
5 changed files with 152 additions and 128 deletions

View File

@@ -101,9 +101,10 @@
* [x] Add several exponential smoothing techniques (@didier) - [PR #132](https://github.com/DidierRLopes/GamestonkTerminal/pull/132)
* [x] Allow backtesting (@didier) - [PR #169](https://github.com/DidierRLopes/GamestonkTerminal/pull/169)
* [x] Add averaging around multiple predictions (@didier) - [PR #252](https://github.com/DidierRLopes/GamestonkTerminal/pull/252)
* [x] CNN 1D (@jmaslek) - [PR #436](https://github.com/GamestonkTerminal/GamestonkTerminal/pull/436)
**NEXT**
* [ ] CNN 1D (@didier)
* [ ] Combine Sentiment Analysis with Chart data - [IS #240](https://github.com/DidierRLopes/GamestonkTerminal/issues/240)
* [ ] Cross-Validation methods (Forward Chaining, K-Fold, Group K-Fold) (@didier)
@@ -204,10 +205,11 @@ ___
* [x] Add Coingecko (@jmaslek) - [PR #283](https://github.com/DidierRLopes/GamestonkTerminal/pull/283)
* [x] view top coins from coinmarketcap (@jmaslek) - [PR #378](https://github.com/DidierRLopes/GamestonkTerminal/pull/378)
* [x] Add binance (@jmaslek) [PR #428](#https://github.com/DidierRLopes/GamestonkTerminal/pull/428)
* [x] Add crypto ta (@jmaslek)
**NEXT**
* [ ] Add [Coinpaprika](https://coinpaprika.com/api/)
* [ ] Add crypto charts
* [ ] Add top altcoin lists
---

View File

@@ -297,9 +297,9 @@ Command|Description
[coinmarketcap](#http://coinmarketcap.com)|
`top` | view top coins from coinmarketcap
[binance](#http://binance.us)|
`select` | Select a coin/currency
`select` | select coin/currency to use and load candle data
`book`| show order book
`candle`| get klines/candles and plot
`candle`| show candles
`balance`| show coin balance
 
@@ -469,4 +469,3 @@ with ticker provided |
`house` | house trades on the ticker
 

View File

@@ -2,6 +2,9 @@
This menu aims to explore crypto world, and 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.
[COINGECKO](#COINGECKO)
* [load](#load)
* load a given coin vs a given currency [CoinGecko]
@@ -9,10 +12,10 @@ This menu aims to explore crypto world, and the usage of the following commands
* plot the loaded crypto data
* [trend](#trend)
* show top 7 trending coins
[COINMARKETCAP](#COINMARKETCAP)
* [top](#top)
* view top coins from coinmarketcap [coinmarketcap.com]
* view top coins from coinmarketcap [coinmarketcap.com]
[BINANCE](#BINANCE)
* [select](#select)
@@ -24,6 +27,10 @@ This menu aims to explore crypto world, and the usage of the following commands
* [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>
@@ -31,11 +38,11 @@ This menu aims to explore crypto world, and the usage of the following commands
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!
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`
* -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,
* -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".
@@ -80,17 +87,18 @@ This command displays the top n cryptocurrencies from coinmarketcap.com.
## select <a name="select"></a>
````
usage: select [-c --coin] [-q --quote]
usage: select [-c --coin] [-q --quote] [-i --interval] [-l --limit]
````
Select a coin/currency to the current object. 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
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
usage: book -l/--limit
````
Gets and shows the order book for the given coin/currency. Shows the cumulative amount of orders.
@@ -102,13 +110,11 @@ Gets and shows the order book for the given coin/currency. Shows the cumulative
## candle <a name="candle"></a>
````
usage: candle [-i --interval] [-l --limit]
usage: candle
````
Show candle chart for loaded coin/currency.
* -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.
![candle](https://user-images.githubusercontent.com/25267873/116886993-abbb2900-ac21-11eb-9ff8-b6a8131fdac5.png)
@@ -119,5 +125,3 @@ usage: balance
````
Shows the current holding balance in your account.

View File

@@ -38,11 +38,14 @@ def select_binance_coin(other_args: List[str]):
-------
coin: str
Coin that is defined on binance
df_coin : pd.DataFrame
Dataframe of prices for selected coin
"""
client = Client(cfg.API_BINANCE_KEY, cfg.API_BINANCE_SECRET)
parser = argparse.ArgumentParser(
prog="select",
add_help=False,
description="Define the coin to be used from binance",
description="Define the coin to be used from binance and get data",
)
parser.add_argument(
"-c", "--coin", help="Coin to get", dest="coin", type=str, default="BTC"
@@ -55,22 +58,76 @@ def select_binance_coin(other_args: List[str]):
type=str,
default="USDT",
)
interval_map = {
"1day": client.KLINE_INTERVAL_1DAY,
"3day": client.KLINE_INTERVAL_3DAY,
"1hour": client.KLINE_INTERVAL_1HOUR,
"2hour": client.KLINE_INTERVAL_2HOUR,
"4hour": client.KLINE_INTERVAL_4HOUR,
"6hour": client.KLINE_INTERVAL_6HOUR,
"8hour": client.KLINE_INTERVAL_8HOUR,
"12hour": client.KLINE_INTERVAL_12HOUR,
"1week": client.KLINE_INTERVAL_1WEEK,
"1min": client.KLINE_INTERVAL_1MINUTE,
"3min": client.KLINE_INTERVAL_3MINUTE,
"5min": client.KLINE_INTERVAL_5MINUTE,
"15min": client.KLINE_INTERVAL_15MINUTE,
"30min": client.KLINE_INTERVAL_30MINUTE,
"1month": client.KLINE_INTERVAL_1MONTH,
}
interval_choices = list(interval_map.keys())
parser.add_argument(
"-i",
"--interval",
help="Interval to get data",
choices=interval_choices,
dest="interval",
default="1day",
type=str,
)
parser.add_argument(
"-l", "--limit", dest="limit", default=100, help="Number to get", type=int
)
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 None, None
return None, None, pd.DataFrame()
coin = ns_parser.coin + ns_parser.quote
if check_valid_binance_str(coin):
print(f"{ns_parser.coin.upper()} loaded vs {ns_parser.quote.upper()}")
return ns_parser.coin.upper(), ns_parser.quote.upper()
candles = client.get_klines(
symbol=coin.upper(),
interval=interval_map[ns_parser.interval],
limit=ns_parser.limit,
)
candles_df = pd.DataFrame(candles).astype(float).iloc[:, :6]
candles_df.columns = [
"Time0",
"Open",
"High",
"Low",
"Close",
"Volume",
]
df_coin = candles_df.set_index(
pd.to_datetime(candles_df["Time0"], unit="ms")
).drop("Time0", axis=1)
return ns_parser.coin.upper(), ns_parser.quote.upper(), df_coin
except Exception as e:
print(e, "\n")
return None, None
return None, None, pd.DataFrame
def order_book(other_args: List[str], coin: str, currency: str):
@@ -121,112 +178,25 @@ def order_book(other_args: List[str], coin: str, currency: str):
print(e, "\n")
def show_candles(other_args: List[str], coin: str, currency: str):
"""Get klines/candles for coin
def show_candles(candles_df: pd.DataFrame, coin: str, currency: str):
"""Show candles
Parameters
----------
other_args: List[str]
Argparse arguments
candles_df: pd.DataFrame
Dataframe of prices
coin: str
Coin to get symbol of
Coin loaded
currency : str
Currency against which to check symbol
Currency loaded
"""
client = Client(cfg.API_BINANCE_KEY, cfg.API_BINANCE_SECRET)
interval_map = {
"1day": client.KLINE_INTERVAL_1DAY,
"3day": client.KLINE_INTERVAL_3DAY,
"1hour": client.KLINE_INTERVAL_1HOUR,
"2hour": client.KLINE_INTERVAL_2HOUR,
"4hour": client.KLINE_INTERVAL_4HOUR,
"6hour": client.KLINE_INTERVAL_6HOUR,
"8hour": client.KLINE_INTERVAL_8HOUR,
"12hour": client.KLINE_INTERVAL_12HOUR,
"1week": client.KLINE_INTERVAL_1WEEK,
"1min": client.KLINE_INTERVAL_1MINUTE,
"3min": client.KLINE_INTERVAL_3MINUTE,
"5min": client.KLINE_INTERVAL_5MINUTE,
"15min": client.KLINE_INTERVAL_15MINUTE,
"30min": client.KLINE_INTERVAL_30MINUTE,
"1month": client.KLINE_INTERVAL_1MONTH,
}
interval_choices = list(interval_map.keys())
parser = argparse.ArgumentParser(
prog="candle",
add_help=False,
description="Program to plot candles for binance data",
plot_candles(
candles_df,
f"{coin+currency} from {candles_df.index[0].strftime('%Y/%m/%d')} to "
f"{candles_df.index[-1].strftime('%Y/%m/%d')}",
)
parser.add_argument(
"-i",
"--interval",
help="Interval to get data",
choices=interval_choices,
dest="interval",
default="1day",
type=str,
)
parser.add_argument(
"-l", "--limit", dest="limit", default=100, help="Number to get", type=int
)
try:
if not coin or not currency:
print("Coin needs to be selected prior to this command\n")
return
coin += currency
ns_parser = parse_known_args_and_warn(parser, other_args)
if not ns_parser:
return
candles = client.get_klines(
symbol=coin,
interval=interval_map[ns_parser.interval],
limit=ns_parser.limit,
)
# Response
# 1499040000000, // Open time
# "0.01634790", // Open
# "0.80000000", // High
# "0.01575800", // Low
# "0.01577100", // Close
# "148976.11427815", // Volume
# 1499644799999, // Close time
# "2434.19055334", // Quote asset volume
# 308, // Number of trades
# "1756.87402397", // Taker buy base asset volume
# "28.46694368", // Taker buy quote asset volume
# "17928899.62484339" // Ignore.
candles_df = pd.DataFrame(candles).astype(float).iloc[:, :7]
candles_df.columns = [
"Time0",
"Open",
"High",
"Low",
"Close",
"Volume",
"Time1",
]
candles_df.index = pd.to_datetime(
(candles_df["Time0"] + candles_df["Time1"]) / 2, unit="ms"
)
plot_candles(
candles_df,
f"{coin} from {candles_df.index[0].strftime('%Y/%m/%d')} to "
f"{candles_df.index[-1].strftime('%Y/%m/%d')}",
)
except Exception as e:
print(e, "\n")
print("")
def balance(coin: str):

View File

@@ -13,6 +13,7 @@ from gamestonk_terminal.cryptocurrency import (
pycoingecko_view,
coinmarketcap_view as cmc_view,
)
from gamestonk_terminal.technical_analysis import ta_controller
class CryptoController:
@@ -30,6 +31,7 @@ class CryptoController:
"candle",
"balance",
"select",
"ta",
]
def __init__(self):
@@ -40,6 +42,7 @@ class CryptoController:
self.current_coin = None
self.current_currency = None
self.current_df = pd.DataFrame()
self.source = ""
def print_help(self):
"""Print help"""
@@ -58,11 +61,13 @@ class CryptoController:
print(" top view top coins from coinmarketcap")
print("")
print("Binance:")
print(" select select coin/currency to use")
print(" select select coin/currency to use and load candle data")
print(" book show order book")
print(" candle get klines/candles and plot")
print(" candle show candles")
print(" balance show coin balance")
print("")
print(" >ta technical analysis menu for")
print("")
def switch(self, an_input: str):
"""Process and dispatch input
@@ -95,6 +100,7 @@ class CryptoController:
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"""
@@ -117,9 +123,11 @@ class CryptoController:
"""Process book command"""
binance_model.order_book(other_args, self.current_coin, self.current_currency)
def call_candle(self, other_args):
def call_candle(self, _):
"""Process candle command"""
binance_model.show_candles(other_args, self.current_coin, self.current_currency)
binance_model.show_candles(
self.current_df, self.current_coin, self.current_currency
)
def call_balance(self, _):
"""Process balance command"""
@@ -127,11 +135,52 @@ class CryptoController:
def call_select(self, other_args):
"""Process select command"""
self.current_coin, self.current_currency = binance_model.select_binance_coin(
other_args
)
(
self.current_coin,
self.current_currency,
self.current_df,
) = binance_model.select_binance_coin(other_args)
self.source = "BIN"
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")
if self.current_df.empty:
print("Price dataframe is empty")
else:
# Need to make the columns in df be compatible. Also since there are no splits or dividends, there is no
# adj close. To tell ta to use Close, we can just set the interval to anything but 1440.
# Binance provides candles so we just need to rename:
if self.source == "BIN":
self.current_df = self.current_df.rename(
columns={
"Open": "1. open",
"High": "2. high",
"Low": "3. low",
"Close": "4. close",
"Volume": "6. volume",
}
)
self.current_df.index.name = "date"
# Coingecko does not provide candles so we can only provide close data.
elif self.source == "CG":
self.current_df = self.current_df[["Price"]].rename(
columns={"Price": "4. close"}
)
self.current_df.index.name = "date"
return ta_controller.menu(
self.current_df,
self.current_coin,
self.current_df.index[0],
"Hi",
)
def menu():
crypto_controller = CryptoController()