def fib_command( ticker="", interval: int = 15, past_days: int = 0, start: str = "", end: str = "", extended_hours: bool = False, heikin_candles: bool = False, news: bool = False, ): """Displays chart with fibonacci retracement [Yahoo Finance]""" # Debug if imps.DEBUG: # pylint: disable=logging-too-many-args logger.debug( "ta fib %s %s %s %s %s %s %s %s", ticker, interval, past_days, start, end, extended_hours, heikin_candles, news, ) past_days = (past_days + 1) if (interval != 1440) or (start != "") else 365 # Retrieve Data ( df_stock, start, end, bar_start, ) = load_candle.stock_data( ticker=ticker, interval=interval, past_days=past_days, extended_hours=extended_hours, start=start, end=end, heikin_candles=heikin_candles, ) if df_stock.empty: raise Exception(f"No data found for {ticker.upper()}.") df_ta = df_stock.loc[(df_stock.index >= start) & (df_stock.index < end)] # Output Data if interval != 1440: df_ta = df_ta.loc[(df_ta.index >= bar_start) & (df_ta.index < end)] ( df_fib, min_date, max_date, min_pr, max_pr, ) = custom_indicators_model.calculate_fib_levels(df_ta, 12, bar_start, None) levels = df_fib.Price # Output Data fibs = [ "<b>0</b>", "<b>0.235</b>", "<b>0.382</b>", "<b>0.5</b>", "<b>0.618</b>", "<b>0.65</b>", "<b>1</b>", ] plot = load_candle.candle_fig( df_ta, ticker, interval, extended_hours, news, bar=bar_start, int_bar=interval, shared_xaxes=True, vertical_spacing=0.07, ) title = f"<b>{plot['plt_title']} Fibonacci-Retracement-Levels</b>" lvl_text: str = "right" if min_date > max_date else "left" fig = plot["fig"] fig.add_trace( go.Scatter( x=[min_date, max_date], y=[min_pr, max_pr], opacity=1, mode="lines", line=imps.PLT_FIB_COLORWAY[8], showlegend=False, ), row=1, col=1, secondary_y=True, ) for i in range(6): fig.add_trace( go.Scatter( name=fibs[i], x=[min_date, max_date], y=[levels[i], levels[i]], opacity=0.2, mode="lines", line_color=imps.PLT_FIB_COLORWAY[i], showlegend=False, ), row=1, col=1, secondary_y=True, ) fig.add_trace( go.Scatter( name=fibs[i + 1], x=[min_date, max_date], y=[levels[i + 1], levels[i + 1]], opacity=0.2, mode="lines", fill="tonexty", line_color=imps.PLT_FIB_COLORWAY[i + 1], showlegend=False, ), row=1, col=1, secondary_y=True, ) for i in range(7): fig.add_trace( go.Scatter( name=fibs[i], x=[min_date], y=[levels[i]], opacity=0.9, mode="text", text=fibs[i], textposition=f"middle {lvl_text}" if i != 5 else f"bottom {lvl_text}", textfont=dict(imps.PLT_FIB_COLORWAY[7], color=imps.PLT_FIB_COLORWAY[i]), showlegend=False, ), row=1, col=1, secondary_y=True, ) fig.update_layout( margin=dict(l=0, r=0, t=50, b=20), template=imps.PLT_TA_STYLE_TEMPLATE, title=title, title_x=0.02, title_font_size=14, dragmode="pan", ) imagefile = "ta_fib.png" # Check if interactive settings are enabled plt_link = "" if imps.INTERACTIVE: plt_link = imps.inter_chart(fig, imagefile, callback=False) fig.update_layout( width=800, height=500, ) imagefile = imps.image_border(imagefile, fig=fig) return { "title": f"Stocks: Fibonacci-Retracement-Levels {ticker.upper()}", "description": plt_link, "imagefile": imagefile, }
def macd_command( ticker="", interval: int = 15, past_days: int = 0, fast="12", slow="26", signal="9", start="", end="", extended_hours: bool = False, heikin_candles: bool = False, news: bool = False, ): """Displays chart with moving average convergence/divergence [Yahoo Finance]""" # Debug if imps.DEBUG: # pylint: disable=logging-too-many-args logger.debug( "ta macd %s %s %s %s %s %s %s %s %s %s %s", ticker, interval, past_days, fast, slow, signal, start, end, extended_hours, heikin_candles, news, ) # Check for argument if ticker == "": raise Exception("Stock ticker is required") # Retrieve Data df_stock, start, end, bar_start = load_candle.stock_data( ticker=ticker, interval=interval, past_days=past_days, extended_hours=extended_hours, start=start, end=end, heikin_candles=heikin_candles, ) if df_stock.empty: raise Exception("No Data Found") if not fast.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") fast = int(fast) if not slow.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") slow = int(slow) if not signal.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") signal = int(signal) df_ta = df_stock.loc[(df_stock.index >= start) & (df_stock.index < end)] if df_ta.empty: raise Exception("No Data Found") ta_data = momentum_model.macd(df_stock["Adj Close"], fast, slow, signal) df_ta = df_ta.join(ta_data) # Output Data if interval != 1440: df_ta = df_ta.loc[(df_ta.index >= bar_start) & (df_ta.index < end)] df_ta = df_ta.fillna(0.0) plot = load_candle.candle_fig( df_ta, ticker, interval, extended_hours, news, bar=bar_start, int_bar=interval, rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.07, row_width=[0.4, 0.6], specs=[[{"secondary_y": True}], [{"secondary_y": False}]], ) title = f"<b>{plot['plt_title']} MACD {fast} {slow} {signal}</b>" fig = plot["fig"] idx = 6 if interval != 1440 else 11 fig.add_trace( go.Bar( name="MACD Histogram", x=df_ta.index, y=df_ta.iloc[:, (idx + 1)].values, opacity=(plot["bar_opacity"] + 0.3), marker_color="#d81aea", ), row=2, col=1, secondary_y=False, ) fig.add_trace( go.Scatter( name="MACD Line", mode="lines", x=df_ta.index, y=df_ta.iloc[:, idx].values, opacity=0.8, line=dict(color="#00e6c3"), ), row=2, col=1, secondary_y=False, ) fig.add_trace( go.Scatter( name="Signal Line", mode="lines", x=df_ta.index, y=df_ta.iloc[:, (idx + 2)].values, opacity=1, line=dict(color="#9467bd"), ), row=2, col=1, secondary_y=False, ) fig.update_layout( margin=dict(l=0, r=0, t=50, b=20), template=imps.PLT_TA_STYLE_TEMPLATE, colorway=imps.PLT_TA_COLORWAY, title=title, title_x=0.02, title_font_size=14, dragmode="pan", ) imagefile = "ta_macd.png" # Check if interactive settings are enabled plt_link = "" if imps.INTERACTIVE: plt_link = imps.inter_chart(fig, imagefile, callback=False) fig.update_layout( width=800, height=500, ) imagefile = imps.image_border(imagefile, fig=fig) return { "title": f"Stocks: Moving-Average-Convergence-Divergence {ticker.upper()}", "description": plt_link, "imagefile": imagefile, }
def stoch_command( ticker: str = "", interval: int = 15, past_days: int = 0, fast_k="14", slow_d="3", slow_k="4", start="", end="", extended_hours: bool = False, heikin_candles: bool = False, news: bool = False, ): """Displays chart with stochastic relative strength average [Yahoo Finance]""" # Debug if imps.DEBUG: logger.debug( "ta stoch %s %s %s %s %s %s %s %s %s %s %s", ticker, interval, past_days, fast_k, slow_k, slow_d, start, end, extended_hours, heikin_candles, news, ) # Check for argument if ticker == "": raise Exception("Stock ticker is required") if not fast_k.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") fast_k = int(fast_k) if not slow_k.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") slow_k = int(slow_k) if not slow_d.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") slow_d = int(slow_d) # Retrieve Data df_stock, start, end, bar_start = load_candle.stock_data( ticker=ticker, interval=interval, past_days=past_days, extended_hours=extended_hours, start=start, end=end, heikin_candles=heikin_candles, ) df_ta = df_stock.loc[(df_stock.index >= start) & (df_stock.index < end)] if df_ta.empty: raise Exception("No Data Found") df_ta = df_ta.join( momentum_model.stoch( df_stock["High"], df_stock["Low"], df_stock["Adj Close"], fast_k, slow_d, slow_k, )) # Output Data if interval != 1440: df_ta = df_ta.loc[(df_ta.index >= bar_start) & (df_ta.index < end)] df_ta = df_ta.fillna(0.0) plot = load_candle.candle_fig( df_ta, ticker, interval, extended_hours, news, bar=bar_start, int_bar=interval, rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.07, row_width=[0.4, 0.6], specs=[[{ "secondary_y": True }], [{ "secondary_y": False }]], ) title = f"<b>{plot['plt_title']} STOCH RSI</b>" fig = plot["fig"] idx = 6 if interval != 1440 else 11 fig.add_trace( go.Scatter( name=f"%K {fast_k}, {slow_d}, {slow_k}", x=df_ta.index, y=df_ta.iloc[:, idx].values, line=dict(width=1.8), mode="lines", opacity=1, ), row=2, col=1, ) fig.add_trace( go.Scatter( name=f"%D {fast_k}, {slow_d}, {slow_k}", x=df_ta.index, y=df_ta.iloc[:, (idx + 1)].values, line=dict(width=1.8, dash="dash"), opacity=1, ), row=2, col=1, ) fig.add_hrect( y0=80, y1=100, fillcolor="red", opacity=0.2, layer="below", line_width=0, row=2, col=1, ) fig.add_hrect( y0=0, y1=20, fillcolor="green", opacity=0.2, layer="below", line_width=0, row=2, col=1, ) fig.add_hline( y=80, fillcolor="green", opacity=1, layer="below", line_width=3, line=dict(color="red", dash="dash"), row=2, col=1, ) fig.add_hline( y=20, fillcolor="green", opacity=1, layer="below", line_width=3, line=dict(color="green", dash="dash"), row=2, col=1, ) fig.update_layout( margin=dict(l=0, r=0, t=50, b=20), template=imps.PLT_TA_STYLE_TEMPLATE, colorway=imps.PLT_TA_COLORWAY, title=title, title_x=0.01, title_font_size=14, dragmode="pan", ) imagefile = "ta_stoch.png" # Check if interactive settings are enabled plt_link = "" if imps.INTERACTIVE: plt_link = imps.inter_chart(fig, imagefile, callback=False) fig.update_layout( width=800, height=500, ) imagefile = imps.image_border(imagefile, fig=fig) return { "title": f"Stocks: Stochastic-Relative-Strength-Index {ticker.upper()}", "description": plt_link, "imagefile": imagefile, }
def adx_command( ticker="", interval: int = 15, past_days: int = 0, length="14", scalar="100", drift="1", start="", end="", extended_hours: bool = False, heikin_candles: bool = False, news: bool = False, ): """Displays chart with average directional movement index [Yahoo Finance]""" # Debug if imps.DEBUG: # pylint: disable=logging-too-many-args logger.debug( "ta adx %s %s %s %s %s %s %s %s %s %s %s", ticker, interval, past_days, length, scalar, drift, start, end, extended_hours, heikin_candles, news, ) # Check for argument if ticker == "": raise Exception("Stock ticker is required") # Retrieve Data df_stock, start, end, bar_start = load_candle.stock_data( ticker=ticker, interval=interval, past_days=past_days, extended_hours=extended_hours, start=start, end=end, heikin_candles=heikin_candles, ) if df_stock.empty: raise Exception("No Data Found") if not length.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") length = float(length) if not scalar.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") scalar = float(scalar) if not drift.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") drift = float(drift) df_ta = df_stock.loc[(df_stock.index >= start) & (df_stock.index < end)] if df_ta.empty: raise Exception("No Data Found") ta_data = trend_indicators_model.adx( df_stock["High"], df_stock["Low"], df_stock["Adj Close"], length, scalar, drift, ) df_ta = df_ta.join(ta_data) # Output Data if interval != 1440: df_ta = df_ta.loc[(df_ta.index >= bar_start) & (df_ta.index < end)] df_ta = df_ta.fillna(0.0) plot = load_candle.candle_fig( df_ta, ticker, interval, extended_hours, news, bar=bar_start, int_bar=interval, rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.07, row_width=[0.4, 0.6], specs=[[{ "secondary_y": True }], [{ "secondary_y": False }]], ) title = f"<b>{plot['plt_title']} Average Directional Movement Index</b>" fig = plot["fig"] idx = 6 if interval != 1440 else 11 fig.add_trace( go.Scatter( name=f"ADX ({length})", mode="lines", x=df_ta.index, y=df_ta.iloc[:, idx].values, opacity=1, line=dict(width=2), ), secondary_y=False, row=2, col=1, ) fig.add_trace( go.Scatter( name=f"+DI ({length})", mode="lines", x=df_ta.index, y=df_ta.iloc[:, (idx + 1)].values, opacity=1, line=dict(width=1), ), secondary_y=False, row=2, col=1, ) fig.add_trace( go.Scatter( name=f"-DI ({length})", mode="lines", x=df_ta.index, y=df_ta.iloc[:, (idx + 2)].values, opacity=1, line=dict(width=1), ), secondary_y=False, row=2, col=1, ) fig.add_hline( y=25, fillcolor="grey", opacity=1, layer="below", line_width=3, line=dict(color="grey", dash="dash"), row=2, col=1, ) fig.update_layout( margin=dict(l=0, r=0, t=50, b=20), template=imps.PLT_TA_STYLE_TEMPLATE, colorway=imps.PLT_TA_COLORWAY, title=title, title_x=0.01, title_font_size=12, dragmode="pan", ) imagefile = "ta_adx.png" # Check if interactive settings are enabled plt_link = "" if imps.INTERACTIVE: plt_link = imps.inter_chart(fig, imagefile, callback=False) fig.update_layout( width=800, height=500, ) imagefile = imps.image_border(imagefile, fig=fig) return { "title": f"Stocks: Average-Directional-Movement-Index {ticker.upper()}", "description": plt_link, "imagefile": imagefile, }
def aroon_command( ticker="", interval: int = 15, past_days: int = 0, length="25", scalar="100", start="", end="", extended_hours: bool = False, heikin_candles: bool = False, news: bool = False, ): """Displays chart with aroon indicator [Yahoo Finance]""" # Debug if imps.DEBUG: logger.debug( "ta aroon %s %s %s %s %s, %s, %s, %s, %s, %s", ticker, interval, past_days, length, scalar, start, end, extended_hours, heikin_candles, news, ) # Check for argument if ticker == "": raise Exception("Stock ticker is required") if not length.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") length = int(length) if not scalar.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") scalar = float(scalar) # Retrieve Data df_stock, start, end, bar_start = load_candle.stock_data( ticker=ticker, interval=interval, past_days=past_days, extended_hours=extended_hours, start=start, end=end, heikin_candles=heikin_candles, ) if df_stock.empty: raise Exception("No Data Found") df_ta = df_stock.loc[(df_stock.index >= start) & (df_stock.index < end)] df_ta = df_ta.join( trend_indicators_model.aroon(df_ta["High"], df_ta["Low"], length, scalar)) # Output Data if interval != 1440: df_ta = df_ta.loc[(df_ta.index >= bar_start) & (df_ta.index < end)] df_ta = df_ta.fillna(0.0) plot = load_candle.candle_fig( df_ta, ticker, interval, extended_hours, news, bar=bar_start, int_bar=interval, rows=3, cols=1, shared_xaxes=True, vertical_spacing=0.02, row_width=[0.2, 0.2, 0.3], specs=[ [{ "secondary_y": True }], [{ "secondary_y": False }], [{ "secondary_y": False }], ], ) title = f"<b>{plot['plt_title']} Aroon ({length})</b>" fig = plot["fig"] idx = 6 if interval != 1440 else 11 fig.add_trace( go.Scatter( name="Aroon DOWN", x=df_ta.index, y=df_ta.iloc[:, idx].values, opacity=1, ), row=2, col=1, secondary_y=False, ) fig.add_trace( go.Scatter( name="Aroon UP", x=df_ta.index, y=df_ta.iloc[:, (idx + 1)].values, opacity=1, ), row=2, col=1, secondary_y=False, ) fig.add_trace( go.Scatter( name="Aroon OSC", x=df_ta.index, y=df_ta.iloc[:, (idx + 2)].values, opacity=1, ), row=3, col=1, secondary_y=False, ) fig.add_hline( y=50, fillcolor="grey", opacity=1, layer="below", line_width=3, line=dict(color="grey", dash="dash"), row=2, col=1, ) fig.update_layout( margin=dict(l=0, r=0, t=50, b=20), template=imps.PLT_TA_STYLE_TEMPLATE, colorway=imps.PLT_TA_COLORWAY, title=title, title_x=0.1, title_font_size=14, dragmode="pan", yaxis=dict(nticks=10), yaxis2=dict(nticks=10), ) imagefile = "ta_aroon.png" # Check if interactive settings are enabled plt_link = "" if imps.INTERACTIVE: plt_link = imps.inter_chart(fig, imagefile, callback=False) fig.update_layout( width=800, height=500, ) imagefile = imps.image_border(imagefile, fig=fig) return { "title": f"Stocks: Aroon-Indicator {ticker.upper()}", "description": plt_link, "imagefile": imagefile, }
def kc_command( ticker="", interval: int = 15, past_days: int = 0, length="20", scalar="2", ma_mode="sma", offset="0", start="", end="", extended_hours: bool = False, heikin_candles: bool = False, news: bool = False, ): """Displays chart with keltner channel [Yahoo Finance]""" # Debug if imps.DEBUG: # pylint: disable=logging-too-many-args logger.debug( "ta kc %s %s %s %s %s %s %s %s %s %s %s %s", ticker, interval, past_days, length, scalar, ma_mode, offset, start, end, extended_hours, heikin_candles, news, ) # Check for argument if not length.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") length = int(length) if not scalar.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") scalar = float(scalar) if not offset.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") offset = float(offset) # Retrieve Data df_stock, start, end, bar_start = load_candle.stock_data( ticker=ticker, interval=interval, past_days=past_days, extended_hours=extended_hours, start=start, end=end, heikin_candles=heikin_candles, ) if df_stock.empty: raise Exception("No Data Found") df_ta = df_stock.loc[(df_stock.index >= start) & (df_stock.index < end)] if df_ta.empty: raise Exception("No Data Found") ta_data = volatility_model.kc( df_stock["High"], df_stock["Low"], df_stock["Adj Close"], length, scalar, ma_mode, offset, ) df_ta = df_ta.join(ta_data) # Output Data if interval != 1440: df_ta = df_ta.loc[(df_ta.index >= bar_start) & (df_ta.index < end)] df_ta = df_ta.fillna(0.0) plot = load_candle.candle_fig( df_ta, ticker, interval, extended_hours, news, bar=bar_start, int_bar=interval, shared_xaxes=True, vertical_spacing=0.07, ) title = f"<b>{plot['plt_title']} Keltner Channels ({ma_mode.upper()})</b>" fig = plot["fig"] idx = 6 if interval != 1440 else 11 fig.add_trace( go.Scatter( name="upper", x=df_ta.index, y=df_ta.iloc[:, (idx + 2)].values, opacity=1, mode="lines", line_color="indigo", showlegend=False, ), row=1, col=1, secondary_y=True, ) fig.add_trace( go.Scatter( name="lower", x=df_ta.index, y=df_ta.iloc[:, idx].values, opacity=1, mode="lines", line_color="indigo", fill="tonexty", fillcolor="rgba(74, 0, 128, 0.2)", showlegend=False, ), row=1, col=1, secondary_y=True, ) fig.add_trace( go.Scatter( name="mid", x=df_ta.index, y=df_ta.iloc[:, (idx + 1)].values, opacity=1, line=dict( width=1.5, dash="dash", ), showlegend=False, ), row=1, col=1, secondary_y=True, ) fig.update_layout( margin=dict(l=0, r=0, t=50, b=20), template=imps.PLT_TA_STYLE_TEMPLATE, colorway=imps.PLT_TA_COLORWAY, title=title, title_x=0.02, title_font_size=14, dragmode="pan", ) imagefile = "ta_kc.png" # Check if interactive settings are enabled plt_link = "" if imps.INTERACTIVE: plt_link = imps.inter_chart(fig, imagefile, callback=False) fig.update_layout( width=800, height=500, ) imagefile = imps.image_border(imagefile, fig=fig) return { "title": f"Stocks: Keltner-Channel {ticker.upper()}", "description": plt_link, "imagefile": imagefile, }
def candle_command( ticker: str = "", interval: int = 15, past_days: int = 0, extended_hours: bool = False, start="", end="", news: bool = False, heikin_candles: bool = False, vwap: bool = False, ): """Shows candle plot of loaded ticker or crypto. [Source: Yahoo Finance or Binance API] Parameters ---------- ticker : Stock Ticker interval : Chart Minute Interval, 1440 for Daily past_days: Past Days to Display. Default: 0(Not for Daily) extended_hours: Display Pre/After Market Hours. Default: False start: YYYY-MM-DD format end: YYYY-MM-DD format news: Display clickable news markers on interactive chart. Default: False heikin_candles: Heikin Ashi candles. Default: False """ logger.info( "candle %s %s %s %s %s %s %s %s", ticker, interval, past_days, extended_hours, start, end, news, heikin_candles, ) # Retrieve Data df_stock, start, end, bar_start = load_candle.stock_data( ticker=ticker, interval=interval, past_days=past_days, extended_hours=extended_hours, start=start, end=end, news=news, heikin_candles=heikin_candles, ) df_stock = df_stock.loc[(df_stock.index >= start) & (df_stock.index < end)] df_stock = df_stock.join(overlap_model.vwap(df_stock, 0)) # Check that loading a stock was not successful if df_stock.empty: raise Exception(f"No data found for {ticker.upper()}.") # Output Data if interval != 1440: df_stock = df_stock.loc[(df_stock.index >= bar_start) & (df_stock.index < end)] plot = load_candle.candle_fig( df_stock, ticker, interval, extended_hours, news, bar=bar_start, int_bar=interval, ) title = f"{plot['plt_title']} Chart" fig = plot["fig"] if interval != 1440 and vwap: fig.add_trace( go.Scatter( name="VWAP", x=df_stock.index, y=df_stock["VWAP_D"], opacity=0.65, line=dict(color="#00e6c3", width=2), showlegend=True, ), secondary_y=True, ) fig.update_layout( margin=dict(l=0, r=0, t=40, b=20), template=imps.PLT_CANDLE_STYLE_TEMPLATE, title=title, title_x=0.5, title_font_size=14, ) imagefile = "candle.png" # Check if interactive settings are enabled plt_link = "" if imps.INTERACTIVE: plt_link = imps.inter_chart(fig, imagefile, callback=True) fig.update_layout( width=800, height=500, ) imagefile = imps.image_border(imagefile, fig=fig) return { "title": title, "description": plt_link, "imagefile": imagefile, }
def rsi_command( ticker="", interval: int = 15, past_days: int = 0, length="14", scalar="100", drift="1", start="", end="", extended_hours: bool = False, heikin_candles: bool = False, news: bool = False, ): """Displays chart with relative strength index [Yahoo Finance]""" # Debug if imps.DEBUG: # pylint: disable=logging-too-many-args logger.debug( "ta rsi %s %s %s %s %s %s", ticker, interval, past_days, length, scalar, drift, start, end, extended_hours, heikin_candles, news, ) # Check for argument if ticker == "": raise Exception("Stock ticker is required") if not length.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") length = int(length) if not scalar.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") scalar = float(scalar) if not drift.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") drift = int(drift) df_stock, start, end, bar_start = load_candle.stock_data( ticker=ticker, interval=interval, past_days=past_days, extended_hours=extended_hours, start=start, end=end, heikin_candles=heikin_candles, ) if df_stock.empty: raise Exception("No Data Found") df_ta = df_stock.loc[(df_stock.index >= start) & (df_stock.index < end)] df_ta = df_ta.join(momentum_model.rsi(df_ta["Adj Close"], length, scalar, drift)) # Output Data if interval != 1440: df_ta = df_ta.loc[(df_ta.index >= bar_start) & (df_ta.index < end)] df_ta = df_ta.fillna(0.0) plot = load_candle.candle_fig( df_ta, ticker, interval, extended_hours, news, bar=bar_start, int_bar=interval, rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.07, row_width=[0.5, 0.6], specs=[ [{"secondary_y": True}], [{"secondary_y": False}], ], ) title = f"<b>{plot['plt_title']} RSI</b>" fig = plot["fig"] fig.add_trace( go.Scatter( name=f"RSI {length}", mode="lines", x=df_ta.index, y=df_ta.iloc[:, 6].values if interval != 1440 else df_ta.iloc[:, 11].values, opacity=1, ), row=2, col=1, secondary_y=False, ) fig.add_hrect( y0=70, y1=100, fillcolor="red", opacity=0.2, layer="below", line_width=0, row=2, col=1, ) fig.add_hrect( y0=0, y1=30, fillcolor="green", opacity=0.2, layer="below", line_width=0, row=2, col=1, ) fig.add_hline( y=70, fillcolor="green", opacity=1, layer="below", line_width=3, line=dict(color="red", dash="dash"), row=2, col=1, ) fig.add_hline( y=30, fillcolor="green", opacity=1, layer="below", line_width=3, line=dict(color="green", dash="dash"), row=2, col=1, ) fig.update_layout( margin=dict(l=0, r=0, t=50, b=20), template=imps.PLT_TA_STYLE_TEMPLATE, colorway=imps.PLT_TA_COLORWAY, title=title, title_x=0.1, title_font_size=14, dragmode="pan", yaxis=dict(nticks=15), yaxis2=dict(nticks=10), ) imagefile = "ta_rsi.png" # Check if interactive settings are enabled plt_link = "" if imps.INTERACTIVE: plt_link = imps.inter_chart(fig, imagefile, callback=False) fig.update_layout( width=800, height=500, ) imagefile = imps.image_border(imagefile, fig=fig) return { "title": f"Stocks: Relative-Strength-Index {ticker.upper()}", "description": plt_link, "imagefile": imagefile, }
def bbands_command( ticker="", interval: int = 15, past_days: int = 0, length="20", n_std: float = 2.0, ma_mode="sma", start="", end="", extended_hours: bool = False, heikin_candles: bool = False, news: bool = False, ): """Displays chart with bollinger bands [Yahoo Finance]""" # Debug if imps.DEBUG: # pylint: disable=logging-too-many-args logger.debug( "ta bbands %s %s %s %s %s %s %s %s %s %s", ticker, past_days, length, n_std, ma_mode, start, end, extended_hours, heikin_candles, news, ) # Check for argument possible_ma = [ "dema", "ema", "fwma", "hma", "linreg", "midpoint", "pwma", "rma", "sinwma", "sma", "swma", "t3", "tema", "trima", "vidya", "wma", "zlma", ] if ticker == "": raise Exception("Stock ticker is required") if not length.lstrip("-").isnumeric(): raise Exception("Number has to be an integer") ta_length = float(length) n_std = float(n_std) if ma_mode not in possible_ma: raise Exception("Invalid ma entered") # Retrieve Data df_stock, start, end, bar_start = load_candle.stock_data( ticker=ticker, interval=interval, past_days=past_days, extended_hours=extended_hours, start=start, end=end, heikin_candles=heikin_candles, ) if df_stock.empty: raise Exception("No Data Found") df_ta = df_stock.loc[(df_stock.index >= start) & (df_stock.index < end)] df_ta = df_ta.join( volatility_model.bbands(df_ta["Adj Close"], ta_length, n_std, ma_mode)) # Output Data if interval != 1440: df_ta = df_ta.loc[(df_ta.index >= bar_start) & (df_ta.index < end)] df_ta = df_ta.fillna(0.0) plot = load_candle.candle_fig(df_ta, ticker, interval, extended_hours, news) title = f"<b>{plot['plt_title']} Bollinger Bands ({ma_mode.upper()})</b>" fig = plot["fig"] idx = 6 if interval != 1440 else 11 fig.add_trace( go.Scatter( name=f"BBU_{length}_{n_std}", x=df_ta.index, y=df_ta.iloc[:, (idx + 2)].values, opacity=1, mode="lines", line_color="indigo", ), secondary_y=True, row=1, col=1, ) fig.add_trace( go.Scatter( name=f"BBL_{length}_{n_std}", x=df_ta.index, y=df_ta.iloc[:, idx].values, opacity=1, mode="lines", line_color="indigo", fill="tonexty", fillcolor="rgba(74, 0, 128, 0.2)", ), secondary_y=True, row=1, col=1, ) fig.add_trace( go.Scatter( name=f"BBM_{length}_{n_std}", x=df_ta.index, y=df_ta.iloc[:, (idx + 1)].values, opacity=1, line=dict( width=1.5, dash="dash", ), ), secondary_y=True, row=1, col=1, ) fig.update_layout( margin=dict(l=0, r=0, t=50, b=20), template=imps.PLT_TA_STYLE_TEMPLATE, colorway=imps.PLT_TA_COLORWAY, title=title, title_x=0.1, title_font_size=14, dragmode="pan", ) imagefile = "ta_bbands.png" # Check if interactive settings are enabled plt_link = "" if imps.INTERACTIVE: plt_link = imps.inter_chart(fig, imagefile, callback=False) fig.update_layout( width=800, height=500, ) imagefile = imps.image_border(imagefile, fig=fig) return { "title": f"Stocks: Bollinger-Bands {ticker.upper()}", "description": plt_link, "imagefile": imagefile, }
def ad_command( ticker="", interval: int = 15, past_days: int = 0, is_open: bool = False, start="", end="", extended_hours: bool = False, heikin_candles: bool = False, news: bool = False, ): """Displays chart with accumulation/distribution line [Yahoo Finance]""" # Debug if imps.DEBUG: # pylint: disable=logging-too-many-args logger.debug( "ta ad %s %s %s %s %s %s %s %s %s", ticker, interval, past_days, is_open, start, end, extended_hours, heikin_candles, news, ) # Check for argument if ticker == "": raise Exception("Stock ticker is required") # Retrieve Data df_stock, start, end, bar_start = load_candle.stock_data( ticker=ticker, interval=interval, past_days=past_days, extended_hours=extended_hours, start=start, end=end, heikin_candles=heikin_candles, ) if df_stock.empty: raise Exception("No Data Found") df_ta = df_stock.loc[(df_stock.index >= start) & (df_stock.index < end)] df_ta = df_ta.join(volume_model.ad(df_stock, is_open)) # Output Data if interval != 1440: df_ta = df_ta.loc[(df_ta.index >= bar_start) & (df_ta.index < end)] df_ta = df_ta.fillna(0.0) plot = load_candle.candle_fig( df_ta, ticker, interval, extended_hours, news, bar=bar_start, int_bar=interval, rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.07, row_width=[0.4, 0.6], specs=[ [{ "secondary_y": True }], [{ "secondary_y": False }], ], ) title = f"<b>{plot['plt_title']} A/D</b>" fig = plot["fig"] fig.add_trace( go.Scatter( name="A/D", x=df_ta.index, y=df_ta.iloc[:, 6].values if interval != 1440 else df_ta.iloc[:, 11].values, mode="lines", line=dict(width=2), opacity=1, ), row=2, col=1, ) fig.add_hline( y=0, fillcolor="grey", opacity=1, layer="below", line_width=3, line=dict(color="grey", dash="dash"), row=2, col=1, ) fig.update_layout( margin=dict(l=0, r=0, t=50, b=20), template=imps.PLT_TA_STYLE_TEMPLATE, colorway=imps.PLT_TA_COLORWAY, title=title, title_x=0.1, title_font_size=14, dragmode="pan", ) imagefile = "ta_ad.png" # Check if interactive settings are enabled plt_link = "" if imps.INTERACTIVE: plt_link = imps.inter_chart(fig, imagefile, callback=False) fig.update_layout( width=800, height=500, ) imagefile = imps.image_border(imagefile, fig=fig) return { "title": f"Stocks: Accumulation/Distribution Line {ticker.upper()}", "description": plt_link, "imagefile": imagefile, }
def ma_command( ticker="", interval: int = 15, past_days: int = 0, ma_mode="ema", window="", offset: int = 0, start="", end="", extended_hours: bool = False, heikin_candles: bool = False, news: bool = False, ): """Displays chart with selected Moving Average [Yahoo Finance]""" # Debug if imps.DEBUG: # pylint: disable=logging-too-many-args logger.debug( "ta ma %s %s %s %s %s %s %s %s %s %s %s", ticker, interval, past_days, ma_mode, window, offset, start, end, extended_hours, heikin_candles, news, ) # Check for argument overlap_ma = { "ema": overlap_model.ema, "hma": overlap_model.hma, "sma": overlap_model.sma, "wma": overlap_model.wma, "zlma": overlap_model.zlma, } if ticker == "": raise Exception("Stock ticker is required") # Retrieve Data df_stock, start, end, bar_start = load_candle.stock_data( ticker=ticker, interval=interval, past_days=past_days, extended_hours=extended_hours, start=start, end=end, heikin_candles=heikin_candles, ) if df_stock.empty: raise Exception("No Data Found") if window == "": window = [20, 50] else: window_temp = list() for wind in window.split(","): try: window_temp.append(int(wind)) except Exception as e: raise Exception("Window needs to be a float") from e window = window_temp df_ta = df_stock.loc[(df_stock.index >= start) & (df_stock.index < end)] if df_ta.empty: raise Exception("No Data Found") for win in window: ema_data = overlap_ma[ma_mode](values=df_ta["Adj Close"], length=win, offset=offset) df_ta = df_ta.join(ema_data) # Output Data if interval != 1440: df_ta = df_ta.loc[(df_ta.index >= bar_start) & (df_ta.index < end)] df_ta = df_ta.fillna(0.0) plot = load_candle.candle_fig( df_ta, ticker, interval, extended_hours, news, bar=bar_start, int_bar=interval, ) title = f"<b>{plot['plt_title']} Moving Average ({ma_mode.upper()})</b>" fig = plot["fig"] i2 = 6 if interval != 1440 else 11 for i in range(i2, df_ta.shape[1]): fig.add_trace( go.Scatter( name=f"{df_ta.iloc[:, i].name}", mode="lines", x=df_ta.index, y=df_ta.iloc[:, i].values, opacity=1, ), secondary_y=True, row=1, col=1, ) fig.update_layout( margin=dict(l=0, r=0, t=50, b=20), template=imps.PLT_TA_STYLE_TEMPLATE, colorway=imps.PLT_TA_COLORWAY, title=title, title_x=0.1, title_font_size=14, dragmode="pan", ) imagefile = "ta_ma.png" # Check if interactive settings are enabled plt_link = "" if imps.INTERACTIVE: plt_link = imps.inter_chart(fig, imagefile, callback=False) fig.update_layout( width=800, height=500, ) imagefile = imps.image_border(imagefile, fig=fig) return { "title": f"Stocks: Moving Average {ma_mode.upper()}", "description": plt_link, "imagefile": imagefile, }
def cci_command( ticker: str = "", interval: int = 15, past_days: int = 0, length="14", scalar="0.015", start="", end="", extended_hours: bool = False, heikin_candles: bool = False, news: bool = False, ): """Displays chart with commodity channel index [Yahoo Finance]""" # Debug if imps.DEBUG: logger.debug( "ta cci %s %s %s %s %s %s %s %s %s %s", ticker, interval, past_days, length, scalar, start, end, extended_hours, heikin_candles, news, ) # Check for argument if ticker == "": raise Exception("Stock ticker is required") # Retrieve Data df_stock, start, end, bar_start = load_candle.stock_data( ticker=ticker, interval=interval, past_days=past_days, extended_hours=extended_hours, start=start, end=end, heikin_candles=heikin_candles, ) if df_stock.empty: raise Exception("No Data Found") # pylint try: length = int(length) except ValueError as e: raise Exception("Length has to be an integer") from e try: scalar = float(scalar) except ValueError as e: raise Exception("Scalar has to be an integer") from e df_ta = df_stock.loc[(df_stock.index >= start) & (df_stock.index < end)] if df_ta.empty: raise Exception("No Data Found") ta_data = momentum_model.cci( df_ta["High"], df_ta["Low"], df_ta["Adj Close"], length, scalar ) df_ta = df_ta.join(ta_data) # Output Data if interval != 1440: df_ta = df_ta.loc[(df_ta.index >= bar_start) & (df_ta.index < end)] df_ta = df_ta.fillna(0.0) plot = load_candle.candle_fig( df_ta, ticker, interval, extended_hours, news, bar=bar_start, int_bar=interval, rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.07, row_width=[0.4, 0.6], specs=[[{"secondary_y": True}], [{"secondary_y": False}]], ) title = f"<b>{plot['plt_title']} Commodity-Channel-Index</b>" fig = plot["fig"] ta_values = ( df_ta.iloc[:, 6].values if interval != 1440 else df_ta.iloc[:, 11].values ) dmin = ta_values.min() dmax = ta_values.max() fig.add_trace( go.Scatter( name=f"CCI ({length}) ({scalar})", mode="lines", x=df_ta.index, y=ta_values, opacity=1, ), row=2, col=1, ) fig.add_hrect( y0=100, y1=dmax, fillcolor="red", opacity=0.2, layer="below", line_width=0, row=2, col=1, ) fig.add_hrect( y0=-100, y1=dmin, fillcolor="green", opacity=0.2, layer="below", line_width=0, row=2, col=1, ) fig.add_hline( y=-100, fillcolor="green", opacity=1, layer="below", line_width=3, line=dict(color="green", dash="dash"), row=2, col=1, ) fig.add_hline( y=100, fillcolor="red", opacity=1, layer="below", line_width=3, line=dict(color="red", dash="dash"), row=2, col=1, ) fig.update_layout( margin=dict(l=0, r=0, t=50, b=20), template=imps.PLT_TA_STYLE_TEMPLATE, colorway=imps.PLT_TA_COLORWAY, title=title, title_x=0.02, title_font_size=14, dragmode="pan", ) imagefile = "ta_cci.png" # Check if interactive settings are enabled plt_link = "" if imps.INTERACTIVE: plt_link = imps.inter_chart(fig, imagefile, callback=False) fig.update_layout( width=800, height=500, ) imagefile = imps.image_border(imagefile, fig=fig) return { "title": f"Stocks: Commodity-Channel-Index {ticker.upper()}", "description": plt_link, "imagefile": imagefile, }