我的某个班级遇到了一些麻烦。这个特定的类应该计算给定列表的移动平均值(包含日期和价格)而不是。天(由用户输入)。这是我的代码:
class Moving_Average:
def calculation(self, alist:list,days:int):
m = days
prices = [float(i) for i in alist[1::2]]
average = [0]* len(prices)
signal = ['']* len(prices)
for m in range(0,len(prices)-days+1):
average[m+2] = sum(prices[m:m+days])/days
if prices[m+2] < average[m+2]:
signal[m+2]='SELL'
elif prices[m+2] > average[m+2] and prices[m+1] < average[m+1]:
signal[m+2]='BUY'
else:
signal[m+2] =''
average = [round(average[i],2) for i in range(0,len(average))]
return average,signal
当我想计算3天的平均值时,这很好用。但是当我尝试计算平均给出2天作为输入时它会给我一个索引错误。当我尝试输入4作为天数时,结果如下:
[0, 0, 33.81, 33.74, 33.51, 33.31, 33.28, 33.49, 33.85, 34.21, 34.43, 34.62, 34.75,
34.88, 34.86, 34.57, 34.26, 34.45, 34.69, 35.13, 35.59, 35.51, 0], ['', '', '', '',
'SELL', 'SELL', 'SELL', 'BUY', '', '', '', '', '', '', '', '', 'SELL', 'SELL', 'BUY',
'', 'SELL', 'BUY', ''])
应该是:
[0, 0, 0, 33.81, 33.74, 33.51, 33.31, 33.28, 33.49, 33.85, 34.21, 34.43, 34.62, 34.75,
34.88, 34.86, 34.57, 34.26, 34.45, 34.69, 35.13, 35.59, 35.51], ['', '', '', '',
'SELL', 'SELL', 'SELL', 'BUY', '', '', '', '', '', '', '', '', 'SELL', 'SELL', 'BUY',
'', 'SELL', 'BUY', ''])
即它最后添加0而不是开头。
答案 0 :(得分:1)
索引错误发生在循环中,因为您尝试访问average[m+2]
元素,其中average
的长度为len(prices)
,但值为m
是len(prices) - 2
(假设为days == 2
),因此m == len(prices)
并且不在列表范围内。
您永远不会访问average
的第一个元素,并且您永远不会编写average
或signal
的第一个或第二个元素。也许这就是为什么你在days == 4
案例中得到额外的零。请记住,Python使用从零开始的索引。
就个人而言,我认为将您的日期和价格全部放在一个长列表中并不是一个好主意。日期价格元组列表会更好。此外,脚本顶部的行m = days
不执行任何操作,因此应将其删除。
答案 1 :(得分:1)
为什么不使用deque
和maxlen=days
来计算移动平均线?此外,不是预先分配输出列表,而是按照您的方式构建它们。避免索引到列表中或使用range()
进行迭代;如果你发现自己做了很多,特别是对于索引的计算,你可能很难做到这一点。
import collections
class MovingAverage(object)::
def calculate(self, alist, days=2):
averages = []
signals = []
days = float(days) # make sure average is always float
prices = [float(n) for n in alist[1::2]]
window = collections.deque(maxlen=days)
# generate moving averages and signals
for price in prices:
window.append(price)
averages.append(0)
signals.append("")
if len(window) == days: # window is full, we can calc moving avg
mavg = sum(window) / days
averages[-1] = mavg
if price < mavg:
signals[-1] = "SELL"
elif price > mavg:
signals[-1] = "BUY"
averages[:] = ("%.2f" % a for a in averages)
averages[:days] = [""] * days
return averages, signals