量化分析(一)数据采集、预处理&SVM建模

一.数据采集

在此量化框架内,全部使用本地化计算。优势:

  • 1. 稳定——不会因网络不稳定而导致分析过程中断。
  • 2. 快速——本地化运算对于数据的访问速度比在线获取数据快,当机器学习的算法涉及到海量数据做训练集或迭代训练的时候,这一点尤其重要。
  • 3. 可复用——无论基础的行情数据还是加工处理后的数据,保存在本地后,对于后续进行结果分析或策略优化时更为方便。

本地化计算,首先要做的,就是将所需的基础数据采集到本地数据库里,本篇的示例源码采用的数据库是MySQL5.5,数据源是tushare pro接口。

我们现在要取一批特定股票的日线行情,部分代码如下:

import datetime
import tushare as ts
import pymysql

if __name__ == '__main__':

    # 设置tushare pro的token并获取连接
    ts.set_token('xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx')
    pro = ts.pro_api()
    # 设定获取日线行情的初始日期和终止日期,其中终止日期设定为昨天。
    start_dt = '20100101'
    time_temp = datetime.datetime.now() - datetime.timedelta(days=1)
    end_dt = time_temp.strftime('%Y%m%d')
    # 建立数据库连接,剔除已入库的部分
    db = pymysql.connect(host='127.0.0.1', user='root', passwd='admin', db='stock', charset='utf8')
    cursor = db.cursor()
    # 设定需要获取数据的股票池
    stock_pool = ['603912.SH','300666.SZ','300618.SZ','002049.SZ','300672.SZ']
    total = len(stock_pool)
    # 循环获取单个股票的日线行情
    for i in range(len(stock_pool)):
        try:
            df = pro.daily(ts_code=stock_pool[i], start_date=start_dt, end_date=end_dt)
			# 打印进度
            print('Seq: ' + str(i+1) + ' of ' + str(total) + '   Code: ' + str(stock_pool[i]))
            c_len = df.shape[0]
        except Exception as aa:
            print(aa)
            print('No DATA Code: ' + str(i))
            continue
        for j in range(c_len):
            resu0 = list(df.ix[c_len-1-j])
            resu = []
            for k in range(len(resu0)):
                if str(resu0[k]) == 'nan':
                    resu.append(-1)
                else:
                    resu.append(resu0[k])
            state_dt = (datetime.datetime.strptime(resu[1], "%Y%m%d")).strftime('%Y-%m-%d')
            try:
                sql_insert = "INSERT INTO stock_all(state_dt,stock_code,open,close,high,low,vol,amount,pre_close,amt_change,pct_change) VALUES ('%s', '%s', '%.2f', '%.2f','%.2f','%.2f','%i','%.2f','%.2f','%.2f','%.2f')" % (state_dt,str(resu[0]),float(resu[2]),float(resu[5]),float(resu[3]),float(resu[4]),float(resu[9]),float(resu[10]),float(resu[6]),float(resu[7]),float(resu[8]))
                cursor.execute(sql_insert)
                db.commit()
            except Exception as err:
                continue
    cursor.close()
    db.close()
    print('All Finished!')

数据采集的程序主要设置三个参数:获取行情的初始日期,终止日期,以及股票代码池

当我们获取数据后,就要往本地数据库进行写入(存储)操作了,本篇代码用的是SQL语言,需提前在数据库内建好相应的表,表配置和表结构如下:

库名:stock       表名:stock_all

其中 state_dt 和 stock_code 是主键和索引。state_dt 的格式是 ‘yyyy-mm-dd’(例:'2018-06-11')。这样的日期格式便于查询,且在MySQL内部能够进行大小比较。

二.数据预处理

以机器学习的视角来看,数据预处理主要包括数据清洗,排序,缺失值或异常值处理,统计量分析,相关性分析,主成分分析(PCA),归一化等。此处数据预处理比较简单,只是将存在本地数据库的日线行情数据整合成一份训练集数据,以用于后续的机器学习建模和训练

此处将以最简单的数据进行分析,我们输入端的数据是个股每日基础行情,输出端数据是股价相较前一交易日的涨跌状态。简单点说就是,我们向模型输入今天的基础行情,让模型预测明天股价是涨还是跌。

