xtquant.qmttools.functions

  1#coding:utf-8
  2
  3import datetime as dt
  4import threading
  5import time
  6import traceback
  7
  8from xtquant import xtdata
  9from xtquant import xtbson as bson
 10
 11_request_id = ''
 12
 13def datetime_to_timetag(timelabel, format = ''):
 14    '''
 15    timelabel: str '20221231' '20221231235959'
 16    format: str '%Y%m%d' '%Y%m%d%H%M%S'
 17    return: int 1672502399000
 18    '''
 19    if not format:
 20        format = '%Y%m%d' if len(timelabel) == 8 else '%Y%m%d%H%M%S'
 21    return dt.datetime.strptime(timelabel, format).timestamp() * 1000
 22
 23def timetag_to_datetime(timetag, format = ''):
 24    '''
 25    timetag: int 1672502399000
 26    format: str '%Y%m%d' '%Y%m%d%H%M%S'
 27    return: str '20221231' '20221231235959'
 28    '''
 29    if not format:
 30        format = '%Y%m%d' if timetag % 86400000 == 57600000 else '%Y%m%d%H%M%S'
 31    return dt.datetime.fromtimestamp(timetag / 1000).strftime(format)
 32
 33def subscribe_quote(stock_code, period, dividend_type, result_type = '', callback = None):
 34    return xtdata.subscribe_quote(stock_code, period, '', '', 0, callback)
 35
 36def subscribe_whole_quote(code_list, callback = None):
 37    return xtdata.subscribe_whole_quote(code_list, callback)
 38
 39def unsubscribe_quote(subscribe_id):
 40    return xtdata.unsubscribe_quote(subscribe_id)
 41
 42def get_market_data(
 43    fields = [], stock_code = [], start_time = '', end_time = ''
 44    , skip_paused = True, period = '', dividend_type = '', count = -1
 45):
 46    res = {}
 47    if period == 'tick':
 48        refixed = False
 49        if count == -2:
 50            refixed = True
 51            count = 1
 52        if 'quoter' not in fields:
 53            return xtdata.get_market_data_ori(
 54                    field_list=fields, stock_list=stock_code, period=period
 55                    , start_time=start_time, end_time=end_time, count=count
 56                    , dividend_type=dividend_type, fill_data=skip_paused
 57                )
 58
 59        fields = []
 60        data = xtdata.get_market_data_ori(
 61            field_list=fields, stock_list=stock_code, period=period
 62            , start_time=start_time, end_time=end_time, count=count
 63            , dividend_type=dividend_type, fill_data=skip_paused
 64        )
 65        fields = ['quoter']
 66
 67        import pandas as pd
 68
 69        stime_fmt = '%Y%m%d' if period == '1d' else '%Y%m%d%H%M%S'
 70        for stock in data:
 71            pd_data = pd.DataFrame(data[stock])
 72            pd_data['stime'] = [timetag_to_datetime(t, stime_fmt) for t in pd_data['time']]
 73            pd_data.index = pd.to_datetime((pd_data['time'] + 28800000) * 1000000)
 74            ans = {}
 75            for j, timetag in enumerate(pd_data['time']):
 76                d_map = {}
 77                for key in pd_data:
 78                    d_map[key] = pd_data[key][j]
 79                ans[str(pd_data.index[j])] = {}
 80                ans[str(pd_data.index[j])]['quoter'] = d_map
 81            res[stock] = ans
 82
 83        oriData = res
 84            # if not pd_data.empty:
 85            #     if count > 0:
 86            #         return list(pd_data.T.to_dict().values())
 87            #     return pd_data.iloc[-1].to_dict()
 88            # return {}
 89        if refixed:
 90            count = -2
 91    else:
 92        refixed = False
 93        if count == -2:
 94            refixed = True
 95            count = 1
 96        index, data = xtdata.get_market_data_ori(
 97            field_list=fields, stock_list=stock_code, period=period
 98            , start_time=start_time, end_time=end_time, count=count
 99            , dividend_type=dividend_type, fill_data=skip_paused
100        )
101        if refixed:
102            end_time = ''
103            count = -1
104        for i, stock in enumerate(index[0]):
105            ans = {}
106            for j, timetag in enumerate(index[1]):
107                d_map = {}
108                for key in data:
109                    d_map[key] = data[key][i][j]
110                ans[timetag] = d_map
111            res[stock] = ans
112        oriData = res
113
114    resultDict = {}
115    for code in oriData:
116        for timenode in oriData[code]:
117            values = []
118            for field in fields:
119                values.append(oriData[code][timenode][field])
120            key = code + timenode
121            resultDict[key] = values
122
123    if len(fields) == 1 and len(stock_code) <= 1 and (
124            (start_time == '' and end_time == '') or start_time == end_time) and (count == -1 or count == -2):
125        # if resultDict:
126            # keys = list(resultDict.keys())
127            # if resultDict[keys[-1]]:
128            #     return resultDict[keys[-1]]
129        for key in resultDict:
130            return resultDict[key][0]
131        return -1
132    import numpy as np
133    import pandas as pd
134    if len(stock_code) <= 1 and start_time == '' and end_time == '' and (count == -1 or count == -2):
135        for key in resultDict:
136            result = pd.Series(resultDict[key], index=fields)
137            return result
138    if len(stock_code) > 1 and start_time == '' and end_time == '' and (count == -1 or count == -2):
139        values = []
140        for code in stock_code:
141            if code in oriData:
142                if not oriData[code]:
143                    values.append([np.nan])
144                for timenode in oriData[code]:
145                    key = code + timenode
146                    values.append(resultDict[key])
147            else:
148                values.append([np.nan])
149        result = pd.DataFrame(values, index=stock_code, columns=fields)
150        return result
151    if len(stock_code) <= 1 and ((start_time != '' or end_time != '') or count >= 0):
152        values = []
153        times = []
154        for code in oriData:
155            for timenode in oriData[code]:
156                key = code + timenode
157                times.append(timenode)
158                values.append(resultDict[key])
159        result = pd.DataFrame(values, index=times, columns=fields)
160        return result
161    if len(stock_code) > 1 and ((start_time != '' or end_time != '') or count >= 0):
162        values = {}
163        for code in stock_code:
164            times = []
165            value = []
166            if code in oriData:
167                for timenode in oriData[code]:
168                    key = code + timenode
169                    times.append(timenode)
170                    value.append(resultDict[key])
171            values[code] = pd.DataFrame(value, index=times, columns=fields)
172        try:
173            result = pd.Panel(values)
174            return result
175        except:
176            return oriData
177    return
178
179def get_market_data_ex(
180    fields = [], stock_code = [], period = ''
181    , start_time = '', end_time = '', count = -1
182    , dividend_type = '', fill_data = True, subscribe = True
183):
184    res = xtdata.get_market_data_ex(
185        field_list = fields, stock_list = stock_code, period = period
186        , start_time = start_time, end_time = end_time, count = count
187        , dividend_type = dividend_type, fill_data = fill_data
188    )
189    for stock in res:
190        res[stock]['stime'] = res[stock].index
191    return res
192
193def get_full_tick(stock_code):
194    return xtdata.get_full_tick(stock_code)
195
196def get_divid_factors(stock_code, date = None):
197    client = xtdata.get_client()
198    if date:
199        data = client.get_divid_factors(stock_code, date, date)
200    else:
201        data = client.get_divid_factors(stock_code, '19700101', '20380119')
202
203    res = {}
204    for value in data.values():
205        res[value['time']] = list(value.values())[1:]
206    return res
207
208def download_history_data(stockcode, period, startTime, endTime):
209    return xtdata.download_history_data(stockcode, period, startTime, endTime)
210
211def get_raw_financial_data(field_list, stock_list, start_date, end_date, report_type = 'announce_time'):
212    client = xtdata.get_client()
213    data = client.get_financial_data(stock_list, field_list, start_date, end_date, report_type)
214
215    import time
216    res = {}
217    for stock in data:
218        stock_data = data[stock]
219        res[stock] = {}
220
221        for field in field_list:
222            fs = field.split('.')
223            table_data = stock_data[fs[0]]
224
225            ans = {}
226            for row_data in table_data:
227                date = time.strftime('%Y%m%d', time.localtime(row_data[report_type] / 1000))
228                if start_date <= date <= end_date:
229                    ans[int(row_data[report_type])] = row_data[fs[1]]
230            res[stock][field] = ans
231    return res
232
233#def download_financial_data(stock_list, table_list): #暂不提供
234#    return xtdata.download_financial_data(stock_list, table_list)
235
236def get_instrument_detail(stock_code):
237    return xtdata.get_instrument_detail(stock_code)
238
239#def get_instrument_type(stock_code): #暂不提供
240#    return xtdata.get_instrument_type(stock_code)
241
242def get_trading_dates(stock_code, start_date, end_date, count = -1, period = '1d'):
243    if period != '1d':
244        return []
245    market = stock_code.split('.')[0]
246    trade_dates = xtdata.get_trading_dates(market, start_date, end_date)
247    if count == -1:
248        return trade_dates
249    if count > 0:
250        return trade_dates[-count:]
251    return []
252
253def get_stock_list_in_sector(sector_name):
254    return xtdata.get_stock_list_in_sector(sector_name)
255
256def download_sector_data():
257    return xtdata.download_sector_data()
258
259download_sector_weight = download_sector_data #compat
260
261def _passorder_impl(
262    optype, ordertype, accountid, ordercode
263    , prtype, modelprice, volume, ordertime, requestid
264):
265    data = {}
266
267    data['optype'] = optype
268    data['ordertype'] = ordertype
269    data['accountid'] = accountid
270    data['ordercode'] = ordercode
271    data['prtype'] = prtype
272    data['modelprice'] = modelprice
273    data['volume'] = volume
274    data['ordertime'] = ordertime
275
276    client = xtdata.get_client()
277    client.callFormula(requestid, 'passorder', bson.BSON.encode(data))
278    return
279
280def passorder(opType, orderType, accountid, orderCode, prType, modelprice, volume, C):
281    return C.passorder(opType, orderType, accountid, orderCode, prType, modelprice, volume)
282
283def get_trade_detail_data(accountid, accounttype, datatype, strategyname = ''):
284
285    data = {}
286
287    data['accountid'] = accountid
288    data['accounttype'] = accounttype
289    data['datatype'] = datatype
290    data['strategyname'] = strategyname
291
292    client = xtdata.get_client()
293    result_bson = client.callFormula(_request_id, 'gettradedetail', bson.BSON.encode(data))
294    result = bson.BSON.decode(result_bson)
295
296    class DetailData(object):
297        def __init__(self, _obj):
298            if _obj:
299                self.__dict__.update(_obj)
300
301    out = []
302    for item in result.get('result'):
303        out.append(DetailData(item))
304    return out
305
306def register_external_resp_callback(reqid, callback):
307    client = xtdata.get_client()
308
309    status = [False, 0, 1, '']
310
311    def on_callback(type, data, error):
312        try:
313            result = bson.BSON.decode(data)
314            callback(type, result, error)
315            return True
316        except:
317            status[0] = True
318            status[3] = 'exception'
319            return True
320
321    client.register_external_resp_callback(reqid, on_callback)
322
323def _set_auto_trade_callback_impl(enable, requestid):
324    data = {}
325    data['enable'] = enable
326
327    client = xtdata.get_client()
328    client.callFormula(requestid, 'setautotradecallback', bson.BSON.encode(data))
329    return
330
331def set_auto_trade_callback(C,enable):
332    return C.set_auto_trade_callback(enable)
333
334def set_account(accountid, requestid):
335    data = {}
336    data['accountid'] = accountid
337
338    client = xtdata.get_client()
339    client.callFormula(requestid, 'setaccount', bson.BSON.encode(data))
340    return
341
342def _get_callback_cache_impl(type, requestid):
343    data = {}
344
345    data['type'] = type
346
347    client = xtdata.get_client()
348    result_bson = client.callFormula(requestid, 'getcallbackcache', bson.BSON.encode(data))
349    return bson.BSON.decode(result_bson)
350
351def get_account_callback_cache(data, C):
352    data = C.get_callback_cache("account").get('')
353    return
354
355def get_order_callback_cache(data, C):
356    data = C.get_callback_cache("order")
357    return
358
359def get_deal_callback_cache(data, C):
360    data = C.get_callback_cache("deal")
361    return
362
363def get_position_callback_cache(data, C):
364    data = C.get_callback_cache("position")
365    return
366
367def get_ordererror_callback_cache(data, C):
368    data = C.get_callback_cache("ordererror")
369    return
def datetime_to_timetag(timelabel, format=''):
14def datetime_to_timetag(timelabel, format = ''):
15    '''
16    timelabel: str '20221231' '20221231235959'
17    format: str '%Y%m%d' '%Y%m%d%H%M%S'
18    return: int 1672502399000
19    '''
20    if not format:
21        format = '%Y%m%d' if len(timelabel) == 8 else '%Y%m%d%H%M%S'
22    return dt.datetime.strptime(timelabel, format).timestamp() * 1000

