I am trying to write a function to calculate RSI data using input from a list or by pulling live price data from an API.
The script worked fine when feeding it data directly from a list, but while I am trying to convert it to a function, I am experiencing issues.
The function needs to remember the output from a previous run in order to calculate a smoothed average, but I keep getting an error that the local variable is being called before assignment. I've eliminated a lot of the code to keep the post short, but it errors on the 15th run. On the 14th run I think I am defining the variable and printing the value, so I don't understand why it errors.
def calc_rsi(price, i):
while price != complete:
window.append(price)
if i == 14:
avg_gain = sum(gains) / len(gains)
avg_loss = sum(losses) / len(losses)
if i > 14:
avg_gain = (prev_avg_gain * (window_length - 1) gain) / window_length
avg_loss = (prev_avg_loss * (window_length - 1) loss) / window_length
if i >= 14:
rs = avg_gain / avg_loss
rsi = round(100 - (100 / (1 rs)), 2)
prev_avg_gain = avg_gain
prev_avg_loss = avg_loss
print ("rsi", rsi)
print ("gain", prev_avg_gain)
print ()
The thing that is throwing me for a real loop (pun intended) is that on run 14, my print statement 'print ("gain=", prev_avg_gain)' returns the proper value, so I know that it is assigning a value to the variable.... I've tried adding the 'prev_avg_gain = avg_gain ' to the block of code for 'if i == 14:' and 'if i > 14:' rather than doing it once in the >= block and it throws the same error.
I am new to python and scripting so please go easy :)
CodePudding user response:
I got some help on a different forum and I still don't understand exactly why, but I guess python resets the 'prev_avg_gain' variable every time it looped so to fix this I created a dictionary outside of the function and updated the dictionary with the variable data when required.
prev_avg = {}
# Calculate Price Differences
def calc_rsi(price, i):
while price != "complete":
window.append(price)
# print (i)
# Calculate Average Gains and Losses
if i == 14:
avg_gain = sum(gains) / len(gains)
avg_loss = sum(losses) / len(losses)
if i > 14:
avg_gain = (prev_avg["prev_avg_gain"] * (window_length - 1) gain) / window_length
avg_loss = (prev_avg["prev_avg_loss"] * (window_length - 1) loss) / window_length
# prev_avg_gain = avg_gain
# prev_avg_loss = avg_loss
# print (output)
if i >= 14:
rs = avg_gain / avg_loss
rsi = round(100 - (100 / (1 rs)), 2)
prev_avg["prev_avg_gain"] = avg_gain
prev_avg["prev_avg_loss"] = avg_loss
# print ("rsi", rsi)
# print ("gain", prev_avg["prev_avg_gain"])
# print ()
CodePudding user response:
The code as you have pasted will work, if you make one call to calc_rsi()
where i
is incremented from <=14
to >14
. In this case prev_avg_gain
will be remembered. But if you make 2 calls to calc_rsi()
then prev_avg_gain
will not be remembered between calls.
To demonstrate, I use a trimmed down example:
def calc_rsi(price, i):
while i <= price:
if i == 14:
avg_gain = 10
if i > 14:
avg_gain = (prev_avg_gain * (10 - 1) 1) / 5
if i >= 14:
prev_avg_gain = avg_gain
print ("gain", prev_avg_gain)
i = 1
# i loops from 13 to 16 in one call, this works!
calc_rsi(price=16, i=14)
# i loops from 13 to 14, prev_avg_gain is set
calc_rsi(price=14, i=13)
# i loops from 15 to 16, throws error! because prev_avg_gain is not remembered
calc_rsi(price=16, i=15)