请 [注册] 或 [登录]  | 返回主站

量化交易吧 /  数理科学 帖子:3364712 新帖:0

【量化课堂】手把手教你如何应用机器学习

我太难了发表于:5 月 10 日 07:35回复(1)

导语:

在我们的数学课堂中,我们给大家简单介绍了几种机器学习方法的算法原理(SVM,朴素贝叶斯,随机森林等等),在每篇文章的最后,我们都放了一个非常小的例子来帮助大家使用这些算法。这一篇就给大家展示一个更贴近实际的例子,来帮助大家更好的使用这些算法。

本文中,为了降低提取的特征中的噪声,我们将常见技术分析指标进行离散化,作为特征值,如RSI,MACD,等等。然后应用SVM,朴素贝叶斯和随机森林算法来预测下一个交易日的涨跌情况。

为了和实际应用场景更接近,我们每天都会向训练数据中添加今天的数据,因为训练数据集发生了改变,我们每天都会训练一个新的模型。下面我们正式开工。


阅读前需要了解:
文中涉及到SVM,随机森林,朴素贝叶斯算法,可以参照量化课堂中的 支持向量机入门,随机森林入门,朴素贝叶斯入门。

训练预测代码介绍:

本文是之前的支持向量机,随机森林,朴素贝叶斯等机器学习算法的应用篇,具体的代码可以参照文中后面的研究模块,下面先将一些重要的代码拿出来说说,以方便大家理解代码的逻辑。

特征计算
我们先通过get_price方法得到该支股票的前35个交易日的开高低收和交易量数据,然后利用talib包提供的特征计算API计算相应的特征。在这次实验中,我们选取了SMA,WMA,MOM,STCK,STCD,MACD,RSI,WILLR,CCI,MFI,OBV,ROC,CMO等技术指标作为训练模型的特征。计算SMA指标的代码如下:

trading_days = get_all_trade_days()
start_day = trading_days[index - 35]
end_day = trading_days[index]
stock_data = get_price(test_stock, start_date=start_day, end_date=end_day, \
                               frequency='daily', fields=['close','high','low','volume'])
close_prices = stock_data['close'].values
sma_data = talib.SMA(close_prices)[-1]

分类标签确定
如果下一个交易日的收盘价比当前交易日的收盘价高,label的值为True,否则为False。相关代码如下:

start_day = trading_days[index]
end_day = trading_days[index   1]
stock_data = get_price(test_stock, start_date=start_day, end_date=end_day, \
                       frequency='daily', fields=['close','high','low','volume'])
close_prices = stock_data['close'].values
label = False
if close_prices[-1] > close_prices[-2]:
label = True

特征离散化
通过talib库计算出来的特征都是连续值,由于股市中的噪声非常多,如果直接将连续值特征放到机器学习算法中训练,得到的结果很可能过拟合的(回测结果好,实盘结果差)。为了避免过拟合,本文中结合各个特征的含义,将连续值特征离散化为二值特征。比如对于SMA特征,离散化的方法就是和当日收盘价相比较,若SMA小于当前收盘价,离散之后的特征值是1,若SMA大于等于收盘价,离散之后的特征值是-1。SMA离散化的代码如下,x_all是存放所有特征值的二维数组,x_all中的第1列存放的就是SMA特征数据。

# SMAif x_all[index][0] < x_all[index][-1]:
x_all[index][0] = 1
else:
x_all[index][0] = -1

应用机器学习算法
在准备好数据之后,就需要利用机器学习算法来训练模型并且利用训练好的模型预测下一个交易日的涨跌情况了。下面是通过SVM算法预测的代码:

clf = svm.SVC()
clf.fit(x_train, y_train)
prediction = clf.predict(x_test)

本文由JoinQuant量化课堂推出,版权归JoinQuant所有,商业转载请联系我们获得授权,非商业转载请注明出处。

版本更迭信息:V 1.0 文章上线

