## 1 概述
小伙伴们期待已久的避免未来函数/数据功能功能终于上线了,从此妈妈再也不用担心我的回测有未来数据了~
欢迎体验尝鲜:[set_option("avoid_future_data", True)](https://www.joinquant.com/help/api/help?name=api#avoid_future_data)
## 2 设置是否开启避免未来数据模式,avoid_future_data
```python
set_option("avoid_future_data", True)
```
设置回测是否开启避免未来数据模式,默认关闭
**参数**
- False, 关闭,回测可能带入未来数据
- True,开启,系统会提示或者处理未来数据
**未来函数,未来数据**
回测中能够引入未来数据的函数,即可以返回未来数据的函数;通过未来函数获取到的数据为未来数据;例如开盘使用get_price获取当天的收盘价,则get_price为未来函数,当天的收盘价为未来数据。
更多的数据可以参考[数据更新频率](https://www.joinquant.com/help/api/help?name=JQData#JQData提供哪些数据及数据更新频率)
**使用方法**
在策略中使用set_option("avoid_future_data", True)来开启此功能,该选项默认为False,表示关闭。
**未来数据类型及处理方法**
- 对于一些当天收盘后才会产生的数据,在标的收盘前(不包含收盘这个时间点,比如股票是< 15:00)尝试获取这些数据都会抛出异常,具体的触发异常使用方式如下:
get_price获取当天day bar中包含'close', 'high', 'low', 'volume', 'money', 'avg', 'price', 'open_interest'
get_extra获取当天'acc_net_value', 'unit_net_value', 'adj_net_value', 'futures_sett_price', 'futures_positions' 数据(不包含is_st,因为is_st在当天开盘前实际上就应该知道了)
get_fundamentals获取当天valuation市值表数据
get_fundamentals_continuously获取当天valuation市值表数据
get_billboard_list获取当天龙虎榜数据
get_mtss获取当天的融资融券资金流数据
get_money_flow获取当天资金流向数据
gte_valuation获取当天市值表数据
- 对于一些用户没法通过时间参数函数参数避免的未来数据(因为用户没法获取数据公布日期的数据,比如季度财报的发布日期,限售解禁数据的发布日期),对于这类数据我们没有抛出异常,而是将未来数据剔除掉,因为直接抛出异常用户可能会很懵,而且用户没法通过已有的API参数去避免这类未来数据。目前做了此类处理的API如下:
get_fundamentals(query_object, date=None, statDate=None) 通过stat_date获取财务数据
get_locked_shares(stock_list, start_date=None, end_date=None, forward_count=None) 获取限售解禁数据
get_call_auction(security, start_date=None, end_date=None, fields=None)获取集合竞价数据
- 对于基础数据来说,当天的数据当天就可以获取到
get_extras的is_st
当日复权因子,当天盘前就可以获取到,对于当日以后的复权因子,用户需要传递end_date > 当日才行,这种情况下会抛出FutureDataError的
## 3 未来函数具体限制细节
每个相关API,具体限制的细节及介绍如下
### 3.1 get_price
#### API说明
get_price(security, start_date=None, end_date=None, frequency='daily', fields=None, skip_paused=False, fq='pre' , count=None, panel=True)
####限制方案
(1)对于分钟数据:
如果end_date > current_dt.date,抛出异常
(2)对于天数据:
如果end_date > current_dt.date,抛出异常
如果end_date == current_dt.date,需要根据当前交易时间来处理:
- (a) current_dt < 标的开盘时间,如果用户尝试获取{'open', 'close', 'high', 'low', 'volume', 'money', 'avg', 'price', 'open_interest'}中的字段,抛出异常
- (b)标的开盘时间(比如09:30) < = current_dt < 标的收盘时间(比如15:00),如果用户尝试获取{'close', 'high', 'low', 'volume', 'money', 'avg', 'price', 'open_interest'}中的字段,抛出异常
### 3.2 get_bars
#### API说明
get_bars(security, count, unit='1d', fields=('date', 'open', 'high', 'low', 'close'), include_now=False, end_dt=None, fq_ref_date=1)
####限制方案
对于天/分钟数据:如果end_dt > current_dt,抛出异常
### 3.3 get_ticks
#### API说明
get_ticks(security, end_dt, start_dt=None, count=None, fields=('time', 'current', 'high', 'low', 'volume', 'money'))
####限制方案
如果用户传入的end_dt大于current_dt,抛出异常
### 3.4 get_current_tick
#### API说明
get_current_tick(security, dt=None)
####限制方案
如果传入的dt参数大于current_dt,抛出异常
### 3.5 get_extras
#### API说明
get_extras(info, security_list, start_date=None, end_date='2015-12-31', df=True, count=None)
####限制方案
(1) 如果传入的end_date > current_dt.date,抛出异常
(2)如果传入的end_date == current_dt.date,由于get_extras获取的数据都是天级别、盘后才产生的数据,所以需要根据标的的收盘时间来进一步处理:
- (a)如果current_dt < 标的收盘时间,抛出异常
- (b)如果current_dt >= 标的的收盘时间,才可以正常获取当天的数据
(3)is st是基础数据,基础数据当天盘前都可以获取,get_extras除了is_st之外的其他数据都是需要盘后才能获取的;
### 3.6 get_index_stocks、get_industry_stocks、get_industry、get_concept_stocks、get_all_securities、get_security_info、get_fund_info、get_margincash_stocks、get_marginsec_stocks、get_dominant_future、get_future_contracts、get_concept、get_trade_day
#### 限制方案:
如果date > current_dt.date,抛出异常
### 3.7 get_fundamentals
#### API说明
get_fundamentals(query_object, date=None, statDate=None)
####限制方案a
(1)如果用户使用date参数
- (a)如果date > current_dt.date,抛出b异常
- (b)如果date == current_dt.date,对于市值表需要根据current_dt区分当前是否是盘后(其他财务数据表可以在当天取到当天的数据);如果用户查询的表中包含valuation表,且current_dt < close_dt(收盘时间),抛出异常
(2)不允许使用statDate参数,使用会抛出异常
### 3.8 get_fundamentals_continuously
#### API说明
get_fundamentals_continuously(query_object, end_date=None, count=1, panel=True)
####限制方案
(1) 如果用户传递的end_date > current_dt.date,抛出异常
(2)如果用户传递的end_date == current_dt.date,需要对市值表进行特殊处理,因为当天收盘前是不能获取当天市值表数据的;如果current_dt < 15:00:抛出异常
### 3.9 get_index_weights
#### API说明
get_index_weights(index_id, date=None)
####限制方案
如果传入的date > current_dt.date,抛出异常
### 3.10 get_billboard_list
#### API说明
get_billboard_list(stock_list=None, start_date=None, end_date=None, count=None)
####限制方案
(1) 如果传入的date参数 > current_date,抛出异常
(2) 如果传入的date参数 == current_date,类似市值表,龙虎榜当天的数据,只有在收盘后才能获取,所以需要根据current_dt细化处理;current_dt < 15:00,抛出异常
### 3.11 get_locked_shares
#### API说明
get_locked_shares(stock_list, start_date=None, end_date=None, forward_count=None)
####限制方案
(1)限售解禁数据用户获取的时候是没法知道pubDate的,因为处理逻辑类似get_fundamentals传递stat_date,将未来数据剔除,而不是抛出异常。先查询数据,查询结果中的pubDate与context_dt.date比较,剔除掉pubDate > context_dt.date的数据(需要去STK_LIMITED_SHARES_UNLIMIT表来查询pubDates);pubDate > current_date的数据剔除掉
### 3.12 get_history_fundamentals
#### API说明
get_history_fundamentals(security, fields, watch_date=None, stat_date=None, count=1, interval='1q', stat_by_year=False)
####限制方案
(1)如果用户用的是watch_dbate
- (a)如果watch_date > current_dt.date,抛出异常
- (b)如果watch_date < = current_dt.date,pass
(2)不允许用户使用stat_date参数,使用会抛出异常
### 3.13 get_call_auction
#### API说明
get_call_auction(security, start_date=None, end_date=None, fields=None)
####限制方案
(1)如果传入的end_date > current_date,抛出异常
(2)如果传入的end_date == current_date;获取完current_date的集合竞价数据之后,剔除掉time > current_dt的tick. (进一步解释:get_call_auction,假设9:25:03产生集合竞价数据,end_date为9:25:00获取时,会返回9:25:00之前的tick数据,并剔除掉9:25:03这个tick。)
### 3.14 get_industries
#### API说明
get_industries(name='zjw', date=None)
####限制方案
date > current_date抛出异常
### 3.15 get_money_flow
#### API说明
get_money_flow(security_list, start_date=None, end_date=None, fields=None, count=None)
####限制方案
(1)end_date > current_date,抛出异常
(2)end_date == current_date,需要根据current_dt是否是盘后来处理;如果尚未收盘,即current_dt < 15:00:抛出异常
### 3.16 get_mtss
#### API说明
get_mtss(security_list, start_date=None, end_date=None, fields=None, count=None)
####限制方案
(1)end_date > current_date,抛出异常
(2)end_date == current_date,需要根据current_dt是否是盘后来处理;如果尚未收盘,即current_dt < 15:00:抛出异常
### 3.17 get_valuation
#### API说明
get_valuation(security, start_date=None, end_date=None, fields=None, count=None)
####限制方案
(1)end_date > current_date,抛出异常
(2)end_date == current_date,需要根据current_dt是否是盘后来处理;如果尚未收盘,即current_dt < 15:00:抛出异常
## 我们在持续优化中,有问题可以在此贴中留言讨论,感谢~
```
previous_date = context.current_dt - datetime.timedelta(days=1)
prices = get_price(g.security, '2005-01-05', previous_date, '1d', ['high', 'low'])
```
提示?
avoid_future_data=True时,get_price取天行情时,end_date(2009-12-31 00:00:00)不能大于当前时间(2010-01-01 00:00:00)
我的endtime取前一天都会报错??
???
```
previous_date = context.current_dt - datetime.timedelta(days=2)
```
FutureDataError: avoid_future_data=True时,get_price取天行情时,end_date(2009-12-30 00:00:00)不能大于当前时间(2010-01-01 00:00:00)
?????
end_date(2009-12-30 00:00:00)不能大于当前时间(2010-01-01 00:00:00)
这个逻辑是咋判断的?
2019-11-16
做了这个设置之后,重新回测的结果比之前还好一些,是说明我之前没有使用未来函数吗?确实所有的include_now都用的False。
另外,如此设置是否能完全规避未来函数,如果是,就更放心了。
2019-11-16
end_date(2009-12-30 00:00:00)不能大于当前时间(2010-01-01 00:00:00)
有问题,请修正
2019-11-16

请问版主,这个判断有问题吧
2019-11-18