While using the BBANDS function present in TA-Lib to generate upper, middle and lower band values for the close price column in my dataframe, it is returning me only a few rows that contain the respective values, whereas the majority of the rows have NaN values.
df = pd.read_csv("3131.csv", parse_dates=True, index_col="datetime")
df["upper_band"], df["middle_band"], df["lower_band"] = talib.BBANDS(df["close"], timeperiod=10)
Above is the function used to find the values for the respective bands and below are a few sample rows of my csv file.
datetime,open,high,low,close,volume
1996-01-01,15.859429,15.944529,15.754989,15.917452,48051995.0
1996-01-02,15.87877,15.956133,15.677626,15.793671,77875009.0
1996-01-03,16.052837,16.783918,15.87877,15.913584,96602936.0
1996-01-04,15.762726,15.813012,15.553845,15.766594,100099436.0
1996-01-05,15.704703,15.704703,15.5229,15.658285,76935930.0
1996-01-08,15.62734,15.638945,14.876918,15.031645,86288584.0
The first 9 rows are expected to have NaN values, but also after row 1900, all the rows have NaN values. Is there any way that I can compute the BBAND values for all the rows together at once?
I think that the problem is in your CSV file (there may be missing values). Bollinger bands are calculated with SMA (simple moving average), so it is calculated in a sliding period. According to your timeperiod
(e.g. 20 days, 10 days) configuration, it calculates. If your time period is 10 days, it cannot calculate the first 9 days as expected. You can also check it (by using data.iloc[9]
=> 10th day, BBAND calculated; but data.iloc[8]
=> 9th day, BBAND is NaN
),
Bolling Band (BBAND) Formula (time-period: 20 days):
* Middle Band = 20-day simple moving average (SMA)
* Upper Band = 20-day SMA + (20-day standard deviation of price x 2)
* Lower Band = 20-day SMA - (20-day standard deviation of price x 2)
Ref: https://school.stockcharts.com/doku.php?id=technical_indicators:bollinger_bands
The following code works after getting data using yfinance
:
Code:
import yfinance as yf
import pandas as pd
import talib
data = yf.download("AAPL", start="1996-01-01", end="2023-01-01")
data["upper_band"], data["middle_band"], data["lower_band"] = talib.BBANDS(data["Close"], timeperiod=10)
print(data)
Output:
[*********************100%%**********************] 1 of 1 completed
Open High Low Close Adj Close Volume upper_band middle_band lower_band
Date
1996-01-02 0.287946 0.287946 0.283482 0.286830 0.243140 139294400 NaN NaN NaN
1996-01-03 0.285714 0.293527 0.284598 0.286830 0.243140 429833600 NaN NaN NaN
1996-01-04 0.289063 0.289063 0.280134 0.281808 0.238883 300182400 NaN NaN NaN
1996-01-05 0.282366 0.305804 0.280134 0.305804 0.259224 445928000 NaN NaN NaN
1996-01-08 0.308036 0.316964 0.303571 0.309152 0.262062 121340800 NaN NaN NaN
... ... ... ... ... ... ... ... ... ...
2022-12-23 130.919998 132.419998 129.639999 131.860001 131.127060 63814900 147.186911 136.839000 126.491089
2022-12-27 131.380005 131.410004 128.720001 130.029999 129.307236 69007800 145.080385 135.392999 125.705614
2022-12-28 129.669998 131.029999 125.870003 126.040001 125.339409 85438400 142.000876 133.449999 124.899123
2022-12-29 127.989998 130.479996 127.730003 129.610001 128.889572 75703700 137.879145 132.089999 126.300852
2022-12-30 128.410004 129.949997 127.430000 129.929993 129.207779 77034200 136.519708 131.432998 126.346288
[6798 rows x 9 columns]