关于涨跌的思考(一)I————python Notebook Research Alpha下机器学习一瞥
由于帖子长度控制有限,,我将内容分两个帖子写
海水朝朝朝朝朝朝朝落,大盘涨跌跌涨跌跌涨涨。依据历史涨跌数据使用机器学习手段,预测下一交易日的涨跌,顺着这样一个朴实无华的思路开始了我的尝试,写出来做个总结我想收获会更多些,同时希望论坛里做机器学习的大牛们可以指点一二。另外感谢@licco li 给我提供最先接触Ipython Notebook Research Alpha 的机会。
这个帖子的框架:
所用策略平台:ricequant,米筐科技的策略平台(www.ricequant.com),ps个人觉得不错,建议大家去用用试试。
机器学习 & scikit-learn简介
机器学习
scikit-learn
Introduction:HS300历史数据特征一览
基于历史涨跌的机器学习预测模型构建
机器学习估计器的选择
训练集样本数量的选择
涨跌时间窗口的选择
机器学习 & scikit-learn简介机器学习简单说:机器学习算法是一类从数据中自动分析获得规律,并利用规律对未知数据进行预测的算法。
用一张图说明它所包含的内容:

我们把目光集中到上图中的有监督学习,它是指数据中包括了我们想预测的属性,有监督学习有以下两类:
- 分类(Classification):样本属于两个或多个类别,我们希望通过从已标记类别的数据学习,来预测未标记数据的分类。例如,识别手写数字就是一个分类问题,其目标是将每个输入向量对应到有穷的数字类别。从另一种角度来思考,分类是一种有监督学习的离散(相对于连续)形式,对于n个样本,一方有对应的有限个类别数量,另一方则试图标记样本并分配到正确的类别。
- 回归(Regression):如果希望的输出是一个或多个连续的变量,那么这项任务被称作回归,比如用年龄和体重的函数来预测三文鱼的长度。
之前对这块没啥接触的伙伴,Andrew Ng 的课是不错的入门选择,另外这里还有一份关于它的笔记。
scikit-learnscikit-learn是一个基于NumPy、SciPy、Matplotlib的机器学习包,主要涵盖了分类、回归和聚类等机器学习算法,例如knn、SVM、逻辑回归、朴素贝叶斯、随机森林、k-means等等,简言之:是一只强大的轮子。
官网有个很好耍的例子:安德森鸢尾花品种亚属预测。
我们有一百五十个鸢尾花的一些尺寸观测值:萼片长度、宽度,花瓣长度和宽度。还有它们的亚属:山鸢尾(Iris setosa)、变色鸢尾(Iris versicolor)和维吉尼亚鸢尾(Iris virginica)。我们使用这些数据,从中学习并预测一个新的数据。在scikit-learn中,通过创建一个估计器(estimator)从已经存在的数据学习,并且调用它的fit(X,Y)方法。
代码如下:
from sklearn
import datasets
from sklearn
import svm
#数据iris = datasets.load_iris()
#估计器clf = svm.LinearSVC()
#学习clf.fit(iris.data, iris.target)
#预测clf.predict([[
5.0,
3.6,
1.3,
0.25]])
输出结果:array([0]),即学习结果认为,萼片长度、宽度,花瓣长度和宽度观测值分别为5.0, 3.6, 1.3, 0.25的安德森鸢尾花的亚属为山鸢尾(Iris setosa)。
Introduction:HS300历史数据特征一览有了些基本概念后,我们开始认识我们关心的数据:首先我们导入所需库并获取过去十年CSI300指数原始数据:
import matplotlib.pyplot
as plt
import numpy
as np
import pandas
as pddf = rd.get_price(
'CSI300.INDX',
'2005-01-01',
'2015-07-25').reset_index()[[
'OpeningPx',
'ClosingPx']]
#当收盘价高于开盘价返回"True"up_and_down = df[
'ClosingPx'] - df[
'OpeningPx'] >
0#每日收益率rate_of_return = (df[
'ClosingPx'] - df[
'OpeningPx']) / df[
'OpeningPx']
#每日涨跌统计up_and_down_statistic = up_and_down.value_counts()
输出每日涨跌统计:
up_and_down_statistic结果:
True 1379
False 1185
dtype: int64
可见过去十年中,有1379个交易日是上涨的,而1185个交易日下跌。我们画个图对比下:
with plt.xkcd(): fig = plt.figure(figsize=(
10,
8)) ax = fig.add_axes((
0.1,
0.2,
0.8,
0.7)) ax.bar([-
0.125,
1.0-
0.125], [up_and_down_statistic[
0], up_and_down_statistic[
1]],
0.25) ax.spines[
'right'].set_color(
'none') ax.spines[
'top'].set_color(
'none') ax.xaxis.set_ticks_position(
'bottom') ax.set_xticks([
0,
1]) ax.set_xlim([-
0.5,
1.5]) ax.set_ylim([
0, up_and_down_statistic.max()]) ax.set_xticklabels([
'DOWN',
'UP']) plt.yticks([]) plt.title(
"DISTRIBUTION OF UP AND DOWN") fig.text(
0.5,
0.05,
'DATA FROM RICEQUANT', ha=
'center')plt.show()
结果:

恩,从图来看差距还是很明显,看来如果心情以每日涨跌来决定的话,快乐的时光还是更多的,真是A股的正能量。
我们进而统计每日收益率的特征:
rate_of_return.describe()
结果:
count 2564.
000000mean
0.
001340std
0.
017139min -
0.
09578325% -
0.
00699250%
0.
00116875%
0.
010438max
0.
085987dtype: float64
可以看到过去2000多个交易日中,沪深300单日涨幅最大为8.5个点(大奇迹日),单日跌幅最大为9.5个点(大盘跌停)。
我们依旧画图:
## Variation in the past decaderate_of_return.plot(kind=
'line', style=
'k--', figsize=(
15,
10), title=
'Daily Yield Changes Over Time Series')

曲线以零为轴上下震荡,可以看到曲线有两大宽幅波动的区间,一个是07年的牛市,另外一个,就是我们现在这个渐行渐远的......似乎开始向0轴收敛的......虽然宽幅波动这意味着风险增强,但同时也诉说着交易市场的活跃,宽幅波动的开端暗示着牛市脚步的靠近,末端预示着牛儿的即将远行。
根据每日收益率的历史数据我们还可进一步绘制频率分布直方图并使用Kernel Density Estimate对数据进行拟合:
## Frequency distribution of up and downrate_of_return.hist(bins=
80, alpha=
0.3, color=
'g', normed=
True)
## Kernel Density Estimaterate_of_return.plot(kind=
'kde', xlim=[-
0.1,
0.1], style=
'r', grid=
True, figsize=(
15,
10), title=
'Frequency Distribution Of Up And Down & Kernel Density Estimate Curve')plt.show()

嚯,乍一看这就是一个标准正态分布,可是如果仔细瞅瞅你会发现,涨跌幅靠近零轴,涨强跌弱;而涨跌幅远离零轴的位置,跌强涨弱。也就是,微涨与微跌,微涨的情况更为显著,大涨与大跌,大跌分布更为明显。