mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-30 22:11:55 +00:00
add Keltner Channels to TA menu (#711)
* hugo server * Update test.yml * Update test.yml * Create gh-pages.yml * Update gh-pages.yml * Update config.toml * Update config.toml * update themes and public * Update gh-pages.yml * Update gh-pages.yml * Update gh-pages.yml * remove themes * add themes * Update gh-pages.yml * Update config.toml * Update config.toml * remove * re-add theme * Update config.toml * Update config.toml * Update config.toml * Update gh-pages.yml * Update gh-pages.yml * Update config.toml * Update config.toml * Update config.toml * Update _index.md * Update config.toml * Update gh-pages.yml * Update README.md * Update README.md * add Keltner Channels to TA menu * add ```if other_args: to call functions Co-authored-by: didier <dro.lopes@campus.fct.unl.pt>
This commit is contained in:
@@ -333,20 +333,20 @@ def view_fisher(
|
||||
else:
|
||||
ax.plot(df_stock.index, df_stock["Close"].values, "k", lw=1)
|
||||
ax.set_xlim(df_stock.index[0], df_stock.index[-1])
|
||||
ax.set_ylabel("Share Price ($)")
|
||||
ax.set_ylabel("Price")
|
||||
ax.grid(b=True, which="major", color="#666666", linestyle="-")
|
||||
|
||||
ax2 = axes[1]
|
||||
ax2.plot(
|
||||
df_ta.index,
|
||||
df_ta["FISHERT_14_1"].values,
|
||||
df_ta.iloc[:, 0].values,
|
||||
"b",
|
||||
lw=2,
|
||||
label="Fisher",
|
||||
)
|
||||
ax2.plot(
|
||||
df_ta.index,
|
||||
df_ta["FISHERTs_14_1"].values,
|
||||
df_ta.iloc[:, 1].values,
|
||||
"fuchsia",
|
||||
lw=2,
|
||||
label="Signal",
|
||||
|
||||
@@ -81,3 +81,58 @@ def donchian(
|
||||
).dropna()
|
||||
|
||||
return df_ta
|
||||
|
||||
|
||||
def kc(
|
||||
s_interval: str,
|
||||
df_stock: pd.DataFrame,
|
||||
length: int,
|
||||
scalar: float,
|
||||
mamode: str,
|
||||
offset: int,
|
||||
) -> pd.DataFrame:
|
||||
"""Keltner Channels
|
||||
|
||||
Parameters
|
||||
----------
|
||||
s_interval : str
|
||||
Interval of stock data
|
||||
df_stock : pd.DataFrame
|
||||
Dataframe of prices
|
||||
length : int
|
||||
Length of window
|
||||
mamode: str
|
||||
Type of filter
|
||||
offset : int
|
||||
Offset value
|
||||
|
||||
Returns
|
||||
-------
|
||||
df_en : pd.DataFrame
|
||||
Dataframe of rolling kc
|
||||
"""
|
||||
# Daily
|
||||
if s_interval == "1440min":
|
||||
df_kc = ta.kc(
|
||||
high=df_stock["High"],
|
||||
low=df_stock["Low"],
|
||||
close=df_stock["Adj Close"],
|
||||
length=length,
|
||||
scalar=scalar,
|
||||
mamode=mamode,
|
||||
offset=offset,
|
||||
).dropna()
|
||||
|
||||
# Intraday
|
||||
else:
|
||||
df_kc = ta.kc(
|
||||
high=df_stock["High"],
|
||||
low=df_stock["Low"],
|
||||
close=df_stock["Close"],
|
||||
length=length,
|
||||
scalar=scalar,
|
||||
mamode=mamode,
|
||||
offset=offset,
|
||||
).dropna()
|
||||
|
||||
return df_kc
|
||||
|
||||
@@ -152,3 +152,74 @@ def view_donchian(
|
||||
"donchian",
|
||||
df_ta,
|
||||
)
|
||||
|
||||
|
||||
def view_kc(
|
||||
s_ticker: str,
|
||||
s_interval: str,
|
||||
df_stock: pd.DataFrame,
|
||||
length: int,
|
||||
scalar: float,
|
||||
mamode: str,
|
||||
offset: int,
|
||||
export: str,
|
||||
):
|
||||
"""View Keltner Channels Indicator
|
||||
|
||||
Parameters
|
||||
----------
|
||||
s_ticker : str
|
||||
Ticker
|
||||
s_interval : str
|
||||
Interval of data
|
||||
df_stock : pd.DataFrame
|
||||
Dataframe of stock prices
|
||||
length : int
|
||||
Length of window
|
||||
mamode: str
|
||||
Type of filter
|
||||
offset : int
|
||||
Offset value
|
||||
export : str
|
||||
Format to export data
|
||||
"""
|
||||
df_ta = volatility_model.kc(s_interval, df_stock, length, scalar, mamode, offset)
|
||||
fig, ax = plt.subplots(figsize=plot_autoscale(), dpi=PLOT_DPI)
|
||||
if s_interval == "1440min":
|
||||
ax.plot(df_stock.index, df_stock["Adj Close"].values, color="fuchsia")
|
||||
else:
|
||||
ax.plot(df_stock.index, df_stock["Close"].values, color="fuchsia")
|
||||
ax.plot(df_ta.index, df_ta.iloc[:, 0].values, "b", lw=1.5, label="upper")
|
||||
ax.plot(df_ta.index, df_ta.iloc[:, 1].values, "b", lw=1.5, ls="--")
|
||||
ax.plot(df_ta.index, df_ta.iloc[:, 2].values, "b", lw=1.5, label="lower")
|
||||
ax.set_title(f"{s_ticker} Keltner Channels")
|
||||
ax.set_xlim(df_stock.index[0], df_stock.index[-1])
|
||||
ax.set_xlabel("Time")
|
||||
ax.set_ylabel("Price")
|
||||
|
||||
ax.legend([s_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,
|
||||
color="b",
|
||||
)
|
||||
ax.grid(b=True, which="major", color="#666666", linestyle="-")
|
||||
|
||||
if gtff.USE_ION:
|
||||
plt.ion()
|
||||
|
||||
plt.gcf().autofmt_xdate()
|
||||
fig.tight_layout(pad=1)
|
||||
|
||||
plt.legend()
|
||||
plt.show()
|
||||
|
||||
print("")
|
||||
export_data(
|
||||
export,
|
||||
os.path.dirname(os.path.abspath(__file__)).replace("common", "stocks"),
|
||||
"kc",
|
||||
df_ta,
|
||||
)
|
||||
|
||||
@@ -62,6 +62,7 @@ class TechnicalAnalysisController:
|
||||
"aroon",
|
||||
"bbands",
|
||||
"donchian",
|
||||
"kc",
|
||||
"ad",
|
||||
"adosc",
|
||||
"obv",
|
||||
@@ -131,6 +132,7 @@ Trend:
|
||||
Volatility:
|
||||
bbands bollinger bands
|
||||
donchian donchian channels
|
||||
kc keltner channels
|
||||
Volume:
|
||||
ad accumulation/distribution line
|
||||
adosc chaikin oscillator
|
||||
@@ -281,6 +283,10 @@ 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
|
||||
@@ -325,6 +331,10 @@ 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
|
||||
@@ -434,6 +444,7 @@ Custom:
|
||||
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
|
||||
@@ -485,6 +496,7 @@ Custom:
|
||||
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
|
||||
@@ -536,6 +548,7 @@ Custom:
|
||||
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
|
||||
@@ -627,6 +640,10 @@ 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
|
||||
@@ -690,6 +707,10 @@ 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
|
||||
@@ -761,6 +782,10 @@ 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
|
||||
@@ -829,6 +854,10 @@ 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
|
||||
@@ -898,6 +927,10 @@ 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
|
||||
@@ -947,6 +980,10 @@ 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
|
||||
@@ -995,9 +1032,14 @@ 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
|
||||
|
||||
momentum_view.view_cg(
|
||||
s_ticker=self.ticker,
|
||||
s_interval=self.interval,
|
||||
@@ -1058,6 +1100,10 @@ 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
|
||||
@@ -1113,15 +1159,6 @@ Custom:
|
||||
default=100,
|
||||
help="scalar",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--offset",
|
||||
action="store",
|
||||
dest="n_offset",
|
||||
type=check_positive,
|
||||
default=0,
|
||||
help="offset",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--export",
|
||||
choices=["csv", "json", "xlsx"],
|
||||
@@ -1132,6 +1169,10 @@ 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
|
||||
@@ -1204,9 +1245,14 @@ 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
|
||||
|
||||
volatility_view.view_bbands(
|
||||
ticker=self.ticker,
|
||||
s_interval=self.interval,
|
||||
@@ -1263,9 +1309,14 @@ 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
|
||||
|
||||
volatility_view.view_donchian(
|
||||
ticker=self.ticker,
|
||||
s_interval=self.interval,
|
||||
@@ -1278,6 +1329,87 @@ Custom:
|
||||
except Exception as e:
|
||||
print(e, "\n")
|
||||
|
||||
def call_kc(self, other_args: List[str]):
|
||||
"""Process kc command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
add_help=False,
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
|
||||
prog="kc",
|
||||
description="""
|
||||
Keltner Channels are volatility-based bands that are placed
|
||||
on either side of an asset's price and can aid in determining
|
||||
the direction of a trend.The Keltner channel uses the average
|
||||
true range (ATR) or volatility, with breaks above or below the top
|
||||
and bottom barriers signaling a continuation.
|
||||
""",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-l",
|
||||
"--length",
|
||||
action="store",
|
||||
dest="n_length",
|
||||
type=check_positive,
|
||||
default=20,
|
||||
help="Window length",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--scalar",
|
||||
action="store",
|
||||
dest="n_scalar",
|
||||
type=check_positive,
|
||||
default=2,
|
||||
help="scalar",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-m",
|
||||
"--mamode",
|
||||
action="store",
|
||||
dest="s_mamode",
|
||||
default="ema",
|
||||
choices=["ema", "sma", "wma", "hma", "zlma"],
|
||||
help="mamode",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--offset",
|
||||
action="store",
|
||||
dest="n_offset",
|
||||
type=int,
|
||||
default=0,
|
||||
help="offset",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--export",
|
||||
choices=["csv", "json", "xlsx"],
|
||||
default="",
|
||||
type=str,
|
||||
dest="export",
|
||||
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
|
||||
|
||||
volatility_view.view_kc(
|
||||
s_ticker=self.ticker,
|
||||
s_interval=self.interval,
|
||||
df_stock=self.stock,
|
||||
length=ns_parser.n_length,
|
||||
scalar=ns_parser.n_scalar,
|
||||
mamode=ns_parser.s_mamode,
|
||||
offset=ns_parser.n_offset,
|
||||
export=ns_parser.export,
|
||||
)
|
||||
except Exception as e:
|
||||
print(e, "\n")
|
||||
|
||||
def call_ad(self, other_args: List[str]):
|
||||
"""Process ad command"""
|
||||
parser = argparse.ArgumentParser(
|
||||
@@ -1314,6 +1446,10 @@ 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
|
||||
@@ -1379,6 +1515,10 @@ 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
|
||||
@@ -1421,6 +1561,10 @@ 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
|
||||
@@ -1475,6 +1619,10 @@ 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
|
||||
|
||||
Reference in New Issue
Block a user