import talibimport pandas as pdfrom jqdata import *from sklearn import preprocessingfrom sklearn import svmfrom sklearn.ensemble import RandomForestClassifierfrom sklearn.naive_bayes import GaussianNBimport datetimeimport matplotlib.pyplot as pltimport warnings # 取消警告,2018-12-10添加warnings.filterwarnings("ignore")test_stock = '399300.XSHE'# 实验数据开始的日期,注意日期需要是一个交易日start_date = datetime.date(2010, 1, 4)# 实验数据终止的日期,也需要是个交易日end_date = datetime.date(2016, 6, 3)# 开始预测的日期,也需要是个交易日test_start_date = datetime.date(2015, 2, 26)# 得到所有的交易日列表trading_days = get_all_trade_days().tolist() # 2018-12-10修改,添加.tolist()start_date_index = trading_days.index(start_date)end_date_index = trading_days.index(end_date)test_start_index = trading_days.index(test_start_date)# 保存每一天预测的结果,如果某天预测对了,保存1,如果某天预测错了,保存-1result_list = []# 每一天都对应于一个index_endfor index_end in range(test_start_index, end_date_index):# x_all中保存所有的特征信息# y_all中保存所有的标签信息(要预测的对象)x_all = []y_all = []# 这个时间段产生所有的训练数据for index in range(start_date_index, index_end):#计算特征的代码start_day = trading_days[index - 35]end_day = trading_days[index]stock_data = get_price(test_stock, start_date=start_day, end_date=end_day, \                               frequency='daily', fields=['close','high','low','volume'])close_prices = stock_data['close'].valueshigh_prices = stock_data['high'].valueslow_prices = stock_data['low'].valuesvolumes = stock_data['volume'].values#通过数据计算指标sma_data = talib.SMA(close_prices)[-1]    wma_data = talib.WMA(close_prices)[-1]mom_data = talib.MOM(close_prices)[-1]stck, stcd = talib.STOCH(high_prices, low_prices, close_prices)stck_data = stck[-1]stcd_data = stcd[-1]macd, macdsignal, macdhist = talib.MACD(close_prices)macd_data = macd[-1]rsi_data = talib.RSI(close_prices,timeperiod=10)[-1]willr_data = talib.WILLR(high_prices, low_prices, close_prices)[-1]cci_data = talib.CCI(high_prices, low_prices, close_prices)[-1]mfi_data = talib.MFI(high_prices, low_prices, close_prices, volumes)[-1]obv_data = talib.OBV(close_prices, volumes)[-1]roc_data = talib.ROC(close_prices)[-1]cmo_data = talib.CMO(close_prices)[-1]# 保存训练数据中的一组训练数据features = []features.append(sma_data)features.append(wma_data)features.append(mom_data)features.append(stck_data)features.append(stcd_data)features.append(macd_data)features.append(rsi_data)features.append(willr_data)features.append(cci_data)features.append(mfi_data)features.append(obv_data)features.append(roc_data)features.append(cmo_data)# 特征离散化的时候用到的临时变量,离散化之后删除features.append(close_prices[-1])# 计算分类标签的代码start_day = trading_days[index]end_day = trading_days[index + 1]stock_data = get_price(test_stock, start_date=start_day, end_date=end_day, \                               frequency='daily', fields=['close','high','low','volume'])close_prices = stock_data['close'].valueslabel = Falseif close_prices[-1] > close_prices[-2]:label = Truex_all.append(features)y_all.append(label)#连续数值离散化#从后面开始向前面遍历,第一行数据需要舍弃,range只包含第一个元素,不包含第二个元素for index in range(len(x_all)-1, 0, -1):# SMAif x_all[index][0] < x_all[index][-1]:x_all[index][0] = 1else:x_all[index][0] = -1# WMAif x_all[index][1] < x_all[index][-1]:x_all[index][1] = 1else:x_all[index][1] = -1# MOMif x_all[index][2] > 0:x_all[index][2] = 1else:x_all[index][2] = -1# STCKif x_all[index][3] > x_all[index-1][3]:x_all[index][3] = 1else:x_all[index][3] = -1# STCDif x_all[index][4] > x_all[index-1][4]:x_all[index][4] = 1else:x_all[index][4] = -1# MACDif x_all[index][5] > x_all[index-1][5]:x_all[index][5] = 1else:x_all[index][5] = -1# RSIif x_all[index][6] > 70:x_all[index][6] = -1elif x_all[index][6] < 30:x_all[index][6] = 1else:if x_all[index][6] > x_all[index-1][6]:x_all[index][6] = 1else:x_all[index][6] = -1# WILLRif x_all[index][7] > x_all[index-1][7]:x_all[index][7] = 1else:x_all[index][7] = -1# CCIif x_all[index][8] > 200:x_all[index][8] = -1elif x_all[index][8] < -200:x_all[index][8] = 1else:if x_all[index][8] > x_all[index-1][8]:x_all[index][8] = 1else:x_all[index][8] = -1# MFIif x_all[index][9] > 90:x_all[index][9] = -1elif x_all[index][9] < 10:x_all[index][9] = 1else:if x_all[index][9] > x_all[index-1][9]:x_all[index][9] = 1else:x_all[index][9] = -1# OBVif x_all[index][10] > x_all[index-1][10]:x_all[index][10] = 1else:x_all[index][10] = -1# ROCif x_all[index][11] > 0:x_all[index][11] = 1else:x_all[index][11] = -1# CMOif x_all[index][12] > 50:x_all[index][12] = -1elif x_all[index][12] < -50:x_all[index][12] = 1else:if x_all[index][12] > x_all[index-1][12]:x_all[index][12] = 1else:x_all[index][12] = -1        # 删除价格x_all[index].pop(-1)
        # 去除第一行数据x_all = x_all[1:]y_all = y_all[1:]# 训练数据是除去最后一个数据之后的全部数据x_train = x_all[:-1]y_train = y_all[:-1]# 测试数据就是最后一个数据x_test = x_all[-1]y_test = y_all[-1]# 以下三行代码分别是利用SVM,随机森林,朴素贝叶斯,调用其中的一句就好clf = svm.SVC()#     clf = RandomForestClassifier(n_estimators=50)#     clf = GaussianNB()# 训练过程clf.fit(x_train, y_train)# 预测过程prediction = clf.predict(x_test)if prediction == y_test:print('True')result_list.append(1)else:print('False')result_list.append(-1)#将准确率曲线画出来x = range(0, len(result_list))y = []for i in range(0, len(result_list)):y.append((1 + float(sum(result_list[:i])) / (i+1)) / 2)line, = plt.plot(x, y)plt.show
