From 9f51c88ec44e66f27bb93c573071bdfebce98905 Mon Sep 17 00:00:00 2001 From: devwolff <62347426+devwolff@users.noreply.github.com> Date: Thu, 26 Aug 2021 07:56:57 +1000 Subject: [PATCH] add offset feature to all filters (#715) * add offset feature to all filters * . * fix wrong arguments * . --- .../technical_analysis/overlap_model.py | 81 ++++++----- .../common/technical_analysis/overlap_view.py | 25 ++-- .../technical_analysis/ta_controller.py | 52 ++++++- .../technical_analysis/ta_controller.py | 137 ++++++++++-------- 4 files changed, 183 insertions(+), 112 deletions(-) diff --git a/gamestonk_terminal/common/technical_analysis/overlap_model.py b/gamestonk_terminal/common/technical_analysis/overlap_model.py index 13bdf816032..ac74e6c6d61 100644 --- a/gamestonk_terminal/common/technical_analysis/overlap_model.py +++ b/gamestonk_terminal/common/technical_analysis/overlap_model.py @@ -5,7 +5,9 @@ import pandas as pd import pandas_ta as ta -def ema(s_interval: str, df_stock: pd.DataFrame, window_length: int) -> pd.DataFrame: +def ema( + s_interval: str, df_stock: pd.DataFrame, length: int, offset: int +) -> pd.DataFrame: """Gets exponential moving average (EMA) for stock Parameters @@ -14,8 +16,10 @@ def ema(s_interval: str, df_stock: pd.DataFrame, window_length: int) -> pd.DataF Data interval df_stock: pd.DataFrame Dataframe of dates and prices - window_length: int + length: int Length of EMA window + offset: int + Length of offset Returns ---------- @@ -24,19 +28,18 @@ def ema(s_interval: str, df_stock: pd.DataFrame, window_length: int) -> pd.DataF """ # Daily if s_interval == "1440min": - df_ta = ta.ema(df_stock["Adj Close"], length=window_length).dropna() + df_ta = ta.ema(df_stock["Adj Close"], length=length, offset=offset).dropna() # Intraday else: - df_ta = ta.ema( - df_stock["Close"], - length=window_length, - ).dropna() + df_ta = ta.ema(df_stock["Close"], length=length, offset=offset).dropna() return pd.DataFrame(df_ta) -def sma(s_interval: str, df_stock: pd.DataFrame, window_length: int) -> pd.DataFrame: +def sma( + s_interval: str, df_stock: pd.DataFrame, length: int, offset: int +) -> pd.DataFrame: """Gets simple moving average (EMA) for stock Parameters @@ -45,8 +48,10 @@ def sma(s_interval: str, df_stock: pd.DataFrame, window_length: int) -> pd.DataF Data interval df_stock: pd.DataFrame Dataframe of dates and prices - window_length: int + length: int Length of SMA window + offset: int + Length of offset Returns ---------- @@ -55,19 +60,18 @@ def sma(s_interval: str, df_stock: pd.DataFrame, window_length: int) -> pd.DataF """ # Daily if s_interval == "1440min": - df_ta = ta.sma(df_stock["Adj Close"], length=window_length).dropna() + df_ta = ta.sma(df_stock["Adj Close"], length=length, offset=offset).dropna() # Intraday else: - df_ta = ta.sma( - df_stock["Close"], - length=window_length, - ).dropna() + df_ta = ta.sma(df_stock["Close"], length=length, offset=offset).dropna() return pd.DataFrame(df_ta) -def wma(s_interval: str, df_stock: pd.DataFrame, window_length: int) -> pd.DataFrame: +def wma( + s_interval: str, df_stock: pd.DataFrame, length: int, offset: int +) -> pd.DataFrame: """Gets weighted moving average (WMA) for stock Parameters @@ -76,8 +80,10 @@ def wma(s_interval: str, df_stock: pd.DataFrame, window_length: int) -> pd.DataF Data interval df_stock: pd.DataFrame Dataframe of dates and prices - window_length: int + length: int Length of SMA window + offset: int + Length of offset Returns ---------- @@ -86,19 +92,18 @@ def wma(s_interval: str, df_stock: pd.DataFrame, window_length: int) -> pd.DataF """ # Daily if s_interval == "1440min": - df_ta = ta.wma(df_stock["Adj Close"], length=window_length).dropna() + df_ta = ta.wma(df_stock["Adj Close"], length=length, offset=offset).dropna() # Intraday else: - df_ta = ta.wma( - df_stock["Close"], - length=window_length, - ).dropna() + df_ta = ta.wma(df_stock["Close"], length=length, offset=offset).dropna() return pd.DataFrame(df_ta) -def hma(s_interval: str, df_stock: pd.DataFrame, window_length: int) -> pd.DataFrame: +def hma( + s_interval: str, df_stock: pd.DataFrame, length: int, offset: int +) -> pd.DataFrame: """Gets hull moving average (HMA) for stock Parameters @@ -107,8 +112,10 @@ def hma(s_interval: str, df_stock: pd.DataFrame, window_length: int) -> pd.DataF Data interval df_stock: pd.DataFrame Dataframe of dates and prices - window_length: int + length: int Length of SMA window + offset: int + Length of offset Returns ---------- @@ -117,19 +124,18 @@ def hma(s_interval: str, df_stock: pd.DataFrame, window_length: int) -> pd.DataF """ # Daily if s_interval == "1440min": - df_ta = ta.hma(df_stock["Adj Close"], length=window_length).dropna() + df_ta = ta.hma(df_stock["Adj Close"], length=length, offset=offset).dropna() # Intraday else: - df_ta = ta.hma( - df_stock["Close"], - length=window_length, - ).dropna() + df_ta = ta.hma(df_stock["Close"], length=length, offset=offset).dropna() return pd.DataFrame(df_ta) -def zlma(s_interval: str, df_stock: pd.DataFrame, window_length: int) -> pd.DataFrame: +def zlma( + s_interval: str, df_stock: pd.DataFrame, length: int, offset: int +) -> pd.DataFrame: """Gets zero-lagged exponential moving average (ZLEMA) for stock Parameters @@ -138,8 +144,10 @@ def zlma(s_interval: str, df_stock: pd.DataFrame, window_length: int) -> pd.Data Data interval df_stock: pd.DataFrame Dataframe of dates and prices - window_length: int + length: int Length of EMA window + offset: int + Length of offset Returns ---------- @@ -148,26 +156,24 @@ def zlma(s_interval: str, df_stock: pd.DataFrame, window_length: int) -> pd.Data """ # Daily if s_interval == "1440min": - df_ta = ta.zlma(df_stock["Adj Close"], length=window_length).dropna() + df_ta = ta.zlma(df_stock["Adj Close"], length=length, offset=offset).dropna() # Intraday else: - df_ta = ta.zlma( - df_stock["Close"], - length=window_length, - ).dropna() + df_ta = ta.zlma(df_stock["Close"], length=length, offset=offset).dropna() return pd.DataFrame(df_ta) -def vwap(day_df: pd.DataFrame) -> pd.DataFrame: +def vwap(day_df: pd.DataFrame, offset: int) -> pd.DataFrame: """Gets volume weighted average price (VWAP) Parameters ---------- day_df: pd.DataFrame Dataframe of dates and prices for the last trading day - + offset: int + Length of offset Returns ---------- df_vwap: pd.DataFrame @@ -179,6 +185,7 @@ def vwap(day_df: pd.DataFrame) -> pd.DataFrame: low=day_df["Low"], close=day_df["Close"], volume=day_df["Volume"], + offset=offset, ) return pd.DataFrame(df_vwap) diff --git a/gamestonk_terminal/common/technical_analysis/overlap_view.py b/gamestonk_terminal/common/technical_analysis/overlap_view.py index 71bcbdd540c..44a2d75e58f 100644 --- a/gamestonk_terminal/common/technical_analysis/overlap_view.py +++ b/gamestonk_terminal/common/technical_analysis/overlap_view.py @@ -22,7 +22,8 @@ def view_ma( s_ticker: str, s_interval: str, df_stock: pd.DataFrame, - window_length: List[int], + length: List[int], + offset: int, export: str, ) -> pd.DataFrame: """Plots MA technical indicator @@ -37,7 +38,7 @@ def view_ma( Interval of data df_stock : pd.DataFrame Dataframe of prices - window_length : List[int] + length : List[int] Length of EMA window export : str Format to export data @@ -52,21 +53,21 @@ def view_ma( ) l_legend = [s_ticker] - for win in window_length: + for win in length: if ma_type == "EMA": - df_ta = overlap_model.ema(s_interval, df_stock, win) + df_ta = overlap_model.ema(s_interval, df_stock, win, offset) l_legend.append(f"EMA {win}") elif ma_type == "SMA": - df_ta = overlap_model.sma(s_interval, df_stock, win) + df_ta = overlap_model.sma(s_interval, df_stock, win, offset) l_legend.append(f"SMA {win}") elif ma_type == "WMA": - df_ta = overlap_model.wma(s_interval, df_stock, win) + df_ta = overlap_model.wma(s_interval, df_stock, win, offset) l_legend.append(f"WMA {win}") elif ma_type == "HMA": - df_ta = overlap_model.hma(s_interval, df_stock, win) + df_ta = overlap_model.hma(s_interval, df_stock, win, offset) l_legend.append(f"HMA {win}") elif ma_type == "ZLMA": - df_ta = overlap_model.zlma(s_interval, df_stock, win) + df_ta = overlap_model.zlma(s_interval, df_stock, win, offset) l_legend.append(f"ZLMA {win}") price_df = price_df.join(df_ta) @@ -98,12 +99,14 @@ def view_ma( export_data( export, os.path.dirname(os.path.abspath(__file__)).replace("common", "stocks"), - f"{ma_type.lower()}{'_'.join([str(win) for win in window_length])}", + f"{ma_type.lower()}{'_'.join([str(win) for win in length])}", price_df, ) -def view_vwap(s_ticker: str, s_interval: str, df_stock: pd.DataFrame, export: str): +def view_vwap( + s_ticker: str, s_interval: str, df_stock: pd.DataFrame, offset: int, export: str +): """Plots EMA technical indicator Parameters @@ -123,7 +126,7 @@ def view_vwap(s_ticker: str, s_interval: str, df_stock: pd.DataFrame, export: st day_df = df_stock[df_stock.Day == df_stock.Day[-1]] - df_vwap = overlap_model.vwap(day_df) + df_vwap = overlap_model.vwap(day_df, offset) mc = mpf.make_marketcolors( up="green", down="red", edge="black", wick="black", volume="in", ohlc="i" ) diff --git a/gamestonk_terminal/cryptocurrency/technical_analysis/ta_controller.py b/gamestonk_terminal/cryptocurrency/technical_analysis/ta_controller.py index 782e6bf4cd9..d49d2f1fd31 100644 --- a/gamestonk_terminal/cryptocurrency/technical_analysis/ta_controller.py +++ b/gamestonk_terminal/cryptocurrency/technical_analysis/ta_controller.py @@ -360,6 +360,15 @@ Custom: default=[20, 50], help="Window lengths. Multiple values indicated as comma separated values.", ) + parser.add_argument( + "-o", + "--offset", + action="store", + dest="n_offset", + type=int, + default=0, + help="offset", + ) parser.add_argument( "--export", choices=["csv", "json", "xlsx"], @@ -371,7 +380,7 @@ Custom: try: if other_args: - if "-l" not in other_args and "-h" not in other_args: + if "-" not in other_args[0]: other_args.insert(0, "-l") ns_parser = parse_known_args_and_warn(parser, other_args) @@ -383,7 +392,8 @@ Custom: s_ticker=self.ticker, s_interval=self.interval, df_stock=self.stock, - window_length=ns_parser.n_length, + length=ns_parser.n_length, + offset=ns_parser.n_offset, export=ns_parser.export, ) @@ -415,6 +425,15 @@ Custom: default=[20, 50], help="Window lengths. Multiple values indicated as comma separated values. ", ) + parser.add_argument( + "-o", + "--offset", + action="store", + dest="n_offset", + type=int, + default=0, + help="offset", + ) parser.add_argument( "--export", choices=["csv", "json", "xlsx"], @@ -426,7 +445,7 @@ Custom: try: if other_args: - if "-l" not in other_args and "-h" not in other_args: + if "-" not in other_args[0]: other_args.insert(0, "-l") ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: @@ -437,7 +456,8 @@ Custom: s_ticker=self.ticker, s_interval=self.interval, df_stock=self.stock, - window_length=ns_parser.n_length, + length=ns_parser.n_length, + offset=ns_parser.n_offset, export=ns_parser.export, ) @@ -469,6 +489,15 @@ Custom: default=[20], help="Window lengths. Multiple values indicated as comma separated values.", ) + parser.add_argument( + "-o", + "--offset", + action="store", + dest="n_offset", + type=int, + default=0, + help="offset", + ) parser.add_argument( "--export", choices=["csv", "json", "xlsx"], @@ -480,7 +509,7 @@ Custom: try: if other_args: - if "-l" not in other_args and "-h" not in other_args: + if "-" not in other_args[0]: other_args.insert(0, "-l") ns_parser = parse_known_args_and_warn(parser, other_args) @@ -492,7 +521,8 @@ Custom: s_ticker=self.ticker, s_interval=self.interval, df_stock=self.stock, - window_length=ns_parser.n_length, + length=ns_parser.n_length, + offset=ns_parser.n_offset, export=ns_parser.export, ) @@ -510,6 +540,15 @@ Custom: by volume. It is typically used with intraday charts to identify general direction. """, ) + parser.add_argument( + "-o", + "--offset", + action="store", + dest="n_offset", + type=int, + default=0, + help="offset", + ) parser.add_argument( "--export", choices=["csv", "json", "xlsx"], @@ -532,6 +571,7 @@ Custom: s_ticker=self.ticker, s_interval=self.interval, df_stock=self.stock, + offset=ns_parser.n_offset, export=ns_parser.export, ) diff --git a/gamestonk_terminal/stocks/technical_analysis/ta_controller.py b/gamestonk_terminal/stocks/technical_analysis/ta_controller.py index e544f3477d8..12b868a0509 100644 --- a/gamestonk_terminal/stocks/technical_analysis/ta_controller.py +++ b/gamestonk_terminal/stocks/technical_analysis/ta_controller.py @@ -283,10 +283,6 @@ Custom: ) try: - if other_args: - if "-l" not in other_args and "-h" not in other_args: - other_args.insert(0, "-l") - ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return @@ -331,9 +327,6 @@ Custom: ) try: - if other_args: - if "-l" not in other_args and "-h" not in other_args: - other_args.insert(0, "-l") ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: @@ -376,6 +369,15 @@ Custom: default=[20, 50], help="Window lengths. Multiple values indicated as comma separated values.", ) + parser.add_argument( + "-o", + "--offset", + action="store", + dest="n_offset", + type=int, + default=0, + help="offset", + ) parser.add_argument( "--export", choices=["csv", "json", "xlsx"], @@ -387,7 +389,7 @@ Custom: try: if other_args: - if "-l" not in other_args and "-h" not in other_args: + if "-" not in other_args[0]: other_args.insert(0, "-l") ns_parser = parse_known_args_and_warn(parser, other_args) @@ -399,7 +401,8 @@ Custom: s_ticker=self.ticker, s_interval=self.interval, df_stock=self.stock, - window_length=ns_parser.n_length, + length=ns_parser.n_length, + offset=ns_parser.n_offset, export=ns_parser.export, ) @@ -431,6 +434,15 @@ Custom: default=[20, 50], help="Window lengths. Multiple values indicated as comma separated values. ", ) + parser.add_argument( + "-o", + "--offset", + action="store", + dest="n_offset", + type=int, + default=0, + help="offset", + ) parser.add_argument( "--export", choices=["csv", "json", "xlsx"], @@ -442,7 +454,7 @@ Custom: try: if other_args: - if "-l" not in other_args and "-h" not in other_args: + if "-" not in other_args[0]: other_args.insert(0, "-l") ns_parser = parse_known_args_and_warn(parser, other_args) @@ -454,7 +466,8 @@ Custom: s_ticker=self.ticker, s_interval=self.interval, df_stock=self.stock, - window_length=ns_parser.n_length, + length=ns_parser.n_length, + offset=ns_parser.n_offset, export=ns_parser.export, ) @@ -483,6 +496,15 @@ Custom: default=[20, 50], help="Window lengths. Multiple values indicated as comma separated values. ", ) + parser.add_argument( + "-o", + "--offset", + action="store", + dest="n_offset", + type=int, + default=0, + help="offset", + ) parser.add_argument( "--export", choices=["csv", "json", "xlsx"], @@ -494,7 +516,7 @@ Custom: try: if other_args: - if "-l" not in other_args and "-h" not in other_args: + if "-" not in other_args[0]: other_args.insert(0, "-l") ns_parser = parse_known_args_and_warn(parser, other_args) @@ -506,7 +528,8 @@ Custom: s_ticker=self.ticker, s_interval=self.interval, df_stock=self.stock, - window_length=ns_parser.n_length, + length=ns_parser.n_length, + offset=ns_parser.n_offset, export=ns_parser.export, ) @@ -535,6 +558,15 @@ Custom: default=[10, 20], help="Window lengths. Multiple values indicated as comma separated values. ", ) + parser.add_argument( + "-o", + "--offset", + action="store", + dest="n_offset", + type=int, + default=0, + help="offset", + ) parser.add_argument( "--export", choices=["csv", "json", "xlsx"], @@ -546,7 +578,7 @@ Custom: try: if other_args: - if "-l" not in other_args and "-h" not in other_args: + if "-" not in other_args[0]: other_args.insert(0, "-l") ns_parser = parse_known_args_and_warn(parser, other_args) @@ -558,7 +590,8 @@ Custom: s_ticker=self.ticker, s_interval=self.interval, df_stock=self.stock, - window_length=ns_parser.n_length, + length=ns_parser.n_length, + offset=ns_parser.n_offset, export=ns_parser.export, ) @@ -590,6 +623,15 @@ Custom: default=[20], help="Window lengths. Multiple values indicated as comma separated values.", ) + parser.add_argument( + "-o", + "--offset", + action="store", + dest="n_offset", + type=int, + default=0, + help="offset", + ) parser.add_argument( "--export", choices=["csv", "json", "xlsx"], @@ -601,7 +643,7 @@ Custom: try: if other_args: - if "-l" not in other_args and "-h" not in other_args: + if "-" not in other_args[0]: other_args.insert(0, "-l") ns_parser = parse_known_args_and_warn(parser, other_args) @@ -613,7 +655,8 @@ Custom: s_ticker=self.ticker, s_interval=self.interval, df_stock=self.stock, - window_length=ns_parser.n_length, + length=ns_parser.n_length, + offset=ns_parser.n_offset, export=ns_parser.export, ) @@ -631,6 +674,15 @@ Custom: by volume. It is typically used with intraday charts to identify general direction. """, ) + parser.add_argument( + "-o", + "--offset", + action="store", + dest="n_offset", + type=int, + default=0, + help="offset", + ) parser.add_argument( "--export", choices=["csv", "json", "xlsx"], @@ -640,10 +692,6 @@ Custom: help="Export dataframe data to csv,json,xlsx file", ) try: - if other_args: - if "-l" not in other_args and "-h" not in other_args: - other_args.insert(0, "-l") - ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return @@ -657,6 +705,7 @@ Custom: s_ticker=self.ticker, s_interval=self.interval, df_stock=self.stock, + offset=ns_parser.n_offset, export=ns_parser.export, ) @@ -707,10 +756,6 @@ Custom: ) try: - if other_args: - if "-l" not in other_args and "-h" not in other_args: - other_args.insert(0, "-l") - ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return @@ -782,10 +827,6 @@ Custom: ) try: - if other_args: - if "-l" not in other_args and "-h" not in other_args: - other_args.insert(0, "-l") - ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return @@ -855,7 +896,7 @@ Custom: try: if other_args: - if "-l" not in other_args and "-h" not in other_args: + if "-" not in other_args[0]: other_args.insert(0, "-l") ns_parser = parse_known_args_and_warn(parser, other_args) @@ -927,10 +968,6 @@ Custom: ) try: - if other_args: - if "-l" not in other_args and "-h" not in other_args: - other_args.insert(0, "-l") - ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return @@ -981,7 +1018,7 @@ Custom: try: if other_args: - if "-l" not in other_args and "-h" not in other_args: + if "-" not in other_args[0]: other_args.insert(0, "-l") ns_parser = parse_known_args_and_warn(parser, other_args) @@ -1033,7 +1070,7 @@ Custom: try: if other_args: - if "-l" not in other_args and "-h" not in other_args: + if "-" not in other_args[0]: other_args.insert(0, "-l") ns_parser = parse_known_args_and_warn(parser, other_args) @@ -1101,7 +1138,7 @@ Custom: try: if other_args: - if "-l" not in other_args and "-h" not in other_args: + if "-" not in other_args[0]: other_args.insert(0, "-l") ns_parser = parse_known_args_and_warn(parser, other_args) @@ -1170,7 +1207,7 @@ Custom: try: if other_args: - if "-l" not in other_args and "-h" not in other_args: + if "-" not in other_args[0]: other_args.insert(0, "-l") ns_parser = parse_known_args_and_warn(parser, other_args) @@ -1246,7 +1283,7 @@ Custom: try: if other_args: - if "-l" not in other_args and "-h" not in other_args: + if "-" not in other_args[0]: other_args.insert(0, "-l") ns_parser = parse_known_args_and_warn(parser, other_args) @@ -1309,10 +1346,6 @@ Custom: ) try: - if other_args: - if "-l" not in other_args and "-h" not in other_args: - other_args.insert(0, "-l") - ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return @@ -1390,7 +1423,7 @@ Custom: try: if other_args: - if "-l" not in other_args and "-h" not in other_args: + if "-" not in other_args[0]: other_args.insert(0, "-l") ns_parser = parse_known_args_and_warn(parser, other_args) @@ -1446,10 +1479,6 @@ Custom: ) try: - if other_args: - if "-l" not in other_args and "-h" not in other_args: - other_args.insert(0, "-l") - ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return @@ -1515,10 +1544,6 @@ Custom: ) try: - if other_args: - if "-l" not in other_args and "-h" not in other_args: - other_args.insert(0, "-l") - ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return @@ -1561,10 +1586,6 @@ Custom: ) try: - if other_args: - if "-l" not in other_args and "-h" not in other_args: - other_args.insert(0, "-l") - ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: return @@ -1620,8 +1641,8 @@ Custom: try: if other_args: - if "-l" not in other_args and "-h" not in other_args: - other_args.insert(0, "-l") + if "-" not in other_args[0]: + other_args.insert(0, "-p") ns_parser = parse_known_args_and_warn(parser, other_args) if not ns_parser: