机器学习策略简介
什么是机器学习策略?
从广义上来说,机器学习是一种能够赋予机器学习的能力以此让它完成直接编程无法完成的功能的方法.但从实践的意义上来说,机器学习是一种通过利用数据,训练出模型,然后使用模型预测的一种方法.而机器学习策略,则是通过机器学习方法,通过输入训练数据与模型来获得对未来数据的价格或者涨跌的预期判断,进而进行投资的量化策略.
支持向量机简介
什么是支持向量机?
支持向量机(Support Vector Machines, SVM) 被Vapnik与他的合作者提出于1995年,基础为统计学习理论和结构风险最小化原则.支持向量机具有完备的理论基础和出色的学习能力,是借助于最优化方法解决有限样本机器学习问题的数据挖掘出色方法之一.
支持向量机的原理是?
假设给定一个特征空间上的训练集:
T=\begin{Bmatrix}(x{1},y{1}),(x{2},y{2}),...,(x{i},y{i})\end{Bmatrix};x{i}\in \boldsymbol{X}=\mathbb{R}^n,y{i}\in \boldsymbol{Y}=
其中x{i}为第i个特征向量,y{i}为x{i}的类标记,当y{i}=+1时,x{i}称为正例,当y{i}=-1时,x_{i}称为负例.
线性可分SVM
假设训练数据集线性T可分,通过间隔最大化或等价求解相应凸二次规划问题得到分离超平面w^{}\cdot x+b^{}=0和相应的分类决策函数f(x)=sign(w^{}\cdot x+b^{})为线性可分SVM.
为了量化分类的正确性和确信度,引入函数间隔的概念.
对于给定的训练数据集T和超平面(w,b),定义超平面关于样本点(x{i},y{i})的函数间隔为:
<center>\hat{\gamma{i}}=y{i}(w\cdot x_{i}+b)</center>
定义超平面(w,b)关于训练数据集T的函数间隔为关于T中所有样本点(x{i},y{i})的函数间隔的最小值:
<center>\hat{\gamma}=\min{i=1,...,N}\hat{\gamma{i}}</center>
为了取消成比例改变w.b导致函数间隔变化但超平面不变的问题,引入规范化\left | w \right |,此时函数间隔变为几何间隔.
对于给定的训练数据集T和超平面(w,b),定义超平面关于样本点(x{i},y{i})的几何间隔为:
<center> \hat{\gamma{i}}=y{i}(\frac{w}{\left | w \right |}\cdot x_{i}+\frac{b}{\left | w \right |})</center>
定义超平面(w,b)关于训练数据集T的函数间隔为关于T中所有样本点(x{i},y{i})的几何间隔的最小值:
<center>\hat{\gamma}=\min{i=1,...,N}\hat{\gamma{i}}</center>
可知函数间隔和几何间隔的关系为:
<center>\gamma{i}=\frac{\hat{\gamma{i}}}{\left | w \right |},\gamma=\frac{\hat{\gamma}}{\left | w \right |} (1)</center>
硬间隔最大化
通过寻找最大化几何间隔的分离超平面可以以充分大的确信度对训练数据进行分类,最大化几何间隔又称为硬间隔最大化,此时的约束最优化问题为:
<center>\max_{w,b} \gamma</center>
<center>s.t. y{i}(\frac{w}{\left | w \right |}\cdot x{i}+\frac{b}{\left | w \right |})s\geqslant \gamma ,i=1,2,...,N</center>
即最大化超平面(w,b)关于训练数据集T的几何间隔\gamma
考虑(1),问题可改写为:
<center>\max_{w,b} \frac{\hat \gamma}{\left | w \right |}</center>
<center>s.t. y{i}(w\cdot x{i}+b)\geqslant \hat\gamma ,i=1,2,...,N</center>
基于与引入规范化\left | w \right |同样的原因,$\hat \gamma的取值对结果没有影响,故取$\hat \gamma=1,考虑
<center>$$\max{w,b} \frac{1}{\left | w \right |}\Leftrightarrow \min{w,b}\frac{1}{2}\left | w \right |^{2}$$</center>
有以下线性可分SVM学习的最优化问题:
<center>\min_{w,b}\frac{1}{2}\left | w \right |^{2} (2)</center>
<center>s.t. y{i}(w\cdot x{i}+b)-1\geqslant 0,i=1,2,...,N (2)</center>
该问题是一个凸二次规划问题.可以证明,若训练数据集T线性可分,那么可将训练数据集中的样本点完全正确分开的最大间隔超平面存在且唯一.
在线性可分的情况下,训练数据集的样本点与分离超平面距离最近的样本点的示例称为支持向量,如下图的H{1}和H{2}上的点:
H{1}和H{2}之间的距离称为间隔,为\frac{2}{\left | w \right |},H{1}和H{2}称为间隔边界.
线性可分SVM对偶学习算法
通过运用拉格朗日对偶性,可以得到原始问题的对偶问题,对偶问题往往更容易求解,也便于引入核函数推广到非线性分类问题.拉格朗日对偶性在此不赘述,但有个重要定理需要特别指出:对于原始问题和对偶问题,在满足特定条件时,则x^{}.\alpha^{}. \beta ^{}分别为原始问题和对偶问题的解的充要条件为x^{}.\alpha^{}. \beta ^{}满足KKT条件.KKT条件表述如下:
<center>\bigtriangledown _{x}L(x^{},\alpha^{}, \beta ^{*})=0</center>
<center>\alpha{i}^{*}c{i}(x^{*})=0,i=1,2,...,k(KKT的对偶互补条件)</center>
<center>c_{i}(x^{*})\leqslant 0,i=1,2,...,k</center>
<center>\alpha_{i}^{*}\geqslant 0,i=1,2,...,k</center>
<center>h_{j}(x^{*})=0,j=1,2,...,l</center>
向(2)引入拉格朗日乘子\alpha_{i}\geq 0,i=1,2,...,N定义拉格朗日函数
<center>L(w,b,\alpha)=\frac{1}{2}\left | w \right |^{2}-\sum{i=1}^{N}\alpha{i}y{i}(w\cdot x{i}+b)+\sum{i=1}^{N}\alpha{i} (3)</center>
其中,\alpha=(\alpha{1},\alpha{2},...,\alpha_{N})^{T}为拉格朗日乘子向量.
根据拉格朗日对偶性可以得到原始问题的对偶问题即极大极小问题:
<center>\max{\alpha}\min{w,b}L(w,b,\alpha)</center>
先求\min_{w,b}L(w,b,\alpha),分别让(3)对w.b的偏导等于0,有:
<center>\bigtriangledown {w}L(w,b, \alpha)=w-\sum{i=1}^{N}\alpha{i}x{i}y_{i}=0</center>
<center>\bigtriangledown {b}L(w,b, \alpha)=-\sum{i=1}^{N}\alpha{i}y{i}=0</center>
<center>w=\sum{i=1}^{N}\alpha{i}x{i}y{i} (4)</center>
<center>\sum{i=1}^{N}\alpha{i}y_{i}=0 (4)</center>
把(4)代入(3)整理可得:
<center>\min{w,b}L(w,b,\alpha)=-\frac{1}{2}\sum{j=1}^{N}\sum{i=1}^{N}\alpha{i}\alpha{j}y{i}y{j}(x{i}\cdot x{j})+\sum{i=1}^{N}\alpha_{i}</center>
接下来再求\max{\alpha}\min{w,b}L(w,b,\alpha),其对偶问题为:
<center>\max{\alpha}-\frac{1}{2}\sum{j=1}^{N}\sum{i=1}^{N}\alpha{i}\alpha{j}y{i}y{j}(x{i}\cdot x{j})+\sum{i=1}^{N}\alpha_{i} (5)</center>
<center>s.t.\sum{i=1}^{N}\alpha{i}y_{i}=0 (5)</center>
<center>\alpha_{i}\geqslant 0,i=1,2,...,N (5)</center>
(5)等价于下面的最优化问题:
<center>\min{\alpha}\frac{1}{2}\sum{j=1}^{N}\sum{i=1}^{N}\alpha{i}\alpha{j}y{i}y{j}(x{i}\cdot x{j})-\sum{i=1}^{N}\alpha_{i}(6)</center>
<center>s.t.\sum{i=1}^{N}\alpha{i}y_{i}=0 (6)</center>
<center>\alpha_{i}\geqslant 0,i=1,2,...,N (6)</center>
可以证明以下定理:设\alpha^{}=(\alpha_{1}^{},\alpha{2}^{*},...,\alpha{i}^{})^{T}为对偶优化问题(6)的解,则\exists j,\alpha_{j}^{}> 0且原始最优化问题可按下式求解w^{}.b^{}:
<center>w^{}=\sum{i=1}^{N}\alpha{i}^{}x{i}y{i} </center>
<center>b^{}=y{j}-\sum{i=1}^{N}\alpha_{i}^{}y{i}(x{i}\cdot x_{j})</center>
此时有分离超平面:
<center>\sum{i=1}^{N}\alpha{i}^{}y{i}(x\cdot x{i})+b^{}=0</center>
分类决策函数:
<center>f(x)=sign[\sum{i=1}^{N}\alpha{i}^{}y{i}(x\cdot x{i})+b^{}]</center>
考虑原始最优化问题(2)和对偶最优化问题(6),将数据集中对应\alpha{i}^{*}>0的样本点(x{i},y{i})的实例x{i}\in \mathbb{R}^{n}称为支持向量.可证明支持向量x_{i}一定在间隔边界上.
线性可分SVM学习算法
构造求解约束最优化问题
<center>\min{\alpha}\frac{1}{2}\sum{j=1}^{N}\sum{i=1}^{N}\alpha{i}\alpha{j}y{i}y{j}(x{i}\cdot x{j})-\sum{i=1}^{N}\alpha_{i}</center>
<center>s.t.\sum{i=1}^{N}\alpha{i}y_{i}=0</center>
<center>\alpha_{i}\geqslant 0,i=1,2,...,N</center>
求得最优解\alpha^{}=(\alpha_{1}^{},\alpha{2}^{*},...,\alpha{i}^{*})^{T}
计算w^{}=\sum{i=1}^{N}\alpha{i}^{}x{i}y{i}并选取\alpha{j}^{}>0计算b^{}=y{j}-\sum{i=1}^{N}\alpha{i}^{*}y{i}(x{i}\cdot x_{j}).
求得分离超平面:w^{}\cdot x+b^{}=0
分类决策函数:f(x)=sign(w^{}\cdot x+b^{})
软间隔最大化线性SVM
假设训练数据集T线性不可分且存在特异点,除特异点以外的数据线性可分.
为了使得线性不可分而不满足(2)中约束条件的的训练数据集T可被训练,对每个样本点(x{i},y{i})引入松弛变量\xi \geq 0,并支付相应的距离代价\xi_{i} ,使得(2)变为:
<center>\min{w,b}\frac{1}{2}\left | w \right |^{2}+C\sum{i=1}^{N}\xi_{i}</center>
<center>s.t. y{i}(w\cdot x{i}+b)\geqslant 1-\xi_{i},i=1,2,...,N</center>
其中C>0,称为惩罚系数,取值由实际问题决定.这个思路称为软间隔最大化.
此时线性不可分SVM的学习问题变为如下的凸二次规划原始问题:
<center>\min{w,b}\frac{1}{2}\left | w \right |^{2}+C\sum{i=1}^{N}\xi_{i} (7)</center>
<center>s.t. y{i}(w\cdot x{i}+b)\geqslant 1-\xi_{i},i=1,2,...,N (7)</center>
<center>\xi_{i}>0,i=1,2,...,N (7)</center>
可以证明\exists (w,b,\xi)为(7)的解,且w唯一,b不唯一且存在于一个区间中.
(7)的对偶问题是:
<center>\min{\alpha}\frac{1}{2}\sum{j=1}^{N}\sum{i=1}^{N}\alpha{i}\alpha{j}y{i}y{j}(x{i}\cdot x{j})-\sum{i=1}^{N}\alpha_{i}(8)</center>
<center>s.t.\sum{i=1}^{N}\alpha{i}y_{i}=0 (8)</center>
<center>0\leq \alpha_{i}\leq C,i=1,2,...,N (8)</center>
线性SVM学习算法
选择惩罚参数C>0,构造并求解凸二次规划问题
<center>\min{\alpha}\frac{1}{2}\sum{j=1}^{N}\sum{i=1}^{N}\alpha{i}\alpha{j}y{i}y{j}(x{i}\cdot x{j})-\sum{i=1}^{N}\alpha_{i}</center>
<center>s.t.\sum{i=1}^{N}\alpha{i}y_{i}=0</center>
<center>C\geqslant \alpha_{i}\geqslant 0,i=1,2,...,N</center>
求得最优解\alpha^{}=(\alpha_{1}^{},\alpha{2}^{*},...,\alpha{i}^{*})^{T}
计算w^{}=\sum{i=1}^{N}\alpha{i}^{}x{i}y{i}并选取C>\alpha{j}^{}>0计算b^{}=y{j}-\sum{i=1}^{N}\alpha{i}^{*}y{i}(x{i}\cdot x_{j}).
求得分离超平面:w^{}\cdot x+b^{}=0
分类决策函数:f(x)=sign[\sum{i=1}^{N}\alpha{i}^{}y{i}(x\cdot x{i})+b^{}]
非线性SVM
假设训练数据集T能用\mathbb{R}^{n}中的一个超曲面将正负例分开,这种分类问题被称为非线性可分问题.
对于这种问题,需要应用SVM的核技巧如下:
通过非线性变换将输入空间(欧式空间\mathbb{R}^{n}或离散集合)对应于一个特征空间(希尔伯特空间\mathbb{H})
输入空间\mathbb{R}^{n}中的超曲面模型对应于特征空间\mathbb{H}中的超平面模型(SVM)
通过求解特征空间\mathbb{H}中的线性SVM完成非线性可分分类问题的学习任务.
设\boldsymbol{X}为输入空间(欧式空间\mathbb{R}^{n}的子集或离散集合),又称\mathbb{H}为特征空间(希尔伯特空间),若\exists \phi (x):\boldsymbol{X}\rightarrow \mathbb{H}使得\forall x.z\in \boldsymbol{X},K(x,z)=\phi (x)\cdot \phi (z),则称K(x,z)为核函数,\phi (x)称为映射函数.\phi (x)\cdot \phi (z)称为\phi(x)和\phi(z)的内积.
用核函数K(x,z)代替对偶问题(8)中的目标函数和分类决策函数的内积,有新的目标函数:
<center>W(\alpha) = \frac{1}{2}\sum{j=1}^{N}\sum{i=1}^{N}\alpha{i}\alpha{j}y{i}y{j}K(x{i},x{j})-\sum{i=1}^{N}\alpha{i}</center>
和新的分类决策函数:
<center>f(x)=sign[\sum{i=1}^{N}\alpha{i}^{}y{i}K(x{i},x)+b^{}]</center>
若使用多项式核函数K(x,z)=(x \cdot z+1 )^{p},对应的SVM为p次多项式分类器,分类决策函数成为:
<center>f(x)=sign[\sum{i=1}^{N}\alpha{i}^{}y{i}(x{i}\cdot x+1)^{p}+b^{}]</center>
若使用高斯核函数K(x,z)=exp(-\frac{\left | x-z \right |^{2}}{2\sigma ^{2}}),对应的SVM为高斯径向基函数(RBF)分类器,分类决策函数成为:
<center>f(x)=sign[\sum{i=1}^{N}\alpha{i}^{}y_{i}exp(-\frac{\left | x-z \right |^{2}}{2\sigma ^{2}})+b^{}]</center>
非线性SVM学习算法
选取适当核函数K(x,z)和适当的惩罚参数C>0,构造并求解最优化问题
<center>\min{\alpha}\frac{1}{2}\sum{j=1}^{N}\sum{i=1}^{N}\alpha{i}\alpha{j}y{i}y{j}K(x{i},x{j})-\sum{i=1}^{N}\alpha_{i} (9)</center>
<center>s.t.\sum{i=1}^{N}\alpha{i}y_{i}=0 (9)</center>
<center>C\geqslant \alpha_{i}\geqslant 0,i=1,2,...,N (9)</center>
求得最优解\alpha^{}=(\alpha_{1}^{},\alpha{2}^{*},...,\alpha{i}^{*})^{T}
并选取C>\alpha{j}^{}>0计算$b^{}=y{j}-\sum{i=1}^{N}\alpha{i}^{*}y{i}K(x{i},x_{j}).
构造分类决策函数:f(x)=sign[\sum{i=1}^{N}\alpha{i}^{}y{i}K(x,x{i})+b^{}]
可以证明,当K(x,z)为正定核函数时,(9)为凸二次规划问题并有解.
机器学习策略实现(基于掘金量化平台)
策略思想
-
选取7个特征变量:1.收盘价/均值2.现量/均量3.最高价/均价4.最低价/均价5.现量6.区间收益率7.区间标准差
-
用时间窗口为15个交易日的历史数据训练出预测未来5个交易日收益率为上涨或下跌的二分类SVM模型
-
在对行情数据预测为上涨的时候买入,并采取止盈止损操作
策略主要步骤实现
订阅数据
subscribe(symbols=context.symbol, frequency='60s')
(symbols=context.symbol, frequency='60s')
订阅数据需要调用subscribe
函数.
-
symbols
设置订阅的标的代码. -
frequency
设置周期级别,这里设置60s
表示以六十秒为周期.
获取历史数据
recent_data = history(symbol=context.symbol, frequency='1d',
start_time=start_date, end_time=end_date,
fill_missing='Last',df=True)
= history(symbol=context.symbol, frequency='1d',
start_time=start_date, end_time=end_date,
fill_missing='Last',df=True)
获取历史数据需要调用history
函数.
-
symbols
需要设置获取数据的标的代码. -
frequency
设置周期级别,这里设置1d
表示以一天为周期. -
start_time
设置获取数据的开始时间. -
end_time
设置获取数据的结束时间. -
fill_missing
设置补全数据的方式,这里设置Last
表示用上一个收盘价填充缺失值. -
df
设置是否返回DataFrame类型数据,这里设置True
表示返回该类型的数据.
设置SVM的参数并训练
context.clf = svm.SVC(C=1.0, kernel='rbf', gamma='auto', shrinking=True, tol=0.001, cache_size=200, verbose=False, max_iter=-1, random_state=None)
context.clf.fit(x_train, y_train)
.clf = svm.SVC(C=1.0, kernel='rbf', gamma='auto', shrinking=True, tol=0.001, cache_size=200, verbose=False, max_iter=-1, random_state=None)
context.clf.fit(x_train, y_train)
-
C
设置误差项的惩罚参数. -
kernel
设置算法中使用的核函数,这里设置rbf
表示用RBF核函数. -
g1amma
设置核的函数系数,这里设置auto
表示设置系数为1/特征数. -
shrinking
设置是否使用启发式搜索算法,这里设置True
表示为使用. -
tol
设置停止训练的精度. -
cache_size
设置训练需要的内存. -
verbose
设置是否输出详细信息,此处设置False
表示不输出. -
max_iter
设置最大的迭代次数,此处设置-1
表示不限制. -
random_state
设置随机数种子使得结果可复现,此处设置None
表示随机生成.
获取当前年月日
today = bar.bob.strftime('%Y-%m-%d')
= bar.bob.strftime('%Y-%m-%d')
返回指定日期的上一个交易日
last_day = get_previous_trading_date(exchange='SHSE', date=today)
= get_previous_trading_date(exchange='SHSE', date=today)
-
exchange
设置交易所,此处设置SHSE
为上交所. -
date
设置作为参考的时间点.
获取持有的仓位
position = context.account().position(symbol=context.symbol, side=PositionSide_Long)
= context.account().position(symbol=context.symbol, side=PositionSide_Long)
-
symbol
设置标的. -
side
设置仓位方向,此处设置为PositionSide_Long
为多仓.
获取预测的结果
prediction = context.clf.predict(features)[0]
= context.clf.predict(features)[0]
获取持有的仓位
position = context.account().position(symbol=context.symbol, side=PositionSide_Long)
= context.account().position(symbol=context.symbol, side=PositionSide_Long)
-
symbol
设置标的. -
side
设置仓位方向,此处设置为PositionSide_Long
为多仓.
调仓到目标持仓比例
order_target_percent(symbol=context.symbol, percent=0.95, order_type=OrderType_Market, position_side=PositionSide_Long)
(symbol=context.symbol, percent=0.95, order_type=OrderType_Market, position_side=PositionSide_Long)
-
symbol
设置标的. -
percent
设置目标比例. -
order_type
设置订单类型,此处设置为OrderType_Market
为市价单. -
side
设置仓位方向,此处设置为PositionSide_Long
为多仓.
平当前所有可平持仓
order_close_all()
()
策略回测分析
回测报告
分析
我们选取了SHESE.60009上海机场2016-04-01到2017-07-30的数据作为训练集,2017年8月1日至2017年9月5日作为回测周期,应用上述的SVM机器学习模型作为买卖的基础.可以看出:
-
胜率(具有盈利的平仓次数与总平仓次数之比)达到了100%,也即策略在回测期间的每次开仓都是盈利的.
-
卡玛比率(年化收益率与历史最大回撤之比)是使用最大回撤率来衡量风险.采用最大回撤率来衡量风险,关注的是最极端的情况.卡玛比率越高表示策略承受每单位最大损失获得的报酬越高.在这里卡玛比率达到了19.57.
-
夏普比率(年化收益率减无风险收益率的差收益波动率之比),也即每承受一单位的总风险,会产生3.27单位的超额回报.
-
策略收益曲线总体曲线向上,体现了机器学习在量化投资中的巨大潜力.
# coding=utf-8
from __future__ import print_function, absolute_import, unicode_literals
from datetime import datetime
import numpy as np
from gm.api import *
import sys
try:
from sklearn import svm
except:
print('请安装scikit-learn库和带mkl的numpy')
sys.exit(-1)
'''
本策略选取了七个特征变量组成了滑动窗口长度为15天的训练集,随后训练了一个二分类(上涨/下跌)的支持向量机模型.
若没有仓位则在每个星期一的时候输入标的股票近15个交易日的特征变量进行预测,并在预测结果为上涨的时候购买标的.
若已经持有仓位则在盈利大于10%的时候止盈,在星期五损失大于2%的时候止损.
特征变量为:1.收盘价/均值2.现量/均量3.最高价/均价4.最低价/均价5.现量6.区间收益率7.区间标准差
训练数据为:SHSE.600000浦发银行,时间从2016-03-01到2017-06-30
回测时间为:2017-07-01 09:00:00到2017-10-01 09:00:00
'''
def init(context):
# 订阅浦发银行的分钟bar行情
context.symbol = 'SHSE.600000'
subscribe(symbols=context.symbol, frequency='60s')
start_date = '2016-03-01' # SVM训练起始时间
end_date = '2017-06-30' # SVM训练终止时间
# 用于记录工作日
# 获取目标股票的daily历史行情
recent_data = history(context.symbol, frequency='1d', start_time=start_date, end_time=end_date, fill_missing='last',
df=True)
days_value = recent_data['bob'].values
days_close = recent_data['close'].values
days = []
# 获取行情日期列表
print('准备数据训练SVM')
for i in range(len(days_value)):
days.append(str(days_value[i])[0:10])
x_all = []
y_all = []
for index in range(15, (len(days) - 5)):
# 计算三星期共15个交易日相关数据
start_day = days[index - 15]
end_day = days[index]
data = history(context.symbol, frequency='1d', start_time=start_day, end_time=end_day, fill_missing='last',
df=True)
close = data['close'].values
max_x = data['high'].values
min_n = data['low'].values
amount = data['amount'].values
volume = []
for i in range(len(close)):
volume_temp = amount[i] / close[i]
volume.append(volume_temp)
close_mean = close[-1] / np.mean(close) # 收盘价/均值
volume_mean = volume[-1] / np.mean(volume) # 现量/均量
max_mean = max_x[-1] / np.mean(max_x) # 最高价/均价
min_mean = min_n[-1] / np.mean(min_n) # 最低价/均价
vol = volume[-1] # 现量
return_now = close[-1] / close[0] # 区间收益率
std = np.std(np.array(close), axis=0) # 区间标准差
# 将计算出的指标添加到训练集X
# features用于存放因子
features = [close_mean, volume_mean, max_mean, min_mean, vol, return_now, std]
x_all.append(features)
# 准备算法需要用到的数据
for i in range(len(days_close) - 20):
if days_close[i + 20] > days_close[i + 15]:
label = 1
else:
label = 0
y_all.append(label)
x_train = x_all[: -1]
y_train = y_all[: -1]
# 训练SVM
context.clf = svm.SVC(C=1.0, kernel='rbf', degree=3, gamma='auto', coef0=0.0, shrinking=True, probability=False,
tol=0.001, cache_size=200, verbose=False, max_iter=-1,
decision_function_shape='ovr', random_state=None)
context.clf.fit(x_train, y_train)
print('训练完成!')
def on_bar(context, bars):
bar = bars[0]
# 获取当前年月日
today = bar.bob.strftime('%Y-%m-%d')
# 获取数据并计算相应的因子
# 于星期一的09:31:00进行操作
# 当前bar的工作日
weekday = datetime.strptime(today, '%Y-%m-%d').isoweekday()
# 获取模型相关的数据
# 获取持仓
position = context.account().position(symbol=context.symbol, side=PositionSide_Long)
# 如果bar是新的星期一且没有仓位则开始预测
if not position and weekday == 1:
# 获取预测用的历史数据
data = history_n(symbol=context.symbol, frequency='1d', end_time=today, count=15,
fill_missing='last', df=True)
close = data['close'].values
train_max_x = data['high'].values
train_min_n = data['low'].values
train_amount = data['amount'].values
volume = []
for i in range(len(close)):
volume_temp = train_amount[i] / close[i]
volume.append(volume_temp)
close_mean = close[-1] / np.mean(close)
volume_mean = volume[-1] / np.mean(volume)
max_mean = train_max_x[-1] / np.mean(train_max_x)
min_mean = train_min_n[-1] / np.mean(train_min_n)
vol = volume[-1]
return_now = close[-1] / close[0]
std = np.std(np.array(close), axis=0)
# 得到本次输入模型的因子
features = [close_mean, volume_mean, max_mean, min_mean, vol, return_now, std]
features = np.array(features).reshape(1, -1)
prediction = context.clf.predict(features)[0]
# 若预测值为上涨则开仓
if prediction == 1:
# 获取昨收盘价
context.price = close[-1]
# 把浦发银行的仓位调至95%
order_target_percent(symbol=context.symbol, percent=0.95, order_type=OrderType_Market,
position_side=PositionSide_Long)
print('SHSE.600000以市价单开多仓到仓位0.95')
# 当涨幅大于10%,平掉所有仓位止盈
elif position and bar.close / context.price >= 1.10:
order_close_all()
print('SHSE.600000以市价单全平多仓止盈')
# 当时间为周五并且跌幅大于2%时,平掉所有仓位止损
elif position and bar.close / context.price < 1.02 and weekday == 5:
order_close_all()
print('SHSE.600000以市价单全平多仓止损')
if __name__ == '__main__':
'''
strategy_id策略ID,由系统生成
filename文件名,请与本文件名保持一致
mode实时模式:MODE_LIVE回测模式:MODE_BACKTEST
token绑定计算机的ID,可在系统设置-密钥管理中生成
backtest_start_time回测开始时间
backtest_end_time回测结束时间
backtest_adjust股票复权方式不复权:ADJUST_NONE前复权:ADJUST_PREV后复权:ADJUST_POST
backtest_initial_cash回测初始资金
backtest_commission_ratio回测佣金比例
backtest_slippage_ratio回测滑点比例
'''
run(strategy_id='strategy_id',
filename='main.py',
mode=MODE_BACKTEST,
token='token_id',
backtest_start_time='2017-07-01 09:00:00',
backtest_end_time='2017-10-01 09:00:00',
backtest_adjust=ADJUST_PREV,
backtest_initial_cash=10000000,
backtest_commission_ratio=0.0001,
backtest_slippage_ratio=0.0001)
----------------------------------------------------------------------------------------------------------------------------------------------------------
更多经典股票/期货量化策略源码查看:
1 | 双均线策略(期货) 量化策略源码 | https://www.myquant.cn/docs/python_strategyies/153 |
2 | alpha对冲(股票+期货) 量化策略源码 | https://www.myquant.cn/docs/python_strategyies/101 |
3 | 集合竞价选股(股票) 量化策略源码 | https://www.myquant.cn/docs/python_strategyies/102 |
4 | 多因子选股(股票) 量化策略源码 | https://www.myquant.cn/docs/python_strategyies/103 |
5 | 网格交易(期货) 量化策略源码 | https://www.myquant.cn/docs/python_strategyies/104 |
6 | 指数增强(股票) 量化策略源码 | https://www.myquant.cn/docs/python_strategyies/105 |
7 | 跨品种套利(期货)量化策略源码 | https://www.myquant.cn/docs/python_strategyies/106 |
8 | 跨期套利(期货) 量化策略源码 | https://www.myquant.cn/docs/python_strategyies/107 |
9 | 日内回转交易(股票)量化策略源码 | https://www.myquant.cn/docs/python_strategyies/108 |
10 | 做市商交易(期货) 量化策略源码 | https://www.myquant.cn/docs/python_strategyies/109 |
11 | 海龟交易法(期货) 量化策略源码 | https://www.myquant.cn/docs/python_strategyies/110 |
12 | 行业轮动(股票) 量化策略源码 | https://www.myquant.cn/docs/python_strategyies/111 |
13 | 机器学习(股票) 量化策略源码 | https://www.myquant.cn/docs/python_strategyies/112 |