From 0e0de86b4996ca22d1fdcfe936c9fc8cf780568b Mon Sep 17 00:00:00 2001 From: Danglewood <85772166+deeleeramone@users.noreply.github.com> Date: Wed, 10 May 2023 17:31:41 -0700 Subject: [PATCH] feature/heikin-ashi-candles: Adds a flag for Heikin Ashi Candles on stocks/candle (#4979) * Adds a flag for Heikin Ashi Candles on stocks/candle * ruff * pylint * doc strings * fix typo * update integration test file * updates the docs accordingly. * remove second if statement * requested change * adds check for the expected columns --------- Co-authored-by: teh_coderer Co-authored-by: James Maslek --- .../stocks/test_stocks.openbb | 1 + openbb_terminal/stocks/stocks_controller.py | 20 ++++-- openbb_terminal/stocks/stocks_helper.py | 63 ++++++++++++++++++- .../terminal/usage/intros/stocks/index.md | 15 ++--- 4 files changed, 85 insertions(+), 14 deletions(-) diff --git a/openbb_terminal/miscellaneous/integration_tests_scripts/stocks/test_stocks.openbb b/openbb_terminal/miscellaneous/integration_tests_scripts/stocks/test_stocks.openbb index 5b6838ea7ea3..b771d3641011 100644 --- a/openbb_terminal/miscellaneous/integration_tests_scripts/stocks/test_stocks.openbb +++ b/openbb_terminal/miscellaneous/integration_tests_scripts/stocks/test_stocks.openbb @@ -11,6 +11,7 @@ candle candle -t --ma 5,10 candle --raw candle --sort AdjClose -r --raw +candle --ha codes news -l 3 news -h diff --git a/openbb_terminal/stocks/stocks_controller.py b/openbb_terminal/stocks/stocks_controller.py index a40211e04b46..4b18963a2c64 100644 --- a/openbb_terminal/stocks/stocks_controller.py +++ b/openbb_terminal/stocks/stocks_controller.py @@ -383,13 +383,13 @@ def call_candle(self, other_args: List[str]): add_help=False, formatter_class=argparse.ArgumentDefaultsHelpFormatter, prog="candle", - description="Shows historic data for a stock", + description="Shows historic price and volume for the asset.", ) parser.add_argument( "-t", "--ticker", dest="ticker", - help="Ticker to analyze", + help="Ticker to analyze.", type=str, default=None, required=not any(x in other_args for x in ["-h", "--help"]) @@ -401,7 +401,7 @@ def call_candle(self, other_args: List[str]): action="store_true", default=False, dest="prepost", - help="Pre/After market hours. Only works for 'yf' source, and intraday data", + help="Pre/After market hours. Only works for intraday data.", ) parser.add_argument( "--sort", @@ -428,13 +428,13 @@ def call_candle(self, other_args: List[str]): action="store_true", dest="raw", default=False, - help="Shows raw data instead of chart.", + help="Shows raw data instead of a chart.", ) parser.add_argument( "--trend", action="store_true", default=False, - help="Flag to add high and low trends to candle", + help="Flag to add high and low trends to candle.", dest="trendlines", ) parser.add_argument( @@ -447,6 +447,13 @@ def call_candle(self, other_args: List[str]): ), default=None, ) + parser.add_argument( + "--ha", + dest="ha", + action="store_true", + default=False, + help="Flag to show Heikin Ashi candles.", + ) parser.add_argument( "--log", help="Plot with y axis on log scale", @@ -498,8 +505,9 @@ def call_candle(self, other_args: List[str]): data=data, add_trend=ns_parser.trendlines, ma=mov_avgs, + ha=ns_parser.ha, prepost=ns_parser.prepost, - asset_type="Stock", + asset_type="", yscale="log" if ns_parser.logy else "linear", external_axes=ns_parser.is_image, ) diff --git a/openbb_terminal/stocks/stocks_helper.py b/openbb_terminal/stocks/stocks_helper.py index f0a98f850e24..afb51468ffb3 100644 --- a/openbb_terminal/stocks/stocks_helper.py +++ b/openbb_terminal/stocks/stocks_helper.py @@ -17,6 +17,7 @@ import pytz import yfinance as yf from pandas.tseries.holiday import USFederalHolidayCalendar +from pandas_ta import candles from requests.exceptions import ReadTimeout from scipy import stats @@ -577,6 +578,7 @@ def display_candle( source: str = "YahooFinance", weekly: bool = False, monthly: bool = False, + ha: Optional[bool] = False, external_axes: bool = False, raw: bool = False, yscale: str = "linear", @@ -611,6 +613,8 @@ def display_candle( Flag to get weekly data monthly: bool Flag to get monthly data + ha: bool + Flag to show Heikin Ashi candles. external_axes : bool, optional Whether to return the figure object or not, by default False raw : bool, optional @@ -672,6 +676,14 @@ def display_candle( data.name = f"{asset_type} {symbol}" + if ha: + data_ = heikin_ashi(data) + data["Open"] = data_["HA Open"] + data["High"] = data_["HA High"] + data["Low"] = data_["HA Low"] + data["Close"] = data_["HA Close"] + data.name = f"{symbol} - Heikin Ashi Candles" + fig = PlotlyTA.plot(data, dict(**kwargs), prepost=prepost) if add_trend: @@ -888,7 +900,10 @@ def clean_function(entry: str) -> Union[str, float]: return entry -def show_quick_performance(stock_df: pd.DataFrame, ticker: str): +def show_quick_performance( + stock_df: pd.DataFrame, + ticker: str, +) -> None: """Show quick performance stats of stock prices. Daily prices expected. @@ -925,6 +940,7 @@ def show_quick_performance(stock_df: pd.DataFrame, ticker: str): ) perf_df["Previous Close"] = str(round(closes[-1], 2)) + print_rich_table( perf_df, show_index=False, @@ -1044,3 +1060,48 @@ def verify_plot_options(command: str, source: str, plot: list) -> bool: ) return True return False + + +def heikin_ashi(data: pd.DataFrame) -> pd.DataFrame: + """Return OHLC data as Heikin Ashi Candles. + + Parameters + ---------- + data: pd.DataFrame + DataFrame containing OHLC data. + + Returns + ------- + pd.DataFrame + Appended DataFrame with Heikin Ashi candle calculations. + """ + + check_columns = ["Open", "High", "Low", "Close"] + + data.rename( + columns={"open": "Open", "high": "High", "low": "Low", "close": "Close"}, + inplace=True, + ) + + for item in check_columns: + if item not in data.columns: + raise ValueError( + "The expected column labels, " + f"{check_columns}" + ", were not found in DataFrame." + ) + + ha = candles.ha( + data["Open"], + data["High"], + data["Low"], + data["Close"], + ) + ha.columns = [ + "HA Open", + "HA High", + "HA Low", + "HA Close", + ] + + return pd.concat([data, ha], axis=1) diff --git a/website/content/terminal/usage/intros/stocks/index.md b/website/content/terminal/usage/intros/stocks/index.md index 9414eb5bc510..783277495cf7 100644 --- a/website/content/terminal/usage/intros/stocks/index.md +++ b/website/content/terminal/usage/intros/stocks/index.md @@ -212,7 +212,7 @@ Loading Daily data for MSFT with starting period 2020-04-08. ![stocks/candle](https://user-images.githubusercontent.com/85772166/231903835-a0157626-1329-4d5a-80a1-8d21b71adcb1.png) -The help dialogue for the `candle` command shows how this chart can be supplemented with additional data; specifically, `-t` for trend, `--ma` for moving averages, and `--log` for a log scale. +The help dialogue for the `candle` command shows how this chart can be supplemented with additional data; specifically, `-t` for trend, `--ma` for moving averages, `--log` for a log scale, and `--ha` to convert the candles to a Heikin Ashi pattern. ```console candle -h @@ -221,21 +221,22 @@ candle -h Which prints to screen: ```console -usage: candle [-t TICKER] [-p] [--sort {open,high,low,close,adjclose,volume,dividends,stock_splits}] [-r] [--raw] [--trend] [--ma MOV_AVG] [--log] [-h] [--export EXPORT] +usage: candle [-t TICKER] [-p] [--sort {open,high,low,close,adjclose,volume,dividends,stock_splits}] [-r] [--raw] [--trend] [--ma MOV_AVG] [--ha] [--log] [-h] [--export EXPORT] [--sheet-name SHEET_NAME [SHEET_NAME ...]] [-l LIMIT] -Shows historic data for a stock +Shows historic price and volume for the asset. options: -t TICKER, --ticker TICKER - Ticker to analyze (default: None) - -p, --prepost Pre/After market hours. Only works for 'yf' source, and intraday data (default: False) + Ticker to analyze. (default: None) + -p, --prepost Pre/After market hours. Only works for intraday data. (default: False) --sort {open,high,low,close,adjclose,volume,dividends,stock_splits} Choose a column to sort by. Only works when raw data is displayed. (default: ) -r, --reverse Data is sorted in descending order by default. Reverse flag will sort it in an ascending way. Only works when raw data is displayed. (default: False) - --raw Shows raw data instead of chart. (default: False) - --trend Flag to add high and low trends to candle (default: False) + --raw Shows raw data instead of a chart. (default: False) + --trend Flag to add high and low trends to candle. (default: False) --ma MOV_AVG Add moving average in number of days to plot and separate by a comma. Value for ma (moving average) keyword needs to be greater than 1. (default: None) + --ha Flag to show Heikin Ashi candles. (default: False) --log Plot with y axis on log scale (default: False) -h, --help show this help message (default: False) --export EXPORT Export raw data into csv, json, xlsx and figure into png, jpg, pdf, svg (default: )