Pandas stock dataframe , initialize a counter in a columns on a condition met (ORB, NR4/7)

Viewed 15

I have some code which downloads stock price data from Yahoo finance. I want to create some sort of distribution statistics for so called "narrow ranges in a given time period - (which lead to expansion bars). Mostly for the narrowst range in 4 or 7 days. After marking those narrow ranges with 'NR7' or 'NR4' - preferably in only column - I want to start a counter which starts with every 'NR' with 1 and they next day increases by 1 so that´s 2 on the second day, after the 'NR' occured, 3 on the third and so on...

I tried to realize it in the vectorized code for defining a narrow range. Look at the code for df['Bars2NR']. It doesn´t work this way bc it´s self referencing? What options would you prefer to realize a renewed counter on every new 'NR'?

import pandas as pd
import numpy as np
import yfinance 

#download stock price time series data
Ticker = 'MSFT' 
df = yfinance.download(Ticker , start='2022-01-01',  end='2022-09-17' )

#Calculate basic indicators / moving averages
df['SMA10'] = df['Close'].rolling(10).mean()
df['ADR20'] = ((df['High'].rolling(20).mean()/df['Low'].rolling(20).mean())-1)*100
df['ADR1'] = (df['High']/df['Low']-1)*100
df['Range'] = df['High']-df['Low']
df['OCRange'] = abs(df['Open']-df['Close'])
BarFillThreshold = 0.75
df['TrendBar'] = df['OCRange']/df['Range'] > BarFillThreshold
df['Bars2NR'] = 0

#Define narrow range bars (smallest of last 7 or 4 bars)
df['NR7'] = np.where((df.Range < df.Range.shift()) & (df.Range < df.Range.shift(-1))
                     & (df.Range < df.Range.shift(-2)) & (df.Range < df.Range.shift(-3))
                     & (df.Range < df.Range.shift(-4)) & (df.Range < df.Range.shift(-5))
                     & (df.Range < df.Range.shift(-6)), 'NR7', '')

#Narrow Range Bar 4 (in days)
df['NR4'] = np.where((df.Range < df.Range.shift()) & (df.Range < df.Range.shift(-1))
                     & (df.Range < df.Range.shift(-2)) & (df.Range < df.Range.shift(-3))
                     , 'NR4', '')

df['Bars2NR'] = np.where((df.Range < df.Range.shift()) & (df.Range < df.Range.shift(-1))
                     & (df.Range < df.Range.shift(-2)) & (df.Range < df.Range.shift(-3))
                     & (df.Range < df.Range.shift(-4)) & (df.Range < df.Range.shift(-5))
                     & (df.Range < df.Range.shift(-6)), 1, df.Bars2NR.shift(1)+2 )' <--- '
#Every time there is a new NR4 or NR7 a new count start with 1 should start

df['RangeExpansion'] =np.where((df.ADR1 > df.ADR20), 1, 0)


df.tail(50)
0 Answers
Related