From c7daf13529e93b8058a90129dc3e6d423c90ea8b Mon Sep 17 00:00:00 2001 From: didier Date: Sun, 2 May 2021 02:28:41 +0100 Subject: [PATCH 01/13] Add pattern recognition to technical analysis --- .../technical_analysis/finhub_view.py | 206 ++++++++++++++++++ .../technical_analysis/ta_controller.py | 8 + 2 files changed, 214 insertions(+) create mode 100644 gamestonk_terminal/technical_analysis/finhub_view.py diff --git a/gamestonk_terminal/technical_analysis/finhub_view.py b/gamestonk_terminal/technical_analysis/finhub_view.py new file mode 100644 index 00000000000..3aa05d3eb28 --- /dev/null +++ b/gamestonk_terminal/technical_analysis/finhub_view.py @@ -0,0 +1,206 @@ +import argparse +from typing import List +import requests +import yfinance as yf +import mplfinance as mpf +import pandas as pd +import math +from gamestonk_terminal import config_terminal as cfg +from gamestonk_terminal.helper_funcs import ( + parse_known_args_and_warn, + plot_autoscale, +) + +from datetime import datetime + + +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, segments: List): + """Plot pattern recognition signal + + Parameters + ---------- + ticker : str + Ticker to display pattern recognition on top of the data + pattern : pd.DataFrame + Pattern recognition signal data + segments : List + Segment lines that indicates some pattern signal in data + """ + + start_time = 999999999999 + for i in pattern: + if pattern[i]["atime"] < start_time: + start_time = pattern[i]["atime"] + + df_stock = yf.download( + ticker, + 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]" + ) + df_stock["date_id"] = df_stock["date_id"].dt.days + 1 + + df_stock["OC_High"] = df_stock[["Open", "Close"]].max(axis=1) + df_stock["OC_Low"] = df_stock[["Open", "Close"]].min(axis=1) + + mc = mpf.make_marketcolors( + up="green", down="red", edge="black", wick="black", volume="in", ohlc="i" + ) + + s = mpf.make_mpf_style(marketcolors=mc, gridstyle=":", y_on_right=False) + + mpf.plot( + df_stock, + type="candle", + volume=False, + title=f"\n{ticker}", + alines=segments, + xrotation=10, + style=s, + figratio=(10, 7), + figscale=1.10, + figsize=plot_autoscale(), + update_width_config=dict( + candle_linewidth=1.0, candle_width=0.8, volume_linewidth=1.0 + ), + ) + + +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, + 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 + + l_segments = list() + for i in df_pattern: + a_part = "" + if "aprice" in df_pattern[i]: + if df_pattern[i]["aprice"] != 0 and not math.isnan( + df_pattern[i]["aprice"] + ): + a_part = ( + datetime.utcfromtimestamp(df_pattern[i]["atime"]).strftime( + "%Y-%m-%d" + ), + df_pattern[i]["aprice"], + ) + + b_part = "" + if "bprice" in df_pattern[i]: + if df_pattern[i]["bprice"] != 0 and not math.isnan( + df_pattern[i]["bprice"] + ): + b_part = ( + datetime.utcfromtimestamp(df_pattern[i]["btime"]).strftime( + "%Y-%m-%d" + ), + df_pattern[i]["bprice"], + ) + + c_part = "" + if "cprice" in df_pattern[i]: + if df_pattern[i]["cprice"] != 0 and not math.isnan( + df_pattern[i]["cprice"] + ): + c_part = ( + datetime.utcfromtimestamp(df_pattern[i]["ctime"]).strftime( + "%Y-%m-%d" + ), + df_pattern[i]["cprice"], + ) + + d_part = "" + if "dprice" in df_pattern[i]: + if df_pattern[i]["dprice"] != 0 and not math.isnan( + df_pattern[i]["dprice"] + ): + d_part = ( + datetime.utcfromtimestamp(df_pattern[i]["dtime"]).strftime( + "%Y-%m-%d" + ), + df_pattern[i]["dprice"], + ) + + segment = (a_part, b_part, c_part, d_part) + + l_segment = list(segment) + while "" in l_segment: + l_segment.remove("") + segment = tuple(l_segment) + + l_segments.append(segment) + + plot_pattern_recognition(ticker, df_pattern, l_segments) + + for ix in range(len(df_pattern.columns)): + print(f"From {l_segments[ix][0][0]} to {l_segments[ix][-1][0]}") + print( + f"Pattern: {df_pattern[0]['patternname']} ({df_pattern[0]['patterntype']})" + ) + print("") + + except Exception as e: + print(e, "\n") diff --git a/gamestonk_terminal/technical_analysis/ta_controller.py b/gamestonk_terminal/technical_analysis/ta_controller.py index 620e13ab55f..685d4b104fa 100644 --- a/gamestonk_terminal/technical_analysis/ta_controller.py +++ b/gamestonk_terminal/technical_analysis/ta_controller.py @@ -20,6 +20,7 @@ from gamestonk_terminal.technical_analysis import volume as ta_volume from gamestonk_terminal.technical_analysis import finbrain_view from gamestonk_terminal.technical_analysis import tradingview_view from gamestonk_terminal.technical_analysis import finviz_view +from gamestonk_terminal.technical_analysis import finhub_view class TechnicalAnalysisController: @@ -33,6 +34,7 @@ class TechnicalAnalysisController: "view", "summary", "recom", + "pr", "ema", "sma", "vwap", @@ -88,6 +90,8 @@ class TechnicalAnalysisController: print( " recom recommendation based on Technical Indicators [Tradingview API]" ) + print(" pr pattern recognition [Finhub]") + print("") print("overlap:") print(" ema exponential moving average") print(" sma simple moving average") @@ -157,6 +161,10 @@ class TechnicalAnalysisController: """Process recom command""" tradingview_view.print_recommendation(other_args, self.ticker) + def call_pr(self, other_args: List[str]): + """Process pr command""" + finhub_view.pattern_recognition_view(other_args, self.ticker) + # OVERLAP def call_ema(self, other_args: List[str]): """Process ema command""" From cab21e566aeaf18b5a9852cee1a4610964aaec87 Mon Sep 17 00:00:00 2001 From: didier Date: Sun, 2 May 2021 12:29:00 +0100 Subject: [PATCH 02/13] fix mypy --- .../technical_analysis/finhub_view.py | 124 ++++++++---------- 1 file changed, 52 insertions(+), 72 deletions(-) diff --git a/gamestonk_terminal/technical_analysis/finhub_view.py b/gamestonk_terminal/technical_analysis/finhub_view.py index 3aa05d3eb28..9dd06f4d756 100644 --- a/gamestonk_terminal/technical_analysis/finhub_view.py +++ b/gamestonk_terminal/technical_analysis/finhub_view.py @@ -1,5 +1,5 @@ import argparse -from typing import List +from typing import List, Any import requests import yfinance as yf import mplfinance as mpf @@ -40,7 +40,7 @@ def get_pattern_recognition(ticker: str, resolution: str) -> pd.DataFrame: return pd.DataFrame() -def plot_pattern_recognition(ticker: str, pattern: pd.DataFrame, segments: List): +def plot_pattern_recognition(ticker: str, pattern: pd.DataFrame): """Plot pattern recognition signal Parameters @@ -49,10 +49,51 @@ def plot_pattern_recognition(ticker: str, pattern: pd.DataFrame, segments: List) Ticker to display pattern recognition on top of the data pattern : pd.DataFrame Pattern recognition signal data - segments : List - Segment lines that indicates some pattern signal in data """ + l_segments = list() + for i in pattern: + a_part = "" + if "aprice" in pattern[i]: + if pattern[i]["aprice"] != 0 and not math.isnan(pattern[i]["aprice"]): + a_part = ( + datetime.utcfromtimestamp(pattern[i]["atime"]).strftime("%Y-%m-%d"), + pattern[i]["aprice"], + ) + + b_part = "" + if "bprice" in pattern[i]: + if pattern[i]["bprice"] != 0 and not math.isnan(pattern[i]["bprice"]): + b_part = ( + datetime.utcfromtimestamp(pattern[i]["btime"]).strftime("%Y-%m-%d"), + pattern[i]["bprice"], + ) + + c_part = "" + if "cprice" in pattern[i]: + if pattern[i]["cprice"] != 0 and not math.isnan(pattern[i]["cprice"]): + c_part = ( + datetime.utcfromtimestamp(pattern[i]["ctime"]).strftime("%Y-%m-%d"), + pattern[i]["cprice"], + ) + + d_part = "" + if "dprice" in pattern[i]: + if pattern[i]["dprice"] != 0 and not math.isnan(pattern[i]["dprice"]): + d_part = ( + datetime.utcfromtimestamp(pattern[i]["dtime"]).strftime("%Y-%m-%d"), + pattern[i]["dprice"], + ) + + segment = (a_part, b_part, c_part, d_part) + + l_segment = list(segment) + while "" in l_segment: + l_segment.remove("") + segment = tuple(l_segment) + + l_segments.append(segment) + start_time = 999999999999 for i in pattern: if pattern[i]["atime"] < start_time: @@ -83,7 +124,7 @@ def plot_pattern_recognition(ticker: str, pattern: pd.DataFrame, segments: List) type="candle", volume=False, title=f"\n{ticker}", - alines=segments, + alines=l_segments, xrotation=10, style=s, figratio=(10, 7), @@ -94,6 +135,11 @@ def plot_pattern_recognition(ticker: str, pattern: pd.DataFrame, segments: List) ), ) + for ix in range(len(pattern.columns)): + print(f"From {l_segments[ix][0][0]} to {l_segments[ix][-1][0]}") + print(f"Pattern: {pattern[0]['patternname']} ({pattern[0]['patterntype']})") + print("") + def pattern_recognition_view(other_args: List[str], ticker: str): """Display pattern recognition signals on the data @@ -134,73 +180,7 @@ def pattern_recognition_view(other_args: List[str], ticker: str): print("No pattern identified in this data", "\n") return - l_segments = list() - for i in df_pattern: - a_part = "" - if "aprice" in df_pattern[i]: - if df_pattern[i]["aprice"] != 0 and not math.isnan( - df_pattern[i]["aprice"] - ): - a_part = ( - datetime.utcfromtimestamp(df_pattern[i]["atime"]).strftime( - "%Y-%m-%d" - ), - df_pattern[i]["aprice"], - ) - - b_part = "" - if "bprice" in df_pattern[i]: - if df_pattern[i]["bprice"] != 0 and not math.isnan( - df_pattern[i]["bprice"] - ): - b_part = ( - datetime.utcfromtimestamp(df_pattern[i]["btime"]).strftime( - "%Y-%m-%d" - ), - df_pattern[i]["bprice"], - ) - - c_part = "" - if "cprice" in df_pattern[i]: - if df_pattern[i]["cprice"] != 0 and not math.isnan( - df_pattern[i]["cprice"] - ): - c_part = ( - datetime.utcfromtimestamp(df_pattern[i]["ctime"]).strftime( - "%Y-%m-%d" - ), - df_pattern[i]["cprice"], - ) - - d_part = "" - if "dprice" in df_pattern[i]: - if df_pattern[i]["dprice"] != 0 and not math.isnan( - df_pattern[i]["dprice"] - ): - d_part = ( - datetime.utcfromtimestamp(df_pattern[i]["dtime"]).strftime( - "%Y-%m-%d" - ), - df_pattern[i]["dprice"], - ) - - segment = (a_part, b_part, c_part, d_part) - - l_segment = list(segment) - while "" in l_segment: - l_segment.remove("") - segment = tuple(l_segment) - - l_segments.append(segment) - - plot_pattern_recognition(ticker, df_pattern, l_segments) - - for ix in range(len(df_pattern.columns)): - print(f"From {l_segments[ix][0][0]} to {l_segments[ix][-1][0]}") - print( - f"Pattern: {df_pattern[0]['patternname']} ({df_pattern[0]['patterntype']})" - ) - print("") + plot_pattern_recognition(ticker, df_pattern) except Exception as e: print(e, "\n") From c4b87531ad74976cf6e76cec5ab849416600bfc3 Mon Sep 17 00:00:00 2001 From: didier Date: Sun, 2 May 2021 12:30:38 +0100 Subject: [PATCH 03/13] remove unused import --- gamestonk_terminal/technical_analysis/finhub_view.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gamestonk_terminal/technical_analysis/finhub_view.py b/gamestonk_terminal/technical_analysis/finhub_view.py index 9dd06f4d756..dc4aa570078 100644 --- a/gamestonk_terminal/technical_analysis/finhub_view.py +++ b/gamestonk_terminal/technical_analysis/finhub_view.py @@ -1,5 +1,5 @@ import argparse -from typing import List, Any +from typing import List import requests import yfinance as yf import mplfinance as mpf From 153a8ce9fd5e317975973a5922a9f8d474e3cbce Mon Sep 17 00:00:00 2001 From: didier Date: Sun, 2 May 2021 12:33:15 +0100 Subject: [PATCH 04/13] add finhub config key --- gamestonk_terminal/config_terminal.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/gamestonk_terminal/config_terminal.py b/gamestonk_terminal/config_terminal.py index dd4092eb45d..a3405ed207e 100644 --- a/gamestonk_terminal/config_terminal.py +++ b/gamestonk_terminal/config_terminal.py @@ -33,7 +33,7 @@ API_TWITTER_SECRET_KEY = os.getenv("GT_API_TWITTER_SECRET_KEY") or "REPLACE_ME" API_TWITTER_BEARER_TOKEN = os.getenv("GT_API_TWITTER_BEARER_TOKEN") or "REPLACE_ME" # https://fred.stlouisfed.org/docs/api/api_key.html -API_FRED_KEY = os.getenv("GT_FRED_API_KEY") or "REPLACE_ME" +API_FRED_KEY = os.getenv("GT_FRED_API_KEY") or "b98e15f1fde39212bce9213f2e3e5afb" # https://newsapi.org API_NEWS_TOKEN = os.getenv("GT_API_NEWS_TOKEN") or "REPLACE_ME" @@ -59,3 +59,6 @@ PATH_TO_SELENIUM_DRIVER = None # Replace with "PATH" # https://coinmarketcap.com/api/ COINMARKETCAP_KEY = os.getenv("GT_CMC_API_KEY") or "REPLACE_ME" + +# https://finnhub.io +API_FINNHUB_KEY = os.getenv("GT_API_FINNHUB_KEY") or "REPLACE_ME" \ No newline at end of file From 9c32da41a981fd4d79e65a3c9f8cd0f396d3dffc Mon Sep 17 00:00:00 2001 From: didier Date: Sun, 2 May 2021 12:36:33 +0100 Subject: [PATCH 05/13] cmon black, we got this --- gamestonk_terminal/config_terminal.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gamestonk_terminal/config_terminal.py b/gamestonk_terminal/config_terminal.py index a3405ed207e..3dfa270ae34 100644 --- a/gamestonk_terminal/config_terminal.py +++ b/gamestonk_terminal/config_terminal.py @@ -61,4 +61,4 @@ PATH_TO_SELENIUM_DRIVER = None # Replace with "PATH" COINMARKETCAP_KEY = os.getenv("GT_CMC_API_KEY") or "REPLACE_ME" # https://finnhub.io -API_FINNHUB_KEY = os.getenv("GT_API_FINNHUB_KEY") or "REPLACE_ME" \ No newline at end of file +API_FINNHUB_KEY = os.getenv("GT_API_FINNHUB_KEY") or "REPLACE_ME" From a3614fb3b7ea56921b6845514786a36d4260675b Mon Sep 17 00:00:00 2001 From: didier Date: Sun, 2 May 2021 12:41:34 +0100 Subject: [PATCH 06/13] fix incompatible type mypy --- .../technical_analysis/finhub_view.py | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/gamestonk_terminal/technical_analysis/finhub_view.py b/gamestonk_terminal/technical_analysis/finhub_view.py index dc4aa570078..6c700b7b12d 100644 --- a/gamestonk_terminal/technical_analysis/finhub_view.py +++ b/gamestonk_terminal/technical_analysis/finhub_view.py @@ -53,37 +53,49 @@ def plot_pattern_recognition(ticker: str, pattern: pd.DataFrame): l_segments = list() for i in pattern: - a_part = "" if "aprice" in pattern[i]: if pattern[i]["aprice"] != 0 and not math.isnan(pattern[i]["aprice"]): a_part = ( datetime.utcfromtimestamp(pattern[i]["atime"]).strftime("%Y-%m-%d"), pattern[i]["aprice"], ) + else: + a_part = "" + else: + a_part = "" - b_part = "" if "bprice" in pattern[i]: if pattern[i]["bprice"] != 0 and not math.isnan(pattern[i]["bprice"]): b_part = ( datetime.utcfromtimestamp(pattern[i]["btime"]).strftime("%Y-%m-%d"), pattern[i]["bprice"], ) + else: + b_part = "" + else: + b_part = "" - c_part = "" if "cprice" in pattern[i]: if pattern[i]["cprice"] != 0 and not math.isnan(pattern[i]["cprice"]): c_part = ( datetime.utcfromtimestamp(pattern[i]["ctime"]).strftime("%Y-%m-%d"), pattern[i]["cprice"], ) + else: + c_part = "" + else: + c_part = "" - d_part = "" if "dprice" in pattern[i]: if pattern[i]["dprice"] != 0 and not math.isnan(pattern[i]["dprice"]): d_part = ( datetime.utcfromtimestamp(pattern[i]["dtime"]).strftime("%Y-%m-%d"), pattern[i]["dprice"], ) + else: + d_part = "" + else: + d_part = "" segment = (a_part, b_part, c_part, d_part) From 8ff6e2903c5391ee61fd3882c0233507e5b8fba0 Mon Sep 17 00:00:00 2001 From: didier Date: Sun, 2 May 2021 12:50:47 +0100 Subject: [PATCH 07/13] can I breath now mypy? --- .../technical_analysis/finhub_view.py | 28 ++++++------------- 1 file changed, 8 insertions(+), 20 deletions(-) diff --git a/gamestonk_terminal/technical_analysis/finhub_view.py b/gamestonk_terminal/technical_analysis/finhub_view.py index 6c700b7b12d..85c588aba76 100644 --- a/gamestonk_terminal/technical_analysis/finhub_view.py +++ b/gamestonk_terminal/technical_analysis/finhub_view.py @@ -53,58 +53,46 @@ def plot_pattern_recognition(ticker: str, pattern: pd.DataFrame): l_segments = list() for i in pattern: + a_part = ("", "") if "aprice" in pattern[i]: if pattern[i]["aprice"] != 0 and not math.isnan(pattern[i]["aprice"]): a_part = ( datetime.utcfromtimestamp(pattern[i]["atime"]).strftime("%Y-%m-%d"), pattern[i]["aprice"], ) - else: - a_part = "" - else: - a_part = "" + b_part = ("", "") if "bprice" in pattern[i]: if pattern[i]["bprice"] != 0 and not math.isnan(pattern[i]["bprice"]): b_part = ( datetime.utcfromtimestamp(pattern[i]["btime"]).strftime("%Y-%m-%d"), pattern[i]["bprice"], ) - else: - b_part = "" - else: - b_part = "" + c_part = ("", "") if "cprice" in pattern[i]: if pattern[i]["cprice"] != 0 and not math.isnan(pattern[i]["cprice"]): c_part = ( datetime.utcfromtimestamp(pattern[i]["ctime"]).strftime("%Y-%m-%d"), pattern[i]["cprice"], ) - else: - c_part = "" - else: - c_part = "" + d_part = ("", "") if "dprice" in pattern[i]: if pattern[i]["dprice"] != 0 and not math.isnan(pattern[i]["dprice"]): d_part = ( datetime.utcfromtimestamp(pattern[i]["dtime"]).strftime("%Y-%m-%d"), pattern[i]["dprice"], ) - else: - d_part = "" - else: - d_part = "" segment = (a_part, b_part, c_part, d_part) l_segment = list(segment) - while "" in l_segment: - l_segment.remove("") - segment = tuple(l_segment) + while ("", "") in l_segment: + l_segment.remove(("", "")) + segm = tuple(l_segment) - l_segments.append(segment) + l_segments.append(segm) start_time = 999999999999 for i in pattern: From a8b5ee8a210888fc47b458b00e0c45960ac4f872 Mon Sep 17 00:00:00 2001 From: didier Date: Sun, 2 May 2021 12:53:19 +0100 Subject: [PATCH 08/13] imports order fixed --- gamestonk_terminal/technical_analysis/finhub_view.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gamestonk_terminal/technical_analysis/finhub_view.py b/gamestonk_terminal/technical_analysis/finhub_view.py index 85c588aba76..67db2b88951 100644 --- a/gamestonk_terminal/technical_analysis/finhub_view.py +++ b/gamestonk_terminal/technical_analysis/finhub_view.py @@ -1,18 +1,17 @@ import argparse from typing import List +import math +from datetime import datetime import requests import yfinance as yf import mplfinance as mpf import pandas as pd -import math from gamestonk_terminal import config_terminal as cfg from gamestonk_terminal.helper_funcs import ( parse_known_args_and_warn, plot_autoscale, ) -from datetime import datetime - def get_pattern_recognition(ticker: str, resolution: str) -> pd.DataFrame: """Get pattern recognition data From 20e3e0f86d6b2fad69f17593f095aecad10ce83e Mon Sep 17 00:00:00 2001 From: DidierRLopes Date: Sun, 2 May 2021 13:05:48 +0100 Subject: [PATCH 09/13] Update README.md --- gamestonk_terminal/technical_analysis/README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/gamestonk_terminal/technical_analysis/README.md b/gamestonk_terminal/technical_analysis/README.md index 0e5c511d850..8ee5d86bf73 100644 --- a/gamestonk_terminal/technical_analysis/README.md +++ b/gamestonk_terminal/technical_analysis/README.md @@ -8,6 +8,8 @@ This menu aims to perform a technical analysis on a pre-loaded ticker chart, and - technical summary report [FinBrain API] * [recom](#recom) - recommendation based on Technical Indicators [Tradingview API] + * [pr](#pr) + - pattern recognition [Finhub] [OVERLAP](#OVERLAP) * [ema](#ema) @@ -79,6 +81,19 @@ Print tradingview recommendation based on technical indicators. [Source: https:/ Captura de ecrã 2021-03-31, às 00 14 41 +## pr +``` +usage: pr [-r {1,5,15,30,60,D,W,M}] +``` +Display pattern recognition signals on the data. [Source: https://finnhub.io] + +* -r : Plot resolution to look for pattern signals. Default 'D'. + +![pr](https://user-images.githubusercontent.com/25267873/116812520-06338700-ab47-11eb-8db4-8f5e940507ed.png) + +Captura de ecrã 2021-05-02, às 02 27 10 + + # OVERLAP ## ema From 83aa19e8c2f21c50a6b8e3860c9e9314823b6150 Mon Sep 17 00:00:00 2001 From: DidierRLopes Date: Sun, 2 May 2021 13:07:09 +0100 Subject: [PATCH 10/13] Update README.md --- gamestonk_terminal/README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/gamestonk_terminal/README.md b/gamestonk_terminal/README.md index 5034728b90c..f1c79fdbaef 100644 --- a/gamestonk_terminal/README.md +++ b/gamestonk_terminal/README.md @@ -183,6 +183,7 @@ Command | Description | Sources `view` | view historical data and trendlines| [Finviz](https://finviz.com/quote.ashx?t=tsla) `summary` | technical summary report| [FinBrain](https://finbrain.tech) `recom` | recommendation based on Technical Indicators| [Tradingview](https://uk.tradingview.com/widget/technical-analysis/) +`pr` | pattern recognition| [Finhub](https://finnhub.io) [overlap](https://github.com/twopirllc/pandas-ta/tree/master/pandas_ta/overlap) | `ema` | exponential moving average | [Wikipedia](https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average), [Investopedia](https://www.investopedia.com/terms/e/ema.asp) `sma` |simple moving average | [Wikipedia](https://en.wikipedia.org/wiki/Moving_average#Simple_moving_average_(boxcar_filter)), [Investopedia](https://www.investopedia.com/terms/s/sma.asp) From 94da5e4199326c673ec5213253b37703b924300c Mon Sep 17 00:00:00 2001 From: DidierRLopes Date: Sun, 2 May 2021 13:08:56 +0100 Subject: [PATCH 11/13] Update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 4e558e73cf5..55fbedbf1f2 100644 --- a/README.md +++ b/README.md @@ -227,10 +227,11 @@ These are the ones where a key is necessary: * Tradier: https://developer.tradier.com/getting_started * Oanda API: https://developer.oanda.com * CoinMarketCap API: https://coinmarketcap.com/api/ + * Finhub API: https://finnhub.io When these are obtained, don't forget to update [config_terminal.py](/gamestonk_terminal/config_terminal.py). -Alternatively, you can also set them to the following environment variables: GT_API_KEY_ALPHAVANTAGE, GT_API_KEY_FINANCIALMODELINGPREP, GT_API_KEY_QUANDL, GT_API_REDDIT_CLIENT_ID, GT_API_REDDIT_CLIENT_SECRET, GT_API_REDDIT_USERNAME, GT_API_REDDIT_USER_AGENT, GT_API_REDDIT_PASSWORD, GT_API_TWITTER_KEY, GT_API_TWITTER_SECRET_KEY, GT_API_TWITTER_BEARER_TOKEN, GT_API_POLYGON_KEY, GT_FRED_API_KEY, GT_API_NEWS_TOKEN, GT_OANDA_TOKEN, GT_OANDA_ACCOUNT, GT_TRADIER_TOKEN, GT_CMC_API_KEY. +Alternatively, you can also set them to the following environment variables: GT_API_KEY_ALPHAVANTAGE, GT_API_KEY_FINANCIALMODELINGPREP, GT_API_KEY_QUANDL, GT_API_REDDIT_CLIENT_ID, GT_API_REDDIT_CLIENT_SECRET, GT_API_REDDIT_USERNAME, GT_API_REDDIT_USER_AGENT, GT_API_REDDIT_PASSWORD, GT_API_TWITTER_KEY, GT_API_TWITTER_SECRET_KEY, GT_API_TWITTER_BEARER_TOKEN, GT_API_POLYGON_KEY, GT_FRED_API_KEY, GT_API_NEWS_TOKEN, GT_OANDA_TOKEN, GT_OANDA_ACCOUNT, GT_TRADIER_TOKEN, GT_CMC_API_KEY, GT_CMC_API_KEY, API_FINNHUB_KEY. Example: ``` From e1151640f58756713eca01368dbdb539d1eadae4 Mon Sep 17 00:00:00 2001 From: DidierRLopes Date: Sun, 2 May 2021 13:09:49 +0100 Subject: [PATCH 12/13] Update ROADMAP.md --- ROADMAP.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ROADMAP.md b/ROADMAP.md index f872efde669..37c69ea2cb1 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -78,9 +78,10 @@ * [x] Add technical summary report provided by FinBrain (@didier) - [PR #294](https://github.com/DidierRLopes/GamestonkTerminal/pull/294) * [x] Add recommendation based on technical indicators from Tradingview (@didier) - [PR #301](https://github.com/DidierRLopes/GamestonkTerminal/pull/301) * [x] Add view of stock historical price with trendlines (support, resistance) by Finviz (@didier) - [PR #317](https://github.com/DidierRLopes/GamestonkTerminal/pull/317) +* [x] Add auto-recognition of major TA patterns (@didier) - [PR #429](https://github.com/DidierRLopes/GamestonkTerminal/pull/429) **NEXT** -* [ ] Add auto-recognition of major TA patterns (@didier) + --- From 162a611973c3dced7edd2e69c8e4b97adb5d75ae Mon Sep 17 00:00:00 2001 From: didier Date: Sun, 2 May 2021 22:17:03 +0100 Subject: [PATCH 13/13] fix finnhub naming --- gamestonk_terminal/README.md | 4 ++-- gamestonk_terminal/technical_analysis/README.md | 2 +- .../technical_analysis/{finhub_view.py => finnhub_view.py} | 0 gamestonk_terminal/technical_analysis/ta_controller.py | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) rename gamestonk_terminal/technical_analysis/{finhub_view.py => finnhub_view.py} (100%) diff --git a/gamestonk_terminal/README.md b/gamestonk_terminal/README.md index f1c79fdbaef..e314b341ba2 100644 --- a/gamestonk_terminal/README.md +++ b/gamestonk_terminal/README.md @@ -183,7 +183,7 @@ Command | Description | Sources `view` | view historical data and trendlines| [Finviz](https://finviz.com/quote.ashx?t=tsla) `summary` | technical summary report| [FinBrain](https://finbrain.tech) `recom` | recommendation based on Technical Indicators| [Tradingview](https://uk.tradingview.com/widget/technical-analysis/) -`pr` | pattern recognition| [Finhub](https://finnhub.io) +`pr` | pattern recognition| [Finnhub](https://finnhub.io) [overlap](https://github.com/twopirllc/pandas-ta/tree/master/pandas_ta/overlap) | `ema` | exponential moving average | [Wikipedia](https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average), [Investopedia](https://www.investopedia.com/terms/e/ema.asp) `sma` |simple moving average | [Wikipedia](https://en.wikipedia.org/wiki/Moving_average#Simple_moving_average_(boxcar_filter)), [Investopedia](https://www.investopedia.com/terms/s/sma.asp) @@ -398,7 +398,7 @@ positionbook |display the positionbook if Oanda provides one for the forex instr Command|Description ------ | -------- `ema` | buy when price exceeds EMA(l) -`ema_cross` | buy when EMA(short) > EMA(long) +`ema_cross` | buy when EMA(short) > EMA(long) `rsi` | buy when RSI < low and sell when RSI > high diff --git a/gamestonk_terminal/technical_analysis/README.md b/gamestonk_terminal/technical_analysis/README.md index 8ee5d86bf73..aa5ca8a0fe6 100644 --- a/gamestonk_terminal/technical_analysis/README.md +++ b/gamestonk_terminal/technical_analysis/README.md @@ -9,7 +9,7 @@ This menu aims to perform a technical analysis on a pre-loaded ticker chart, and * [recom](#recom) - recommendation based on Technical Indicators [Tradingview API] * [pr](#pr) - - pattern recognition [Finhub] + - pattern recognition [Finnhub] [OVERLAP](#OVERLAP) * [ema](#ema) diff --git a/gamestonk_terminal/technical_analysis/finhub_view.py b/gamestonk_terminal/technical_analysis/finnhub_view.py similarity index 100% rename from gamestonk_terminal/technical_analysis/finhub_view.py rename to gamestonk_terminal/technical_analysis/finnhub_view.py diff --git a/gamestonk_terminal/technical_analysis/ta_controller.py b/gamestonk_terminal/technical_analysis/ta_controller.py index 685d4b104fa..2d48fced7d9 100644 --- a/gamestonk_terminal/technical_analysis/ta_controller.py +++ b/gamestonk_terminal/technical_analysis/ta_controller.py @@ -20,7 +20,7 @@ from gamestonk_terminal.technical_analysis import volume as ta_volume from gamestonk_terminal.technical_analysis import finbrain_view from gamestonk_terminal.technical_analysis import tradingview_view from gamestonk_terminal.technical_analysis import finviz_view -from gamestonk_terminal.technical_analysis import finhub_view +from gamestonk_terminal.technical_analysis import finnhub_view class TechnicalAnalysisController: @@ -90,7 +90,7 @@ class TechnicalAnalysisController: print( " recom recommendation based on Technical Indicators [Tradingview API]" ) - print(" pr pattern recognition [Finhub]") + print(" pr pattern recognition [Finnhub]") print("") print("overlap:") print(" ema exponential moving average") @@ -163,7 +163,7 @@ class TechnicalAnalysisController: def call_pr(self, other_args: List[str]): """Process pr command""" - finhub_view.pattern_recognition_view(other_args, self.ticker) + finnhub_view.pattern_recognition_view(other_args, self.ticker) # OVERLAP def call_ema(self, other_args: List[str]):