简介
我们在之前的文章《使用Python进行股票分析(1)》中,通过自动获取股票的历史数据,然后选择在一定时间内处于上涨的股票作为我们投资的标的。在本文中,我们进一步通过分析股票的短期趋势,选择处于短期上涨趋势的股票,进一步筛选我们的理想投资标的。
数据平均线和趋势分析
一支股票每个交易日内的价格变化很快,并且随机性比较大。通过计算股票在某个时间段内的平均线,可以获得更加稳定的趋势。比如5日平均线,和20日平均线。相对来说,选择的时间段越短,越能反应股票在短期内的变化趋势;而选择的时间段越长,越能反应股票在长期的变化趋势。当短期平均线处于长期平均线上方时,说明股票短期处于有利的趋势;而短期平均线处于长期平均线下方,说明股票处于不利的趋势。这里需要注意的是,这里的有利和不利不是绝对意义的上涨和下跌,而是相对意义的。换句话说,这里的有利仅仅说明股票短期的表现对比于长期表现,开始加速上涨或者减慢下跌,但是绝对值上来说上涨和下跌都是有可能的。我们希望买入处于有利趋势的股票,而避免购买处于不利趋势的股票。
获取处于有利趋势的股票
注意,本文中的代码是基于《使用Python进行股票分析(1)》的,如果想运行本文的代码的同学,请先阅读之前的文章。
我们通过计算5日均线和20日均线,并且比较两条均线的最后一个数据点的值,5日均线高于20日均线的股票就是我们想要选择的股票。我们可以通过以下的函数获得符合要求的股票列表:
def get_stocks_with_increase_trend(closing_prices):average_5 = closing_prices.rolling(window=5).mean()average_20 = closing_prices.rolling(window=20).mean()return list(closing_prices.loc[:, average_5.iloc[-1] > average_20.iloc[-1]].columns)get_stocks_with_increase_trend(close)
其次,我们还希望通过观察股票均线的图形,进一步对股票的趋势有一个直观的了解。我们可以通过如下代码来绘制各支股票的5日均线和20日均线,并且将处于有利趋势的股票的图形边框染成绿色,将处于不利趋势的股票的图形边框染成红色,来进一步使得图形更为容易理解:
# set color of axes board
def set_axes_color(ax, color):ax.spines['bottom'].set_color(color)ax.spines['top'].set_color(color)ax.spines['left'].set_color(color)ax.spines['right'].set_color(color)# ax.xaxis.label.set_color(color)# ax.yaxis.label.set_color(color)# ax.grid(alpha=0.1)ax.title.set_color(color)# drow 5 days moving average and 20 days moving average of closing price for symbols
LINE_SIZE = 2
def draw_moving_average(symbols, closing_prices):sz = len(symbols)rows = (int)(sz / LINE_SIZE) + (1 if sz % LINE_SIZE != 0 else 0)fig, axes = plt.subplots(rows, LINE_SIZE, figsize=(24, 96))plt.tight_layout(pad=48)for i in range(sz):row = (int)(i/LINE_SIZE)col = i % LINE_SIZEsymbol = symbols[i]average_5 = closing_prices[symbol].rolling(window=5).mean()average_20 = closing_prices[symbol].rolling(window=20).mean()if average_5.iloc[-1]>average_20.iloc[-1]:set_axes_color(axes[row, col], 'green')else:set_axes_color(axes[row, col], 'red')axes[row, col].plot(average_5)axes[row, col].plot(average_20)axes[row, col].set_xlabel('time')axes[row, col].set_xticklabels(axes[row, col].get_xticklabels(), rotation=90)axes[row, col].set_ylabel('price')axes[row, col].set_title(symbol)axes[row, col].legend(['5 days', '20 days'])draw_moving_average(tickers, close)
为了测试我们的函数功能,我们选择更多的股票加入到候选股票列表中:
tickers = ['U', 'SHOP', 'DDOG', 'SNOW', 'PLTR', 'MSFT', 'GOOGL', 'NVDA', 'META', 'TSLA', 'AAPL']
运行函数get_stocks_with_increase_trend(),我们得到以下结果:
['SHOP', 'MSFT', 'GOOGL', 'NVDA', 'META']
我们发现在11支候选股票中仅仅有5支目前是处于有利趋势的。然后我们运行绘制趋势图的函数,会得到以下图形:
更改选择股票函数
我们进一步更改我们选择股票的函数。我们同时考虑股票在过去一段时间是否上涨和该股票是否处于有利的趋势。这里我们考虑两种情况:
1. 假如一支股票既有价格的上涨,又处于有利的趋势,我们将考虑买入股票;
2. 假如一支股票有价格的上涨,但是处于不利的趋势,我们考虑进一步观察该股票以后的表现,等待有利的时机再进行购买;
3. 处于其它情况的股票都不考虑购买。
现在我们实现函数如下。它将返回两个列表,一个考虑购买的股票列表,一个是考虑进一步观察的股票的列表:
# select stocks based on protitable and trending
# stocks have profits and have increase trending are indicated to buy
# stocks have profits and have decrease trending are indicated to further observe
# other stocks are ignored
def select_stocks(closing_price):protitable_list = get_profitable_stocks(closing_price)increase_list = get_stocks_with_increase_trend(closing_price)buy_list = list(set(protitable_list).intersection(set(increase_list)))ob_list = list(set(protitable_list).difference(set(increase_list)))return buy_list, ob_list
现在我们运行该函数:
buy_list, ob_list = select_stocks(close)
print(f"Buy these stocks: {buy_list}\nObserve these stocks further: {ob_list}")
并且得到如下的输出:
Buy these stocks: ['NVDA', 'META', 'GOOGL', 'MSFT', 'SHOP']
Observe these stocks further: ['TSLA', 'PLTR', 'SNOW', 'AAPL', 'DDOG', 'U']
我们有五支股票是可以考虑现在买入的,另外六支股票可以进一步观察。
小结
我们可以看到加入了股票趋势的判断,使得我们进一步缩小了选择购买股票的条件。假如这个条件是合理的,将可以进一步增加我们购买股票的合理性。但是我们还可以进一步判断股票的趋势,以及对股票未来的价格进行预测,来进一步试图增加我们选择股票的能力。我们将在以后的文章中对这些想法进行进一步实现。