我编写了一个函数,在给定日期和价格列表的情况下计算股票的移动平均线。但输出不正确。我只需要第二眼看代码。这是我的代码。
def calculate(self, stock_date_price_list, min_days=2):
'''Calculates the moving average and generates a signal strategy for buy or sell
strategy given a list of stock date and price. '''
stock_averages = []
stock_signals = []
price_list = [float(n) for n in stock_date_price_list[1::2]]
days_window = collections.deque(maxlen=min_days)
rounding_point = 0.01
for price in price_list:
days_window.append(price)
stock_averages.append(0)
stock_signals.append("")
if len(days_window) == min_days:
moving_avg = sum(days_window) / min_days
stock_averages[-1] = moving_avg
if price < moving_avg:
stock_signals[-1] = "SELL"
elif price > moving_avg:
if price_list[-2] < stock_averages[-2]:
stock_signals[-1] = "BUY"
stock_averages[:] = ("%.2f" % avg if abs(avg)>=rounding_point else ' ' for avg in stock_averages)
return stock_averages, stock_signals
输入是以下列格式的股票价格和日期列表:
[2012-10-10,52.30,2012-10-09,51.60]
我得到的输出是:
2012-10-01 659.39
2012-10-02 661.31
2012-10-03 671.45
2012-10-04 666.80
2012-10-05 652.59
2012-10-08 638.17
2012-10-09 635.85
2012-10-10 640.91
2012-10-11 628.10
2012-10-12 629.71 648.43 SELL
2012-10-15 634.76 645.97 SELL
2012-10-16 649.79 644.81 BUY
2012-10-17 644.61 642.13 BUY
2012-10-18 632.64 638.71 SELL
2012-10-19 609.84 634.44 SELL
2012-10-22 634.03 634.02 BUY
2012-10-23 613.36 631.77 SELL
2012-10-24 616.83 629.37 SELL
它应该是:
2012-10-01 659.39
2012-10-02 661.31
2012-10-03 671.45
2012-10-04 666.80
2012-10-05 652.59
2012-10-08 638.17
2012-10-09 635.85
2012-10-10 640.91
2012-10-11 628.10
2012-10-12 629.71 648.43
2012-10-15 634.76 645.97
2012-10-16 649.79 644.81 BUY
2012-10-17 644.61 642.13
2012-10-18 632.64 638.71 SELL
2012-10-19 609.84 634.44
2012-10-22 634.03 634.02 BUY
2012-10-23 613.36 631.77 SELL
2012-10-24 616.83 629.37
买卖参数:
如果特定日的收盘价超过简单移动平均线(即当天的收盘价高于当天的简单移动平均线,而前一个收盘价不高于之前的收盘价)移动平均线),产生买入信号。
如果某一天的收盘价低于简单移动平均线,则产生卖出信号。
否则,不产生信号。
答案 0 :(得分:1)
正如您所说,购买的条件不仅仅是
price > moving_avg
也是previous_price < previous_moving_avg
。
您可以使用
price_list[-2] < stock_averages[-2]
除了price_list
是一个大列表,price_list[-2]
始终是大列表中的倒数第二项。它不一定是相对于您在循环中的位置的先前价格。
同样,销售信号不仅需要price < moving_avg
,还需要previous_price > previous_moving_avg
。
calculate
还有其他(主要是文体)问题。
stock_data_price_list
是必需的输入,但您只能使用
切片stock_data_price_list[1::2]
。如果是这种情况,您应该要求切片作为输入,而不是stock_data_price_list
price_list
基本上是这个切片,除了你调用float
在每个项目上。这意味着数据尚未正确解析。
不要让calculate
既是数据解析器又是数据
分析仪。制作简单的功能可以完成一项且只能完成一项任务。同样,calculate
不应该进行格式化
结果:
stock_averages[:] = ("%.2f" % avg if abs(avg)>=rounding_point else ' ' for avg in stock_averages)
以下是使用pandas修复代码的方法:
import pandas as pd
data = [('2012-10-01', 659.38999999999999),
('2012-10-02', 661.30999999999995),
('2012-10-03', 671.45000000000005),
('2012-10-04', 666.79999999999995),
('2012-10-05', 652.59000000000003),
('2012-10-08', 638.16999999999996),
('2012-10-09', 635.85000000000002),
('2012-10-10', 640.90999999999997),
('2012-10-11', 628.10000000000002),
('2012-10-12', 629.71000000000004),
('2012-10-15', 634.75999999999999),
('2012-10-16', 649.78999999999996),
('2012-10-17', 644.61000000000001),
('2012-10-18', 632.63999999999999),
('2012-10-19', 609.84000000000003),
('2012-10-22', 634.02999999999997),
('2012-10-23', 613.36000000000001),
('2012-10-24', 616.83000000000004)]
df = pd.DataFrame(data, columns=['date','price'])
df['average'] = pd.rolling_mean(df['price'], 10)
df['prev_price'] = df['price'].shift(1)
df['prev_average'] = df['average'].shift(1)
df['signal'] = ''
buys = (df['price']>df['average']) & (df['prev_price']<df['prev_average'])
sells = (df['price']<df['average']) & (df['prev_price']>df['prev_average'])
df.loc[buys, 'signal'] = 'BUY'
df.loc[sells, 'signal'] = 'SELL'
print(df)
产量
date price average prev_price prev_average signal
0 2012-10-01 659.39 NaN NaN NaN
1 2012-10-02 661.31 NaN 659.39 NaN
2 2012-10-03 671.45 NaN 661.31 NaN
3 2012-10-04 666.80 NaN 671.45 NaN
4 2012-10-05 652.59 NaN 666.80 NaN
5 2012-10-08 638.17 NaN 652.59 NaN
6 2012-10-09 635.85 NaN 638.17 NaN
7 2012-10-10 640.91 NaN 635.85 NaN
8 2012-10-11 628.10 NaN 640.91 NaN
9 2012-10-12 629.71 648.428 628.10 NaN
10 2012-10-15 634.76 645.965 629.71 648.428
11 2012-10-16 649.79 644.813 634.76 645.965 BUY
12 2012-10-17 644.61 642.129 649.79 644.813
13 2012-10-18 632.64 638.713 644.61 642.129 SELL
14 2012-10-19 609.84 634.438 632.64 638.713
15 2012-10-22 634.03 634.024 609.84 634.438 BUY
16 2012-10-23 613.36 631.775 634.03 634.024 SELL
17 2012-10-24 616.83 629.367 613.36 631.775
[18 rows x 6 columns]
没有熊猫,你可以这样做:
nan = float('nan')
def calculate(prices, size=2):
'''Calculates the moving average and generates a signal strategy for buy or sell
strategy given a list of stock date and price. '''
averages = [nan]*(size-1) + moving_average(prices, size)
previous_prices = ([nan] + prices)[:-1]
previous_averages = ([nan] + averages)[:-1]
signal = []
for price, ave, prev_price, prev_ave in zip(
prices, averages, previous_prices, previous_averages):
if price > ave and prev_price < prev_ave:
signal.append('BUY')
elif price < ave and prev_price > prev_ave:
signal.append('SELL')
else:
signal.append('')
return averages, signal
def window(seq, n=2):
"""
Returns a sliding window (of width n) over data from the sequence
s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ...
"""
for i in xrange(len(seq) - n + 1):
yield tuple(seq[i:i + n])
def moving_average(data, size):
return [(sum(grp)/len(grp)) for grp in window(data, n=size)]
def report(*args):
for row in zip(*args):
print(''.join(map('{:>10}'.format, row)))
dates = ['2012-10-01',
'2012-10-02',
'2012-10-03',
'2012-10-04',
'2012-10-05',
'2012-10-08',
'2012-10-09',
'2012-10-10',
'2012-10-11',
'2012-10-12',
'2012-10-15',
'2012-10-16',
'2012-10-17',
'2012-10-18',
'2012-10-19',
'2012-10-22',
'2012-10-23',
'2012-10-24']
prices = [659.38999999999999,
661.30999999999995,
671.45000000000005,
666.79999999999995,
652.59000000000003,
638.16999999999996,
635.85000000000002,
640.90999999999997,
628.10000000000002,
629.71000000000004,
634.75999999999999,
649.78999999999996,
644.61000000000001,
632.63999999999999,
609.84000000000003,
634.02999999999997,
613.36000000000001,
616.83000000000004]
averages, signals = calculate(prices, size=10)
report(dates, prices, averages, signals)
产生
2012-10-01 659.39 nan
2012-10-02 661.31 nan
2012-10-03 671.45 nan
2012-10-04 666.8 nan
2012-10-05 652.59 nan
2012-10-08 638.17 nan
2012-10-09 635.85 nan
2012-10-10 640.91 nan
2012-10-11 628.1 nan
2012-10-12 629.71 648.428
2012-10-15 634.76 645.965
2012-10-16 649.79 644.813 BUY
2012-10-17 644.61 642.129
2012-10-18 632.64 638.713 SELL
2012-10-19 609.84 634.438
2012-10-22 634.03 634.024 BUY
2012-10-23 613.36 631.775 SELL
2012-10-24 616.83 629.367