天软-如何规避非正周期数据陷阱

详情链接:2014-05-13-应用专题-数据提取专题03:非整周期行情数据提取陷阱和时点真实行情数据回溯

  • 针对在使用行情类数据及其衍生指标做建模和回测的时候,可能用到“未来数据”的陷阱,可以使用天软的时点系统参数PN_ViewPoint()避免此问题的发生。
  • 分析了使用行情类数据可能用到未来数据的原因:在基于非整周期行情数据建模中,犯使用“未来数据”的错误概率很大

取行情数据可能用到未来数据的分析

什么是非整周期?

在我们日常基于行情数据开发的策略中,存在两个日期的概念:

(1) 与周期参数对应的本周期最后一个交易日d1:即通常我们所说的日线、周线、1分钟线、10分钟线等用固定周期描述的“本周期最后一个交易日”。在我们开发中,一般不会特意提到这个日期或者忽略此日期。我们常说的是:这个策略用的日线数据,周线数据,10分钟数据等等

(2) 选股/回测日期d2:选股日期,即用户运行策略的日期

所谓整周期,即:d1=d2

所谓非整周期,即:d1<>d2

如果是整周期数据,一般不存在所谓的使用“未来数据”陷阱。在上述范例中,如果你使用的周线数据(其每个周期对应的最后一个交易日d1=2013-08-16、2013-08-23、2013-08-30),而你的调仓日/选股日如果正好是d2=2013-08-16、2013-08-23、2013-08-30。在本应用中,d1=d2为整周期应用,一般不会犯用“未来数据”的错误

而如果使用的是非整周期数据,则经常会犯使用“未来数据”的错误。在上述范例中,如果你使用的周线数据,而你的选股日期是d2=2013-08-16、2013-08-23、2013-08-29日。注意:其中的2013-08-29和周线的最后一个交易日2013-08-30不相等。 其中有d1<>d2为非整周期应用,犯使用“未来数据”的错误概率很大。

非整周期数据提取的陷阱

在实际开发基于行情数据的策略中,如上所述经常会用到多周期行情数据(或其衍生类数据)。要特别强调的是,即使这么一个简单的需求,经常会碰到数据提取的陷阱,即:很可能会用到所谓的“未来数据”。

低频非整周期数据提取时可能用到“未来数据”

我们还是以一个实例来说明。

假设我们的策略日期是2013-08-12日,我们可以取得到的SZ000002的真实收盘是10.13元。不管用什么周期,何时提取此数据(回测或实时监控),这都应该是确定的答案。事实真的如此吗?我们看一下几个范例(详细测试代码见范例:TSFL_SJTQ_TrapOfTradingData1):

EndT:=20130812T;

SetSysParam(PN_Stock(),"SZ000002");

SetSysParam(PN_Date(),EndT);

SetSysParam(PN_Rate(),0);

//日线数据:10.13

SetSysParam(PN_Cycle(),cy_day());

c1:=close();

//周线数据:9.89

SetSysParam(PN_Cycle(),cy_Week());

c2:=close();

//月线数据:9.46

SetSysParam(PN_Cycle(),cy_Month());

c3:=close();

//季线数据:9.13

SetSysParam(PN_Cycle(),cy_quarter());

c4:=close();

//半年线数据:8.03

SetSysParam(PN_Cycle(),cy_halfyear());

c5:=close();

//年线数据:8.03

SetSysParam(PN_Cycle(),cy_Year());

C6:=close();

Return array(c1,c2,c3,c4,c5,c6);

为什么会有这样的结果呢?原因在于行情数据的多周期转换机制(祥见上期内容-关于不同周期的变换规则)。所有的非日线类低频周期数据,都来自日线数据,且以“本周期的最后一个交易日”为参照点。虽然我们的截止日是2013-08-12(星期一,是一个非整周期),但是按照多周期转换机制,实际的各个周期的最后一个交易日分别为:

如果真的这样处理,在做历史回测的时候,相当于在2013-8-12的时候,我们已经知道2013-8-12所在的周收盘是2013/8/16的9.89;知道2013-08-12所在的月收盘是2013/8/30的9.46。

OMG,这就是典型的在做历史回测的时候用到“未来数据”的陷阱

如果你的回测日期,正好是非整周期日期,一定存在用“未来数据”的陷阱和可能