在代码实现方式上,我们采用面向对象的思想,将整个数据预处理过程和结果,封装成一个类,每次创建一个类实例,就得到了特定条件下的一份训练集。示例代码如下:

# -*- coding:utf8 -*-
import numpy as np
import pymysql


class data_collect(object):

    def __init__(self, in_code,start_dt,end_dt):
        ans = self.collectDATA(in_code,start_dt,end_dt)

    def collectDATA(self,in_code,start_dt,end_dt):
        # 建立数据库连接,获取日线基础行情(开盘价,收盘价,最高价,最低价,成交量,成交额)
        db = pymysql.connect(host='127.0.0.1', user='root', passwd='admin', db='stock', charset='utf8')
        cursor = db.cursor()
        sql_done_set = "SELECT * FROM stock_all a where stock_code = '%s' and state_dt >= '%s' and state_dt <= '%s' order by state_dt asc" % (in_code, start_dt, end_dt)
        cursor.execute(sql_done_set)
        done_set = cursor.fetchall()
        if len(done_set) == 0:
            raise Exception
        self.date_seq = []
        self.open_list = []
        self.close_list = []
        self.high_list = []
        self.low_list = []
        self.vol_list = []
        self.amount_list = []
        for i in range(len(done_set)):
            self.date_seq.append(done_set[i][0])
            self.open_list.append(float(done_set[i][2]))
            self.close_list.append(float(done_set[i][3]))
            self.high_list.append(float(done_set[i][4]))
            self.low_list.append(float(done_set[i][5]))
            self.vol_list.append(float(done_set[i][6]))
            self.amount_list.append(float(done_set[i][7]))
        cursor.close()
        db.close()
        # 将日线行情整合为训练集(其中self.train是输入集,self.target是输出集,self.test_case是end_dt那天的单条测试输入)
        self.data_train = []
        self.data_target = []
        self.data_target_onehot = []
        self.cnt_pos = 0
        self.test_case = []

        for i in range(1,len(self.close_list)):
            train = [self.open_list[i-1],self.close_list[i-1],self.high_list[i-1],self.low_list[i-1],self.vol_list[i-1],self.amount_list[i-1]]
            self.data_train.append(np.array(train))

            if self.close_list[i]/self.close_list[i-1] > 1.0:
                self.data_target.append(float(1.00))
                self.data_target_onehot.append([1,0,0])
            else:
                self.data_target.append(float(0.00))
                self.data_target_onehot.append([0,1,0])
        self.cnt_pos =len([x for x in self.data_target if x == 1.00])
        self.test_case = np.array([self.open_list[-1],self.close_list[-1],self.high_list[-1],self.low_list[-1],self.vol_list[-1],self.amount_list[-1]])
        self.data_train = np.array(self.data_train)
        self.data_target = np.array(self.data_target)
        return 1

最终这个类实例化后是要整合出三个数据:

  • 1. self.train :训练集中的输入端数据,本例中是每日基础行情。
  • 2. self.target :训练集中的输出数据,本例中相较于前一天股价的涨跌,涨为1,不涨为0。并且在排序上,每条 t 交易日的self.train里的数据对应的是 t+1 天股价的涨跌状态。
  • 3. self.test_case :在 t 末交易日的基础行情数据,作为输入端,用于模型训练完成后,对第二天的涨跌进行预测。

三.SVM建模

model = svm.SVC()               # 建模
model.fit(train, target)        # 训练
ans2 = model.predict(test_case) # 预测

机器学习框架是scikit-learn。是个非常强大的算法库,如果熟悉算法原理可以查阅官方API文档,可修改模型参数,进一步调优模型;亦可尝试其他算法比如决策树,逻辑回归,朴素贝叶斯等。

虽然顺利建模并作出预测,我们仍面对两个主要问题:1.模型预测能力如何?或者说该如何评估一个模型的质量?2.该如何结合模型进行仓位管理?风险如何?如何量化?

发布了287 篇原创文章 · 获赞 25 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_35812205/article/details/104578947
今日推荐