mirror of
https://github.com/wassname/pandas-ta.git
synced 2026-08-06 13:20:12 +08:00
1.3 MiB
1.3 MiB
In [1]:
%matplotlib inline
import datetime as dt
import random as rnd
import numpy as np
import pandas as pd
import mplfinance as mpf
import pandas_ta as ta
%pylab inline
from alphaVantageAPI.alphavantage import AlphaVantage # pip install alphaVantage-api
e = pd.DataFrame()Populating the interactive namespace from numpy and matplotlib
In [2]:
e.ta.indicators()Pandas TA - Technical Analysis Indicators - v0.1.92b
Total Indicators: 116
Abbreviations:
aberration, above, above_value, accbands, ad, adosc, adx, amat, ao, aobv, apo, aroon, atr, bbands, below, below_value, bias, bop, brar, cci, cdl_doji, cg, chop, cksp, cmf, cmo, coppock, cross, cross_value, decreasing, dema, donchian, dpo, efi, ema, entropy, eom, er, eri, fisher, fwma, ha, hl2, hlc3, hma, ichimoku, increasing, inertia, kama, kc, kdj, kst, kurtosis, linear_decay, linreg, log_return, long_run, macd, mad, massi, median, mfi, midpoint, midprice, mom, natr, nvi, obv, ohlc4, pdist, percent_return, pgo, ppo, psar, psl, pvi, pvo, pvol, pvt, pwma, qstick, quantile, rma, roc, rsi, rvgi, rvi, short_run, sinwma, skew, slope, sma, squeeze, stdev, stoch, supertrend, swma, t3, tema, trend_return, trima, trix, true_range, tsi, ui, uo, variance, vortex, vp, vwap, vwma, wcp, willr, wma, zlma, zscore
In [3]:
help(ta.ema)Help on function ema in module pandas_ta.overlap.ema:
ema(close, length=None, offset=None, **kwargs)
Exponential Moving Average (EMA)
The Exponential Moving Average is more responsive moving average compared to the
Simple Moving Average (SMA). The weights are determined by alpha which is
proportional to it's length. There are several different methods of calculating
EMA. One method uses just the standard definition of EMA and another uses the
SMA to generate the initial value for the rest of the calculation.
Sources:
https://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_averages
https://www.investopedia.com/ask/answers/122314/what-exponential-moving-average-ema-formula-and-how-ema-calculated.asp
Calculation:
Default Inputs:
length=10, adjust=False, sma=True
if sma:
sma_nth = close[0:length].sum() / length
close[:length - 1] = np.NaN
close.iloc[length - 1] = sma_nth
EMA = close.ewm(span=length, adjust=adjust).mean()
Args:
close (pd.Series): Series of 'close's
length (int): It's period. Default: 10
offset (int): How many periods to offset the result. Default: 0
Kwargs:
adjust (bool, optional): Default: False
sma (bool, optional): If True, uses SMA for initial value. Default: True
fillna (value, optional): pd.DataFrame.fillna(value)
fill_method (value, optional): Type of fill method
Returns:
pd.Series: New feature generated.
In [4]:
def farm(ticker = "SPY", timeframe="DA", cols=["dividend", "split_coefficient"]):
AV = AlphaVantage(api_key="YOUR API KEY", premium=False, clean=True, output_size="full")
df = AV.data(symbol=ticker, function=timeframe)
df.set_index(pd.DatetimeIndex(df["date"]), inplace=True) if not df.ta.datetime_ordered else None
df.drop(cols, axis=1, inplace=True, errors="ignore")
df.name = ticker
return df
def ctitle(indicator_name, ticker="SPY", length=100):
return f"{ticker}: {indicator_name} from {recent_startdate} to {recent_startdate} ({length})"In [5]:
price_size = (16, 8)
ind_size = (16, 3.25)
ticker = "SPY"
# All Data: 0, Last Four Years: 0.25, Last Two Years: 0.5, This Year: 1, Last Half Year: 2, Last Quarter: 3
yearly_divisor = 1
recent = int(ta.TRADING_DAYS_PER_YEAR / yearly_divisor) if yearly_divisor > 0 else df.shape[0]In [6]:
# All the Data
df = farm(ticker)
print(f"{df.name}{df.shape} from {df.index[0]} to {df.index[-1]}\n{df.describe()}")
df.head()Out [6]:
SPY(5235, 7) from 1999-11-01 00:00:00 to 2020-08-20 00:00:00
open high low close adj_close \
count 5235.000000 5235.000000 5235.000000 5235.000000 5235.000000
mean 162.013736 162.972247 160.949666 162.013316 138.020292
std 62.843466 63.027789 62.644873 62.862584 70.313749
min 67.950000 70.000000 67.100000 68.110000 53.914200
25% 116.390000 117.320000 115.520000 116.495000 87.478150
50% 138.190000 139.150000 137.070000 138.031200 106.277400
75% 204.320000 205.700000 203.715000 204.595000 184.752650
max 339.050000 339.610000 337.480000 338.640000 338.640000
volume
count 5.235000e+03
mean 1.112973e+08
std 9.811238e+07
min 6.790000e+04
25% 4.755950e+07
50% 8.224767e+07
75% 1.493329e+08
max 8.708580e+08
| date | open | high | low | close | adj_close | volume | |
|---|---|---|---|---|---|---|---|
| date | |||||||
| 1999-11-01 | 1999-11-01 | 136.5000 | 137.0000 | 135.5625 | 135.5625 | 91.9725 | 4006500.0 |
| 1999-11-02 | 1999-11-02 | 135.9687 | 137.2500 | 134.5937 | 134.5937 | 91.3152 | 6516900.0 |
| 1999-11-03 | 1999-11-03 | 136.0000 | 136.3750 | 135.1250 | 135.5000 | 91.9301 | 7222300.0 |
| 1999-11-04 | 1999-11-04 | 136.7500 | 137.3593 | 135.7656 | 136.5312 | 92.6297 | 7907500.0 |
| 1999-11-05 | 1999-11-05 | 138.6250 | 139.1093 | 136.7812 | 137.8750 | 93.5414 | 7431500.0 |
In [7]:
# Recent Data
recent_startdate = df.tail(recent).index[0]
recent_enddate = df.tail(recent).index[-1]
print(f"{df.name}{df.tail(recent).shape} from {recent_startdate} to {recent_enddate}\n{df.describe()}")
df.tail(recent).head()Out [7]:
SPY(251, 7) from 2019-08-23 00:00:00 to 2020-08-20 00:00:00
open high low close adj_close \
count 5235.000000 5235.000000 5235.000000 5235.000000 5235.000000
mean 162.013736 162.972247 160.949666 162.013316 138.020292
std 62.843466 63.027789 62.644873 62.862584 70.313749
min 67.950000 70.000000 67.100000 68.110000 53.914200
25% 116.390000 117.320000 115.520000 116.495000 87.478150
50% 138.190000 139.150000 137.070000 138.031200 106.277400
75% 204.320000 205.700000 203.715000 204.595000 184.752650
max 339.050000 339.610000 337.480000 338.640000 338.640000
volume
count 5.235000e+03
mean 1.112973e+08
std 9.811238e+07
min 6.790000e+04
25% 4.755950e+07
50% 8.224767e+07
75% 1.493329e+08
max 8.708580e+08
| date | open | high | low | close | adj_close | volume | |
|---|---|---|---|---|---|---|---|
| date | |||||||
| 2019-08-23 | 2019-08-23 | 290.92 | 292.76 | 283.47 | 284.85 | 279.1950 | 149318151.0 |
| 2019-08-26 | 2019-08-26 | 287.27 | 288.00 | 285.58 | 288.00 | 282.2825 | 72620598.0 |
| 2019-08-27 | 2019-08-27 | 289.54 | 289.95 | 286.03 | 286.87 | 281.1749 | 68262998.0 |
| 2019-08-28 | 2019-08-28 | 286.14 | 289.07 | 285.25 | 288.89 | 283.1548 | 58891544.0 |
| 2019-08-29 | 2019-08-29 | 291.72 | 293.16 | 290.61 | 292.58 | 286.7716 | 57998913.0 |
In [8]:
opendf = df["open"]
closedf = df["close"]
volumedf = df["volume"]In [9]:
# help(df.ta.constants) # for more info
chart_lines = np.append(np.arange(-5, 6, 1), np.arange(-100, 110, 10))
df.ta.constants(True, chart_lines) # Adding the constants for the charts
df.ta.constants(False, np.array([-60, -40, 40, 60])) # Removing some constants from the DataFrame
print(f"Columns: {', '.join(list(df.columns))}")Columns: date, open, high, low, close, adj_close, volume, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, -100, -90, -80, -70, -50, -30, -20, -10, 10, 20, 30, 50, 70, 80, 90, 100
In [10]:
def cscheme(colors: str):
aliases = {
"BkBu": ["black", "blue"],
"gr": ["green", "red"],
"grays": ["silver", "gray"],
"mas": ["black", "green", "orange", "red"],
"bbands": ["blue", "navy", "blue"],
"kc": ["purple", "fuchsia", "purple"],
}
aliases["default"] = aliases["gr"]
return aliases[colors]
def ta_ylim(series: pd.Series, percent: float = 0.1):
smin, smax = series.min(), series.max()
if isinstance(percent, float) and 0 <= float(percent) <= 1:
y_min = (1 + percent) * smin if smin < 0 else (1 - percent) * smin
y_max = (1 - percent) * smax if smax < 0 else (1 + percent) * smax
return (y_min, y_max)
return (smin, smax)In [11]:
class Chart(object):
def __init__(self, df: pd.DataFrame = None, strategy: ta.Strategy = ta.CommonStrategy, *args, **kwargs):
self.verbose = kwargs.pop("verbose", False)
if isinstance(df, pd.DataFrame) and df.ta.datetime_ordered:
self.df = df
if self.df.name is not None and self.df.name != "":
df_name = str(self.df.name)
else:
df_name = "DataFrame"
if self.verbose: print(f"[i] Loaded {df_name}{self.df.shape}")
else:
print(f"[X] Oops! Missing 'ohlcv' data or index is not datetime ordered.\n")
return None
self._validate_ta_strategy(strategy)
self._validate_mpf_kwargs(**kwargs)
self._validate_chart_kwargs(**kwargs)
# Build TA and Plot
self.df.ta.strategy(self.strategy, verbose=self.verbose)
self._plot(**kwargs)
def _validate_ta_strategy(self, strategy):
if strategy is not None or isinstance(strategy, ta.Strategy):
self.strategy = strategy
elif len(self.strategy_ta) > 0:
print(f"[+] Strategy: {self.strategy_name}")
else:
self.strategy = ta.CommonStrategy
def _validate_chart_kwargs(self, **kwargs):
"""Chart Settings"""
self.config = {}
self.config["last"] = kwargs.pop("last", recent)
self.config["rpad"] = kwargs.pop("rpad", 10)
self.config["title"] = kwargs.pop("title", "Asset")
self.config["volume"] = kwargs.pop("volume", True)
def _validate_mpf_kwargs(self, **kwargs):
# mpf global chart settings
default_chart = mpf.available_styles()[-1]
default_mpf_width = {
'candle_linewidth': 0.6,
'candle_width': 0.525,
'volume_width': 0.525
}
mpfchart = {}
mpf_style = kwargs.pop("style", "")
if mpf_style == "" or mpf_style.lower() == "random":
mpf_styles = mpf.available_styles()
mpfchart["style"] = mpf_styles[rnd.randrange(len(mpf_styles))]
elif mpf_style.lower() in mpf.available_styles():
mpfchart["style"] = mpf_style
mpfchart["figsize"] = kwargs.pop("figsize", (12, 10))
mpfchart["non_trading"] = kwargs.pop("nontrading", False)
mpfchart["rc"] = kwargs.pop("rc", {'figure.facecolor': '#EDEDED'})
mpfchart["plot_ratios"] = kwargs.pop("plot_ratios", (12, 1.7))
mpfchart["scale_padding"] = kwargs.pop("scale_padding", {'left': 1, 'top': 4, 'right': 1, 'bottom': 1})
mpfchart["tight_layout"] = kwargs.pop("tight_layout", True)
mpfchart["type"] = kwargs.pop("type", "candle")
mpfchart["width_config"] = kwargs.pop("width_config", default_mpf_width)
mpfchart["xrotation"] = kwargs.pop("xrotation", 15)
self.mpfchart = mpfchart
def _attribution(self):
print(f"\nPandas v: {pd.__version__} [pip install pandas] https://github.com/pandas-dev/pandas")
print(f"\nData from AlphaVantage v: 1.0.19 [pip install alphaVantage-api] http://www.alphavantage.co https://github.com/twopirllc/AlphaVantageAPI")
print(f"Technical Analysis with Pandas TA v: {ta.version} [pip install pandas_ta] https://github.com/twopirllc/pandas-ta")
print(f"Charts by Matplotlib Finance v: {mpf.__version__} [pip install mplfinance] https://github.com/matplotlib/mplfinance\n")
def _right_pad_df(self, rpad: int, delta_unit: str = "D", range_freq: str = "B"):
if rpad > 0:
dfpad = self.df[-rpad:].copy()
dfpad.iloc[:,:] = np.NaN
df_frequency = self.df.index.value_counts().mode()[0] # Most common frequency
freq_delta = pd.Timedelta(df_frequency, unit=delta_unit)
new_dr = pd.date_range(start=self.df.index[-1] + freq_delta, periods=rpad, freq=range_freq)
dfpad.index = new_dr # Update the padded index with new dates
self.df = self.df.append(dfpad)
def _plot(self, **kwargs):
if not isinstance(self.mpfchart["plot_ratios"], tuple):
print(f"[X] plot_ratios must be a tuple")
return
# Override Chart Title Option
chart_title = self.config["title"]
if "title" in kwargs and isinstance(kwargs["title"], str):
chart_title = kwargs.pop("title")
# Override Right Bar Padding Option
rpad = self.config["rpad"]
if "rpad" in kwargs and kwargs["rpad"] > 0:
rpad = int(kwargs["rpad"])
def cpanel():
return len(self.mpfchart['plot_ratios'])
# Last Second Default TA Indicators
linreg = kwargs.pop("linreg", False)
linreg_name = self.df.ta.linreg(append=True).name if linreg else ""
midpoint = kwargs.pop("midpoint", False)
midpoint_name = self.df.ta.midpoint(append=True).name if midpoint else ""
ohlc4 = kwargs.pop("ohlc4", False)
ohlc4_name = self.df.ta.ohlc4(append=True).name if ohlc4 else ""
clr = kwargs.pop("clr", False)
clr_name = self.df.ta.log_return(cumulative=True, append=True).name if clr else ""
rsi = kwargs.pop("rsi", False)
rsi_length = kwargs.pop("rsi_length", None)
if isinstance(rsi_length, int) and rsi_length > 1:
rsi_name = self.df.ta.rsi(length=rsi_length, append=True).name
elif rsi:
rsi_name = self.df.ta.rsi(append=True).name
else: rsi_name = ""
zscore = kwargs.pop("zscore", False)
zscore_length = kwargs.pop("zscore_length", None)
if isinstance(zscore_length, int) and zscore_length > 1:
zs_name = self.df.ta.zscore(length=zscore_length, append=True).name
elif zscore:
zs_name = self.df.ta.zscore(append=True).name
else: zs_name = ""
macd = kwargs.pop("macd", False)
macd_name = ""
if macd:
macds = self.df.ta.macd(append=True)
macd_name = macds.name
squeeze = kwargs.pop("squeeze", False)
lazybear = kwargs.pop("lazybear", False)
squeeze_name = ""
if squeeze:
squeezes = self.df.ta.squeeze(lazybear=lazybear, detailed=True, append=True)
squeeze_name = squeezes.name
ama = kwargs.pop("archermas", False)
ama_name = ""
if ama:
amas = self.df.ta.amat(append=True)
ama_name = amas.name
aobv = kwargs.pop("archerobv", False)
aobv_name = ""
if aobv:
aobvs = self.df.ta.aobv(append=True)
aobv_name = aobvs.name
treturn = kwargs.pop("trendreturn", False)
if treturn:
# Long Trend requires Series Comparison (<=. <, = >, >=)
# or Trade Logic that yields trends in binary.
default_long = self.df["SMA_10"] > self.df["SMA_20"]
long_trend = kwargs.pop("long_trend", default_long)
short_trend = ~long_trend # Opposite/Inverse
self.df["TRl"] = ta.trend_return(self.df["close"], long_trend, cumulative=True)
self.df["TRs"] = ta.trend_return(self.df["close"], short_trend, cumulative=True)
self.df["TR"] = self.df["TRl"] + self.df["TRs"]
# Pad and trim Chart
self._right_pad_df(rpad)
mpfdf = self.df.tail(self.config["last"])
mpfdf_columns = list(self.df.columns)
# BEGIN: Custom TA Plots and Panels
# Modify the area below
taplots = [] # Holds all the additional plots
# Panel 0: Price Overlay
if linreg_name in mpfdf_columns:
taplots += [mpf.make_addplot(mpfdf[linreg_name], type=kwargs.pop("linreg_type", "line"), color=kwargs.pop("linreg_color", "black"), linestyle="-.", width=1.2, panel=0)]
if midpoint_name in mpfdf_columns:
taplots += [mpf.make_addplot(mpfdf[midpoint_name], type=kwargs.pop("midpoint_type", "scatter"), color=kwargs.pop("midpoint_color", "fuchsia"), width=0.4, panel=0)]
if ohlc4_name in mpfdf_columns:
taplots += [mpf.make_addplot(mpfdf[ohlc4_name], ylabel=ohlc4_name, type=kwargs.pop("ohlc4_type", "scatter"), color=kwargs.pop("ohlc4_color", "blue"), alpha=0.85, width=0.4, panel=0)]
if self.strategy.name == ta.CommonStrategy.name:
total_sma = 0 # Check if all the overlap indicators exists before adding plots
for c in ["SMA_10", "SMA_20", "SMA_50", "SMA_200"]:
if c in mpfdf_columns: total_sma += 1
else: print(f"[X] Indicator: {c} missing!")
if total_sma == 4:
ta_smas = [
mpf.make_addplot(mpfdf["SMA_10"], color="green", width=1.5, panel=0),
mpf.make_addplot(mpfdf["SMA_20"], color="orange", width=2, panel=0),
mpf.make_addplot(mpfdf["SMA_50"], color="red", width=2, panel=0),
mpf.make_addplot(mpfdf["SMA_200"], color="maroon", width=3, panel=0),
]
taplots += ta_smas
if len(ama_name):
amat_sr_ = mpfdf[amas.columns[-1]][mpfdf[amas.columns[-1]] > 0]
amat_sr = amat_sr_.index.to_list()
else:
amat_sr = None
# Panel 1: If volume=True, the add the VOL MA. Since we know there is only one, we immediately pop it.
if self.config["volume"]:
volma = [x for x in list(self.df.columns) if x.startswith("VOL_")].pop()
max_vol = mpfdf["volume"].max()
ta_volume = [mpf.make_addplot(mpfdf[volma], color="red", width=2, panel=1, ylim=(-.2 * max_vol, 1.5 * max_vol))]
taplots += ta_volume
# Panels 2 - 9
common_plot_ratio = (3,)
if len(aobv_name):
_p = kwargs.pop("aobv_percenty", 0.2)
aobv_ylim = ta_ylim(mpfdf[aobvs.columns[0]], _p)
taplots += [
mpf.make_addplot(mpfdf[aobvs.columns[0]], ylabel=aobv_name, color="black", width=1.5, panel=cpanel(), ylim=aobv_ylim),
mpf.make_addplot(mpfdf[aobvs.columns[2]], color="silver", width=1, panel=cpanel(), ylim=aobv_ylim),
mpf.make_addplot(mpfdf[aobvs.columns[3]], color="green", width=1, panel=cpanel(), ylim=aobv_ylim),
mpf.make_addplot(mpfdf[aobvs.columns[4]], color="red", width=1.2, panel=cpanel(), ylim=aobv_ylim),
]
self.mpfchart["plot_ratios"] += common_plot_ratio # Required to add a new Panel
if clr_name in mpfdf_columns:
_p = kwargs.pop("clr_percenty", 0.1)
clr_ylim = ta_ylim(mpfdf[clr_name], _p)
taplots += [mpf.make_addplot(mpfdf[clr_name], ylabel=clr_name, color="black", width=1.5, panel=cpanel(), ylim=clr_ylim)]
if (1 - _p) * mpfdf[clr_name].min() < 0 and (1 + _p) * mpfdf[clr_name].max() > 0:
taplots += [mpf.make_addplot(mpfdf["0"], color="gray", width=1.2, panel=cpanel(), ylim=clr_ylim)]
self.mpfchart["plot_ratios"] += common_plot_ratio # Required to add a new Panel
if rsi_name in mpfdf_columns:
rsi_ylim = (0, 100)
taplots += [
mpf.make_addplot(mpfdf[rsi_name], ylabel=rsi_name, color=kwargs.pop("rsi_color", "black"), width=1.5, panel=cpanel(), ylim=rsi_ylim),
mpf.make_addplot(mpfdf["20"], color="green", width=1, panel=cpanel(), ylim=rsi_ylim),
mpf.make_addplot(mpfdf["50"], color="gray", width=0.8, panel=cpanel(), ylim=rsi_ylim),
mpf.make_addplot(mpfdf["80"], color="red", width=1, panel=cpanel(), ylim=rsi_ylim),
]
self.mpfchart["plot_ratios"] += common_plot_ratio # Required to add a new Panel
if macd_name in mpfdf_columns:
_p = kwargs.pop("macd_percenty", 0.15)
macd_ylim = ta_ylim(mpfdf[macd_name], _p)
taplots += [
mpf.make_addplot(mpfdf[macd_name], ylabel=macd_name, color="black", width=1.5, panel=cpanel()),#, ylim=macd_ylim),
mpf.make_addplot(mpfdf[macds.columns[-1]], color="blue", width=1.1, panel=cpanel()),#, ylim=macd_ylim),
mpf.make_addplot(mpfdf[macds.columns[1]], type="bar", alpha=0.8, color="dimgray", width=0.8, panel=cpanel()),#, ylim=macd_ylim),
mpf.make_addplot(mpfdf["0"], color="black", width=1.2, panel=cpanel()),#, ylim=macd_ylim),
]
self.mpfchart["plot_ratios"] += common_plot_ratio # Required to add a new Panel
if zs_name in mpfdf_columns:
_p = kwargs.pop("zascore_percenty", 0.2)
zs_ylim = ta_ylim(mpfdf[zs_name], _p)
taplots += [
mpf.make_addplot(mpfdf[zs_name], ylabel=zs_name, color="black", width=1.5, panel=cpanel(), ylim=zs_ylim),
mpf.make_addplot(mpfdf["-3"], color="red", width=1.2, panel=cpanel(), ylim=zs_ylim),
mpf.make_addplot(mpfdf["-2"], color="orange", width=1, panel=cpanel(), ylim=zs_ylim),
mpf.make_addplot(mpfdf["-1"], color="silver", width=1, panel=cpanel(), ylim=zs_ylim),
mpf.make_addplot(mpfdf["0"], color="black", width=1.2, panel=cpanel(), ylim=zs_ylim),
mpf.make_addplot(mpfdf["1"], color="silver", width=1, panel=cpanel(), ylim=zs_ylim),
mpf.make_addplot(mpfdf["2"], color="orange", width=1, panel=cpanel(), ylim=zs_ylim),
mpf.make_addplot(mpfdf["3"], color="red", width=1.2, panel=cpanel(), ylim=zs_ylim)
]
self.mpfchart["plot_ratios"] += common_plot_ratio # Required to add a new Panel
if squeeze_name in mpfdf_columns:
_p = kwargs.pop("squeeze_percenty", 0.6)
sqz_ylim = ta_ylim(mpfdf[squeeze_name], _p)
taplots += [
mpf.make_addplot(mpfdf[squeezes.columns[-4]], type="bar", color="lime", alpha=0.65, width=0.8, panel=cpanel(), ylim=sqz_ylim),
mpf.make_addplot(mpfdf[squeezes.columns[-3]], type="bar", color="green", alpha=0.65, width=0.8, panel=cpanel(), ylim=sqz_ylim),
mpf.make_addplot(mpfdf[squeezes.columns[-2]], type="bar", color="maroon", alpha=0.65, width=0.8, panel=cpanel(), ylim=sqz_ylim),
mpf.make_addplot(mpfdf[squeezes.columns[-1]], type="bar", color="red", alpha=0.65, width=0.8, panel=cpanel(), ylim=sqz_ylim),
mpf.make_addplot(mpfdf["0"], color="black", width=1.2, panel=cpanel(), ylim=sqz_ylim),
mpf.make_addplot(mpfdf[squeezes.columns[4]], ylabel=squeeze_name, color="green", width=2, panel=cpanel(), ylim=sqz_ylim),
mpf.make_addplot(mpfdf[squeezes.columns[5]], color="red", width=1.8, panel=cpanel(), ylim=sqz_ylim),
]
self.mpfchart["plot_ratios"] += common_plot_ratio # Required to add a new Panel
if treturn:
_p = kwargs.pop("treturn_percenty", 0.33)
treturn_ylim = ta_ylim(mpfdf["TR"], _p)
taplots += [
mpf.make_addplot(mpfdf["TRl"], ylabel="Trend Return", type="bar", color="green", alpha=0.45, width=0.8, panel=cpanel(), ylim=treturn_ylim),
mpf.make_addplot(mpfdf["TRs"], type="bar", color="red", alpha=0.45, width=0.8, panel=cpanel(), ylim=treturn_ylim),
mpf.make_addplot(mpfdf["TR"], color="black", width=1.5, panel=cpanel(), ylim=treturn_ylim),
mpf.make_addplot(mpfdf["0"], color="black", width=1.2, panel=cpanel(), ylim=treturn_ylim),
]
self.mpfchart["plot_ratios"] += common_plot_ratio # Required to add a new Panel
_p = kwargs.pop("cstreturn_percenty", 0.33)
trcs = mpfdf["TR"].cumsum()
treturncs_ylim = ta_ylim(trcs, _p)
taplots += [
mpf.make_addplot(trcs, ylabel="Trend B&H", color="black", width=1.5, panel=cpanel(), ylim=treturncs_ylim),
mpf.make_addplot(mpfdf["0"], color="black", width=1.2, panel=cpanel(), ylim=treturncs_ylim),
]
self.mpfchart["plot_ratios"] += common_plot_ratio # Required to add a new Panel
# END: Custom TA Plots and Panels
if self.verbose:
additional_ta = []
chart_title = f"{chart_title} [{self.strategy.name}] (last {self.config['last']} bars)"
chart_title += f"\nSince {mpfdf.index[0]} till {mpfdf.index[-1]}"
if len(linreg_name) > 0: additional_ta.append(linreg_name)
if len(midpoint_name) > 0: additional_ta.append(midpoint_name)
if len(ohlc4_name) > 0: additional_ta.append(ohlc4_name)
if len(additional_ta) > 0:
chart_title += f"\nIncluding: {', '.join(additional_ta)}"
if amat_sr:
vlines_ = dict(vlines=amat_sr, alpha=0.1, colors="red")
else:
# Hidden because vlines needs valid arguments even if None
vlines_ = dict(vlines=mpfdf.index[0], alpha=0, colors="white")
# Create Final Plot
mpf.plot(mpfdf,
title=chart_title,
type=self.mpfchart["type"],
style=self.mpfchart["style"],
datetime_format="%-m/%-d/%Y",
volume=self.config["volume"],
figsize=self.mpfchart["figsize"],
tight_layout=self.mpfchart["tight_layout"],
scale_padding=self.mpfchart["scale_padding"],
panel_ratios=self.mpfchart["plot_ratios"], # This key needs to be update above if adding more panels
xrotation=self.mpfchart["xrotation"],
update_width_config=self.mpfchart["width_config"],
show_nontrading=self.mpfchart["non_trading"],
vlines=vlines_,
addplot=taplots
)
self._attribution()In [12]:
# Used for example Trend Return Long Trend Below
macd_ = ta.macd(closedf)
macdh = macd_[macd_.columns[1]]
Chart(df,
# style: which mplfinance chart style to use. Added "random" as an option.
# rpad: how many bars to leave empty on the right of the chart
style="yahoo", title=ticker, last=recent, rpad=10,
# Overlap Indicators
linreg=True, midpoint=False, ohlc4=False, archermas=True,
# Example Indicators with default parameters
volume=True, rsi=True, clr=True, macd=True, zscore=False, squeeze=False, lazybear=False,
# Archer OBV and OBV MAs (https://www.tradingview.com/script/Co1ksara-Trade-Archer-On-balance-Volume-Moving-Averages-v1/)
archerobv=False,
# Create trends and see their returns
trendreturn=False,
# Example Trends or create your own. Trend must yield Booleans
long_trend=ta.sma(closedf,10) > ta.sma(closedf,20), # trend: sma(close,10) > sma(close,20) [Default Example]
# long_trend=closedf > ta.ema(closedf,5), # trend: close > ema(close,5)
# long_trend=ta.sma(closedf,10) > ta.ema(closedf,50), # trend: sma(close,10) > ema(close,50)
# long_trend=macdh > 0, # trend: macd hist > 0
# long_trend=ta.increasing(ta.sma(ta.rsi(closedf), 10), 5, asint=False), # trend: rising sma(rsi, 10) for the previous 5 periods
show_nontrading=False, # Intraday use if needed
verbose=True, # More detail
)Out [12]:
[i] Loaded SPY(5235, 34)
[+] Strategy: Common Price and Volume SMAs
[i] Indicator arguments: {'append': True}
[i] Total indicators: 5
[i] Columns added: 5
Pandas v: 1.1.0 [pip install pandas] https://github.com/pandas-dev/pandas Data from AlphaVantage v: 1.0.19 [pip install alphaVantage-api] http://www.alphavantage.co https://github.com/twopirllc/AlphaVantageAPI Technical Analysis with Pandas TA v: 0.1.92b [pip install pandas_ta] https://github.com/twopirllc/pandas-ta Charts by Matplotlib Finance v: 0.12.6a3 [pip install mplfinance] https://github.com/matplotlib/mplfinance
<__main__.Chart at 0x117f86a90>
In [13]:
clr_ma_length = 8
clrdf = df.ta.log_return(cumulative=True, append=True)
clrmadf = ta.ema(clrdf, length=clr_ma_length)
qqdf = pd.DataFrame({f"{clrdf.name}": clrdf, f"{clrmadf.name}({clrdf.name})": clrmadf})
qqdf.tail(recent).plot(figsize=ind_size, color=cscheme("BkBu"), linewidth=1, title=ctitle(clrdf.name, ticker=ticker, length=recent), grid=True)Out [13]:
<matplotlib.axes._subplots.AxesSubplot at 0x11ac81940>
In [14]:
macddf = df.ta.macd(fast=8, slow=21, signal=9, min_periods=None, append=True)
macddf[[macddf.columns[0], macddf.columns[2]]].tail(recent).plot(figsize=(16, 2), color=cscheme("BkBu"), linewidth=1.3)
macddf[macddf.columns[1]].tail(recent).plot.area(figsize=ind_size, stacked=False, color=["silver"], linewidth=1, title=ctitle(macddf.name, ticker=ticker, length=recent), grid=True).axhline(y=0, color="black", lw=1.1)Out [14]:
<matplotlib.lines.Line2D at 0x11b180a60>
In [15]:
zscoredf = df.ta.zscore(length=30, append=True)
zcolors = ["darkgreen", "green", "silver", "silver", "red", "maroon", "black"]
zcols = df[["-4", "-3", "-2", "2", "3", "4", zscoredf.name]].tail(recent)
zcols.plot(figsize=ind_size, color=zcolors, linewidth=1.2, title=ctitle(zscoredf.name, ticker=ticker, length=recent), grid=True).axhline(y=0, color="black", lw=1.1)Out [15]:
<matplotlib.lines.Line2D at 0x11b15d7f0>
In [16]:
# Now Volume Z Score
zvscoredf = df.ta.zscore(close="volume", length=30, prefix="VOL", append=True)
zcolors = ["darkgreen", "green", "silver", "silver", "red", "maroon", "black"]
zvcols = df[["-4", "-3", "-2", "2", "3", "4", zvscoredf.name]].tail(recent)
zvcols.plot(figsize=ind_size, color=zcolors, linewidth=1.2, title=ctitle(zvscoredf.name, ticker=ticker, length=recent), grid=True).axhline(y=0, color="black", lw=1.1)Out [16]:
<matplotlib.lines.Line2D at 0x11b180580>
In [17]:
# help(ta.squeeze)In [18]:
Chart(df, style="yahoo", title=ticker, verbose=False,
last=recent, rpad=10, clr=True, squeeze=True,
show_nontrading=False, # Intraday use if needed
)Out [18]:
Pandas v: 1.1.0 [pip install pandas] https://github.com/pandas-dev/pandas Data from AlphaVantage v: 1.0.19 [pip install alphaVantage-api] http://www.alphavantage.co https://github.com/twopirllc/AlphaVantageAPI Technical Analysis with Pandas TA v: 0.1.92b [pip install pandas_ta] https://github.com/twopirllc/pandas-ta Charts by Matplotlib Finance v: 0.12.6a3 [pip install mplfinance] https://github.com/matplotlib/mplfinance
<__main__.Chart at 0x11bb394f0>
In [19]:
Chart(df, style="yahoo", title=ticker, verbose=False,
last=recent, rpad=10, clr=True, squeeze=True, lazybear=True,
show_nontrading=False, # Intraday use if needed
)Out [19]:
Pandas v: 1.1.0 [pip install pandas] https://github.com/pandas-dev/pandas Data from AlphaVantage v: 1.0.19 [pip install alphaVantage-api] http://www.alphavantage.co https://github.com/twopirllc/AlphaVantageAPI Technical Analysis with Pandas TA v: 0.1.92b [pip install pandas_ta] https://github.com/twopirllc/pandas-ta Charts by Matplotlib Finance v: 0.12.6a3 [pip install mplfinance] https://github.com/matplotlib/mplfinance
<__main__.Chart at 0x11bb39cd0>
In [20]:
Chart(df, style="yahoo", title=ticker, verbose=False,
last=recent, rpad=10,
volume=True, midpoint=False, ohlc4=False,
rsi=False, clr=True, macd=False, zscore=False, squeeze=False, lazybear=False,
archermas=True, archerobv=False,
show_nontrading=False, # Intraday use if needed
)Out [20]:
Pandas v: 1.1.0 [pip install pandas] https://github.com/pandas-dev/pandas Data from AlphaVantage v: 1.0.19 [pip install alphaVantage-api] http://www.alphavantage.co https://github.com/twopirllc/AlphaVantageAPI Technical Analysis with Pandas TA v: 0.1.92b [pip install pandas_ta] https://github.com/twopirllc/pandas-ta Charts by Matplotlib Finance v: 0.12.6a3 [pip install mplfinance] https://github.com/matplotlib/mplfinance
<__main__.Chart at 0x11c688640>
In [21]:
Chart(df, style="yahoo", title=ticker, verbose=False,
last=recent, rpad=10,
volume=True, midpoint=False, ohlc4=False,
rsi=False, clr=True, macd=False, zscore=False, squeeze=False, lazybear=False,
archermas=False, archerobv=True,
show_nontrading=False, # Intraday use if needed
)Out [21]:
Pandas v: 1.1.0 [pip install pandas] https://github.com/pandas-dev/pandas Data from AlphaVantage v: 1.0.19 [pip install alphaVantage-api] http://www.alphavantage.co https://github.com/twopirllc/AlphaVantageAPI Technical Analysis with Pandas TA v: 0.1.92b [pip install pandas_ta] https://github.com/twopirllc/pandas-ta Charts by Matplotlib Finance v: 0.12.6a3 [pip install mplfinance] https://github.com/matplotlib/mplfinance
<__main__.Chart at 0x11c5ad850>
In [ ]: