使用Python构建和验证简单的股票交易算法
用Python打造并验证简单股票交易算法
介绍
算法交易是一种被广泛采用的交易策略,彻底改变了人们交易股票的方式。越来越多的人通过投资股票并自动化他们的交易策略来赚取额外收入。本教程将教你如何使用基本技术指标(如MACD、SMA、EMA等)通过Python构建股票交易算法,并根据实际表现/收益选择最佳策略。
学习目标
- 了解算法交易是什么。
- 使用Python构建简单的股票交易算法,利用技术指标生成买卖信号。
- 学会在Python中实施交易策略并自动化。
- 学会根据平均收益比较和选择最佳交易策略。
本文作为 Data Science Blogathon 的一部分发布。
免责声明 – 本项目中的所有工作都仅供教育目的,并不构成财务建议。
什么是算法交易?
算法交易是一种使用自动化计算机程序执行订单的金融资产交易方法,这些程序基于预定义的规则和策略。它涉及使用多种交易策略,包括统计套利、趋势跟踪和均值回归等。
算法交易有许多不同类型。其中之一是高频交易,它涉及以极高速度执行交易,几乎没有延迟,以利用小幅价格波动。另一种是基于新闻的交易,它涉及根据新闻和其他市场事件进行交易。
在本文中,我们将使用Python根据技术指标和K线图形态检测进行股票交易。
如何使用Python算法进行股票交易分析?
我们可以使用Python分析股票市场,找出趋势,制定交易策略,并设置信号来自动化股票交易!使用Python进行算法交易的过程包括几个步骤,如选择数据库、安装特定库和提取历史数据等。现在让我们深入了解这些步骤,并学习如何构建简单的股票交易算法。
选择数据集
有成千上万只上市股票可供选择,我们可以考虑任何一组股票来构建算法。然而,考虑到它们的基本面和技术面将是可比较的,选择类似种类的股票总是一个很好的选择。
在本文中,我们将考虑Nifty 50股票。Nifty 50指数包括印度的50家顶级公司,这些公司根据市值、流动性、行业代表性和财务业绩等多个因素进行选择。该指数也被广泛用作衡量印度股票市场表现的基准,相对于投资小市值或中市值公司,投资这些公司的风险较小。在本文中,我将选择WIPRO进行分析。在一个for循环中为每支股票调用函数,可以对任何一组类似的股票执行本文中讨论的分析方法。
安装所需库
我们将使用默认的库,如pandas、numpy、matplotlib,以及yfinance和pandas_ta。yfinance库将用于提取历史股票价格。pandas_ta库将用于实施SMA和MACD指标,并构建交易算法。这些模块可以像安装其他Python库一样直接使用pip进行安装。安装完后,让我们导入这些模块。
!pip install yfinance!pip install pandas-ta
import yfinance as yfimport pandas as pdimport pandas_ta as taimport numpy as npfrom datetime import datetime as dtimport matplotlib.pyplot as pltfrom datetime import timedelta as deltaimport numpy as npimport osimport seaborn as sb
现在我们已经安装并导入了所有所需的库,让我们开始动手构建策略。
使用yfinance提取历史股票价格
我们将使用yfinance模块的“download()”函数提取股票的历史价格,该函数接受股票的代码、起始日期和结束日期作为参数。出于简单起见,我们将以“2000-01-01”作为起始日期,当前日期作为结束日期。我们将编写一个简单的函数,提取历史股票价格并将其作为数据框返回,以便进一步处理,同时将其保存为CSV文件。
“`html
def get_stock_info(stock, save_to_disk=False): start_date = '2000-01-01' end_date = (dt.now() + delta(1)).strftime('%Y-%m-%d') df = yf.download(f"{stock}.NS", period='1d', start=start_date, end=end_date, progress=False) if(save_to_disk == True): path = './csv' try: os.mkdir(path) except OSError as error: pass df.to_csv(f'{path}/{stock}.csv') return dfdf = get_stock_info('WIPRO', save_to_disk = True)
使用技术指标构建股票交易算法
有很多可用于进行股票交易的指标,但我们将使用两个最简单且非常流行的指标之一,即SMA和MACD。SMA代表简单移动平均线,而MACD代表移动平均线收敛背离。如果您对这些术语不熟悉,可以在这篇文章中了解更多信息。简而言之,我们将尝试找到SMA交叉和MACD交叉作为交易信号,并寻找最佳组合以最大化回报。
对于SMA交叉,我们将考虑10天、30天、50天和200天的移动平均线。对于MACD交叉,我们将考虑12天、26天和9天的指数移动平均线。让我们使用pandas_ta库计算这些值。
为了计算SMA,我们将使用“sma()”函数,通过传递股票的调整收盘价和天数来计算。为了计算MACD,我们将使用“macd()”函数,通过传递股票的调整收盘价并将快速、慢速和信号参数设置为12、26和9。SMA和MACD的值本身并没有太多意义。因此,让我们对它们进行编码,以了解是否存在交叉。
对于SMA,我们将有3个条件:
- 10天SMA应该高于30天SMA。
- 10天和30天SMA应该高于50天SMA。
- 10天、30天和50天SMA应该高于200天SMA。
对于MACD,我们将有2个条件:
- MACD应该高于MACD信号。
- MACD应大于0。
以下Python代码创建了一个函数来实现上述条件。
def add_signal_indicators(df): df['SMA_10'] = ta.sma(df['Adj Close'],length=10) df['SMA_30'] = ta.sma(df['Adj Close'],length=30) df['SMA_50'] = ta.sma(df['Adj Close'],length=50) df['SMA_200'] = ta.sma(df['Adj Close'],length=200) macd = ta.macd(df['Adj Close'], fast=12, slow=26, signal=9) df['MACD'] = macd['MACD_12_26_9'] df['MACD_signal'] = macd['MACDs_12_26_9'] df['MACD_hist'] = macd['MACDh_12_26_9'] df['10_cross_30'] = np.where(df['SMA_10'] > df['SMA_30'], 1, 0) df['MACD_Signal_MACD'] = np.where(df['MACD_signal'] < df['MACD'], 1, 0) df['MACD_lim'] = np.where(df['MACD']>0, 1, 0) df['abv_50'] = np.where((df['SMA_30']>df['SMA_50']) &(df['SMA_10']>df['SMA_50']), 1, 0) df['abv_200'] = np.where((df['SMA_30']>df['SMA_200']) &(df['SMA_10']>df['SMA_200'])&(df['SMA_50']>df['SMA_200']), 1, 0) return dfdf = add_signal_indicators(df)
“`
现在我们已经将所有的信号添加到我们的数据中,是时候计算收益了。收益率将是从中选择最佳交易策略的最重要因素。我们将计算股票的5天和10天收益率。我们还将将收益率标签编码为0和1,其中0表示负收益,1表示正收益。让我们继续创建实施相同功能的函数。
def calculate_returns(df): df['5D_returns'] = (df['Adj Close'].shift(-5)-df['Adj Close'])/df['Close']*100 df['10D_returns'] = (df['Adj Close'].shift(-10)-df['Adj Close'])/df['Close']*100 df['5D_positive'] = np.where(df['5D_returns']>0, 1, 0) df['10D_positive'] = np.where(df['10D_returns']>0, 1, 0) return df.dropna()df = calculate_returns(df)
理解信号的表现
我们可以根据上述所有条件进行简单的汇总,计算我们在基于这些信号进行交易时可以期望的平均收益率和中位收益率。我们还可以提取每个信号在过去生成的最小和最大收益率。这不仅可以让我们大致了解信号的好坏,还可以了解在使用这些信号进行交易时可以期望多少收益。让我们用Python编写一个简单的代码来做到这一点。
def get_eda_and_deepdive(df): eda = df.dropna().groupby(['10_cross_30', 'MACD_Signal_MACD', 'MACD_lim', 'abv_50', 'abv_200'])[['5D_returns', '10D_returns']]\ .agg(['count', 'mean','median', 'min', 'max']) deepdive = df.dropna().groupby(['10_cross_30', 'MACD_Signal_MACD', 'MACD_lim', 'abv_50', 'abv_200','5D_positive', '10D_positive'])[['5D_returns', '10D_returns']]\ .agg(['count', 'mean','median', 'min', 'max']) return eda, deepdive eda, deepdive = get_eda_and_deepdive(df)
让我们可视化根据5天和10天收益率排序的前10个信号组合的箱线图。
x = df.copy()def _fun(x): code = '' for i in x.keys(): code += str(x[i]) return codex['signal'] = x[['10_cross_30', 'MACD_Signal_MACD', 'MACD_lim', 'abv_50', 'abv_200', '5D_positive', '10D_positive']].apply(_fun, axis=1)x = x.dropna()lim = x.groupby(['10_cross_30', 'MACD_Signal_MACD', 'MACD_lim', 'abv_50', 'abv_200', '5D_positive', '10D_positive'])['5D_returns'].agg(['mean']).reset_index()lim = lim.sort_values(by='mean', ascending=False).head(10)x = x.merge(lim, on=['10_cross_30', 'MACD_Signal_MACD', 'MACD_lim', 'abv_50', 'abv_200', '5D_positive', '10D_positive'], how='inner')
ax = sb.boxplot(x='signal', y='5D_returns', data=x)ax.set_xticklabels(ax.get_xticklabels(), rotation=45)plt.show()
ax = sb.boxplot(x='signal', y='10D_returns', data=x)ax.set_xticklabels(ax.get_xticklabels(), rotation=45)plt.show()
仅根据5天和10天的收益率来选择最佳信号并不是最佳方法,因为我们永远不会知道信号给出正收益与负收益的次数。这种方法可以在选择最佳策略时考虑,这可能会提高策略的性能。为了保持本文的简单性和适合初学者,我不采用这种方法。
结论
算法交易的概念对许多人来说可能非常诱人,因为它可能非常有利可图,但同时,从零开始建立股票交易算法是一项非常复杂和繁琐的任务。非常重要的一点是要理解所有算法都可能失败,这可能会导致在实时交易环境中造成巨大的财务损失。本文的目的是探索如何使用Python构建和验证简单的交易算法。要在该项目中进一步进行,您可以考虑其他技术指标和蜡烛图模式,并将它们互换使用以构建更复杂的算法和策略。
主要收获
- 在本文中,我们学习了使用yfinance提取历史股价。
- 我们学习了根据股价计算MACD和SMA值,并使用这些值构建Python算法来创建信号/策略。
- 我们还学习了计算和可视化策略在股票上的5天和10天回报率。
注意:这不是金融建议,本项目中的所有工作只用于教育目的。以上就是本文的内容。希望您喜欢阅读本文并学到了新知识。感谢您的阅读和愉快学习!
常见问题
本文中显示的媒体不属于Analytics Vidhya所有,仅由作者决定使用。




