mirror of
https://github.com/wassname/pandas-ta.git
synced 2026-07-21 12:40:45 +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
from alphaVantageAPI.alphavantage import AlphaVantage
import pandas_ta as ta
from watchlist import colors
%pylab inline
e = pd.DataFrame()Populating the interactive namespace from numpy and matplotlib
In [2]:
e.ta.indicators()Pandas TA - Technical Analysis Indicators - v0.1.72b0
Total Indicators: 122
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, cdl_inside, cfo, cg, chop, cksp, cmf, cmo, coppock, cross, cross_value, decay, decreasing, dema, donchian, dpo, efi, ema, entropy, eom, er, eri, fisher, fwma, ha, hilo, hl2, hlc3, hma, ichimoku, increasing, inertia, kama, kc, kdj, kst, kurtosis, 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, smi, squeeze, stdev, stoch, stochrsi, supertrend, swma, t3, tema, trend_return, trima, trix, true_range, tsi, ttm_trend, 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})"
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 [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.RATE["TRADING_DAYS_PER_YEAR"] / yearly_divisor) if yearly_divisor > 0 else df.shape[0]
# print(recent)
def recent_bars(df, tf: str = "1y"):
# All Data: 0, Last Four Years: 0.25, Last Two Years: 0.5, This Year: 1, Last Half Year: 2, Last Quarter: 4
yearly_divisor = {"all": 0, "10y": 0.1, "5y": 0.2, "4y": 0.25, "3y": 1./3, "2y": 0.5, "1y": 1, "6mo": 2, "3mo": 4}
yd = yearly_divisor[tf] if tf in yearly_divisor.keys() else 0
return int(ta.RATE["TRADING_DAYS_PER_YEAR"] / yd) if yd > 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(5260, 6) from 1999-11-01 00:00:00 to 2020-09-25 00:00:00
open high low close adj_close \
count 5260.000000 5260.000000 5260.000000 5260.000000 5260.000000
mean 162.855008 163.818126 161.791343 162.854531 138.415896
std 63.881042 64.077112 63.643854 63.888599 71.216117
min 67.950000 70.000000 67.100000 68.110000 53.696800
25% 116.500000 117.415000 115.602500 116.557500 87.158050
50% 138.448750 139.413100 137.329050 138.255000 106.140900
75% 205.025000 206.260000 204.150000 205.212500 184.708225
max 355.870000 358.750000 353.430000 357.700000 356.257100
volume
count 5.260000e+03
mean 1.112009e+08
std 9.790351e+07
min 1.708170e+05
25% 4.766909e+07
50% 8.223804e+07
75% 1.485869e+08
max 8.710263e+08
| open | high | low | close | adj_close | volume | |
|---|---|---|---|---|---|---|
| date | ||||||
| 1999-11-01 | 136.5000 | 137.0000 | 135.5625 | 135.5625 | 91.5996 | 4006500.0 |
| 1999-11-02 | 135.9687 | 137.2500 | 134.5937 | 134.5937 | 90.9450 | 6516900.0 |
| 1999-11-03 | 136.0000 | 136.3750 | 135.1250 | 135.5000 | 91.5574 | 7222300.0 |
| 1999-11-04 | 136.7500 | 137.3593 | 135.7656 | 136.5312 | 92.2542 | 7907500.0 |
| 1999-11-05 | 138.6250 | 139.1093 | 136.7812 | 137.8750 | 93.1622 | 7431500.0 |
In [7]:
# Recent Data
recent_startdate = df.tail(recent_bars(df)).index[0]
recent_enddate = df.tail(recent_bars(df)).index[-1]
print(f"{df.name}{df.tail(recent_bars(df)).shape} from {recent_startdate} to {recent_enddate}\n{df.describe()}")
df.tail(recent_bars(df)).head()Out [7]:
SPY(252, 6) from 2019-09-27 00:00:00 to 2020-09-25 00:00:00
open high low close adj_close \
count 5260.000000 5260.000000 5260.000000 5260.000000 5260.000000
mean 162.855008 163.818126 161.791343 162.854531 138.415896
std 63.881042 64.077112 63.643854 63.888599 71.216117
min 67.950000 70.000000 67.100000 68.110000 53.696800
25% 116.500000 117.415000 115.602500 116.557500 87.158050
50% 138.448750 139.413100 137.329050 138.255000 106.140900
75% 205.025000 206.260000 204.150000 205.212500 184.708225
max 355.870000 358.750000 353.430000 357.700000 356.257100
volume
count 5.260000e+03
mean 1.112009e+08
std 9.790351e+07
min 1.708170e+05
25% 4.766909e+07
50% 8.223804e+07
75% 1.485869e+08
max 8.710263e+08
| open | high | low | close | adj_close | volume | |
|---|---|---|---|---|---|---|
| date | ||||||
| 2019-09-27 | 297.83 | 297.95 | 293.69 | 295.40 | 289.7052 | 84755721.0 |
| 2019-09-30 | 295.97 | 297.55 | 295.92 | 296.77 | 291.0488 | 52438861.0 |
| 2019-10-01 | 297.74 | 298.46 | 293.00 | 293.24 | 287.5869 | 89425082.0 |
| 2019-10-02 | 291.50 | 291.51 | 286.64 | 288.06 | 282.5067 | 124208927.0 |
| 2019-10-03 | 287.81 | 290.45 | 284.82 | 290.42 | 284.8212 | 85718095.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: 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 [ ]:
In [10]:
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_bars(self.df))
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"Data 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 [11]:
# 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_bars(df), 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 [11]:
[i] Loaded SPY(5260, 33)
[+] Strategy: Common Price and Volume SMAs
[i] Indicator arguments: {'append': True}
[i] Multiprocessing: 4 of 4 cores.
[i] Total indicators: 5
[i] Columns added: 5
<__main__.Chart at 0x111c9f340>
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.72b0 [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
In [12]:
clr_ma_length = 8
clrdf = df.ta.log_return(cumulative=True, append=True)
clrmadf = ta.ema(clrdf, length=clr_ma_length)
clrxdf = pd.DataFrame({f"{clrdf.name}": clrdf, f"{clrmadf.name}({clrdf.name})": clrmadf})
clrxdf.tail(recent_bars(df)).plot(figsize=ind_size, color=colors("BkBl"), linewidth=1, title=ctitle(clrdf.name, ticker=ticker, length=recent_bars(df)), grid=True)Out [12]:
<matplotlib.axes._subplots.AxesSubplot at 0x111c344c0>
In [13]:
macddf = df.ta.macd(fast=8, slow=21, signal=9, min_periods=None, append=True)
macddf[[macddf.columns[0], macddf.columns[2]]].tail(recent_bars(df)).plot(figsize=(16, 2), color=colors("BkBl"), linewidth=1.3)
macddf[macddf.columns[1]].tail(recent_bars(df)).plot.area(figsize=ind_size, stacked=False, color=["silver"], linewidth=1, title=ctitle(macddf.name, ticker=ticker, length=recent_bars(df)), grid=True).axhline(y=0, color="black", lw=1.1)Out [13]:
<matplotlib.lines.Line2D at 0x114d4abb0>
In [14]:
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_bars(df))
zcols.plot(figsize=ind_size, color=zcolors, linewidth=1.2, title=ctitle(zscoredf.name, ticker=ticker, length=recent_bars(df)), grid=True).axhline(y=0, color="black", lw=1.1)Out [14]:
<matplotlib.lines.Line2D at 0x1142c7640>
In [15]:
# 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_bars(df))
zvcols.plot(figsize=ind_size, color=zcolors, linewidth=1.2, title=ctitle(zvscoredf.name, ticker=ticker, length=recent_bars(df)), grid=True).axhline(y=0, color="black", lw=1.1)Out [15]:
<matplotlib.lines.Line2D at 0x11573dd30>
In [16]:
# help(ta.squeeze)In [17]:
Chart(df, style="yahoo", title=ticker, verbose=False,
last=recent_bars(df), rpad=10, clr=True, squeeze=True,
show_nontrading=False, # Intraday use if needed
)Out [17]:
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.72b0 [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 0x115782640>
In [18]:
Chart(df, style="yahoo", title=ticker, verbose=False,
last=recent_bars(df), rpad=10, clr=True, squeeze=True, lazybear=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.72b0 [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 0x1147b4340>
In [19]:
Chart(df, style="yahoo", title=ticker, verbose=False,
last=recent_bars(df), 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 [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.72b0 [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 0x1168e1580>
In [20]:
Chart(df, style="yahoo", title=ticker, verbose=False,
last=recent_bars(df), 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 [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.72b0 [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 0x1169b5880>
In [ ]: