继使用SVM预测大盘涨跌, 使用决策树预测大盘涨跌后的第三个预测大盘涨跌的模型。包括调参的过程以及模型稳健性验证。

  • 经过调参之后,预测准确率可以达到平均90%,上下波动范围约10%。

  • 看到预测的准确率还不错,我提取出了特征的权重值,来思考决策树为什么预测准确率还不错。然后做了策略不加预测大盘和加上预测大盘的对比。可以发现,一般的策略(例如纯随机,小于4购买)在加上了对大盘预测的系数后,收益不一定得到了明显提高,但是风险得到了明显的降低。

  • 经过提取特征值比对,发现对于未来30个交易日后的涨跌预测,最重要的是前30个交易日的最小值,最大值,以及日变化,可以简单理解为市场震荡程度。
  • 可以认为决策树预测大盘是有效的,对量化交易有一定的积极作用。
import numpy as np
import pandas as pd
from CAL.PyCAL import Date
from CAL.PyCAL import Calendar
from CAL.PyCAL import BizDayConvention
from sklearn.tree import DecisionTreeClassifier
start = '2014-01-01'                       # 回测起始时间
end = '2016-12-01'                         # 回测结束时间
benchmark = 'HS300'                        # 策略参考标准
universe = set_universe('HS300')  # 证券池,支持股票和基金
capital_base = 100000                      # 起始资金
freq = 'd'                                 # 策略类型,'d'表示日间策略使用日dw线回测,'m'表示日内策略使用分钟线回测
refresh_rate = 1                           # 调仓频率,表示执行handle_data的时间间隔,若freq = 'd'时间间隔的单位为交易日,若freq = 'm'时间间隔为分钟

处理数据

×1
fields = ['tradeDate','closeIndex', 'highestIndex','lowestIndex', 'turnoverVol','CHG','CHGPct']
2
stock = '000300'
3
#tradeDate是交易日、closeIndex是收盘指数、highestIndex是当日最大指数,lowestIndex是当日最小指数,CHG是涨跌
4
index_raw = DataAPI.MktIdxdGet(ticker=stock,beginDate=u"2006-03-01",endDate=u"2015-03-01",field=fields,pandas="1")
5
#获取2006年3月1日到2015年3月1日,上一行代码设定的所有索引的相关信息。
6
​
7
index_date = index_raw.set_index('tradeDate')
8
index_date = index_date.dropna()
9
index_date['max_difference'] = index_date['highestIndex'] - index_date['lowestIndex']
10
​
11
index_date['max_of_30day'] = None
12
index_date['min_of_30day'] = None
13
index_date['max_difference_of_30day'] = None
14
index_date['closeIndex_after30days'] = None
15
#预设需要处理的值为None,方便之后直接用dropna函数去掉无效数据
16
​
17
for i in xrange(len(index_date)-30):
18#对数据进行处理
19index_date['max_of_30day'][i+30] = max(index_date['highestIndex'][i:i+30])
20#找出前30天最大值。
21index_date['min_of_30day'][i+30] = min(index_date['lowestIndex'][i:i+30])
22#找出前30天最小值
23index_date['max_difference_of_30day'][i+30] = max(index_date['max_difference'][i:i+30])
24#找出前30天最大日波动
25index_date['closeIndex_after30days'][i]=index_date['closeIndex'][i+30]
26#找出30天后的收盘价。
27
​
28
index_date = index_date.dropna()   #去掉前30个和后30个无效的数据。
29
lables_raw = index_date['closeIndex_after30days'] #提取出需要预测的数据
30
lables = index_date['closeIndex_after30days'] > index_date['closeIndex'] #为分类处理数据,判断30天后的收盘价是否大于今日收盘价
31
lables_ud = lables.replace({True:'up',False:'down'}) #方便他人阅读,将True和False改为up和down,意味着30天后收盘价涨了还是跌了
32
features = index_date.drop(['closeIndex_after30days'],axis = 1) #在特征值中去掉我们要预测的数据。

