From c984e993d5690a2e655ca4cc16309d5d24245a5e Mon Sep 17 00:00:00 2001 From: jmaslek Date: Fri, 13 Aug 2021 11:57:06 -0400 Subject: [PATCH] Refactored stock->TA (#664) * Ignore nft of the day test * Refactor stock only TA functions --- .../technical_analysis/finbrain_model.py | 30 ++ .../technical_analysis/finbrain_view.py | 66 +---- .../technical_analysis/finnhub_model.py | 40 +++ .../stocks/technical_analysis/finnhub_view.py | 108 ++----- .../stocks/technical_analysis/finviz_model.py | 28 ++ .../stocks/technical_analysis/finviz_view.py | 64 ++-- .../technical_analysis/ta_controller.py | 279 +++++++++++++----- .../technical_analysis/tradingview_model.py | 81 +++++ .../technical_analysis/tradingview_view.py | 164 ++-------- 9 files changed, 465 insertions(+), 395 deletions(-) create mode 100644 gamestonk_terminal/stocks/technical_analysis/finbrain_model.py create mode 100644 gamestonk_terminal/stocks/technical_analysis/finnhub_model.py create mode 100644 gamestonk_terminal/stocks/technical_analysis/finviz_model.py create mode 100644 gamestonk_terminal/stocks/technical_analysis/tradingview_model.py diff --git a/gamestonk_terminal/stocks/technical_analysis/finbrain_model.py b/gamestonk_terminal/stocks/technical_analysis/finbrain_model.py new file mode 100644 index 00000000000..1d3b81b9047 --- /dev/null +++ b/gamestonk_terminal/stocks/technical_analysis/finbrain_model.py @@ -0,0 +1,30 @@ +"""Finbrain model""" +__docformat__ = "numpy" + +import requests + + +def get_technical_summary_report(ticker: str) -> str: + """Get technical summary report provided by FinBrain's API + + Parameters + ---------- + ticker : str + Ticker to get the technical summary + + Returns + ------- + report:str + technical summary report + """ + result = requests.get(f"https://api.finbrain.tech/v0/technicalSummary/{ticker}") + report = "" + if result.status_code == 200: + if "technicalSummary" in result.json(): + report = result.json()["technicalSummary"] + else: + print("Unexpected data format from FinBrain API") + else: + print("Request error in retrieving sentiment from FinBrain API") + + return report diff --git a/gamestonk_terminal/stocks/technical_analysis/finbrain_view.py b/gamestonk_terminal/stocks/technical_analysis/finbrain_view.py index f10395df458..de735307ef2 100644 --- a/gamestonk_terminal/stocks/technical_analysis/finbrain_view.py +++ b/gamestonk_terminal/stocks/technical_analysis/finbrain_view.py @@ -1,38 +1,10 @@ -import argparse -from typing import List -import requests -from gamestonk_terminal.helper_funcs import ( - parse_known_args_and_warn, -) +"""Finbrain view""" +__docformat__ = "numpy" + +from gamestonk_terminal.stocks.technical_analysis import finbrain_model -def get_technical_summary_report(ticker: str) -> str: - """Get technical summary report provided by FinBrain's API - - Parameters - ---------- - ticker : str - Ticker to get the technical summary - - Returns - ------- - str - technical summary report - """ - result = requests.get(f"https://api.finbrain.tech/v0/technicalSummary/{ticker}") - report = "" - if result.status_code == 200: - if "technicalSummary" in result.json(): - report = result.json()["technicalSummary"] - else: - print("Unexpected data format from FinBrain API") - else: - print("Request error in retrieving sentiment from FinBrain API") - - return report - - -def technical_summary_report(other_args: List[str], ticker: str): +def technical_summary_report(ticker: str): """Print technical summary report provided by FinBrain's API Parameters @@ -42,28 +14,8 @@ def technical_summary_report(other_args: List[str], ticker: str): ticker : str Ticker to get the technical summary """ - parser = argparse.ArgumentParser( - add_help=False, - formatter_class=argparse.ArgumentDefaultsHelpFormatter, - prog="summary", - description=""" - Technical summary report provided by FinBrain's API. - FinBrain Technologies develops deep learning algorithms for financial analysis - and prediction, which currently serves traders from more than 150 countries - all around the world. [Source: https://finbrain.tech] - """, - ) - try: - ns_parser = parse_known_args_and_warn(parser, other_args) - if not ns_parser: - return - - report = get_technical_summary_report(ticker) - if report: - print(report.replace(". ", ".\n")) - print("") - - except Exception as e: - print(e) - print("") + report = finbrain_model.get_technical_summary_report(ticker) + if report: + print(report.replace(". ", ".\n")) + print("") diff --git a/gamestonk_terminal/stocks/technical_analysis/finnhub_model.py b/gamestonk_terminal/stocks/technical_analysis/finnhub_model.py new file mode 100644 index 00000000000..f344acf2f26 --- /dev/null +++ b/gamestonk_terminal/stocks/technical_analysis/finnhub_model.py @@ -0,0 +1,40 @@ +"""Finnhub model""" +__docformat__ = "numpy" + +import requests +import pandas as pd + +from gamestonk_terminal import config_terminal as cfg + + +def get_pattern_recognition(ticker: str, resolution: str) -> pd.DataFrame: + """Get pattern recognition data + + Parameters + ---------- + ticker : str + Ticker to get pattern recognition data + resolution : str + Resolution of data to get pattern recognition from + + Returns + ------- + pd.DataFrame + Get datapoints corresponding to pattern signal data + """ + + response = requests.get( + f"https://finnhub.io/api/v1/scan/pattern?symbol={ticker}&resolution={resolution}&token={cfg.API_FINNHUB_KEY}" + ) + + # pylint:disable=no-else-return + if response.status_code == 200: + d_data = response.json() + if "points" in d_data: + return pd.DataFrame(d_data["points"]).T + else: + print("Response is empty") + return pd.DataFrame() + else: + print(f"Error in requests with code: {response.status_code}") + return pd.DataFrame() diff --git a/gamestonk_terminal/stocks/technical_analysis/finnhub_view.py b/gamestonk_terminal/stocks/technical_analysis/finnhub_view.py index 1afd4fa33f0..b7b83042f23 100644 --- a/gamestonk_terminal/stocks/technical_analysis/finnhub_view.py +++ b/gamestonk_terminal/stocks/technical_analysis/finnhub_view.py @@ -1,54 +1,39 @@ -import argparse -from typing import List +"""Finnhub view""" +__docformat__ = "numpy" + +import os + import math from datetime import datetime -import requests import yfinance as yf import mplfinance as mpf -import pandas as pd -from gamestonk_terminal import config_terminal as cfg -from gamestonk_terminal.helper_funcs import ( - parse_known_args_and_warn, - plot_autoscale, -) + +from gamestonk_terminal.helper_funcs import plot_autoscale, export_data +from gamestonk_terminal.stocks.technical_analysis import finnhub_model -def get_pattern_recognition(ticker: str, resolution: str) -> pd.DataFrame: - """Get pattern recognition data - - Parameters - ---------- - ticker : str - Ticker to get pattern recognition data - resolution : str - Resolution of data to get pattern recognition from - - Returns - ------- - pd.DataFrame - Get datapoints corresponding to pattern signal data - """ - response = requests.get( - f"https://finnhub.io/api/v1/scan/pattern?symbol={ticker}&resolution={resolution}&token={cfg.API_FINNHUB_KEY}" - ) - if response.status_code == 200: - d_data = response.json() - if "points" in d_data: - return pd.DataFrame(d_data["points"]).T - - return pd.DataFrame() - - -def plot_pattern_recognition(ticker: str, pattern: pd.DataFrame): +def plot_pattern_recognition(ticker: str, resolution: str, export: str): """Plot pattern recognition signal Parameters ---------- ticker : str Ticker to display pattern recognition on top of the data - pattern : pd.DataFrame - Pattern recognition signal data + resolution : str + Resolution of data to get pattern recognition from + export: str + Format of export file """ + + pattern = finnhub_model.get_pattern_recognition(ticker, resolution) + + export_data( + export, + os.path.dirname(os.path.abspath(__file__)), + "pr", + pattern, + ) + l_segments = list() for i in pattern: a_part = ("", "") @@ -102,7 +87,6 @@ def plot_pattern_recognition(ticker: str, pattern: pd.DataFrame): start=datetime.utcfromtimestamp(start_time).strftime("%Y-%m-%d"), progress=False, ) - df_stock["date_id"] = (df_stock.index.date - df_stock.index.date.min()).astype( "timedelta64[D]" ) @@ -138,49 +122,3 @@ def plot_pattern_recognition(ticker: str, pattern: pd.DataFrame): print( f"Pattern: {pattern[0]['patternname']} ({pattern[0]['patterntype']})", "\n" ) - - -def pattern_recognition_view(other_args: List[str], ticker: str): - """Display pattern recognition signals on the data - - Parameters - ---------- - other_args : List[str] - Command line arguments to be processed with argparse - ticker : str - Ticker to display pattern recognition on top of the data - """ - parser = argparse.ArgumentParser( - add_help=False, - formatter_class=argparse.ArgumentDefaultsHelpFormatter, - prog="pr", - description=""" - Display pattern recognition signals on the data. [Source: https://finnhub.io] - """, - ) - parser.add_argument( - "-r", - "--resolution", - action="store", - dest="resolution", - type=str, - default="D", - choices=["1", "5", "15", "30", "60", "D", "W", "M"], - help="Plot resolution to look for pattern signals", - ) - - try: - ns_parser = parse_known_args_and_warn(parser, other_args) - if not ns_parser: - return - - df_pattern = get_pattern_recognition(ticker, ns_parser.resolution) - - if df_pattern.empty: - print("No pattern identified in this data", "\n") - return - - plot_pattern_recognition(ticker, df_pattern) - - except Exception as e: - print(e, "\n") diff --git a/gamestonk_terminal/stocks/technical_analysis/finviz_model.py b/gamestonk_terminal/stocks/technical_analysis/finviz_model.py new file mode 100644 index 00000000000..b31c1505d19 --- /dev/null +++ b/gamestonk_terminal/stocks/technical_analysis/finviz_model.py @@ -0,0 +1,28 @@ +"""Finviz model""" +__docformat__ = "numpy" + +import requests +from finvizfinance.quote import finvizfinance +from finvizfinance.util import headers + + +def get_finviz_image(ticker: str) -> bytes: + """Get finviz image for given ticker + + Parameters + ---------- + ticker : str + ticker + + Returns + ------- + bytes + Image in byted format + """ + stock = finvizfinance(ticker) + image_url = stock.TickerCharts(urlonly=True) + + r = requests.get(image_url, stream=True, headers=headers, timeout=5) + r.raise_for_status() + r.raw.decode_content = True + return r.content diff --git a/gamestonk_terminal/stocks/technical_analysis/finviz_view.py b/gamestonk_terminal/stocks/technical_analysis/finviz_view.py index 99dd5646dfe..fabfed40330 100644 --- a/gamestonk_terminal/stocks/technical_analysis/finviz_view.py +++ b/gamestonk_terminal/stocks/technical_analysis/finviz_view.py @@ -1,67 +1,39 @@ """ Finviz View """ __docformat__ = "numpy" -import argparse + import io -from typing import List -import requests import matplotlib.pyplot as plt -from finvizfinance.quote import finvizfinance -from finvizfinance.util import headers + from PIL import Image from gamestonk_terminal.helper_funcs import ( - parse_known_args_and_warn, plot_autoscale, ) +from gamestonk_terminal.stocks.technical_analysis import finviz_model from gamestonk_terminal.config_plot import PLOT_DPI from gamestonk_terminal import feature_flags as gtff -def view(other_args: List[str], ticker: str): - """View historical price with trendlines. [Source: Finviz] +def view(ticker: str): + """View finviz image for ticker Parameters ---------- - other_args : List[str] - argparse other args - ticker: str - stock ticker + ticker : str + Stock ticker """ - parser = argparse.ArgumentParser( - add_help=False, - formatter_class=argparse.ArgumentDefaultsHelpFormatter, - prog="view", - description=""" - View historical price with trendlines. [Source: Finviz] - """, - ) + image_data = finviz_model.get_finviz_image(ticker) + dataBytesIO = io.BytesIO(image_data) + im = Image.open(dataBytesIO) - try: - ns_parser = parse_known_args_and_warn(parser, other_args) - if not ns_parser: - return + fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI) + ax.set_axis_off() + fig.subplots_adjust(left=0, right=1, top=1, bottom=0) - stock = finvizfinance(ticker) - image_url = stock.TickerCharts(urlonly=True) + if gtff.USE_ION: + plt.ion() - r = requests.get(image_url, stream=True, headers=headers, timeout=5) - r.raise_for_status() - r.raw.decode_content = True - - dataBytesIO = io.BytesIO(r.content) - im = Image.open(dataBytesIO) - - fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI) - ax.set_axis_off() - fig.subplots_adjust(left=0, right=1, top=1, bottom=0) - - if gtff.USE_ION: - plt.ion() - - plt.imshow(im) - plt.show() - print("") - - except SystemExit: - print("") + plt.imshow(im) + plt.show() + print("") diff --git a/gamestonk_terminal/stocks/technical_analysis/ta_controller.py b/gamestonk_terminal/stocks/technical_analysis/ta_controller.py index bcc99b0d201..258b3dd95d5 100644 --- a/gamestonk_terminal/stocks/technical_analysis/ta_controller.py +++ b/gamestonk_terminal/stocks/technical_analysis/ta_controller.py @@ -10,7 +10,7 @@ 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.helper_funcs import get_flair, parse_known_args_and_warn from gamestonk_terminal.menu import session from gamestonk_terminal.stocks.technical_analysis import ( finviz_view, @@ -62,13 +62,13 @@ class TechnicalAnalysisController: def __init__( self, - ticker: str, + s_stock: str, start: datetime, interval: str, stock: pd.DataFrame, ): """Constructor""" - self.ticker = ticker + self.s_stock = s_stock self.start = start self.interval = interval self.stock = stock @@ -81,55 +81,50 @@ class TechnicalAnalysisController: def print_help(self): """Print help""" - print( - "https://github.com/GamestonkTerminal/GamestonkTerminal/tree/main/gamestonk_terminal" - "/stocks/technical_analysis" - ) - s_intraday = (f"Intraday {self.interval }", "Daily")[self.interval == "1440min"] - + s_intraday = (f"Intraday {self.interval}", "Daily")[self.interval == "1440min"] if self.start: - print( - f"\n{s_intraday} Stock: {self.ticker} (from {self.start.strftime('%Y-%m-%d')})" - ) + str1 = f"\n{s_intraday} Stock: {self.s_stock} (from {self.start.strftime('%Y-%m-%d')})" else: - print(f"\n{s_intraday} Stock: {self.ticker}") + str1 = f"\n{s_intraday} Stock: {self.s_stock}" - print("\nTechnical Analysis:") - print(" cls clear screen") - 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(" view view historical data and trendlines [Finviz]") - print(" summary technical summary report [FinBrain API]") - print( - " recom recommendation based on Technical Indicators [Tradingview API]" - ) - print(" pr pattern recognition [Finnhub]") - print("") - print("overlap:") - print(" ema exponential moving average") - print(" sma simple moving average") - print(" vwap volume weighted average price") - print(" zlma zero lag moving average") - print("momentum:") - print(" cci commodity channel index") - print(" macd moving average convergence/divergence") - print(" rsi relative strength index") - print(" stoch stochastic oscillator") - print(" fisher fisher transform") - print(" cg centre of gravity") - print("trend:") - print(" adx average directional movement index") - print(" aroon aroon indicator") - print("volatility:") - print(" bbands bollinger bands") - print("volume:") - print(" ad accumulation/distribution line values") - print(" obv on balance volume") - print("custom:") - print(" fib fibonacci retracement") - print("") + help_str = f"""https://github.com/GamestonkTerminal/GamestonkTerminal/tree/main/gamestonk_terminal/stocks/technical_analysis +{str1} + +Technical Analysis: + cls clear screen + help show this menu again + q quit this menu, and shows back to main menu + quit quit to abandon program + + view view historical data and trendlines [Finviz] + summary technical summary report [FinBrain API] + recom recommendation based on Technical Indicators [Tradingview API] + pr pattern recognition [Finnhub] + +overlap: + ema exponential moving average + sma simple moving average + zlma zero lag moving average" + vwap volume weighted average price +momentum: + cci commodity channel index + macd moving average convergence/divergence + rsi relative strength index + stoch stochastic oscillator + fisher fisher transform + cg centre of gravity +trend: + adx average directional movement index + aroon aroon indicator +volatility: + bbands bollinger bands +volume: + ad accumulation/distribution line values + obv on balance volume +custom: + fib fibonacci retracement +""" + print(help_str) def switch(self, an_input: str): """Process and dispatch input @@ -178,92 +173,234 @@ class TechnicalAnalysisController: # SPECIFIC def call_view(self, other_args: List[str]): """Process view command""" - finviz_view.view(other_args, self.ticker) + + parser = argparse.ArgumentParser( + add_help=False, + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + prog="view", + description=""" + View historical price with trendlines. [Source: Finviz] + """, + ) + try: + ns_parser = parse_known_args_and_warn(parser, other_args) + if not ns_parser: + return + + finviz_view.view(self.s_stock) + + except Exception as e: + print(e, "\n") def call_summary(self, other_args: List[str]): """Process summary command""" - finbrain_view.technical_summary_report(other_args, self.ticker) + parser = argparse.ArgumentParser( + add_help=False, + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + prog="summary", + description=""" + Technical summary report provided by FinBrain's API. + FinBrain Technologies develops deep learning algorithms for financial analysis + and prediction, which currently serves traders from more than 150 countries + all around the world. [Source: https://finbrain.tech] + """, + ) + + try: + ns_parser = parse_known_args_and_warn(parser, other_args) + if not ns_parser: + return + + finbrain_view.technical_summary_report(self.s_stock) + + except Exception as e: + print(e, "\n") def call_recom(self, other_args: List[str]): """Process recom command""" - tradingview_view.print_recommendation(other_args, self.ticker) + + parser = argparse.ArgumentParser( + add_help=False, + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + prog="recom", + description=""" + Print tradingview recommendation based on technical indicators. + [Source: https://pypi.org/project/tradingview-ta/] + """, + ) + parser.add_argument( + "-s", + "--screener", + action="store", + dest="screener", + type=str, + default="america", + choices=["crypto", "forex", "cfd"], + help="Screener. See https://python-tradingview-ta.readthedocs.io/en/latest/usage.html", + ) + parser.add_argument( + "-e", + "--exchange", + action="store", + dest="exchange", + type=str, + default="", + help="""Set exchange. For Forex use: 'FX_IDC', and for crypto use 'TVC'. + See https://python-tradingview-ta.readthedocs.io/en/latest/usage.html. + By default Alpha Vantage tries to get this data from the ticker. """, + ) + parser.add_argument( + "-i", + "--interval", + action="store", + dest="interval", + type=str, + default="", + choices=["1M", "1W", "1d", "4h", "1h", "15m", "5m", "1m"], + help="""Interval, that corresponds to the recommendation given by tradingview based on technical indicators. + See https://python-tradingview-ta.readthedocs.io/en/latest/usage.html""", + ) + parser.add_argument( + "--export", + choices=["csv", "json", "xlsx"], + default="", + type=str, + dest="export", + help="Export dataframe data to csv,json,xlsx file", + ) + + try: + ns_parser = parse_known_args_and_warn(parser, other_args) + if not ns_parser: + return + tradingview_view.print_recommendation( + ticker=self.s_stock, + screener=ns_parser.screener, + exchange=ns_parser.exchange, + interval=ns_parser.interval, + export=ns_parser.export, + ) + + except Exception as e: + print(e, "\n") def call_pr(self, other_args: List[str]): """Process pr command""" - finnhub_view.pattern_recognition_view(other_args, self.ticker) + + parser = argparse.ArgumentParser( + add_help=False, + formatter_class=argparse.ArgumentDefaultsHelpFormatter, + prog="pr", + description=""" + Display pattern recognition signals on the data. [Source: https://finnhub.io] + """, + ) + parser.add_argument( + "-r", + "--resolution", + action="store", + dest="resolution", + type=str, + default="D", + choices=["1", "5", "15", "30", "60", "D", "W", "M"], + help="Plot resolution to look for pattern signals", + ) + + parser.add_argument( + "--export", + choices=["csv", "json", "xlsx"], + default="", + type=str, + dest="export", + help="Export dataframe data to csv,json,xlsx file", + ) + + try: + ns_parser = parse_known_args_and_warn(parser, other_args) + if not ns_parser: + return + + finnhub_view.plot_pattern_recognition( + ticker=self.s_stock, + resolution=ns_parser.resolution, + export=ns_parser.export, + ) + + except Exception as e: + print(e, "\n") # COMMON def call_ema(self, other_args: List[str]): """Process ema command""" - overlap.ema(other_args, self.ticker, self.interval, self.stock) + overlap.ema(other_args, self.s_stock, self.interval, self.stock) def call_sma(self, other_args: List[str]): """Process sma command""" - overlap.sma(other_args, self.ticker, self.interval, self.stock) + overlap.sma(other_args, self.s_stock, self.interval, self.stock) def call_vwap(self, other_args: List[str]): """Process vwap command""" - overlap.vwap(other_args, self.ticker, self.interval, self.stock) + overlap.vwap(other_args, self.s_stock, self.interval, self.stock) def call_zlma(self, other_args: List[str]): """Process zlma command""" - overlap.zlma(other_args, self.ticker, self.interval, self.stock) + overlap.zlma(other_args, self.s_stock, self.interval, self.stock) def call_cci(self, other_args: List[str]): """Process cci command""" - momentum.cci(other_args, self.ticker, self.interval, self.stock) + momentum.cci(other_args, self.s_stock, self.interval, self.stock) def call_macd(self, other_args: List[str]): """Process macd command""" - momentum.macd(other_args, self.ticker, self.interval, self.stock) + momentum.macd(other_args, self.s_stock, self.interval, self.stock) def call_rsi(self, other_args: List[str]): """Process rsi command""" - momentum.rsi(other_args, self.ticker, self.interval, self.stock) + momentum.rsi(other_args, self.s_stock, self.interval, self.stock) def call_stoch(self, other_args: List[str]): """Process stoch command""" - momentum.stoch(other_args, self.ticker, self.interval, self.stock) + momentum.stoch(other_args, self.s_stock, self.interval, self.stock) def call_fisher(self, other_args: List[str]): """Process fisher command""" - momentum.fisher(other_args, self.ticker, self.interval, self.stock) + momentum.fisher(other_args, self.s_stock, self.interval, self.stock) def call_cg(self, other_args: List[str]): """Process cg command""" - momentum.cg(other_args, self.ticker, self.interval, self.stock) + momentum.cg(other_args, self.s_stock, self.interval, self.stock) def call_adx(self, other_args: List[str]): """Process adx command""" - trend_indicators.adx(other_args, self.ticker, self.interval, self.stock) + trend_indicators.adx(other_args, self.s_stock, self.interval, self.stock) def call_aroon(self, other_args: List[str]): """Process aroon command""" - trend_indicators.aroon(other_args, self.ticker, self.interval, self.stock) + trend_indicators.aroon(other_args, self.s_stock, self.interval, self.stock) def call_bbands(self, other_args: List[str]): """Process bbands command""" - volatility.bbands(other_args, self.ticker, self.interval, self.stock) + volatility.bbands(other_args, self.s_stock, self.interval, self.stock) def call_ad(self, other_args: List[str]): """Process ad command""" - volume.ad(other_args, self.ticker, self.interval, self.stock) + volume.ad(other_args, self.s_stock, self.interval, self.stock) def call_obv(self, other_args: List[str]): """Process obv command""" - volume.obv(other_args, self.ticker, self.interval, self.stock) + volume.obv(other_args, self.s_stock, self.interval, self.stock) def call_fib(self, other_args: List[str]): """Process fib command""" custom_indicators_view.fibinocci_retracement( - other_args, self.stock, self.ticker + other_args, self.stock, self.s_stock ) -def menu(ticker: str, start: datetime, interval: str, stock: pd.DataFrame): +def menu(s_stock: str, start: datetime, interval: str, stock: pd.DataFrame): """Technical Analysis Menu""" - ta_controller = TechnicalAnalysisController(ticker, start, interval, stock) + ta_controller = TechnicalAnalysisController(s_stock, start, interval, stock) ta_controller.call_help(None) while True: diff --git a/gamestonk_terminal/stocks/technical_analysis/tradingview_model.py b/gamestonk_terminal/stocks/technical_analysis/tradingview_model.py new file mode 100644 index 00000000000..1bc05f5b9fe --- /dev/null +++ b/gamestonk_terminal/stocks/technical_analysis/tradingview_model.py @@ -0,0 +1,81 @@ +"""Tradingview model""" +__docformat__ = "numpy" + +import requests +from tradingview_ta import TA_Handler +import pandas as pd + +from gamestonk_terminal import config_terminal as cfg + +INTERVALS = { + "1m": "1 min", + "5m": "5 min", + "15m": "15 min", + "1h": "1 hour", + "4h": "4 hours", + "1d": "1 day", + "1W": "1 week", + "1M": "1 month", +} + + +def get_tradingview_recommendation( + ticker: str, screener: str, exchange: str, interval: str +) -> pd.DataFrame: + """Get tradingview recommendation based on technical indicators + + Parameters + ---------- + ticker : str + Ticker to get the recommendation from tradingview based on technical indicators + screener : str + Screener based on tradingview docs https://python-tradingview-ta.readthedocs.io/en/latest/usage.html + exchange: str + Exchange based on tradingview docs https://python-tradingview-ta.readthedocs.io/en/latest/usage.html + interval: str + Interval time to check technical indicators and correspondent recommendation + + Returns + ------- + df_recommendation: pd.DataFrame + Dataframe of tradingview recommendations based on technical indicators + """ + + if not exchange: + s_req = f"https://www.alphavantage.co/query?function=OVERVIEW&symbol={ticker}&apikey={cfg.API_KEY_ALPHAVANTAGE}" + result = requests.get(s_req, stream=True) + exchange = result.json()["Exchange"] + + if not interval: + df_recommendation = pd.DataFrame() + index_recommendation = list() + for interv in ["1M", "1W", "1d", "4h", "1h", "15m", "5m", "1m"]: + # If the returned data was successful + if result.status_code == 200: + stock_recommendation = TA_Handler( + symbol=ticker, + screener=screener, + exchange=exchange, + interval=interv, + ) + d_recommendation = stock_recommendation.get_analysis().summary + df_recommendation = df_recommendation.append( + d_recommendation, ignore_index=True + ) + index_recommendation.append(INTERVALS[interv]) + df_recommendation.index = index_recommendation + df_recommendation[["BUY", "NEUTRAL", "SELL"]] = df_recommendation[ + ["BUY", "NEUTRAL", "SELL"] + ].astype(int) + + df_recommendation.index.name = "Interval" + + else: + stock_recommendation = TA_Handler( + symbol=ticker, screener=screener, exchange=exchange, interval=interval + ) + d_recommendation = stock_recommendation.get_analysis().summary + df_recommendation = pd.DataFrame.from_dict(d_recommendation, orient="index").T + df_recommendation.index = INTERVALS[interv] + + return df_recommendation diff --git a/gamestonk_terminal/stocks/technical_analysis/tradingview_view.py b/gamestonk_terminal/stocks/technical_analysis/tradingview_view.py index 216f6bb6e46..11fb309b5d3 100644 --- a/gamestonk_terminal/stocks/technical_analysis/tradingview_view.py +++ b/gamestonk_terminal/stocks/technical_analysis/tradingview_view.py @@ -1,155 +1,47 @@ -import argparse -from typing import List -import requests -import pandas as pd -from tradingview_ta import TA_Handler +"""Tradingview view""" +__docformat__ = "numpy" -from gamestonk_terminal import config_terminal as cfg -from gamestonk_terminal.helper_funcs import ( - parse_known_args_and_warn, -) +import os -INTERVALS = { - "1m": "1 min", - "5m": "5 min", - "15m": "15 min", - "1h": "1 hour", - "4h": "4 hours", - "1d": "1 day", - "1W": "1 week", - "1M": "1 month", -} +from tabulate import tabulate + +from gamestonk_terminal.stocks.technical_analysis import tradingview_model +from gamestonk_terminal.helper_funcs import export_data -def get_tradingview_recommendation( - ticker: str, screener: str, exchange: str, interval: str -) -> str: - """Get tradingview recommendation based on technical indicators +def print_recommendation( + ticker: str, screener: str, exchange: str, interval: str, export: str +): + """Print tradingview recommendation based on technical indicators Parameters ---------- ticker : str - Ticker to get the recommendation from tradingview based on technical indicators + Ticker to get tradingview recommendation based on technical indicators screener : str Screener based on tradingview docs https://python-tradingview-ta.readthedocs.io/en/latest/usage.html exchange: str Exchange based on tradingview docs https://python-tradingview-ta.readthedocs.io/en/latest/usage.html interval: str Interval time to check technical indicators and correspondent recommendation - - Returns - ------- - str - tradingview recommendation based on technical indicators + export: str + Format of export file """ - if not exchange: - s_req = f"https://www.alphavantage.co/query?function=OVERVIEW&symbol={ticker}&apikey={cfg.API_KEY_ALPHAVANTAGE}" - result = requests.get(s_req, stream=True) - exchange = result.json()["Exchange"] - - if not interval: - df_recommendation = pd.DataFrame() - index_recommendation = list() - for interv in ["1M", "1W", "1d", "4h", "1h", "15m", "5m", "1m"]: - # If the returned data was successful - if result.status_code == 200: - stock_recommendation = TA_Handler( - symbol=ticker, - screener=screener, - exchange=exchange, - interval=interv, - ) - d_recommendation = stock_recommendation.get_analysis().summary - df_recommendation = df_recommendation.append( - d_recommendation, ignore_index=True - ) - index_recommendation.append(INTERVALS[interv]) - df_recommendation.index = index_recommendation - df_recommendation[["BUY", "NEUTRAL", "SELL"]] = df_recommendation[ - ["BUY", "NEUTRAL", "SELL"] - ].astype(int) - df_recommendation["-----"] = "-----" - df_recommendation.index.name = "Interval" - recommendation = df_recommendation[ - ["RECOMMENDATION", "-----", "BUY", "NEUTRAL", "SELL"] - ].to_string() - - else: - stock_recommendation = TA_Handler( - symbol=ticker, screener=screener, exchange=exchange, interval=interval - ) - d_recommendation = stock_recommendation.get_analysis().summary - recommendation = f"Interval: {INTERVALS[interval]}\n" - recommendation += f"Recommendation: {d_recommendation['RECOMMENDATION']}\n" - recommendation += f"{int(d_recommendation['BUY'])} BUY, {int(d_recommendation['NEUTRAL'])} NEUTRAL" - recommendation += f", {int(d_recommendation['SELL'])} SELL" - - return recommendation - - -def print_recommendation(other_args: List[str], ticker: str): - """Print tradingview recommendation based on technical indicators - - Parameters - ---------- - other_args : List[str] - Command line arguments to be processed with argparse - ticker : str - Ticker to get tradingview recommendation based on technical indicators - """ - parser = argparse.ArgumentParser( - add_help=False, - formatter_class=argparse.ArgumentDefaultsHelpFormatter, - prog="recom", - description=""" - Print tradingview recommendation based on technical indicators. - [Source: https://pypi.org/project/tradingview-ta/] - """, - ) - parser.add_argument( - "-s", - "--screener", - action="store", - dest="screener", - type=str, - default="america", - choices=["crypto", "forex", "cfd"], - help="Screener. See https://python-tradingview-ta.readthedocs.io/en/latest/usage.html", - ) - parser.add_argument( - "-e", - "--exchange", - action="store", - dest="exchange", - type=str, - default="", - help="""Set exchange. For Forex use: 'FX_IDC', and for crypto use 'TVC'. - See https://python-tradingview-ta.readthedocs.io/en/latest/usage.html. - By default Alpha Vantage tries to get this data from the ticker. """, - ) - parser.add_argument( - "-i", - "--interval", - action="store", - dest="interval", - type=str, - default="", - choices=["1M", "1W", "1d", "4h", "1h", "15m", "5m", "1m"], - help="""Interval, that corresponds to the recommendation given by tradingview based on technical indicators. - See https://python-tradingview-ta.readthedocs.io/en/latest/usage.html""", + recom = tradingview_model.get_tradingview_recommendation( + ticker, screener, exchange, interval ) - try: - ns_parser = parse_known_args_and_warn(parser, other_args) - if not ns_parser: - return + export_data( + export, + os.path.dirname(os.path.abspath(__file__)), + "recom", + recom, + ) - recom = get_tradingview_recommendation( - ticker, ns_parser.screener, ns_parser.exchange, ns_parser.interval - ) - print(recom) - print("") - - except Exception as e: - print(e, "\n") + print( + tabulate( + recom, headers=["INTERVAL"] + list(recom.columns), tablefmt="fancy_grid" + ), + "\n", + )