I am doing my first project in python. I have a pandas dataframe called df with two columns "close" and "volume". I want to calculate/obtain OBV column based on first two columns. The formula is given below;
If the close is above the prior close then: Current OBC = Previous OBC + Current Volume
If the closing price is below the prior close price then: Current OBV = Previous OBV - Current Volume
If the closing prices equals the prior close price then: Current OBV = Previous OBV (no change)
close volume OBC
30 2500 nan
32 3000 5500
25 2700 2800
35 4000 6800
20 1000 5800
I am using this code:
for i in df.close[1:]:
if i > df.close.shift(-1):
df["OBC"] = df.volume + df.OBC.shift(-1)
elif i < df.close.shift(-1):
df["OBC"] = df.OBC.shift(-1) - df.volume
else:
df["OBC"] = df.OBC
and i get this error:
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
I have looked at this question but didn't get any help. Truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all()
Beyond this error, I feel that code may run into trouble in calculating correct OBV. Any help will be of great value.
I'm basing this on Olli's answer, but I think it's a slightly cleaner solution:
obv = (np.sign(df['close'].diff()) * df['volume']).fillna(0).cumsum()
I dont know why you are getting the error but here is a solution to get OBV:
np.where(df['close'] > df['close'].shift(1), df['volume'],
np.where(df['close'] < df['close'].shift(1), -df['volume'], 0)).cumsum()
It is also faster, which is good if you are gonna do many iterations!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With