在未调参之前,我们先获取一次准确率:得到0.88

from sklearn import cross_validation
from sklearn import preprocessing
scaler = preprocessing.StandardScaler().fit(features)
features_scaler = scaler.transform(features)
#上面两行代码用来标准化数据X_train,X_test, y_train, y_test = cross_validation.train_test_split(features_scaler, lables, test_size = 0.2, random_state = 0)clf_tree = DecisionTreeClassifier(random_state=0)
clf_tree.fit(X_train, y_train)
print "预测准确率为:%0.2f" % (clf_tree.score(X_test, y_test))

然后调C值,这里我是先让max_depth在1~100的range跑,然后作图

×1
i_list = []
2
score_list = []
3
for i in range(1,100,1):
4i=i/1.
5clf_tree = DecisionTreeClassifier(max_depth =i )   #使用SVM分类器来判断涨跌
6clf_tree.fit(X_train, y_train)
7i_list.append(i)
8score_list.append(clf_tree.score(X_test, y_test))
9
​
10
score_list_df =  pd.DataFrame({'max_depth':i_list,'score_list':score_list})
11
score_list_df.plot(x='max_depth' ,y='score_list',title='score change with max_depth')

然后是min_samples_leaf值,同理。这里是从0.1到10变动范围

i_list = []
score_list = []
for i in range(1,100,1):i=i/10.clf_tree = DecisionTreeClassifier(min_samples_leaf  = i ) clf_tree.fit(X_train, y_train)i_list.append(i)score_list.append(clf_tree.score(X_test, y_test))score_list_df =  pd.DataFrame({'min_samples_leaf':i_list,'score_list':score_list})
score_list_df.plot(x='min_samples_leaf' ,y='score_list',title='score change with min_samples_leaf')

然后是min_samples,这里选用2~50

i_list = []
score_list = []min_samples  =  range(2,50,1)
for i in min_samples :clf_tree = DecisionTreeClassifier(min_samples_split  = i ) clf_tree.fit(X_train, y_train)i_list.append(i)score_list.append(clf_tree.score(X_test, y_test))score_list_df =  pd.DataFrame({'min_samples_split':i_list,'score_list':score_list})
score_list_df.plot(x='min_samples_split' ,y='score_list',title='score change with min_samples_split')

然后是min_weight_fraction_leaf……自己看图。发现调整这个参数对模型影响意义并不大。
i_list = []
score_list = []min_weight  =  [x /1000. for x in range(1,500,1)]
for i in min_weight :clf_tree = DecisionTreeClassifier(min_weight_fraction_leaf  = i ) clf_tree.fit(X_train, y_train)i_list.append(i)score_list.append(clf_tree.score(X_test, y_test))score_list_df =  pd.DataFrame({'min_weight_fraction_leaf':i_list,'score_list':score_list})
score_list_df.plot(x='min_weight_fraction_leaf' ,y='score_list',title='score change with min_weight')

知道了大致参数最优范围以后,我们使用grisearchCV在这个范围内找到最优解。

from sklearn.grid_search import GridSearchCV
from sklearn.cross_validation import ShuffleSplit
params = {'max_depth':range(1,50,1),'min_samples_split':range(2,50,1)}X_train,X_test, y_train, y_test = cross_validation.train_test_split(features_scaler, lables, test_size = 0.2, random_state = 0)clf_tree = DecisionTreeClassifier() # cv_sets = ShuffleSplit(X_train.shape[0], n_iter = 10, test_size = 0.20, random_state = 0)grid = GridSearchCV(clf_tree, params)
grid = grid.fit(X_train, y_train)
print grid.best_estimator_

然后在最优解的基础上再次计算一次准确率