在做历史回测的时候,不能用一点点未来数据,这是一个基本的底线。否则可能造成历史回测的时候,一个很好的策略在真实上线运行的时候,可能达不到预计的效果。去除掉其他因素,对于开发者而言,在你开发的策略中,是否用到了“未来数据”,这个弦必须绷紧,不能有丝毫的含糊。记住:我们做历史回测的目的,不是为了找到一个虚无缥缈的,看起来很好的一个策略。而应该是基于当时那个时点可以看到和用到的数据,未来数据是绝对不能使用的。

好在中国的证券市场不长,用户在开发策略的时候,如果用到多周期低频数据,多半用的最多的是周线。

高频非整周期数据提取时可能用到“未来数据”

同低频数据的提取,如果在高频策略中,你的策略回测时间是一个非整周期,也存在可能用到“未来数据”的陷阱(详细测试代码见范例:

TSFL_SJTQ_TrapOfTradingData2

SetSysParam(PN_Stock(),"SH600519");

EndT:=StrToDateTime("2013-08-12 14:08:05");

SetSysParam(PN_Date(),EndT);

//本周期的最后一个交易时间:2013-08-12 14:09:00 175.86

SetSysParam(PN_Cycle(),cy_1m());

c1:=close();

//本周期的最后一个交易时间:2013-08-12 14:10:00 175.90

SetSysParam(PN_Cycle(),cy_10m());

c2:=close();

//本周期的最后一个交易时间:2013-08-12 14:08:06 175.70

SetSysParam(PN_Cycle(),cy_6s());

c3:=close();

//本周期的最后一个交易时间:2013-08-1214:08:12 175.71

SetSysParam(PN_Cycle(),cy_12s());

c4:=close();

return array(c1,c2,c3,c4);

就本实例而言,我们通过Tick数据知道,在2013-08-12 14:08:05能取得到的收盘,只可能是175.70

SetSysParam(PN_Stock(),"SH600519");

EndT:=StrToDateTime("2013-08-12 14:08:05");

SetSysParam(PN_Date(),EndT);

SetSysParam(PN_Cycle(),cy_detail());

//在这个时点,能取得到的当前盘口数据,只能是截止2013-08-12 14:08:04的盘口数据 175.70

return close();

即在使用高频数据中,如果提取数据时间是非整周期,也可能存在使用“未来数据”的陷阱

非整周期数据提取陷阱汇总

从以上分析可以看出在做用行情数据做历史回测的时候,经常会犯使用“未来数据”陷阱。对此我们汇总如下:

结论:如果是非整周期,除了日线数据和Tick,都可能犯使用“未来数据”的陷阱

设置时点参数支持时点回测

设置时点参数的必要性

天软为了提供更好的历史回溯仿真支持,增加了新的系统参数PN_ViewPoint(),我们在下文中称之为:时点系统参数/时点参数/PN_ViewPoint()

使用时点参数,在非整周期中可以保证可以还原到该时点,避免使用到未来数据,从而提供更好的历史回溯仿真支持。

如何设置时点参数?

PN_ViewPoint(),该系统参数为一个日期时间类型,可以在非整周期的回溯中还原该时点,避免使用到未来数据。

在原来提取行情数据的模型中,只要加一条语句:

SetSysParam(PN_ViewPoint(),EndTTime);

其中:EndTTime一般是一个日期时间类型,行情数据对应的提取时点

注意:一般在PN_ViewPoint()设置的时点时间系统参数的值>=在PN_Date()设置的截止日参数的值。如:假设使用日线数据,PN_Date()和PN_ViewPoint()使用方法如下:

EndT:=20130812T;

SetSysParam(PN_Stock(),"SZ000002");

//在PN_Date()设置数据的截止日=2013-08-12

SetSysParam(PN_Date(),EndT);

//在PN_ViewPoint()设置数据的时点时间=2013-08-12 16:00:00,即时点时间是收盘后

SetSysParam(PN_ViewPoint(),EndT+16/24);

常见设置时点参数范例

说明:

(1) 对于日期格式,最好采用日期参数或者yyyymmddT格式

(2) 对于整点/整半点时点,最好使用/24模式。如:10:00:00用10/24,尽量不要采取StrToTime('10:00:00');10:30:00用10.5/24,尽量不要采取StrToTime('10:30:00')

(3) 除非万不得已,尽量少用StrToDate/StrToTime(大量使用可能带来性能问题)

除非万不得已,尽量少用StrToDate/StrToTime(大量使用可能带来性能问题)

除非万不得已,尽量少用StrToDate/StrToTime(大量使用可能带来性能问题)

重要的事情说三遍……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值