timelabel: str '20221231' '20221231235959' format: str '%Y%m%d' '%Y%m%d%H%M%S' return: int 1672502399000

def timetag_to_datetime(timetag, format=''):
24def timetag_to_datetime(timetag, format = ''):
25    '''
26    timetag: int 1672502399000
27    format: str '%Y%m%d' '%Y%m%d%H%M%S'
28    return: str '20221231' '20221231235959'
29    '''
30    if not format:
31        format = '%Y%m%d' if timetag % 86400000 == 57600000 else '%Y%m%d%H%M%S'
32    return dt.datetime.fromtimestamp(timetag / 1000).strftime(format)

timetag: int 1672502399000 format: str '%Y%m%d' '%Y%m%d%H%M%S' return: str '20221231' '20221231235959'

def subscribe_quote(stock_code, period, dividend_type, result_type='', callback=None):
34def subscribe_quote(stock_code, period, dividend_type, result_type = '', callback = None):
35    return xtdata.subscribe_quote(stock_code, period, '', '', 0, callback)
def subscribe_whole_quote(code_list, callback=None):
37def subscribe_whole_quote(code_list, callback = None):
38    return xtdata.subscribe_whole_quote(code_list, callback)
def unsubscribe_quote(subscribe_id):
40def unsubscribe_quote(subscribe_id):
41    return xtdata.unsubscribe_quote(subscribe_id)
def get_market_data( fields=[], stock_code=[], start_time='', end_time='', skip_paused=True, period='', dividend_type='', count=-1):
 43def get_market_data(
 44    fields = [], stock_code = [], start_time = '', end_time = ''
 45    , skip_paused = True, period = '', dividend_type = '', count = -1
 46):
 47    res = {}
 48    if period == 'tick':
 49        refixed = False
 50        if count == -2:
 51            refixed = True
 52            count = 1
 53        if 'quoter' not in fields:
 54            return xtdata.get_market_data_ori(
 55                    field_list=fields, stock_list=stock_code, period=period
 56                    , start_time=start_time, end_time=end_time, count=count
 57                    , dividend_type=dividend_type, fill_data=skip_paused
 58                )
 59
 60        fields = []
 61        data = xtdata.get_market_data_ori(
 62            field_list=fields, stock_list=stock_code, period=period
 63            , start_time=start_time, end_time=end_time, count=count
 64            , dividend_type=dividend_type, fill_data=skip_paused
 65        )
 66        fields = ['quoter']
 67
 68        import pandas as pd
 69
 70        stime_fmt = '%Y%m%d' if period == '1d' else '%Y%m%d%H%M%S'
 71        for stock in data:
 72            pd_data = pd.DataFrame(data[stock])
 73            pd_data['stime'] = [timetag_to_datetime(t, stime_fmt) for t in pd_data['time']]
 74            pd_data.index = pd.to_datetime((pd_data['time'] + 28800000) * 1000000)
 75            ans = {}
 76            for j, timetag in enumerate(pd_data['time']):
 77                d_map = {}
 78                for key in pd_data:
 79                    d_map[key] = pd_data[key][j]
 80                ans[str(pd_data.index[j])] = {}
 81                ans[str(pd_data.index[j])]['quoter'] = d_map
 82            res[stock] = ans
 83
 84        oriData = res
 85            # if not pd_data.empty:
 86            #     if count > 0:
 87            #         return list(pd_data.T.to_dict().values())
 88            #     return pd_data.iloc[-1].to_dict()
 89            # return {}
 90        if refixed:
 91            count = -2
 92    else:
 93        refixed = False
 94        if count == -2:
 95            refixed = True
 96            count = 1
 97        index, data = xtdata.get_market_data_ori(
 98            field_list=fields, stock_list=stock_code, period=period
 99            , start_time=start_time, end_time=end_time, count=count
100            , dividend_type=dividend_type, fill_data=skip_paused
101        )
102        if refixed:
103            end_time = ''
104            count = -1
105        for i, stock in enumerate(index[0]):
106            ans = {}
107            for j, timetag in enumerate(index[1]):
108                d_map = {}
109                for key in data:
110                    d_map[key] = data[key][i][j]
111                ans[timetag] = d_map
112            res[stock] = ans
113        oriData = res
114
115    resultDict = {}
116    for code in oriData:
117        for timenode in oriData[code]:
118            values = []
119            for field in fields:
120                values.append(oriData[code][timenode][field])
121            key = code + timenode
122            resultDict[key] = values
123
124    if len(fields) == 1 and len(stock_code) <= 1 and (
125            (start_time == '' and end_time == '') or start_time == end_time) and (count == -1 or count == -2):
126        # if resultDict:
127            # keys = list(resultDict.keys())
128            # if resultDict[keys[-1]]:
129            #     return resultDict[keys[-1]]
130        for key in resultDict:
131            return resultDict[key][0]
132        return -1
133    import numpy as np
134    import pandas as pd
135    if len(stock_code) <= 1 and start_time == '' and end_time == '' and (count == -1 or count == -2):
136        for key in resultDict:
137            result = pd.Series(resultDict[key], index=fields)
138            return result
139    if len(stock_code) > 1 and start_time == '' and end_time == '' and (count == -1 or count == -2):
140        values = []
141        for code in stock_code:
142            if code in oriData:
143                if not oriData[code]:
144                    values.append([np.nan])
145                for timenode in oriData[code]:
146                    key = code + timenode
147                    values.append(resultDict[key])
148            else:
149                values.append([np.nan])
150        result = pd.DataFrame(values, index=stock_code, columns=fields)
151        return result
152    if len(stock_code) <= 1 and ((start_time != '' or end_time != '') or count >= 0):
153        values = []
154        times = []
155        for code in oriData:
156            for timenode in oriData[code]:
157                key = code + timenode
158                times.append(timenode)
159                values.append(resultDict[key])
160        result = pd.DataFrame(values, index=times, columns=fields)
161        return result
162    if len(stock_code) > 1 and ((start_time != '' or end_time != '') or count >= 0):
163        values = {}
164        for code in stock_code:
165            times = []
166            value = []
167            if code in oriData:
168                for timenode in oriData[code]:
169                    key = code + timenode
170                    times.append(timenode)
171                    value.append(resultDict[key])
172            values[code] = pd.DataFrame(value, index=times, columns=fields)
173        try:
174            result = pd.Panel(values)
175            return result
176        except:
177            return oriData
178    return
def get_market_data_ex( fields=[], stock_code=[], period='', start_time='', end_time='', count=-1, dividend_type='', fill_data=True, subscribe=True):
180def get_market_data_ex(
181    fields = [], stock_code = [], period = ''
182    , start_time = '', end_time = '', count = -1
183    , dividend_type = '', fill_data = True, subscribe = True
184):
185    res = xtdata.get_market_data_ex(
186        field_list = fields, stock_list = stock_code, period = period
187        , start_time = start_time, end_time = end_time, count = count
188        , dividend_type = dividend_type, fill_data = fill_data
189    )
190    for stock in res:
191        res[stock]['stime'] = res[stock].index
192    return res
def get_full_tick(stock_code):
194def get_full_tick(stock_code):
195    return xtdata.get_full_tick(stock_code)
def get_divid_factors(stock_code, date=None):
197def get_divid_factors(stock_code, date = None):
198    client = xtdata.get_client()
199    if date:
200        data = client.get_divid_factors(stock_code, date, date)
201    else:
202        data = client.get_divid_factors(stock_code, '19700101', '20380119')
203
204    res = {}
205    for value in data.values():
206        res[value['time']] = list(value.values())[1:]
207    return res
def download_history_data(stockcode, period, startTime, endTime):
209def download_history_data(stockcode, period, startTime, endTime):
210    return xtdata.download_history_data(stockcode, period, startTime, endTime)
def get_raw_financial_data( field_list, stock_list, start_date, end_date, report_type='announce_time'):
212def get_raw_financial_data(field_list, stock_list, start_date, end_date, report_type = 'announce_time'):
213    client = xtdata.get_client()
214    data = client.get_financial_data(stock_list, field_list, start_date, end_date, report_type)
215
216    import time
217    res = {}
218    for stock in data:
219        stock_data = data[stock]
220        res[stock] = {}
221
222        for field in field_list:
223            fs = field.split('.')
224            table_data = stock_data[fs[0]]
225
226            ans = {}
227            for row_data in table_data:
228                date = time.strftime('%Y%m%d', time.localtime(row_data[report_type] / 1000))
229                if start_date <= date <= end_date:
230                    ans[int(row_data[report_type])] = row_data[fs[1]]
231            res[stock][field] = ans
232    return res
def get_instrument_detail(stock_code):
237def get_instrument_detail(stock_code):
238    return xtdata.get_instrument_detail(stock_code)
def get_trading_dates(stock_code, start_date, end_date, count=-1, period='1d'):
243def get_trading_dates(stock_code, start_date, end_date, count = -1, period = '1d'):
244    if period != '1d':
245        return []
246    market = stock_code.split('.')[0]
247    trade_dates = xtdata.get_trading_dates(market, start_date, end_date)
248    if count == -1:
249        return trade_dates
250    if count > 0:
251        return trade_dates[-count:]
252    return []
def get_stock_list_in_sector(sector_name):
254def get_stock_list_in_sector(sector_name):
255    return xtdata.get_stock_list_in_sector(sector_name)
def download_sector_data():
257def download_sector_data():
258    return xtdata.download_sector_data()
def download_sector_weight():
257def download_sector_data():
258    return xtdata.download_sector_data()
def passorder( opType, orderType, accountid, orderCode, prType, modelprice, volume, C):
281def passorder(opType, orderType, accountid, orderCode, prType, modelprice, volume, C):
282    return C.passorder(opType, orderType, accountid, orderCode, prType, modelprice, volume)
def get_trade_detail_data(accountid, accounttype, datatype, strategyname=''):
284def get_trade_detail_data(accountid, accounttype, datatype, strategyname = ''):
285
286    data = {}
287
288    data['accountid'] = accountid
289    data['accounttype'] = accounttype
290    data['datatype'] = datatype
291    data['strategyname'] = strategyname
292
293    client = xtdata.get_client()
294    result_bson = client.callFormula(_request_id, 'gettradedetail', bson.BSON.encode(data))
295    result = bson.BSON.decode(result_bson)
296
297    class DetailData(object):
298        def __init__(self, _obj):
299            if _obj:
300                self.__dict__.update(_obj)
301
302    out = []
303    for item in result.get('result'):
304        out.append(DetailData(item))
305    return out
def register_external_resp_callback(reqid, callback):
307def register_external_resp_callback(reqid, callback):
308    client = xtdata.get_client()
309
310    status = [False, 0, 1, '']
311
312    def on_callback(type, data, error):
313        try:
314            result = bson.BSON.decode(data)
315            callback(type, result, error)
316            return True
317        except:
318            status[0] = True
319            status[3] = 'exception'
320            return True
321
322    client.register_external_resp_callback(reqid, on_callback)
def set_auto_trade_callback(C, enable):
332def set_auto_trade_callback(C,enable):
333    return C.set_auto_trade_callback(enable)
def set_account(accountid, requestid):
335def set_account(accountid, requestid):
336    data = {}
337    data['accountid'] = accountid
338
339    client = xtdata.get_client()
340    client.callFormula(requestid, 'setaccount', bson.BSON.encode(data))
341    return
def get_account_callback_cache(data, C):
352def get_account_callback_cache(data, C):
353    data = C.get_callback_cache("account").get('')
354    return
def get_order_callback_cache(data, C):
356def get_order_callback_cache(data, C):
357    data = C.get_callback_cache("order")
358    return
def get_deal_callback_cache(data, C):
360def get_deal_callback_cache(data, C):
361    data = C.get_callback_cache("deal")
362    return
def get_position_callback_cache(data, C):
364def get_position_callback_cache(data, C):
365    data = C.get_callback_cache("position")
366    return
def get_ordererror_callback_cache(data, C):
368def get_ordererror_callback_cache(data, C):
369    data = C.get_callback_cache("ordererror")
370    return