from sklearn import cross_validation
from sklearn import preprocessing
scaler = preprocessing.StandardScaler().fit(features)
features_scaler = scaler.transform(features)
#上面两行代码用来标准化数据X_train,X_test, y_train, y_test = cross_validation.train_test_split(features_scaler, lables, test_size = 0.2, random_state = 0)clf_tree = DecisionTreeClassifier(max_depth = 32 , min_samples_split=3 )
clf_tree.fit(X_train, y_train)
print "预测准确率为:%0.2f" % (clf_tree.score(X_test, y_test))

然后我们通过返回数据重要性,来看看对我们决策树哪些特征影响最大。

通过下方的表格(和直方图)发现影响最大的特征主要是30日的最小值,30日的最大值以及30日的最大日波动,然后是当日交易量。可以简单认为,前30日的波动幅度,最大震荡能一定程度上反映出未来30日后的市场涨跌趋势。

为了判断模型是否稳健,我们让训练集合处于变化中,然后观察随着训练集合的变化,准确率的波动范围图。这里采取的是1000~2500数据每10个变化一次。

从图的表现可以看出,波动范围0.1左右,平均线在0.88左右,大致还算稳健……吧。

num_list = []
score_list = []
for i in xrange((len(features_scaler)-1000)/2):num_now = len(features_scaler)%2 + 2*i +1000X_train,X_test, y_train, y_test = cross_validation.train_test_split(features_scaler[:num_now], lables[:num_now], test_size = 0.2, random_state = 0)clf_tree = DecisionTreeClassifier( max_depth = 32 , min_samples_split=3 )   #使用SVM分类器来判断涨跌clf_tree.fit(X_train, y_train)num_list.append(num_now)score_list.append(clf_tree.score(X_test, y_test))score_list_df =  pd.DataFrame({'sets_num':num_list,'accuracy':score_list})
score_list_df.plot(x='sets_num' ,y='accuracy',title='Accuracy with sets')

接下来是比对用的空白组,纯随机策略(不控制风险,只是随机买,1.20倍卖出)

import random
start = '2016-01-01'                       # 回测起始时间
end = '2016-12-01'                         # 回测结束时间
benchmark = 'HS300'                        # 策略参考标准
universe = set_universe('HS300')  # 证券池,支持股票和基金
capital_base = 100000                      # 起始资金
freq = 'd'                                 # 策略类型,'d'表示日间策略使用日线回测,'m'表示日内策略使用分钟线回测
refresh_rate = 1                           # 调仓频率,表示执行handle_data的时间间隔,若freq = 'd'时间间隔的单位为交易日,若freq = 'm'时间间隔为分钟def initialize(account):                   # 初始化虚拟账户状态passfeatures_list = []
def handle_data(account):random.shuffle(account.universe)       # 随机化股票池一遍随机策略for stock in account.universe:         # 股票是股票池中的股票,并且优矿帮你自动剔除了当天停牌退市的股票p = account.reference_price[stock]        # 股票前一天的收盘价cost = account.security_cost.get(stock)  # 股票的平均持仓成本if not cost:                           # 判断当前没有买入该股票order_pct_to(stock, 0.10)          # 将满足条件的股票买入,总价值占虚拟帐户的10%elif cost and p >= cost * 1.20:        # 卖出条件,当p这个价格涨幅到买入价的1.20倍;order_to(stock, 0)        # 将满足条件的股票卖到剩余0股,即全部卖出

然后是纯随机策略基础上,只增加一个预测盘指的涨跌,如果预测涨,则随机买入,否则不买。和纯随机策略比,的确好了一丢丢。

