历史数据相对时间查询

新手专区
标签: #<Tag:0x00007fcf6d3d0e70>

(hugo) #1

微信截图_20171201152900
如果上图是一个DataFrame类型的数据,我需要以date为起始或者结束日期,查询instrument中股票的120个交易日的历史信息,在回测中context.Data可以实现,但是如果不是在回测如何实现?我想的是用D.history_data+D.tranding_days来做,但是感觉有点麻烦,能不能D.history_data(instruments,“2017/1/1”,“120TD”,…)实现查询以2017/1/1为起始日查询120个交易日日之后的信息,D.history_data(instrument,“120TD”,“2017/1/1”)以2017/1/1为截止日,查询120个交易日之前的信息呢?


(iQuant) #2
get_history_data_by_days(['000002.SZA'],'2017-10-01',20,1,['close'])

位置参数说明:
股票池
日期
相对时间天数
向前取还是向后取,0表示向前,1表示向后
字段

克隆策略
In [7]:
def get_near_date(date,direction):
    td = D.trading_days(market='CN', start_date=None, end_date=None)
    td['date'] = td['date'].apply(lambda x:x.strftime('%Y-%m-%d'))
    while True:
        if direction == 0:
            pre_date = datetime.datetime.strptime(date,'%Y-%m-%d') - datetime.timedelta(1)
        elif direction == 1:
            pre_date = datetime.datetime.strptime(date,'%Y-%m-%d') + datetime.timedelta(1)
        pre_date = pre_date.strftime('%Y-%m-%d')
        date = pre_date
        if pre_date in list(td['date']):
            break
    return date

def get_date_index(date,direction):
    td = D.trading_days(market='CN', start_date=None, end_date=None)
    td['date'] = td['date'].apply(lambda x:x.strftime('%Y-%m-%d'))
    try:
        ix = td[td['date']== date].index[0]
    except IndexError as e:
        date = get_near_date(date,direction)
        ix = td[td['date']== date].index[0]
    return ix

def get_date_range(ix,direction,days):
    td = D.trading_days(market='CN', start_date=None, end_date=None)
    if direction == 0: 
        start_ix = ix-days+1
        assert len(td.ix[start_ix:ix]) == days
        start_date = td.ix[start_ix:ix]['date'].min()
        end_date = td.ix[start_ix:ix]['date'].max()
    elif direction ==1:
        end_ix = ix+days-1
        assert len(td.ix[ix:end_ix]) == days
        start_date = td.ix[ix:end_ix]['date'].min()
        end_date = td.ix[ix:end_ix]['date'].max()
    return (start_date, end_date)
    
In [8]:
def get_history_data_by_days(instruments,date,days,direction,fields):
    ix = get_date_index(date, direction)
    start_date = get_date_range(ix,direction,days)[0]
    end_date = get_date_range(ix,direction,days)[1]
    return D.history_data(instruments=instruments,start_date=start_date,end_date=end_date,fields=fields)
In [9]:
get_history_data_by_days(['000002.SZA'],'2017-10-01',20,1,['close'])
Out[9]:
close date instrument
0 3634.332275 2017-10-09 000002.SZA
1 3650.808350 2017-10-10 000002.SZA
2 3689.252197 2017-10-11 000002.SZA
3 3720.831299 2017-10-12 000002.SZA
4 3697.490234 2017-10-13 000002.SZA
5 3612.364258 2017-10-16 000002.SZA
6 3598.634277 2017-10-17 000002.SZA
7 3628.840332 2017-10-18 000002.SZA
8 3576.666260 2017-10-19 000002.SZA
9 3591.769287 2017-10-20 000002.SZA
10 3560.190186 2017-10-23 000002.SZA
11 3707.101318 2017-10-24 000002.SZA
12 3766.140381 2017-10-25 000002.SZA
13 3779.870361 2017-10-26 000002.SZA
14 3775.751465 2017-10-27 000002.SZA
15 3978.955322 2017-10-30 000002.SZA
16 3976.209473 2017-10-31 000002.SZA
17 4002.296387 2017-11-01 000002.SZA
18 4043.486328 2017-11-02 000002.SZA
19 3870.488281 2017-11-03 000002.SZA


(hugo) #3

谢谢 你的这个思路 比我自己想的好很多,我自己写的更复杂…


(hugo) #4

有点小问题,更正一下

def get_date_range(ix,direction,days):
    td = D.trading_days(market='CN', start_date=None, end_date=None)
    if direction == 0: 
        start_ix = ix-days+1
        assert len(td.ix[start_ix:ix]) == days
        start_date = td.ix[start_ix:ix]['date'].min()
        end_date = td.ix[start_ix:ix]['date'].max()
    elif direction ==1:
        end_ix = ix+days-1
        assert len(td.ix[ix:end_ix]) == days
        start_date = td.ix[ix:end_ix]['date'].min()
        end_date = td.ix[ix:end_ix]['date'].max()
    return (start_date, end_date)

def get_history_data_by_days(instruments,date,days,direction,fields):
    ix = get_date_index(date, direction)
    start_date = get_date_range(ix,direction,days)[0]
    end_date = get_date_range(ix,direction,days)[1]
    return D.history_data(instruments=instruments,start_date=start_date,end_date=end_date,fields=fields)

(iQuant) #5

好,谢谢,已修改。