0

我的一门课遇到了一些麻烦。这个特定的类应该计算给定列表(包含日期和价格)的移动平均线并且没有。天数(由用户输入)。这是我的代码:

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 而不是开头。

4

2 回答 2

1

索引错误发生在循环中,因为您试图访问 element average[m+2],其中averageis 是 length len(prices),但 valuemlen(prices) - 2(假设days == 2),因此m == len(prices)and 超出了列表的范围。

您永远不会访问 的第一个元素average,也永远不会编写 or 的第一个或第二个average元素signal。也许这就是为什么您在days == 4案例中得到额外的零的原因。请记住,Python 使用从零开始的索引。

就我个人而言,我认为将您的日期和价格都列在一个长长的列表中并不是一个好主意。日期价格元组列表会更好。此外,m = days脚本顶部的行什么也不做,因此应该将其删除。

于 2013-11-04T21:13:35.193 回答
1

为什么不使用 adeque和 amaxlen=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
于 2013-11-04T21:30:49.343 回答