I am trying to recreate a portion of the Bollinger Band Width Percentile pine indicator created by The_Caretaker into pandas_ta. The relevant code is:
# Pine Script
float _basis = ta.sma( close, 13 )
float _dev = ta.stdev ( close, 13 )
_bbw = ( _basis + _dev - ( _basis - _dev )) / _basis
_bbwSum = 0.0
_len = bar_index < 252 ? bar_index : 252
for _i = 1 to _len by 1
_bbwSum += ( _bbw[_i] > _bbw ? 0 : 1 )
_bbwp = bar_index >= 13 ? ( _bbwSum / _len) * 100 : na
I am stumbling on how to recreate the for
loop efficiently. The below code has hardcoded in some shifts, how would you do it in a dynamic loop?
import numpy as np
import pandas as pd
import pandas_ta as ta
import yfinance as yf
btc = yf.Ticker("BTC-USD")
df = pd.DataFrame()
df = btc.history(start="2022-06-08", interval="15m", actions=False)
df.index = [x for x in range(0, len(df.values))]
df["BASIS"] = ta.sma(df.Close, length=13)
df["STDEV"] = ta.stdev(df.Close, length=13)
df["BBW"] = ( df["BASIS"] + df["STDEV"] - ( df["BASIS"] - df["STDEV"] )) / df["BASIS"]
df["BBWLEN"] = np.where(df.index < 252, df.index, 252)
# How to do this so it looks back -1...-df["BBWLEN"]?
df['BBWSUM'] = \
np.where(df["BBW"].shift(-1) > df["BBW"], 0, 1) + \
np.where(df["BBW"].shift(-2) > df["BBW"], 0, 1) + \
np.where(df["BBW"].shift(-3) > df["BBW"], 0, 1)
df["BBWP"] = np.where(df.index >= 13, df["BBWSUM"] / df["BBWLEN"] * 100, None)
print(df)