I'm creating a class based directional indicator that given a number of days (n_days
) and a list of numbers, it gives the (number of numbers out of the most recent n_days
on which the number was higher than the previous number minus the n_days
out of the previous n_days
on which the number went down). So if the number in the list increases I want it to return +1
, if it decreases I want it to return -1
, otherwise it should be 0
so the first number should always be 0
since you can't compare it to anything. Then based on n_days
I basically want to take the sum of the of the recent n_days, so for example in a list of [1,2,2,1,2,1]
the change should be [0,+1,0,-1,1,-1]
and if I want the sum of the change in the 2 recent numbers for each day so it should be [0,+1,-1,0,+1,0]
because on the first day there is only 0, on the second day you take the sum of the most recent two days 0+(+1)=1
, the third day (+1)+0=+1
, the fourth day 0+(-1)=-1
and so forth. Here is my code that's not working:
class Directionalindicator():
def __init__(self, n_days, list_of_prices):
self.n_days = n_days
self.list_of_prices = list_of_prices
def calculate(self):
change = []
for i in range(len(self.list_of_prices)):
if self.list_of_prices[i-1] < self.list_of_prices[i]:
change.append(1)
elif self.list_of_prices[i-1] > self.list_of_prices[i]:
change.append(-1)
else:
change.append(0)
directional = []
for i in range(len(change)):
directional.append(sum(change[i+1-self.n_days:i+1]))
return directional
testing it with:
y = Directionalindicator(2,[1,2,2,1,2,1])
y.calculate()
should return:
[0,+1,+1,-1,0,0]
and it does.
But testing it with:
y = Directionalindicator(3, [1,2,3,4,5,6,7,8,9,10])
y.calculate()
should return
[0, 0, 2, 3, 3, 3, 3, 3, 3, 3]
but it returns
[0, 0, 1, 3, 3, 3, 3, 3, 3, 3]
I printed change to see what it was doing and the first value is a -1 instead of a 0. Also, the code in one of the answers works using zip, but I don't understand why mine doesn't work for that list from 1-10.
Your comparison
will always be
True
. You are comparing each price to itself minus one, which will always be smaller. Instead, you should be comparing pairs of prices.zip
is useful for this:When you plug this into your code and use your example
you get:
This seems to be correct according to your initial statement of the rules, but for some reason doesn't match your "expected output"
[0, 1, -1, 0, 1, 0]
from the end of your question.The reason your edit doesn't work is that you are using an index
i
on the list. Wheni == 0
,i-1 == -1
. When used as an indexlist_of_prices[-1]
, this gives you the last element in the list. Thereforechange
contains[-1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
, as it compares1
with10
, not[0, 1, 1, 1, 1, 1, 1, 1, 1, 1]
as you expected.