import random
2
start = '2016-01-01'                       # 回测起始时间
3
end = '2016-12-15'                         # 回测结束时间
4
benchmark = 'HS300'                        # 策略参考标准
5
universe = set_universe('HS300')  # 证券池,支持股票和基金
6
capital_base = 100000                      # 起始资金
7
freq = 'd'                                 # 策略类型,'d'表示日间策略使用日线回测,'m'表示日内策略使用分钟线回测
8
refresh_rate = 1                           # 调仓频率,表示执行handle_data的时间间隔,若freq = 'd'时间间隔的单位为交易日,若freq = 'm'时间间隔为分钟
9
stock = '000300' #预测的指数,沪深300指数。和策略参考池一致。
10
fields = ['tradeDate','closeIndex', 'highestIndex','lowestIndex', 'turnoverVol','CHG','CHGPct']
11
#tradeDate是交易日、closeIndex是收盘指数、highestIndex是当日最大指数,lowestIndex是当日最小指数,CHG是涨跌
12
​
13
def initialize(account):                   # 初始化虚拟账户状态
14pass
15
​
16
features_list = []
17
def handle_data(account):
18# 生成买入列表
19last_date = account.previous_date.strftime("%Y-%m-%d") #获取上一个交易日日期并格式化
20begin_date = pd.date_range(end=last_date,periods=60)[0] #获取60日之前的交易日日期
21begin_date = begin_date.strftime("%Y-%m-%d") #格式化这个日期
22to_class = DataAPI.MktIdxdGet(ticker='000300',beginDate=begin_date,endDate=last_date,field=fields,pandas="1")
23to_class = to_class.dropna()
24to_class = to_class[-30:] #获取我们要的30天的指数信息
25to_class_date = to_class.set_index('tradeDate')
26to_class_date['max_difference'] = to_class_date['highestIndex'] - to_class_date['lowestIndex']
2728to_class_date_max_of_30day = max(to_class_date['highestIndex'])
29#找出前30天最大值。
30to_class_date_min_of_30day = min(to_class_date['lowestIndex'])
31#找出前30天最小值
32to_class_date_max_difference_of_30day = max(to_class_date['max_difference'])
33#找出前30天最大日波动
3435features_for_predict = to_class_date[-1:]
36features_for_predict['max_of_30day'] = to_class_date_max_of_30day
37features_for_predict['min_of_30day'] = to_class_date_min_of_30day
38features_for_predict['max_difference_of_30day'] = to_class_date_max_difference_of_30day
3940features_fp_scaler = scaler.transform(features_for_predict)
41predict_up = clf_tree.predict(features_fp_scaler)
42
​
43#预测30天后的收盘是涨还是跌。
44random.shuffle(account.universe)
45for stock in account.universe:         # 股票是股票池中的股票,并且优矿帮你自动剔除了当天停牌退市的股票
46p = account.reference_price[stock]        # 股票前一天的收盘价
47cost = account.security_cost.get(stock)  # 股票的平均持仓成本
48if predict_up and not cost:                        # 判断当前没有买入该股票
49order_pct_to(stock, 0.10)          # 将满足条件的股票买入,总价值占虚拟帐户的10%
50elif cost and p >= cost * 1.20:        # 卖出条件,当p这个价格涨幅到买入价的1.20倍;
51order_to(stock, 0)        # 将满足条件的股票卖到剩余0股,即全部卖出