True
False
True
True
True
True
False
True
True
False
True
True
True
True
True
False
False
True
True
False
True
True
True
False
True
True
True
True
True
False
False
True
True
False
True
True
False
False
True
True
False
False
False
True
False
False
True
False
True
False
True
False
False
True
True
True
False
False
False
True
True
True
False
True
True
True
True
False
False
False
True
False
False
False
True
False
False
False
True
True
True
True
True
False
False
True
True
True
False
True
True
False
True
False
False
True
True
False
False
False
True
True
False
False
False
True
False
True
False
False
False
True
True
True
True
False
True
False
False
True
True
False
True
True
True
False
False
False
True
True
False
False
True
False
True
False
True
True
True
False
False
False
True
True
False
True
False
True
True
True
True
True
True
True
True
False
False
True
False
True
True
False
True
False
True
True
True
False
True
False
True
False
True
False
True
False
False
False
True
True
False
True
False
False
False
True
True
False
False
False
True
False
True
False
False
False
True
False
True
True
False
True
True
True
False
False
True
True
True
False
True
True
True
True
True
True
True
True
True
True
False
True
False
False
True
True
True
False
False
False
True
True
False
True
False
True
False
True
False
True
True
False
True
True
True
True
False
True
False
True
True
True
True
True
False
True
True
True
False
True
True
True
False
True
True
True
True
True
False
True
True
False
False
True
True
True
False
True
True
True
True
False
True
False
False
False
False
True
True
True
True
False
False
True
False
False
True
True
True
False
True
True
False
False
True
False
False
True
True
False
False
True
False
<function matplotlib.pyplot.show(*args, **kw)>
 

全部回复

0/140

量化课程

    移动端课程