16.3 模块介绍

16.3 模块介绍

16.3.1 前期准备

首先需要构建标的的历史本地数据,由于Wind个人免费版限制了时间序列wsd的使用范围,所以需要另外找历史数据。可以通过通达信行情系统获得,股票数据保存在originaldata(前复权)文件夹内,期货数据保存在Foriginaldata(连续合约)文件夹内。注意期货的.txt文件需要把文件名改为Wind期货连续合约代码的形式,例如股指改成IF.CFE.txt,然后把获得的.txt格式数据进行标准化,保存到data文件夹中。

标准化用的文件Savingdata.m的编译代码如下:

接下来介绍本系统用到的核心函数。

(1) timer函数:该函数是本系统的核心函数,交易过程是实时地接收和处理数据并做出反应的过程。由于MATLAB不能进行多线程运算,所以在并行运算中需要借助timer函数,对不同对象的运算创建不同的timer,达到并行运算的效果。

timer函数的语法格式为:

常用属性和值介绍如下。

• Name:用于命名该timer。

• TimerFcn:确定目标程序。在GUI设计中,需要注意数据在不同模块中的传递。此时,timer的TimerFcn格式应该为{@TimerFcn,handles },通过handles把各timer所需的数据进行一一对应的传递。

• Period:上次运行目标函数与下次运行目标函数之间的延迟,以秒为单位,可视为周期。

• ExecutionMode:在忙时,在完成上次TimerFcn前,到添加下一TimerFcn的模式。

singleShot (默认值):只运行一次,此时Period无效。

 fixedDelay:固定延迟。

fixedRate:固定频率。

 fixedSpacing:固定间隔。

相关函数介绍如下。

• 查找对应的timer:p=timerfind('Name',' ...')。

• 开启timer:start(T) 。

• 停止timer:stop(T) 。

• 删除timer;delete(T) 。

• 定时开启timer:startat(T,'clock') 。

以上是本系统的常用属性, 更多属性请参考MATLAB的Doc文件夹。

(2) eval函数:该函数把括号内的字符串视为运算语句运行。例如:

输出的值是7。运用此函数,能够先按某些规则命名矩阵名称,然后再赋值。

另外,还需要介绍Wind中的内置函数。

(1) 账户查询函数tquery,在账户查询模块会有更详细的例子,其语法格式为:

查询方式有以下几种。

• Capital:账户总体情况。

• Position:持仓情况。

• Order:委托单情况。

• Trade:成交情况。

(2) 交易函数torder,其语法格式为:

其中,委托方式有多种,不同的市场需选用不同的委托方式。

• OrderType=LMT:限价委托。

• OrderType=BOC:对方最优价格委托(仅深市可用)。

• OrderType=BOP:本方最优价格委托(仅深市可用)。

• OrderType=1TC:即时成交剩余转撤销(仅深市可用)。

