Using IF THEN function to calculate a rolling number in a dataframe
I am in need of help trying to create a calculated metric. I am trying to create an RSI calculation for a stock dataset. To do so I want to look at the last 14 days and find the average gain for all days where the stock price was up. I then will have to do the same for all days the stock market is down. I am doing these calculations across multiple stocks, so I created a dictionary which I then concatenate. Here is the code:
stocklist=["^SPX", "^DJI"]
d={}
def averageGain14(dailyGain):
if dailyGain>= 0:
gain = dailyGain
return gain
for name in stocklist:
d[name]= pd.DataFrame()
data = yf.Ticker(name)
data = data.history(start=myStart, end=myEnd)
d[name]= pd.DataFrame(data)
d[name]["Daily Gain"]=d[name]["Close"].diff()
d[name]['Average Gain'] = d[name]["Daily Gain"].apply(averageGain14)
d[name] = d[name].add_prefix(name)
modelData = pd.concat(d.values(), axis=1)
As you can see, I try to define a function for averagegain14 at the top, which is not currently doing anything yet but returning the gain value if the day was up (step 1 of getting this working). In the For loop, I am trying to set the "Average Gain" Column to a calculated field that applies the function to the "Daily Gain" column, but I seem to be running into an error.
I tried a few approaches, but to no avail. First I tried
d[name]['Average Gain'] = d[name].rolling(14).mean().where(d[name]['Daily Gain'] >= 0, 0)
That returned an error regarding the Daily Gain value being a list and not a single value. I then tried appending the daily gain call with .values, but that didn't work either. I then tried this approach above that is not working. I think to add complexity, I need this to also be a rolling average based on the last 14 days, so to not only calculate add up the positive days, but to also then find the average gain for those days (know the denominator of how many days were up in the 14 day window). Hopefully this is making sense and someone can point me in the right direction.