×1
import random
2
start = '2015-01-01'                       # 回测起始时间
3
end = '2016-12-15'                         # 回测结束时间
4
benchmark = 'HS300'                        # 策略参考标准
5
universe = set_universe('HS300')  # 证券池,支持股票和基金
6
capital_base = 100000                      # 起始资金
7
freq = 'd'                                 # 策略类型,'d'表示日间策略使用日线回测,'m'表示日内策略使用分钟线回测
8
refresh_rate = 1                           # 调仓频率,表示执行handle_data的时间间隔,若freq = 'd'时间间隔的单位为交易日,若freq = 'm'时间间隔为分钟
9
stock = '000300' #预测的指数,沪深300指数。和策略参考池一致。
10
fields = ['tradeDate','closeIndex', 'highestIndex','lowestIndex', 'turnoverVol','CHG','CHGPct']
11
#tradeDate是交易日、closeIndex是收盘指数、highestIndex是当日最大指数,lowestIndex是当日最小指数,CHG是涨跌
12
​
13
def initialize(account):                   # 初始化虚拟账户状态
14pass
15
​
16
features_list = []
17
def handle_data(account):
18# 生成买入列表
19last_date = account.previous_date.strftime("%Y-%m-%d") #获取上一个交易日日期并格式化
20begin_date = pd.date_range(end=last_date,periods=60)[0] #获取60日之前的交易日日期
21begin_date = begin_date.strftime("%Y-%m-%d") #格式化这个日期
22to_class = DataAPI.MktIdxdGet(ticker='000300',beginDate=begin_date,endDate=last_date,field=fields,pandas="1")
23to_class = to_class.dropna()
24to_class = to_class[-30:] #获取我们要的30天的指数信息
25to_class_date = to_class.set_index('tradeDate')
26to_class_date['max_difference'] = to_class_date['highestIndex'] - to_class_date['lowestIndex']
2728to_class_date_max_of_30day = max(to_class_date['highestIndex'])
29#找出前30天最大值。
30to_class_date_min_of_30day = min(to_class_date['lowestIndex'])
31#找出前30天最小值
32to_class_date_max_difference_of_30day = max(to_class_date['max_difference'])
33#找出前30天最大日波动
3435features_for_predict = to_class_date[-1:]
36features_for_predict['max_of_30day'] = to_class_date_max_of_30day
37features_for_predict['min_of_30day'] = to_class_date_min_of_30day
38features_for_predict['max_difference_of_30day'] = to_class_date_max_difference_of_30day
3940features_fp_scaler = scaler.transform(features_for_predict)
41predict_up = clf_tree.predict(features_fp_scaler)
42
​
43#预测30天后的收盘是涨还是跌。
44random.shuffle(account.universe)
45for stock in account.universe:         # 股票是股票池中的股票,并且优矿帮你自动剔除了当天停牌退市的股票
46p = account.reference_price[stock]        # 股票前一天的收盘价
47cost = account.security_cost.get(stock)  # 股票的平均持仓成本
48if p<4 and  not cost:                        # 判断当前没有买入该股票
49order_pct_to(stock, 0.10)          # 将满足条件的股票买入,总价值占虚拟帐户的10%
50elif cost and p >= cost * 1.20:        # 卖出条件,当p这个价格涨幅到买入价的1.20倍;
51order_to(stock, 0)        # 将满足条件的股票卖到剩余0股,即全部卖出

