使用SVM预测大盘涨跌的简单策略
来源:互联网 发布:微店淘宝哪个买东西好 编辑:程序博客网 时间:2024/05/03 21:09
本策略是为了验证SVM对于大盘涨跌的预测是否有效,相比于纯随机策略,是否有明显的提高。
SVM模型用06~14年的数据训练,16年1月~12月的数据用来回测,这样是为了避免因为在模型中投入了现阶段的数据导致的过拟合。
第一次运算准确率为.66,不过个人认为这个准确率不一定能复现,所以做了Accuracy with sets这张图来看数据量和准确率的变化趋势。
Accuracy with sets这张图描述了准确率随着数据量提高的变化,可以看出准确率的变化趋势,以及准确率的变化范围。可以重复生成这张图,以便了解最低测试准确率为多少。
- 克隆notebook后,通过更改最后一段数据中第48行的 代码
if predict_up and not cost:
将predict_up去掉,改为:
if not cost:
就可以生成出不使用我们的SVM模型,纯粹的随机策略的图了。用以比较该模型和纯随机策略的相比,是否有显著的提高。
从结果来看,在16年的小范围下跌中,该模型表现还凑合吧……
import numpy as npimport pandas as pdfrom CAL.PyCAL import Datefrom CAL.PyCAL import Calendarfrom CAL.PyCAL import BizDayConventionfrom sklearn import svmstart = '2014-01-01' # 回测起始时间end = '2016-12-01' # 回测结束时间benchmark = 'HS300' # 策略参考标准universe = set_universe('HS300') # 证券池,支持股票和基金capital_base = 100000 # 起始资金freq = 'd' # 策略类型,'d'表示日间策略使用日dw线回测,'m'表示日内策略使用分钟线回测re
处理数据
fields = ['tradeDate','closeIndex', 'highestIndex','lowestIndex', 'turnoverVol','CHG','CHGPct']2stock = '000300'3#tradeDate是交易日、closeIndex是收盘指数、highestIndex是当日最大指数,lowestIndex是当日最小指数,CHG是涨跌4index_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日,上一行代码设定的所有索引的相关信息。67index_date = index_raw.set_index('tradeDate')8index_date = index_date.dropna()9index_date['max_difference'] = index_date['highestIndex'] - index_date['lowestIndex']1011index_date['max_of_30day'] = None12index_date['min_of_30day'] = None13index_date['max_difference_of_30day'] = None14index_date['closeIndex_after30days'] = None15#预设需要处理的值为None,方便之后直接用dropna函数去掉无效数据1617for i in xrange(len(index_date)-30):18 #对数据进行处理19 index_date['max_of_30day'][i+30] = max(index_date['highestIndex'][i:i+30])20 #找出前30天最大值。21 index_date['min_of_30day'][i+30] = min(index_date['lowestIndex'][i:i+30])22 #找出前30天最小值23 index_date['max_difference_of_30day'][i+30] = max(index_date['max_difference'][i:i+30])24 #找出前30天最大日波动25 index_date['closeIndex_after30days'][i]=index_date['closeIndex'][i+30]26 #找出30天后的收盘价。2728index_date = index_date.dropna() #去掉前30个和后30个无效的数据。29lables_raw = index_date['closeIndex_after30days'] #提取出需要预测的数据30lables = index_date['closeIndex_after30days'] > index_date['closeIndex'] #为分类处理数据,判断30天后的收盘价是否大于今日收盘价31lables_ud = lables.replace({True:'up',False:'down'}) #方便他人阅读,将True和False改为up和down,意味着30天后收盘价涨了还是跌了32features = index_date.drop(['closeIndex_after30days'],axis = 1) #在特征值中去掉我们要预测的数据。
在未调参之前,我们先获取一次准确率:
from sklearn import cross_validationfrom sklearn import preprocessingscaler = 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_svm = svm.SVC() #使用SVM分类器来判断涨跌clf_svm.fit(X_train, y_train)print "预测准确率为:%0.2f" % (clf_svm.score(X_test, y_test))
然后调C值,这里我是先让C在1~100的range跑,然后100~200……到300~400的时候发现不会进一步提高了。其实可以直接从1~1000跑一次,很快就能绘画出整个变动的图,然而我电脑渣带不动。
i_list = []score_list = []for i in range(300,400,1): i=i/1. clf_svm = svm.SVC(C = i) #使用SVM分类器来判断涨跌 clf_svm.fit(X_train, y_train) i_list.append(i) score_list.append(clf_svm.score(X_test, y_test))score_list_df = pd.DataFrame({'i_list':i_list,'score_list':score_list})score_list_df.plot(x='i_list' ,y='score_list',title='score change with c')
然后是gamma值,和C值调参上也是同理。
i_list = []score_list = []for i in range(100,200,1): i=i/100. clf_svm = svm.SVC(C=350 , gamma = i) #使用SVM分类器来判断涨跌 clf_svm.fit(X_train, y_train) i_list.append(i) score_list.append(clf_svm.score(X_test, y_test))score_list_df = pd.DataFrame({'gamma_list':i_list,'score_list':score_list})score_list_df.plot(x='gamma_list' ,y='score_list',title='score change with gamma')
虽说没什么卵用……还是假吧意思的比对一下不同核函数下的准确率吧。理所当然的是默认的高斯核表现最好。
i_list = []score_list = []kernels = ['linear', 'rbf','sigmoid']for i in kernels : clf_svm = svm.SVC(C=350 , gamma = 1.8 , kernel = i ) clf_svm.fit(X_train, y_train) i_list.append(i) score_list.append(clf_svm.score(X_test, y_test))score_list_df = pd.DataFrame({'kernels':i_list,'score_list':score_list})score_list_df.plot(x='kernels' ,y='score_list',title='score change with kernels',kind='bar')
知道了大致参数最优范围以后,我们使用grisearchCV在这个范围内找到最优解。
from sklearn.grid_search import GridSearchCVfrom sklearn.cross_validation import ShuffleSpliti = range(100,200,1)params = {'C':range(300,400,1),'gamma':[x /100. for x in range(100,200,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_svm = svm.SVC()# cv_sets = ShuffleSplit(X_train.shape[0], n_iter = 10, test_size = 0.20, random_state = 0)grid = GridSearchCV(clf_svm, params )grid = grid.fit(X_train, y_train)print grid.best_estimator_
然后在最优解的基础上再次计算一次准确率
from sklearn import cross_validationfrom sklearn import preprocessingscaler = 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_svm = svm.SVC(C = 300,gamma = 1.03) #使用SVM分类器来判断涨跌clf_svm.fit(X_train, y_train)print "预测准确率为:%0.2f" % (clf_svm.score(X_test, y_test))
为了判断模型是否稳健,我们让训练集合处于变化中,然后观察随着训练集合的变化,准确率的波动范围图。这里采取的是1000~2500数据每10个变化一次。
发现最低没有低于过0.72的准确率,波动较大在0.14左右,模型稳健度一般。
num_list = []score_list = []for i in xrange((len(features_scaler)-1000)/10): num_now = len(features_scaler)%10 + 10*i +1000 X_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_svm = svm.SVC(C=350,gamma = 1.8) #使用SVM分类器来判断涨跌 clf_svm.fit(X_train, y_train) num_list.append(num_now) score_list.append(clf_svm.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 randomstart = '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 random2start = '2016-01-01' # 回测起始时间3end = '2016-12-15' # 回测结束时间4benchmark = 'HS300' # 策略参考标准5universe = set_universe('HS300') # 证券池,支持股票和基金6capital_base = 100000 # 起始资金7freq = 'd' # 策略类型,'d'表示日间策略使用日线回测,'m'表示日内策略使用分钟线回测8refresh_rate = 1 # 调仓频率,表示执行handle_data的时间间隔,若freq = 'd'时间间隔的单位为交易日,若freq = 'm'时间间隔为分钟9stock = '000300' #预测的指数,沪深300指数。和策略参考池一致。10fields = ['tradeDate','closeIndex', 'highestIndex','lowestIndex', 'turnoverVol','CHG','CHGPct'] 11#tradeDate是交易日、closeIndex是收盘指数、highestIndex是当日最大指数,lowestIndex是当日最小指数,CHG是涨跌1213def initialize(account): # 初始化虚拟账户状态14 pass1516features_list = []17def handle_data(account):18 # 生成买入列表19 last_date = account.previous_date.strftime("%Y-%m-%d") #获取上一个交易日日期并格式化20 begin_date = pd.date_range(end=last_date,periods=60)[0] #获取60日之前的交易日日期21 begin_date = begin_date.strftime("%Y-%m-%d") #格式化这个日期22 to_class = DataAPI.MktIdxdGet(ticker='000300',beginDate=begin_date,endDate=last_date,field=fields,pandas="1")23 to_class = to_class.dropna()24 to_class = to_class[-30:] #获取我们要的30天的指数信息25 to_class_date = to_class.set_index('tradeDate')26 to_class_date['max_difference'] = to_class_date['highestIndex'] - to_class_date['lowestIndex']27 28 to_class_date_max_of_30day = max(to_class_date['highestIndex'])29 #找出前30天最大值。30 to_class_date_min_of_30day = min(to_class_date['lowestIndex'])31 #找出前30天最小值32 to_class_date_max_difference_of_30day = max(to_class_date['max_difference'])33 #找出前30天最大日波动34 35 features_for_predict = to_class_date[-1:]36 features_for_predict['max_of_30day'] = to_class_date_max_of_30day37 features_for_predict['min_of_30day'] = to_class_date_min_of_30day38 features_for_predict['max_difference_of_30day'] = to_class_date_max_difference_of_30day39 40 features_fp_scaler = scaler.transform(features_for_predict)41 predict_up = clf_svm.predict(features_fp_scaler)4243 #预测30天后的收盘是涨还是跌。44 random.shuffle(account.universe)45 for stock in account.universe: # 股票是股票池中的股票,并且优矿帮你自动剔除了当天停牌退市的股票46 p = account.reference_price[stock] # 股票前一天的收盘价47 cost = account.security_cost.get(stock) # 股票的平均持仓成本48 if predict_up and not cost: # 判断当前没有买入该股票49 order_pct_to(stock, 0.10) # 将满足条件的股票买入,总价值占虚拟帐户的10%50 elif cost and p >= cost * 1.20: # 卖出条件,当p这个价格涨幅到买入价的1.20倍;51 order_to(stock, 0) # 将满足条件的股票卖到剩余0股,即全部卖出
更多实盘源码请点击链接
0 0
- 使用SVM预测大盘涨跌的简单策略
- 使用AdaBoost预测预测大盘涨跌
- 用SVM预测股票涨跌
- 小波分析 + 支持向量机(SVM)预测股票涨跌幅的实现
- 小波分析 + 支持向量机(SVM)预测股票涨跌幅的实现作者:k474905973
- 用 线性回归 预测股票的涨跌
- 用 线性回归 预测股票的涨跌
- 股票指标使用 - 预测大盘
- 使用决策树预测大盘指数
- 大盘未来三个月的涨跌走势:3000点归来
- SVM的简单使用
- 算法-基于MACD的Adaboost股价涨跌预测模型
- 算法-基于成交量的Adaboost股价涨跌预测模型
- python 涨跌价格幅度 大盘凑合
- SVM用于上证指数的预测
- SVM预测
- SVM对文字识别的简单使用
- 用贝叶斯判别分析再次预测股票涨跌情况
- Oracle 实现select(查询)的结果集随机顺序展示
- Mysql数据库调优和性能优化
- 进程system占用80端口的解决方法
- POI创建Excel
- 限定符(Qualifiers),Android AutoLayout
- 使用SVM预测大盘涨跌的简单策略
- eclipse工作空间配置拷贝
- 多种数据库查询表字段是否存在
- mybatis逆向工程generatorSqlmapCustom生成简单javaBean以及mybatis映射文件
- com.model
- Conditional Variational Autoencoders
- 静态方法不能new内部类实例对象
- Android混淆 笔记
- Cent OS安装zip(yum方式)