Files
OpenBB/openbb_terminal/common/technical_analysis/volatility_view.py
Minha, Jeong 2815f42a3c patternize validation of axes count with typo fix (#1781)
* patternize validation of axes count with typo fix

* remove unused console import

* fix suffix_text arg name typo

* Black

* add docstring with typehint, fast return if true

* Common : ta > fixing import

* Portfolio : view fix

* Black

* Helper : simplify `is_valid_axes_count`

Co-authored-by: didierlopes.eth <dro.lopes@campus.fct.unl.pt>
Co-authored-by: Chavithra PARANA <chavithra@gmail.com>
Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com>
2022-05-17 20:20:48 +02:00

278 lines
7.4 KiB
Python

"""Volatility Technical Indicators View"""
__docformat__ = "numpy"
import logging
import os
from typing import Optional, List
import matplotlib.pyplot as plt
import pandas as pd
from openbb_terminal.config_terminal import theme
from openbb_terminal.common.technical_analysis import volatility_model
from openbb_terminal.config_plot import PLOT_DPI
from openbb_terminal.decorators import log_start_end
from openbb_terminal.helper_funcs import (
export_data,
plot_autoscale,
reindex_dates,
is_valid_axes_count,
)
logger = logging.getLogger(__name__)
@log_start_end(log=logger)
def display_bbands(
ohlc: pd.DataFrame,
ticker: str = "",
length: int = 15,
n_std: float = 2,
mamode: str = "sma",
export: str = "",
external_axes: Optional[List[plt.Axes]] = None,
):
"""Show bollinger bands
Parameters
----------
ohlc : pd.DataFrame
Dataframe of stock prices
ticker : str
Ticker
length : int
Length of window to calculate BB
n_std : float
Number of standard deviations to show
mamode : str
Method of calculating average
export : str
Format of export file
external_axes : Optional[List[plt.Axes]], optional
External axes (1 axis is expected in the list), by default None
"""
df_ta = volatility_model.bbands(ohlc["Adj Close"], length, n_std, mamode)
plot_data = pd.merge(ohlc, df_ta, how="outer", left_index=True, right_index=True)
plot_data = reindex_dates(plot_data)
# This plot has 1 axis
if not external_axes:
_, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
elif is_valid_axes_count(external_axes, 1):
(ax,) = external_axes
else:
return
ax.plot(
plot_data.index,
plot_data["Adj Close"].values,
)
ax.plot(
plot_data.index,
plot_data[df_ta.columns[0]].values,
theme.down_color,
linewidth=0.7,
)
ax.plot(plot_data.index, plot_data[df_ta.columns[1]].values, ls="--", linewidth=0.7)
ax.plot(
plot_data.index,
plot_data[df_ta.columns[2]].values,
theme.up_color,
linewidth=0.7,
)
ax.set_title(f"{ticker} Bollinger Bands")
ax.set_xlim(plot_data.index[0], plot_data.index[-1])
ax.set_ylabel("Share Price ($)")
ax.legend([ticker, df_ta.columns[0], df_ta.columns[1], df_ta.columns[2]])
ax.fill_between(
df_ta.index, df_ta.iloc[:, 0].values, df_ta.iloc[:, 2].values, alpha=0.1
)
theme.style_primary_axis(
ax,
data_index=plot_data.index.to_list(),
tick_labels=plot_data["date"].to_list(),
)
if external_axes is None:
theme.visualize_output()
export_data(
export,
os.path.dirname(os.path.abspath(__file__)).replace("common", "stocks"),
"bbands",
df_ta,
)
@log_start_end(log=logger)
def display_donchian(
ohlc: pd.DataFrame,
ticker: str = "",
upper_length: int = 20,
lower_length: int = 20,
export: str = "",
external_axes: Optional[List[plt.Axes]] = None,
):
"""Show donchian channels
Parameters
----------
ohlc : pd.DataFrame
Dataframe of stock prices
ticker : str
Ticker
upper_length : int
Length of window to calculate upper channel
lower_length : int
Length of window to calculate lower channel
export : str
Format of export file
external_axes : Optional[List[plt.Axes]], optional
External axes (1 axis is expected in the list), by default None
"""
df_ta = volatility_model.donchian(
ohlc["High"], ohlc["Low"], upper_length, lower_length
)
plot_data = pd.merge(ohlc, df_ta, how="outer", left_index=True, right_index=True)
plot_data = reindex_dates(plot_data)
# This plot has 1 axis
if external_axes is None:
_, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
elif is_valid_axes_count(external_axes, 1):
(ax,) = external_axes
else:
return
ax.plot(plot_data.index, plot_data["Adj Close"].values)
ax.plot(
plot_data.index,
plot_data[df_ta.columns[0]].values,
linewidth=0.7,
label="Upper",
)
ax.plot(plot_data.index, plot_data[df_ta.columns[1]].values, linewidth=0.7, ls="--")
ax.plot(
plot_data.index,
plot_data[df_ta.columns[2]].values,
linewidth=0.7,
label="Lower",
)
ax.fill_between(
plot_data.index,
plot_data[df_ta.columns[0]].values,
plot_data[df_ta.columns[2]].values,
alpha=0.1,
)
ax.set_title(f"{ticker} donchian")
ax.set_xlim(plot_data.index[0], plot_data.index[-1])
ax.set_ylabel("Price ($)")
ax.legend([ticker, df_ta.columns[0], df_ta.columns[1], df_ta.columns[2]])
theme.style_primary_axis(
ax,
data_index=plot_data.index.to_list(),
tick_labels=plot_data["date"].to_list(),
)
if external_axes is None:
theme.visualize_output()
export_data(
export,
os.path.dirname(os.path.abspath(__file__)).replace("common", "stocks"),
"donchian",
df_ta,
)
@log_start_end(log=logger)
def view_kc(
ohlc: pd.DataFrame,
length: int = 20,
scalar: float = 2,
mamode: str = "ema",
offset: int = 0,
s_ticker: str = "",
export: str = "",
external_axes: Optional[List[plt.Axes]] = None,
):
"""View Keltner Channels Indicator
Parameters
----------
ohlc : pd.DataFrame
Dataframe of stock prices
length : int
Length of window
mamode: str
Type of filter
offset : int
Offset value
s_ticker : str
Ticker
export : str
Format to export data
external_axes : Optional[List[plt.Axes]], optional
External axes (2 axes are expected in the list), by default None
"""
df_ta = volatility_model.kc(
ohlc["High"],
ohlc["Low"],
ohlc["Adj Close"],
length,
scalar,
mamode,
offset,
)
plot_data = pd.merge(ohlc, df_ta, how="outer", left_index=True, right_index=True)
plot_data = reindex_dates(plot_data)
# This plot has 1 axis
if external_axes is None:
_, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
elif is_valid_axes_count(external_axes, 1):
(ax,) = external_axes
else:
return
ax.plot(plot_data.index, plot_data["Adj Close"].values)
ax.plot(
plot_data.index,
plot_data[df_ta.columns[0]].values,
linewidth=0.7,
label="Upper",
)
ax.plot(plot_data.index, plot_data[df_ta.columns[1]].values, linewidth=0.7, ls="--")
ax.plot(
plot_data.index,
plot_data[df_ta.columns[2]].values,
linewidth=0.7,
label="Lower",
)
ax.fill_between(
plot_data.index,
plot_data[df_ta.columns[0]].values,
plot_data[df_ta.columns[2]].values,
alpha=0.1,
)
ax.set_title(f"{s_ticker} Keltner Channels")
ax.set_xlim(plot_data.index[0], plot_data.index[-1])
ax.set_ylabel("Price")
ax.legend([s_ticker, df_ta.columns[0], df_ta.columns[1], df_ta.columns[2]])
theme.style_primary_axis(
ax,
data_index=plot_data.index.to_list(),
tick_labels=plot_data["date"].to_list(),
)
if external_axes is None:
theme.visualize_output()
export_data(
export,
os.path.dirname(os.path.abspath(__file__)).replace("common", "stocks"),
"kc",
df_ta,
)