使用AdaBoost预测预测大盘涨跌相关推荐

  1. python支持向量机 股票_小蛇学python(4)利用SVM预测股票涨跌

    最近接了一个私活,指导学妹完成毕业设计.核心思想就是利用SVM模型来预测股票涨跌,并完成策略构建,自动化选择最优秀的股票进行资产配置. 在做这个项目的过程中,我体会到想成为一个合格的数据分析或者数据挖 ...

  2. python应用(3)svm模型预测股票涨跌

    最近接了一个私活,指导学妹完成毕业设计.核心思想就是利用SVM模型来预测股票涨跌,并完成策略构建,自动化选择最优秀的股票进行资产配置. 在做这个项目的过程中,我体会到想成为一个合格的数据分析或者数据挖 ...

  3. 【手把手教你】使用Logistic回归、LDA和QDA模型预测指数涨跌

    1 引言 机器学习(Machine Learning)是人工智能(AI)的重要组成部分,目前已广泛应用于数据挖掘.自然语言处理.信用卡欺诈检测.证券市场分析等领域.量化投资作为机器学习在投资领域内最典 ...

  4. 量化交易是不是用机器预测股票涨跌?这靠谱吗?

    量化交易是不是用机器预测股票涨跌?是又不全是,量化交易是策略制定的基础上进行自动化交易,也不能全说是机器预测涨跌的,而且机器学习预测股票涨跌也不太靠谱,结果和丢硬币差不了太多. 虽然用机器学习来预测涨 ...

  5. 传统机器学习分类模型预测股价涨跌

    前言 股票市场风起云涌,只有对股价有良好的预测才能够更好的抓住盈利机会.那么传统的机器学习分类模型在这方面的效果如何呢? 本文在只考虑5.10.20日移动平均线.移动指数平均线这六项指标的情况下,比较 ...

  6. CNN模型预测股票涨跌的始末过程——(一)股票数据的获取

    CNN模型预测股票涨跌的始末过程--(一)股票数据的获取[附源码和数据] 股票数据的获取 Choice数据 - 东方财富 Tushare BigQuant 最后列一下我下载成功的数据 股票数据的获取 ...

  7. svm预测股价 python_小蛇学python(4)利用SVM预测股票涨跌

    最近接了一个私活,指导学妹完成毕业设计.核心思想就是利用SVM模型来预测股票涨跌,并完成策略构建,自动化选择最优秀的股票进行资产配置. 在做这个项目的过程中,我体会到想成为一个合格的数据分析或者数据挖 ...

  8. 逻辑回归模型预测股票涨跌

    http://www.cnblogs.com/lafengdatascientist/p/5567038.html 逻辑回归模型预测股票涨跌 逻辑回归是一个分类器,其基本思想可以概括为:对于一个二分类 ...

  9. R语言逻辑回归Logistic回归分析预测股票涨跌

    最近我们被客户要求撰写关于逻辑回归的研究报告,包括一些图形和统计输出. 视频:R语言逻辑回归(Logistic回归)模型分类预测病人冠心病风险 逻辑回归Logistic模型原理和R语言分类预测冠心病风 ...

最新文章

  1. debain安装lyx2.2.2,以及报错整理:
  2. matlab做pca人脸识别,[转载]一个修改后的PCA进行人脸识别的Matlab代码,识
  3. mysql union order_MySQL中union和order by同时使用的实现方法
  4. LiveVideoStackCon讲师热身分享 ( 九 ) —— 51Talk音视频技术思考及非典型挑战
  5. 微信小程序 - 实战小案例 - 简易记事本
  6. Dart编译技术在服务端的探索和应用
  7. Vue笔记——Vue组件中引入jQuery
  8. 向 Linux kernel 社区提交patch补丁步骤总结(已验证成功)
  9. 基于easyui的 增 删 改 查
  10. 让游戏通过红蓝立体眼镜展现立体效果
  11. 【好东西】ACM在线模版-f-zyj
  12. 移动地图应用普及给企业带来的利益
  13. python提取数列数字_从pandas datafram中的列中提取字符串中的数字
  14. nova shelve 的使用
  15. 计算机看不了pdf,电脑桌面变成pdf打不开怎么办
  16. while循环因为内部使用ssh命令而导致不能循环文件的所有行
  17. mb63.net/ios.html,Document
  18. php warning require,Thinkphp 网站打开提示Warning: require(): open_basedir restriction in effect另一种解决方法...
  19. 华为电子邮件显示未读邮件1_您所说的话:如何使电子邮件垃圾邮件保持整洁...
  20. Windows 98 安装全程图解 一看就会(转)

热门文章

  1. STM32笔记 (七)中断系统与NVIC嵌套向量中断控制器
  2. 百分百背后是百度电商的悲哀
  3. Python基础之算数运算符
  4. 什么是「逼格」?怎么才能提高「逼格」?
  5. 学习WordPress必须知道的函数(转)
  6. 父母教养方式与幼儿焦虑关系的三水平元分析
  7. cordova-plugin-battery-status监听电池状态
  8. python socks代理 命令行_Python使用socks代理
  9. 白加黑木马拆分HTTP协议躲避网络单包侦测
  10. 8.中学班级管理与教师心理