• OrderType=B5TC;最优五档剩余转撤销(仅沪深可用〉。

• OrderType=B5TL:最优五档剩余转限价(仅沪市可用)。

• OrderType=FOK;全额成交或撤销委托(仅深市可用)。

(3)数据获取函数wsd(日期序列)、wsq(实时行情)和wsi(分钟序列),语法格式如下:

由于个人免费版的wsd和WSl函数在使用上有所限制,解决方法是把历史数据保存在本地,在分析数据的时候先读取本地历史数据,然后拼接实时数据,从而获得较为完整的数据流。

(4) 登录与登出函数tlogn和tlogout,其语法格式为:

(5) 撤单函数tcancel,其语法格式为:

上述函数的具体使用方法可从下面的例子中获得。

16.3.2 初始化

在系统刚开始启动时,需要进行必要变量的定义,同时创建必要的timer。

以下是系统初始化时的回调函数:

16.3.3 登录/登出模块

单击登录账户,弹出登录弹窗,输入账户信息,选择需要登录的市场,单击"登录账户"按钮进行账户登录。Wind登录账户时会有两个返回信息:一个是账户号码,另一个是账户序号。这里用两组全局变量Fllure_ID/Stock_ID和Future_Num/Stock_Nurn记录登录信息,方便以后调用。成功登录的账户会按顺序展示。

以下是登录按钮的回调函数:

单击"退出账户"按钮,在登出模块的弹窗中,选择要登出的账户井登出。这里需要注意的是,在登出账户时,必须把账户相关的运行全部停止,并删除登录信息,以免产生混淆。

选择市场的回调函数如下:

登出模块中"退出登录"按钮的回调函数如下:

16.3.4 策略控制模块

策略控制模块提供了指标参数的修改、后台数据自动更新、策略图形展示,以及策略的开启与停止等功能,如图16-6所示。

首先对账户对应策略的开启与停止进行介绍。在账户登录后,账户号码和相关信息会按顺序记录在Stock_table和Future_table中。单击table中的账户号码作为目标账户, 并以全局变量Future_sel_ID/Stock_sel_ID记录目标账户。这里所记录的账户是后面账户策略监控、手动交易和账户信息查询的目标账户,后面所提及的选定账户便是该账户。

以下是Stock_table的CellSelection的回调函数:

以下是Future_table的CellSelection的回调函数:

接下来是策略的启动与停止,通过单击"启动/停止"按钮进行策略的控制。Stock_table的Celllidit回调函数如下:

启动账户对应的策略,便是启动对应的timer,timer的回调函数也就是策略本身的设计。以下介绍的是股票策略的回调函数,这里选用简单双均线策略MA_tactic.m作为隔夜策略的例子。

策略规则如下:

(1) 对股票池中的待交易股票等权重分配资金。

(2) 每次交易都是一个标准仓位。

(3) 持有信号:当日短均线高于当日长均线,并且当日短均线高于昨日短均线,并且当日长均线高于昨日长均线,并且当日价位高于当日短均线。若不在持仓则买入,若在持仓则持有。

(4) 观望信号:当日短均线低于当日长均线,或者当日短均线低于昨日短均线,或者当日长均线低于昨日长均线,或者当日价位低于当日短均线。若在持仓则卖出,若不在持仓则观望。

(5) 交易时间(策略运算时间):收盘前15分钟。

策略文件MA_tactic.m函数如下:

在期货方面,选取开盘区间突破策略作为日内策略例子。

策略如下:

(1) 在回顾期中(N=10),每天最高价与开盘价之差,以及最低价与开盘价之差,取二者间的最小值,并求出该组数据的平均值,作为ORB指标。

(2) 每次交易l手。

(3) 用当天开盘价加减ORB指标作为上下轨,并用M修正区间宽度。

(4) 当价格突破上轨时做多,固定止损为下轨,向上一定幅度触发移动止损,移动止损为成交后最高价和成交价之差的0.6,回撤再入场是该差值的0.3。

(5) 当价格突破上轨时做空,固定止损为上轨,向上一定幅度触发移动止损,移动止损为成交后最低价和成交价之差的0.6,回撤再入场是该差值的0.3。

(6) 在14:55:00全部平仓,结束策略。

策略文件ORB_tactic.m函数如下:


接下来介绍后台历史数据的更新,通过单击"自动更新数据"按钮Updata,确定是否自动更新数据。由于序列数据wsd的使用限制,这里不使用wsd,而使用实时数据wsq,所以只能当日的数据当日更新,过时的数据需要根据前期准备中下载历史数据的方法获取。

"自动更新数据"按钮的回调函数如下:

其中,该timer的回调函数Stock_updata.m编写如下:

策略控制模块最后一部分是"策略图形展示"按钮,该部分需要和标的池模块一起使用,这里先介绍该按钮的回调函数,在介绍股票池时再详细讲解。

其回调函数如下:

16.3.5 标的池模块

该模块的功能是构建策略对应的标的池,能够对标的进行增减、保存现有的标的池、读取以往的标的池及通过选取标的池中的标的,获得该标的的实时数据和策略展示图,如图16-7所示。股票池和商品池的编写基本一致,所以这里以编写股票池作为例子,商品池的编写则不再叙述。

在空白框中输入个股代码,例如00000l.SZ,然后单击"添加股票"按钮,把个股添加到股票池中。这里需要注意的是,添加的股票需要确保存在于本地数据中,否则在后面的调用中会出错。"添加股票"按钮的回调函数如下:

在股票池中选定个股,单击"删除股票"按钮能删除该个股。该按钮的回调函数如下:

单击"添加池"按钮,能导入以往保存的股票池,同时检查股票池中的个股是否在本地数据中存在,若不存在,则报错。该按钮的回调函数如下:

单击"保存池"按钮,对现有的股票池进行保存。该按钮的回调函数如下:

按下策略控制模块中的"展示策略图形"按钮,单击股票池中的股票,能够在绘图窗口中展示K线图、策略图及该个股的实时行情数据。为了方便观察图表和提高运算速度,可以自定义策略展示长度,以及通过绘图窗口中的silder选择展示位置。具体的Stock_pool的回调函数如下:

给图timer的回调函数Stock_plot.m的编写如下(商品期货的绘图和股票的绘图大同小异,主要区别在于实时数据的不同,Future_plot.m的编写便不再叙述):

16.3.6 策略监控模块

在策略监控模块中,可以对策略的运行情况进行检测,运行情况主要通过持仓情况和成交情况反映。由于股票市场实行的是T+l交易制度,和期货市场的T+0交易制度不同,所以这里分别设计了对应该市场的监控方法。

"开启仓位管理" Manage_Future_pos回调函数如下(股票中的按钮Manage_Stock pos编写大同小异,此处不再赘述):

由于期货市场实行的是T+0交易制度,策略能够实时对现行价格做出反应,仓位管理可以镶嵌在策略中,因此这里Future_ GetPosition.m的编写比较简单,只需调用策略的动态数据库井显示即可,编写如下:

由于股票市场实行的是T+l交易机制,定时运行的策略无法及时对当前的价格运动做出反应,尤其是在急速行情下,所以需要对理论仓位和实际仓位进行监控,同时提供"手动调仓"和"平衡仓位"两种调仓方式,把理论仓位和实际仓位对齐,另外提供"追单"披钮,对己委托未成交的单进行撤单再委托。

股票中"开启仓位管理"按钮的回调函数如下:

监控函数Stock_GetPosition.m的编写如下:

对理论持仓Stock_theory_position中的标的进行选择,能够快速获得该标的的理论持仓和实际持仓,同时该标的是下面"手动调仓"中对应的标的。该回调函数如下:

对选中的单个标的进行理论仓位和实际仓位对齐,在对齐之前,把该标的的委托未成交单先撤销。"手动调仓"按钮的回调函数如下:

"一键追单"按钮只会对委托未成交单进行撤单再委托,并不会对理论仓位和实际仓位之间进行对齐。其回调函数如下:

16.3.7 账户信息模块

在账户信息模块中,可以读取选定账户的信息,包括资金状况、持仓状况、委托情况及成交情况,同样利用timer进行循环获取。该timer的回调函数Inquiry.m编写如下:

16.3.8 手动交易

在绘图窗口中提供了手动交易模块,选定的标的是当前展示中的标的,并在选定账户中进行交易。手动交易模块中"确认下单"按钮的回调函数如下:

16.3.9 选股模型

交易系统大致介绍至此,上述策略也只是对交易标的进行择时交易,却在如何构建股票池中保留空白。这里对选股方法进行简单编写,模型是动量模型和反转模型,规则如下。

· 动量选股:在回顾期中表现较好的股票,会在持有期中延续较好的表现。

· 反转选股:在回顾期中表现不佳的股票,会在持有期中反转向好。

模型编写如下:

此时,继续抛出另一个问题:这样的选股模型有效吗?借助本地历史数据库对上面的选股模型进行历史回测,回测函数(以反转模型为例,动量模型同理,此处不再赘述)如下:

回测结果显示,使用30天反转组合,在2011年1月26日至2014年10月7日期间,跑赢沪深300指数的概率为56.1%,如图16-8 所示。

图16-8中显示,当沪深300指数为正收益时,该组合大致都能有正收益,同时在指数为正收益时跑赢指数的情况比较多。因此,我们可以在市场向好的情况下考虑选用该选股模型(此处旨在介绍选股模型和如何对该模型进行回测,不作为实际交易的依据) 。