xtquant.xttrader

   1#coding=utf-8
   2import asyncio
   3import os
   4from threading import Thread
   5from concurrent.futures import ThreadPoolExecutor, Future
   6from . import xtpythonclient as XTQC
   7from . import xttype
   8
   9def title(s = None):
  10    import inspect
  11    if not s:
  12        s = inspect.stack()[1].function
  13    print('-' * 33 + s + '-' * 33)
  14    return
  15
  16def cp(s = None):
  17    import inspect
  18    st = inspect.stack()
  19    pos = {'title':st[1].function, 'line':st[1].lineno}
  20    print('-' * 33 + f'{pos}, {s}' + '-' * 33)
  21    return
  22
  23# 交易回调类
  24class XtQuantTraderCallback(object):
  25    def on_connected(self):
  26        """
  27        连接成功推送
  28        """
  29        pass
  30        
  31    def on_disconnected(self):
  32        """
  33        连接断开推送
  34        """
  35        pass
  36
  37    def on_account_status(self, status):
  38        """
  39        :param status: XtAccountStatus对象
  40        :return:
  41        """
  42        pass
  43
  44    def on_stock_asset(self, asset):
  45        """
  46        :param asset: XtAsset对象
  47        :return:
  48        """
  49        pass
  50
  51    def on_stock_order(self, order):
  52        """
  53        :param order: XtOrder对象
  54        :return:
  55        """
  56        pass
  57
  58    def on_stock_trade(self, trade):
  59        """
  60        :param trade: XtTrade对象
  61        :return:
  62        """
  63        pass
  64
  65    def on_stock_position(self, position):
  66        """
  67        :param position: XtPosition对象
  68        :return:
  69        """
  70        pass
  71
  72    def on_order_error(self, order_error):
  73        """
  74        :param order_error: XtOrderError 对象
  75        :return:
  76        """
  77        pass
  78
  79    def on_cancel_error(self, cancel_error):
  80        """
  81        :param cancel_error:XtCancelError 对象
  82        :return:
  83        """
  84        pass
  85
  86    def on_order_stock_async_response(self, response):
  87        """
  88        :param response: XtOrderResponse 对象
  89        :return:
  90        """
  91        pass
  92    
  93    def on_smt_appointment_async_response(self, response):
  94        """
  95        :param response: XtAppointmentResponse 对象
  96        :return:
  97        """
  98        pass
  99    
 100    def on_cancel_order_stock_async_response(self, response):
 101        """
 102        :param response: XtCancelOrderResponse 对象
 103        :return:
 104        """
 105        pass
 106
 107class XtQuantTrader(object):
 108    def __init__(self, path, session, callback=None):
 109        """
 110        :param path: mini版迅投极速交易客户端安装路径下,userdata文件夹具体路径
 111        :param session: 当前任务执行所属的会话id
 112        :param callback: 回调方法
 113        """
 114        self.async_client = XTQC.XtQuantAsyncClient(path.encode('gb18030'), 'xtquant', session)
 115        self.callback = callback
 116
 117        self.connected = False
 118
 119        self.oldloop = asyncio.get_event_loop()
 120        self.loop = asyncio.new_event_loop()
 121        asyncio.set_event_loop(self.loop)
 122        self.cbs = {}
 123
 124        self.executor = None
 125        self.resp_executor = None
 126
 127        self.relaxed_resp_order_enabled = False
 128        self.relaxed_resp_executor = None
 129
 130        self.handled_async_order_stock_order_id = set()
 131        self.sync_order_stock_order_id = set()
 132        self.queuing_order_errors = {}
 133
 134        self.handled_async_smt_appointment_order_id = set()
 135        self.sync_smt_appointment_order_id = set()
 136         
 137        self.handled_async_cancel_order_stock_order_id = set()
 138        self.handled_async_cancel_order_stock_order_sys_id = set()
 139        self.handled_sync_cancel_order_stock_order_id = set()
 140        self.handled_sync_cancel_order_stock_order_sys_id = set()
 141        self.queuing_cancel_errors_by_order_id = {}
 142        self.queuing_cancel_errors_by_order_sys_id = {}
 143        
 144        
 145    #########################
 146        #push
 147        def on_common_push_callback_wrapper(argc, callback):
 148            if argc == 0:
 149                def on_push_data():
 150                    self.executor.submit(callback)
 151                return on_push_data
 152            elif argc == 1:
 153                def on_push_data(data):
 154                    self.executor.submit(callback, data)
 155                return on_push_data
 156            elif argc == 2:
 157                def on_push_data(data1, data2):
 158                    self.executor.submit(callback, data1, data2)
 159                return on_push_data
 160            else:
 161                return None
 162        
 163        #response
 164        def on_common_resp_callback(seq, resp):
 165            callback = self.cbs.pop(seq, None)
 166            if callback:
 167                self.resp_executor.submit(callback, resp)
 168            return
 169        
 170        self.async_client.bindOnSubscribeRespCallback(on_common_resp_callback)
 171        self.async_client.bindOnUnsubscribeRespCallback(on_common_resp_callback)
 172        self.async_client.bindOnQueryStockAssetCallback(on_common_resp_callback)
 173        self.async_client.bindOnQueryStockOrdersCallback(on_common_resp_callback)
 174        self.async_client.bindOnQueryStockTradesCallback(on_common_resp_callback)
 175        self.async_client.bindOnQueryStockPositionsCallback(on_common_resp_callback)
 176        self.async_client.bindOnQueryCreditDetailRespCallback(on_common_resp_callback)
 177        self.async_client.bindOnQueryStkCompactsRespCallback(on_common_resp_callback)
 178        self.async_client.bindOnQueryCreditSubjectsRespCallback(on_common_resp_callback)
 179        self.async_client.bindOnQueryCreditSloCodeRespCallback(on_common_resp_callback)
 180        self.async_client.bindOnQueryCreditAssureRespCallback(on_common_resp_callback)
 181        self.async_client.bindOnQueryNewPurchaseLimitCallback(on_common_resp_callback)
 182        self.async_client.bindOnQueryIPODataCallback(on_common_resp_callback)
 183        self.async_client.bindOnQueryAppointmentInfoRespCallback(on_common_resp_callback)
 184        self.async_client.bindOnQuerySMTSecuInfoRespCallback(on_common_resp_callback)
 185        self.async_client.bindOnQuerySMTSecuRateRespCallback(on_common_resp_callback)
 186        
 187        self.async_client.bindOnQueryAccountInfosCallback(on_common_resp_callback)
 188        self.async_client.bindOnQueryAccountStatusCallback(on_common_resp_callback)
 189    #########################
 190        
 191        enable_push = 1
 192        
 193        #order push
 194        
 195        def on_push_SmtAppointmentAsyncResponse(seq, resp):
 196            callback = self.cbs.pop(seq, None)
 197            if callback:
 198                resp = xttype.XtAppointmentResponse(resp.m_strAccountID, resp.m_nOrderID, resp.m_nErrorID, resp.m_strErrorMsg, seq)
 199                callback(resp)
 200                self.handled_async_smt_appointment_order_id.add(resp.order_id)
 201            return
 202        
 203        if enable_push:
 204            self.async_client.bindOnSmtAppointmentRespCallback(on_common_push_callback_wrapper(2, on_push_SmtAppointmentAsyncResponse))
 205        
 206        def on_push_OrderStockAsyncResponse(seq, resp):
 207            callback = self.cbs.pop(seq, None)
 208            if callback:
 209                resp = xttype.XtOrderResponse(resp.m_strAccountID, resp.m_nOrderID, resp.m_strStrategyName, resp.m_strOrderRemark, resp.m_strErrorMsg, seq)
 210                callback(resp)
 211                self.handled_async_order_stock_order_id.add(resp.order_id)
 212                e = self.queuing_order_errors.pop(resp.order_id, None)
 213                if e is not None:
 214                    self.callback.on_order_error(e)
 215                    self.handled_async_order_stock_order_id.discard(resp.order_id)
 216            return
 217        
 218        if enable_push:
 219            self.async_client.bindOnOrderStockRespCallback(on_common_push_callback_wrapper(2, on_push_OrderStockAsyncResponse))
 220        
 221        def on_push_CancelOrderStockAsyncResponse(seq, resp):
 222            callback = self.cbs.pop(seq, None)
 223            if callback:
 224                resp = xttype.XtCancelOrderResponse(resp.m_strAccountID, resp.m_nCancelResult, resp.m_nOrderID, resp.m_strOrderSysID, seq)
 225                callback(resp)
 226                
 227                if not resp.order_sysid:
 228                    self.handled_async_cancel_order_stock_order_id.add(resp.order_id)
 229                    e = self.queuing_cancel_errors_by_order_id.pop(resp.order_id, None)
 230                    if e is not None:
 231                        self.handled_async_cancel_order_stock_order_id.discard(resp.order_id)
 232                        self.callback.on_cancel_error(e)
 233                else:
 234                    self.handled_async_cancel_order_stock_order_sys_id.add(resp.order_sysid)
 235                    e = self.queuing_cancel_errors_by_order_sys_id.pop(resp.order_sysid, None)
 236                    if e is not None:
 237                        self.handled_async_cancel_order_stock_order_sys_id.discard(resp.order_sysid)
 238                        self.callback.on_cancel_error(e)
 239            return
 240        
 241        if enable_push:
 242            self.async_client.bindOnCancelOrderStockRespCallback(on_common_push_callback_wrapper(2, on_push_CancelOrderStockAsyncResponse))
 243            
 244        def on_push_disconnected():
 245            if self.callback:
 246                self.callback.on_disconnected()
 247
 248        if enable_push:
 249            self.async_client.bindOnDisconnectedCallback(on_common_push_callback_wrapper(0, on_push_disconnected))
 250
 251        def on_push_AccountStatus(data):
 252            data = xttype.XtAccountStatus(data.m_strAccountID, data.m_nAccountType, data.m_nStatus)
 253            self.callback.on_account_status(data)
 254
 255        if enable_push:
 256            self.async_client.bindOnUpdateAccountStatusCallback(on_common_push_callback_wrapper(1, on_push_AccountStatus))
 257
 258        def on_push_StockAsset(data):
 259            self.callback.on_stock_asset(data)
 260
 261        if enable_push:
 262            self.async_client.bindOnStockAssetCallback(on_common_push_callback_wrapper(1, on_push_StockAsset))
 263
 264        def on_push_OrderStock(data):
 265            self.callback.on_stock_order(data)
 266
 267        if enable_push:
 268            self.async_client.bindOnStockOrderCallback(on_common_push_callback_wrapper(1, on_push_OrderStock))
 269
 270        def on_push_StockTrade(data):
 271            self.callback.on_stock_trade(data)
 272
 273        if enable_push:
 274            self.async_client.bindOnStockTradeCallback(on_common_push_callback_wrapper(1, on_push_StockTrade))
 275
 276        def on_push_StockPosition(data):
 277            self.callback.on_stock_position(data)
 278
 279        if enable_push:
 280            self.async_client.bindOnStockPositionCallback(on_common_push_callback_wrapper(1, on_push_StockPosition))
 281
 282        def on_push_OrderError(data):
 283            if data.order_id in self.handled_async_order_stock_order_id or data.order_id in self.sync_order_stock_order_id:
 284                self.handled_async_order_stock_order_id.discard(data.order_id)
 285                self.sync_order_stock_order_id.discard(data.order_id)
 286                self.callback.on_order_error(data)
 287            else:
 288                self.queuing_order_errors[data.order_id] = data
 289
 290        if enable_push:
 291            self.async_client.bindOnOrderErrorCallback(on_common_push_callback_wrapper(1, on_push_OrderError))
 292
 293        def on_push_CancelError(data):
 294            if not data.order_sysid:
 295                if data.order_id in self.handled_async_cancel_order_stock_order_id or data.order_id in self.handled_sync_cancel_order_stock_order_id:
 296                    self.handled_async_cancel_order_stock_order_id.discard(data.order_id)
 297                    self.handled_sync_cancel_order_stock_order_id.discard(data.order_id)
 298                    self.callback.on_cancel_error(data)
 299                else:
 300                    self.queuing_cancel_errors_by_order_id[data.order_id] = data
 301            else:
 302                if data.order_sysid in self.handled_async_cancel_order_stock_order_sys_id or data.order_sysid in self.handled_sync_cancel_order_stock_order_sys_id:
 303                    self.handled_async_cancel_order_stock_order_sys_id.discard(data.order_sysid)
 304                    self.handled_sync_cancel_order_stock_order_sys_id.discard(data.order_sysid)
 305                    self.callback.on_cancel_error(data)
 306                else:
 307                    self.queuing_cancel_errors_by_order_sys_id[data.order_sysid] = data
 308
 309        if enable_push:
 310            self.async_client.bindOnCancelErrorCallback(on_common_push_callback_wrapper(1, on_push_CancelError))
 311        
 312    ########################
 313
 314    def common_op_async_with_seq(self, seq, callable, callback):
 315        self.cbs[seq] = callback
 316
 317        def apply(func, *args):
 318            return func(*args)
 319        apply(*callable)
 320
 321        return seq
 322
 323    def common_op_sync_with_seq(self, seq, callable):
 324        future = Future()
 325        self.cbs[seq] = lambda resp:future.set_result(resp)
 326
 327        def apply(func, *args):
 328            return func(*args)
 329        apply(*callable)
 330
 331        return future.result()
 332
 333    #########################
 334    
 335    
 336    def __del__(self):
 337        if hasattr(self, 'oldloop'):
 338            asyncio.set_event_loop(self.oldloop)
 339
 340    def register_callback(self, callback):
 341        self.callback = callback
 342
 343    def start(self):
 344        self.async_client.init()
 345        self.async_client.start()
 346        self.executor = ThreadPoolExecutor(max_workers = 1)
 347        self.relaxed_resp_executor = ThreadPoolExecutor(max_workers = 1)
 348        self.resp_executor = self.relaxed_resp_executor if self.relaxed_resp_order_enabled else self.executor
 349        return
 350
 351    def stop(self):
 352        self.async_client.stop()
 353        self.loop.call_soon_threadsafe(self.loop.stop)
 354        self.executor.shutdown(wait = True)
 355        self.relaxed_resp_executor.shutdown(wait = True)
 356        return
 357
 358    def connect(self):
 359        result = self.async_client.connect()
 360        self.connected = result == 0
 361        return result
 362
 363    def sleep(self, time):
 364        async def sleep_coroutine(time):
 365            await asyncio.sleep(time)
 366        asyncio.run_coroutine_threadsafe(sleep_coroutine(time), self.loop).result()
 367
 368    def run_forever(self):
 369        import time
 370        while True:
 371            time.sleep(0.2)
 372        return
 373
 374    def set_relaxed_response_order_enabled(self, enabled):
 375        self.relaxed_resp_order_enabled = enabled
 376        self.resp_executor = self.relaxed_resp_executor if self.relaxed_resp_order_enabled else self.executor
 377        return
 378
 379    def subscribe(self, account):
 380        req = XTQC.SubscribeReq()
 381        req.m_nAccountType = account.account_type
 382        req.m_strAccountID = account.account_id
 383        seq = self.async_client.nextSeq()
 384        return self.common_op_sync_with_seq(
 385            seq,
 386            (self.async_client.subscribeWithSeq, seq, req)
 387        )
 388
 389    def unsubscribe(self, account):
 390        req = XTQC.UnsubscribeReq()
 391        req.m_nAccountType = account.account_type
 392        req.m_strAccountID = account.account_id
 393        seq = self.async_client.nextSeq()
 394        return self.common_op_sync_with_seq(
 395            seq,
 396            (self.async_client.unsubscribeWithSeq, seq, req)
 397        )
 398
 399    def order_stock_async(self, account, stock_code, order_type, order_volume, price_type, price, strategy_name='',
 400                          order_remark=''):
 401        """
 402        :param account: 证券账号
 403        :param stock_code: 证券代码, 例如"600000.SH"
 404        :param order_type: 委托类型, 23:买, 24:卖
 405        :param order_volume: 委托数量, 股票以'股'为单位, 债券以'张'为单位
 406        :param price_type: 报价类型, 详见帮助手册
 407        :param price: 报价价格, 如果price_type为指定价, 那price为指定的价格, 否则填0
 408        :param strategy_name: 策略名称
 409        :param order_remark: 委托备注
 410        :return: 返回下单请求序号, 成功委托后的下单请求序号为大于0的正整数, 如果为-1表示委托失败
 411        """
 412        req = XTQC.OrderStockReq()
 413        req.m_nAccountType = account.account_type
 414        req.m_strAccountID = account.account_id
 415        req.m_strStockCode = stock_code
 416        req.m_nOrderType = order_type
 417        req.m_nOrderVolume = order_volume
 418        req.m_nPriceType = price_type
 419        req.m_dPrice = price
 420        req.m_strStrategyName = strategy_name
 421        req.m_strOrderRemark = order_remark
 422
 423        seq = self.async_client.nextSeq()
 424        self.cbs[seq] = self.callback.on_order_stock_async_response
 425        self.async_client.orderStockWithSeq(seq, req)
 426        return seq
 427
 428    def order_stock(self, account, stock_code, order_type, order_volume, price_type, price, strategy_name='',
 429                          order_remark=''):
 430        """
 431        :param account: 证券账号
 432        :param stock_code: 证券代码, 例如"600000.SH"
 433        :param order_type: 委托类型, 23:买, 24:卖
 434        :param order_volume: 委托数量, 股票以'股'为单位, 债券以'张'为单位
 435        :param price_type: 报价类型, 详见帮助手册
 436        :param price: 报价价格, 如果price_type为指定价, 那price为指定的价格, 否则填0
 437        :param strategy_name: 策略名称
 438        :param order_remark: 委托备注
 439        :return: 返回下单请求序号, 成功委托后的下单请求序号为大于0的正整数, 如果为-1表示委托失败
 440        """
 441        req = XTQC.OrderStockReq()
 442        req.m_nAccountType = account.account_type
 443        req.m_strAccountID = account.account_id
 444        req.m_strStockCode = stock_code
 445        req.m_nOrderType = order_type
 446        req.m_nOrderVolume = order_volume
 447        req.m_nPriceType = price_type
 448        req.m_dPrice = price
 449        req.m_strStrategyName = strategy_name
 450        req.m_strOrderRemark = order_remark
 451        
 452        seq = self.async_client.nextSeq()
 453        resp = self.common_op_sync_with_seq(
 454            seq,
 455            (self.async_client.orderStockWithSeq, seq, req)
 456        )
 457        self.sync_order_stock_order_id.add(resp.order_id)
 458        return resp.order_id
 459
 460    def cancel_order_stock(self, account, order_id):
 461        """
 462        :param account: 证券账号
 463        :param order_id: 委托编号, 报单时返回的编号
 464        :return: 返回撤单成功或者失败, 0:成功,  -1:委托已完成撤单失败, -2:未找到对应委托编号撤单失败, -3:账号未登陆撤单失败
 465        """
 466        req = XTQC.CancelOrderStockReq()
 467        req.m_nAccountType = account.account_type
 468        req.m_strAccountID = account.account_id
 469        req.m_nOrderID = order_id
 470        
 471        seq = self.async_client.nextSeq()
 472        resp = self.common_op_sync_with_seq(
 473            seq,
 474            (self.async_client.cancelOrderStockWithSeq, seq, req)
 475        )
 476        self.handled_sync_cancel_order_stock_order_id.add(resp.order_id)
 477        return resp.cancel_result
 478
 479    def cancel_order_stock_async(self, account, order_id):
 480        """
 481        :param account: 证券账号
 482        :param order_id: 委托编号, 报单时返回的编号
 483        :return: 返回撤单请求序号, 成功委托后的撤单请求序号为大于0的正整数, 如果为-1表示委托失败
 484        """
 485        req = XTQC.CancelOrderStockReq()
 486        req.m_nAccountType = account.account_type
 487        req.m_strAccountID = account.account_id
 488        req.m_nOrderID = order_id
 489        
 490        seq = self.async_client.nextSeq()
 491        self.cbs[seq] = self.callback.on_cancel_order_stock_async_response
 492        self.async_client.cancelOrderStockWithSeq(seq, req)
 493        return seq
 494
 495    def cancel_order_stock_sysid(self, account, market, sysid):
 496        """
 497        :param account:证券账号
 498        :param market: 交易市场 0:上海 1:深圳
 499        :param sysid: 柜台合同编号
 500        :return:返回撤单成功或者失败, 0:成功,  -1:撤单失败
 501        """
 502        req = XTQC.CancelOrderStockReq()
 503        req.m_nAccountType = account.account_type
 504        req.m_strAccountID = account.account_id
 505        req.m_nMarket = market
 506        req.m_strOrderSysID = sysid
 507        
 508        seq = self.async_client.nextSeq()
 509        resp = self.common_op_sync_with_seq(
 510            seq,
 511            (self.async_client.cancelOrderStockWithSeq, seq, req)
 512        )
 513        self.handled_sync_cancel_order_stock_order_sys_id.add(resp.order_sysid)
 514        return resp.cancel_result
 515
 516    def cancel_order_stock_sysid_async(self, account, market, sysid):
 517        """
 518        :param account:证券账号
 519        :param market: 交易市场 0:上海 1:深圳
 520        :param sysid: 柜台编号
 521        :return:返回撤单请求序号, 成功委托后的撤单请求序号为大于0的正整数, 如果为-1表示委托失败
 522        """
 523        req = XTQC.CancelOrderStockReq()
 524        req.m_nAccountType = account.account_type
 525        req.m_strAccountID = account.account_id
 526        req.m_nMarket = market
 527        req.m_strOrderSysID = sysid
 528        
 529        seq = self.async_client.nextSeq()
 530        self.cbs[seq] = self.callback.on_cancel_order_stock_async_response
 531        self.async_client.cancelOrderStockWithSeq(seq, req)
 532        return seq
 533
 534    def query_account_infos(self):
 535        """
 536        :return: 返回账号列表
 537        """
 538        req = XTQC.QueryAccountInfosReq()
 539        
 540        seq = self.async_client.nextSeq()
 541        return self.common_op_sync_with_seq(
 542            seq,
 543            (self.async_client.queryAccountInfosWithSeq, seq, req)
 544        )
 545        
 546    query_account_info = query_account_infos
 547    
 548    def query_account_infos_async(self, callback):
 549        """
 550        :return: 返回账号列表
 551        """
 552        req = XTQC.QueryAccountInfosReq()
 553        
 554        seq = self.async_client.nextSeq()
 555        return self.common_op_async_with_seq(
 556            seq,
 557            (self.async_client.queryAccountInfosWithSeq, seq, req)
 558            , callback
 559        )
 560        
 561    def query_account_status(self):
 562        """
 563        :return: 返回账号状态
 564        """
 565        req = XTQC.QueryAccountStatusReq()
 566        
 567        seq = self.async_client.nextSeq()
 568        return self.common_op_sync_with_seq(
 569            seq,
 570            (self.async_client.queryAccountStatusWithSeq, seq, req)
 571        )
 572    
 573    def query_account_status_async(self, callback):
 574        """
 575        :return: 返回账号状态
 576        """
 577        req = XTQC.QueryAccountStatusReq()
 578        
 579        seq = self.async_client.nextSeq()
 580        return self.common_op_async_with_seq(
 581            seq,
 582            (self.async_client.queryAccountStatusWithSeq, seq, req)
 583            , callback
 584        )
 585
 586    def query_stock_asset(self, account):
 587        """
 588        :param account: 证券账号
 589        :return: 返回当前证券账号的资产数据
 590        """
 591        req = XTQC.QueryStockAssetReq()
 592        req.m_nAccountType = account.account_type
 593        req.m_strAccountID = account.account_id
 594        
 595        seq = self.async_client.nextSeq()
 596        resp = self.common_op_sync_with_seq(
 597            seq,
 598            (self.async_client.queryStockAssetWithSeq, seq, req)
 599        )
 600
 601        if resp and len(resp):
 602            return resp[0]
 603        return None
 604    
 605    def query_stock_asset_async(self, account, callback):
 606        """
 607        :param account: 证券账号
 608        :return: 返回当前证券账号的资产数据
 609        """
 610        req = XTQC.QueryStockAssetReq()
 611        req.m_nAccountType = account.account_type
 612        req.m_strAccountID = account.account_id
 613        
 614        seq = self.async_client.nextSeq()
 615        def _cb(resp):
 616            callback(resp[0] if resp else None)
 617        resp = self.common_op_async_with_seq(
 618            seq,
 619            (self.async_client.queryStockAssetWithSeq, seq, req)
 620            , _cb
 621        )
 622        return
 623
 624    def query_stock_order(self, account, order_id):
 625        """
 626        :param account: 证券账号
 627        :param order_id:  订单编号,同步报单接口返回的编号
 628        :return: 返回订单编号对应的委托对象
 629        """
 630        req = XTQC.QueryStockOrdersReq()
 631        req.m_nAccountType = account.account_type
 632        req.m_strAccountID = account.account_id
 633        req.m_nOrderID = order_id
 634        
 635        seq = self.async_client.nextSeq()
 636        resp = self.common_op_sync_with_seq(
 637            seq,
 638            (self.async_client.queryStockOrdersWithSeq, seq, req)
 639        )
 640        if resp and len(resp):
 641            return resp[0]
 642        return None
 643
 644    def query_stock_orders(self, account, cancelable_only = False):
 645        """
 646        :param account: 证券账号
 647        :param cancelable_only: 仅查询可撤委托
 648        :return: 返回当日所有委托的委托对象组成的list
 649        """
 650        req = XTQC.QueryStockOrdersReq()
 651        req.m_nAccountType = account.account_type
 652        req.m_strAccountID = account.account_id
 653        req.m_bCanCancel = cancelable_only
 654        
 655        seq = self.async_client.nextSeq()
 656        return self.common_op_sync_with_seq(
 657            seq,
 658            (self.async_client.queryStockOrdersWithSeq, seq, req)
 659        )
 660    
 661    def query_stock_orders_async(self, account, callback, cancelable_only = False):
 662        """
 663        :param account: 证券账号
 664        :param cancelable_only: 仅查询可撤委托
 665        :return: 返回当日所有委托的委托对象组成的list
 666        """
 667        req = XTQC.QueryStockOrdersReq()
 668        req.m_nAccountType = account.account_type
 669        req.m_strAccountID = account.account_id
 670        req.m_bCanCancel = cancelable_only
 671        
 672        seq = self.async_client.nextSeq()
 673        return self.common_op_async_with_seq(
 674            seq,
 675            (self.async_client.queryStockOrdersWithSeq, seq, req)
 676            , callback
 677        )
 678    
 679    def query_stock_trades(self, account):
 680        """
 681        :param account:  证券账号
 682        :return:  返回当日所有成交的成交对象组成的list
 683        """
 684        req = XTQC.QueryStockTradesReq()
 685        req.m_nAccountType = account.account_type
 686        req.m_strAccountID = account.account_id
 687        
 688        seq = self.async_client.nextSeq()
 689        return self.common_op_sync_with_seq(
 690            seq,
 691            (self.async_client.queryStockTradesWithSeq, seq, req)
 692        )
 693    
 694    def query_stock_trades_async(self, account, callback):
 695        """
 696        :param account:  证券账号
 697        :return:  返回当日所有成交的成交对象组成的list
 698        """
 699        req = XTQC.QueryStockTradesReq()
 700        req.m_nAccountType = account.account_type
 701        req.m_strAccountID = account.account_id
 702        
 703        seq = self.async_client.nextSeq()
 704        return self.common_op_async_with_seq(
 705            seq,
 706            (self.async_client.queryStockTradesWithSeq, seq, req)
 707            , callback
 708        )
 709
 710    def query_stock_position(self, account, stock_code):
 711        """
 712        :param account: 证券账号
 713        :param stock_code: 证券代码, 例如"600000.SH"
 714        :return: 返回证券代码对应的持仓对象
 715        """
 716        req = XTQC.QueryStockPositionsReq()
 717        req.m_nAccountType = account.account_type
 718        req.m_strAccountID = account.account_id
 719        req.m_strStockCode = stock_code
 720        
 721        seq = self.async_client.nextSeq()
 722        resp = self.common_op_sync_with_seq(
 723            seq,
 724            (self.async_client.queryStockPositionsWithSeq, seq, req)
 725        )
 726        if resp and len(resp):
 727            return resp[0]
 728        return None
 729
 730    def query_stock_positions(self, account):
 731        """
 732        :param account: 证券账号
 733        :return: 返回当日所有持仓的持仓对象组成的list
 734        """
 735        req = XTQC.QueryStockPositionsReq()
 736        req.m_nAccountType = account.account_type
 737        req.m_strAccountID = account.account_id
 738        
 739        seq = self.async_client.nextSeq()
 740        return self.common_op_sync_with_seq(
 741            seq,
 742            (self.async_client.queryStockPositionsWithSeq, seq, req)
 743        )
 744    
 745    def query_stock_positions_async(self, account, callback):
 746        """
 747        :param account: 证券账号
 748        :return: 返回当日所有持仓的持仓对象组成的list
 749        """
 750        req = XTQC.QueryStockPositionsReq()
 751        req.m_nAccountType = account.account_type
 752        req.m_strAccountID = account.account_id
 753        
 754        seq = self.async_client.nextSeq()
 755        return self.common_op_async_with_seq(
 756            seq
 757            , (self.async_client.queryStockPositionsWithSeq, seq, req)
 758            , callback
 759        )
 760
 761    def query_credit_detail(self, account):
 762        """
 763        :param account: 证券账号
 764        :return: 返回当前证券账号的资产数据
 765        """
 766        req = XTQC.QueryCreditDetailReq()
 767        req.m_nAccountType = account.account_type
 768        req.m_strAccountID = account.account_id
 769        
 770        seq = self.async_client.nextSeq()
 771        return self.common_op_sync_with_seq(
 772            seq,
 773            (self.async_client.queryCreditDetailWithSeq, seq, req)
 774        )
 775    
 776    def query_credit_detail_async(self, account, callback):
 777        """
 778        :param account: 证券账号
 779        :return: 返回当前证券账号的资产数据
 780        """
 781        req = XTQC.QueryCreditDetailReq()
 782        req.m_nAccountType = account.account_type
 783        req.m_strAccountID = account.account_id
 784        
 785        seq = self.async_client.nextSeq()
 786        return self.common_op_async_with_seq(
 787            seq,
 788            (self.async_client.queryCreditDetailWithSeq, seq, req)
 789            , callback
 790        )
 791
 792    def query_stk_compacts(self, account):
 793        """
 794        :param account: 证券账号
 795        :return: 返回负债合约
 796        """
 797        req = XTQC.QueryStkCompactsReq()
 798        req.m_nAccountType = account.account_type
 799        req.m_strAccountID = account.account_id
 800        
 801        seq = self.async_client.nextSeq()
 802        return self.common_op_sync_with_seq(
 803            seq,
 804            (self.async_client.queryStkCompactsWithSeq, seq, req)
 805        )
 806    
 807    def query_stk_compacts_async(self, account, callback):
 808        """
 809        :param account: 证券账号
 810        :return: 返回负债合约
 811        """
 812        req = XTQC.QueryStkCompactsReq()
 813        req.m_nAccountType = account.account_type
 814        req.m_strAccountID = account.account_id
 815        
 816        seq = self.async_client.nextSeq()
 817        return self.common_op_async_with_seq(
 818            seq,
 819            (self.async_client.queryStkCompactsWithSeq, seq, req)
 820            , callback
 821        )
 822    
 823    def query_credit_subjects(self, account):
 824        """
 825        :param account: 证券账号
 826        :return: 返回融资融券标的
 827        """
 828        req = XTQC.QueryCreditSubjectsReq()
 829        req.m_nAccountType = account.account_type
 830        req.m_strAccountID = account.account_id
 831        
 832        seq = self.async_client.nextSeq()
 833        return self.common_op_sync_with_seq(
 834            seq,
 835            (self.async_client.queryCreditSubjectsWithSeq, seq, req)
 836        )
 837    
 838    def query_credit_subjects_async(self, account, callback):
 839        """
 840        :param account: 证券账号
 841        :return: 返回融资融券标的
 842        """
 843        req = XTQC.QueryCreditSubjectsReq()
 844        req.m_nAccountType = account.account_type
 845        req.m_strAccountID = account.account_id
 846        
 847        seq = self.async_client.nextSeq()
 848        return self.common_op_async_with_seq(
 849            seq,
 850            (self.async_client.queryCreditSubjectsWithSeq, seq, req)
 851            , callback
 852        )
 853    
 854    def query_credit_slo_code(self, account):
 855        """
 856        :param account: 证券账号
 857        :return: 返回可融券数据
 858        """
 859        req = XTQC.QueryCreditSloCodeReq()
 860        req.m_nAccountType = account.account_type
 861        req.m_strAccountID = account.account_id
 862        
 863        seq = self.async_client.nextSeq()
 864        return self.common_op_sync_with_seq(
 865            seq,
 866            (self.async_client.queryCreditSloCodeWithSeq, seq, req)
 867        )
 868    
 869    def query_credit_slo_code_async(self, account, callback):
 870        """
 871        :param account: 证券账号
 872        :return: 返回可融券数据
 873        """
 874        req = XTQC.QueryCreditSloCodeReq()
 875        req.m_nAccountType = account.account_type
 876        req.m_strAccountID = account.account_id
 877        
 878        seq = self.async_client.nextSeq()
 879        return self.common_op_async_with_seq(
 880            seq,
 881            (self.async_client.queryCreditSloCodeWithSeq, seq, req)
 882            , callback
 883        )
 884    
 885    def query_credit_assure(self, account):
 886        """
 887        :param account: 证券账号
 888        :return: 返回标的担保品
 889        """
 890        req = XTQC.QueryCreditAssureReq()
 891        req.m_nAccountType = account.account_type
 892        req.m_strAccountID = account.account_id
 893        
 894        seq = self.async_client.nextSeq()
 895        return self.common_op_sync_with_seq(
 896            seq,
 897            (self.async_client.queryCreditAssureWithSeq, seq, req)
 898        )
 899    
 900    def query_credit_assure_async(self, account, callback):
 901        """
 902        :param account: 证券账号
 903        :return: 返回标的担保品
 904        """
 905        req = XTQC.QueryCreditAssureReq()
 906        req.m_nAccountType = account.account_type
 907        req.m_strAccountID = account.account_id
 908        
 909        seq = self.async_client.nextSeq()
 910        return self.common_op_async_with_seq(
 911            seq,
 912            (self.async_client.queryCreditAssureWithSeq, seq, req)
 913            , callback
 914        )
 915    
 916    def query_new_purchase_limit(self, account):
 917        """
 918        :param account: 证券账号
 919        :return: 返回账户新股申购额度数据
 920        """
 921        req = XTQC.QueryNewPurchaseLimitReq()
 922        req.m_nAccountType = account.account_type
 923        req.m_strAccountID = account.account_id
 924        
 925        seq = self.async_client.nextSeq()
 926        new_purchase_limit_list = self.common_op_sync_with_seq(
 927            seq,
 928            (self.async_client.queryNewPurchaseLimitWithSeq, seq, req)
 929        )
 930        new_purchase_limit_result = dict()
 931        for item in new_purchase_limit_list:
 932            new_purchase_limit_result[item.m_strNewPurchaseLimitKey] = item.m_nNewPurchaseLimitValue
 933        return new_purchase_limit_result
 934        
 935    def query_new_purchase_limit_async(self, account, callback):
 936        """
 937        :param account: 证券账号
 938        :return: 返回账户新股申购额度数据
 939        """
 940        req = XTQC.QueryNewPurchaseLimitReq()
 941        req.m_nAccountType = account.account_type
 942        req.m_strAccountID = account.account_id
 943        
 944        seq = self.async_client.nextSeq()
 945        return self.common_op_async_with_seq(
 946            seq,
 947            (self.async_client.queryNewPurchaseLimitWithSeq, seq, req)
 948            , callback
 949        )
 950    
 951    def query_ipo_data(self):
 952        """
 953        :return: 返回新股新债信息
 954        """
 955        req = XTQC.QueryIPODataReq()
 956        req.m_strIPOType = ''
 957        
 958        seq = self.async_client.nextSeq()
 959        ipo_data_list = self.common_op_sync_with_seq(
 960            seq,
 961            (self.async_client.queryIPODataWithSeq, seq, req)
 962        )
 963        ipo_data_result = dict()
 964        for item in ipo_data_list:
 965            ipo_data_result[item.m_strIPOCode] = {
 966                'name': item.m_strIPOName, 
 967                'type':  item.m_strIPOType, 
 968                'maxPurchaseNum':  item.m_nMaxPurchaseNum, 
 969                'minPurchaseNum':  item.m_nMinPurchaseNum, 
 970                'purchaseDate':  item.m_strPurchaseDate, 
 971                'issuePrice': item.m_dIssuePrice,
 972            }
 973        return ipo_data_result
 974        
 975    def query_ipo_data_async(self, callback):
 976        """
 977        :return: 返回新股新债信息
 978        """
 979        req = XTQC.QueryIPODataReq()
 980        req.m_strIPOType = ''
 981        
 982        seq = self.async_client.nextSeq()
 983        return self.common_op_async_with_seq(
 984            seq,
 985            (self.async_client.queryIPODataWithSeq, seq, req)
 986            , callback
 987        )
 988    
 989    def query_appointment_info(self, account):
 990        """
 991        :param account: 证券账号
 992        :return: 返回约券合约信息
 993        """
 994        req = XTQC.QueryAppointmentInfoReq()
 995        req.m_nAccountType = 3
 996        req.m_strAccountID = account.account_id
 997        
 998        seq = self.async_client.nextSeq()
 999        appointment_info_list = self.common_op_sync_with_seq(
1000            seq,
1001            (self.async_client.queryAppointmentInfoWithSeq, seq, req)
1002        )      
1003        appointment_info_result = dict()
1004        for item in appointment_info_list:
1005            appointment_info_result[item.m_strCompactId] = {
1006                'success': item.m_bSuccess,
1007                'error': item.m_strError,
1008                'fundAccount': item.m_strFundAccount,
1009                'origCompactId': item.m_strOrigCompactId,
1010                'exchangeType': item.m_strExchangeType,
1011                'stockCode': item.m_strStockCode,
1012                'stockName': item.m_strStockName,
1013                'contractEndDate': item.m_nContractEndDate,
1014                'feeRatio': item.m_dFeeRatio,
1015                'compactTerm': item.m_nCompactTerm,
1016                'compactAmount': item.m_nCompactAmount,
1017                'compactRepayDate': item.m_nCompactRepayDate,
1018                'compactStatus': item.m_strCompactStatus,
1019                'positionStr': item.m_strPositionStr,
1020            }
1021        return appointment_info_result
1022    
1023    def query_appointment_info_async(self, account, callback):
1024        """
1025        :param account: 证券账号
1026        :return: 返回约券合约信息
1027        """
1028        req = XTQC.QueryAppointmentInfoReq()
1029        req.m_nAccountType = account.account_type
1030        req.m_strAccountID = account.account_id
1031        
1032        seq = self.async_client.nextSeq()
1033        return self.common_op_async_with_seq(
1034            seq,
1035            (self.async_client.queryAppointmentInfoWithSeq, seq, req)
1036            , callback
1037        )
1038
1039    def smt_appointment_async(self, account, stock_code, apt_days, apt_volume, fare_ratio, sub_rare_ratio, fine_ratio,
1040                          begin_date):
1041        """
1042        :param account: 证券账号
1043        :param stock_code: 证券代码, 例如"600000.SH"
1044        :param apt_days: 约定期限
1045        :param apt_volume: 约定数量
1046        :param fare_ratio: 约券费率
1047        :param sub_rare_ratio: 提前归还费率
1048        :param fine_ratio: 违约金率
1049        :param begin_date: 约定日期
1050        :return: 返回下单请求序号
1051        """
1052        req = XTQC.SmtAppointmentReq()
1053        req.m_strAccountID = account.account_id
1054        req.m_strStockCode = stock_code
1055        req.m_nAptDays = apt_days
1056        req.m_nVolume = apt_volume
1057        req.m_dFareRatio = fare_ratio
1058        req.m_dSubRareRatio = sub_rare_ratio
1059        req.m_dFineRatio = fine_ratio
1060        req.m_strBeginDate = begin_date
1061        
1062        
1063        seq = self.async_client.nextSeq()
1064        self.cbs[seq] = self.callback.on_smt_appointment_async_response
1065        self.async_client.smtAppointmentWithSeq(seq, req)
1066        return seq
1067       
1068    def query_smt_secu_info(self, account):
1069        """
1070        :param account: 证券账号
1071        :return: 返回券源券单信息
1072        """
1073        req = XTQC.QuerySMTSecuInfoReq()
1074        req.m_nAccountType = 3
1075        req.m_strAccountID = account.account_id
1076
1077        seq = self.async_client.nextSeq()
1078        smt_secu_info_list = self.common_op_sync_with_seq(
1079            seq,
1080            (self.async_client.querySMTSecuInfoWithSeq, seq, req)
1081        )
1082        smt_secu_info_result = dict()
1083        for item in smt_secu_info_list:
1084            stock = item.m_strStockCode + '.' +item.m_strExchangeType
1085            smt_secu_info_result[stock] = {
1086                'success': item.m_bSuccess, 
1087                'error':  item.m_strError, 
1088                'stockName': item.m_strStockName,
1089                'creditType':  item.m_strCreditType, 
1090                'tradeType': item.m_strTradeType,
1091                'compactTerm': item.m_nCompactTerm,
1092                'maxTerm': item.m_nMaxTerm,
1093                'lendAmount': item.m_nLendAmount,
1094                'remark': item.m_strRemark,
1095                'fareWay': item.m_strFareWay,
1096                'fareRateNew': item.m_dFareRateNew,
1097            }
1098        return smt_secu_info_result
1099    
1100    def query_smt_secu_rate(self, account, stock_code, max_term, fare_way, credit_type, trade_type):
1101        """
1102        :param account: 证券账号
1103        :param stock_code: 证券代码, 例如"600000.SH"
1104        :param max_term: 最大约定期限
1105        :param fare_way: 折扣标志
1106        :param credit_type: 资券类型
1107        :param trade_type: 业务类型
1108        :return: 返回券源费率信息
1109        """
1110        req = XTQC.QuerySMTSecuRateReq()
1111        req.m_nAccountType = 3
1112        req.m_strAccountID = account.account_id
1113        req.m_strStockCode = stock_code
1114        req.m_nMaxTerm = max_term
1115        req.m_strFareWay = fare_way
1116        req.m_strCreditType = credit_type
1117        req.m_strTradeType = trade_type
1118        
1119        seq = self.async_client.nextSeq()
1120        smt_secu_rate_list = self.common_op_sync_with_seq(
1121            seq,
1122            (self.async_client.querySMTSecuRateWithSeq, seq, req)
1123        )
1124        smt_secu_rate_result = dict()
1125        if smt_secu_rate_list:
1126            item = smt_secu_rate_list[0]
1127            smt_secu_rate_result = {
1128                'success': item.m_bSuccess, 
1129                'error':  item.m_strError, 
1130                'fareRatio': item.m_dFareRatio,
1131                'subRareRatio': item.m_dSubRareRatio,
1132                'fineRatio': item.m_dFineRatio,
1133        }
1134        return smt_secu_rate_result
def title(s=None):
10def title(s = None):
11    import inspect
12    if not s:
13        s = inspect.stack()[1].function
14    print('-' * 33 + s + '-' * 33)
15    return
def cp(s=None):
17def cp(s = None):
18    import inspect
19    st = inspect.stack()
20    pos = {'title':st[1].function, 'line':st[1].lineno}
21    print('-' * 33 + f'{pos}, {s}' + '-' * 33)
22    return
class XtQuantTraderCallback:
 25class XtQuantTraderCallback(object):
 26    def on_connected(self):
 27        """
 28        连接成功推送
 29        """
 30        pass
 31        
 32    def on_disconnected(self):
 33        """
 34        连接断开推送
 35        """
 36        pass
 37
 38    def on_account_status(self, status):
 39        """
 40        :param status: XtAccountStatus对象
 41        :return:
 42        """
 43        pass
 44
 45    def on_stock_asset(self, asset):
 46        """
 47        :param asset: XtAsset对象
 48        :return:
 49        """
 50        pass
 51
 52    def on_stock_order(self, order):
 53        """
 54        :param order: XtOrder对象
 55        :return:
 56        """
 57        pass
 58
 59    def on_stock_trade(self, trade):
 60        """
 61        :param trade: XtTrade对象
 62        :return:
 63        """
 64        pass
 65
 66    def on_stock_position(self, position):
 67        """
 68        :param position: XtPosition对象
 69        :return:
 70        """
 71        pass
 72
 73    def on_order_error(self, order_error):
 74        """
 75        :param order_error: XtOrderError 对象
 76        :return:
 77        """
 78        pass
 79
 80    def on_cancel_error(self, cancel_error):
 81        """
 82        :param cancel_error:XtCancelError 对象
 83        :return:
 84        """
 85        pass
 86
 87    def on_order_stock_async_response(self, response):
 88        """
 89        :param response: XtOrderResponse 对象
 90        :return:
 91        """
 92        pass
 93    
 94    def on_smt_appointment_async_response(self, response):
 95        """
 96        :param response: XtAppointmentResponse 对象
 97        :return:
 98        """
 99        pass
100    
101    def on_cancel_order_stock_async_response(self, response):
102        """
103        :param response: XtCancelOrderResponse 对象
104        :return:
105        """
106        pass
def on_connected(self):
26    def on_connected(self):
27        """
28        连接成功推送
29        """
30        pass

连接成功推送

def on_disconnected(self):
32    def on_disconnected(self):
33        """
34        连接断开推送
35        """
36        pass

连接断开推送

def on_account_status(self, status):
38    def on_account_status(self, status):
39        """
40        :param status: XtAccountStatus对象
41        :return:
42        """
43        pass
Parameters
  • status: XtAccountStatus对象
Returns
def on_stock_asset(self, asset):
45    def on_stock_asset(self, asset):
46        """
47        :param asset: XtAsset对象
48        :return:
49        """
50        pass
Parameters
  • asset: XtAsset对象
Returns
def on_stock_order(self, order):
52    def on_stock_order(self, order):
53        """
54        :param order: XtOrder对象
55        :return:
56        """
57        pass
Parameters
  • order: XtOrder对象
Returns
def on_stock_trade(self, trade):
59    def on_stock_trade(self, trade):
60        """
61        :param trade: XtTrade对象
62        :return:
63        """
64        pass
Parameters
  • trade: XtTrade对象
Returns
def on_stock_position(self, position):
66    def on_stock_position(self, position):
67        """
68        :param position: XtPosition对象
69        :return:
70        """
71        pass
Parameters
  • position: XtPosition对象
Returns
def on_order_error(self, order_error):
73    def on_order_error(self, order_error):
74        """
75        :param order_error: XtOrderError 对象
76        :return:
77        """
78        pass
Parameters
  • order_error: XtOrderError 对象
Returns
def on_cancel_error(self, cancel_error):
80    def on_cancel_error(self, cancel_error):
81        """
82        :param cancel_error:XtCancelError 对象
83        :return:
84        """
85        pass
Parameters
  • cancel_error: XtCancelError 对象
Returns
def on_order_stock_async_response(self, response):
87    def on_order_stock_async_response(self, response):
88        """
89        :param response: XtOrderResponse 对象
90        :return:
91        """
92        pass
Parameters
  • response: XtOrderResponse 对象
Returns
def on_smt_appointment_async_response(self, response):
94    def on_smt_appointment_async_response(self, response):
95        """
96        :param response: XtAppointmentResponse 对象
97        :return:
98        """
99        pass
Parameters
  • response: XtAppointmentResponse 对象
Returns
def on_cancel_order_stock_async_response(self, response):
101    def on_cancel_order_stock_async_response(self, response):
102        """
103        :param response: XtCancelOrderResponse 对象
104        :return:
105        """
106        pass
Parameters
  • response: XtCancelOrderResponse 对象
Returns
class XtQuantTrader:
 108class XtQuantTrader(object):
 109    def __init__(self, path, session, callback=None):
 110        """
 111        :param path: mini版迅投极速交易客户端安装路径下,userdata文件夹具体路径
 112        :param session: 当前任务执行所属的会话id
 113        :param callback: 回调方法
 114        """
 115        self.async_client = XTQC.XtQuantAsyncClient(path.encode('gb18030'), 'xtquant', session)
 116        self.callback = callback
 117
 118        self.connected = False
 119
 120        self.oldloop = asyncio.get_event_loop()
 121        self.loop = asyncio.new_event_loop()
 122        asyncio.set_event_loop(self.loop)
 123        self.cbs = {}
 124
 125        self.executor = None
 126        self.resp_executor = None
 127
 128        self.relaxed_resp_order_enabled = False
 129        self.relaxed_resp_executor = None
 130
 131        self.handled_async_order_stock_order_id = set()
 132        self.sync_order_stock_order_id = set()
 133        self.queuing_order_errors = {}
 134
 135        self.handled_async_smt_appointment_order_id = set()
 136        self.sync_smt_appointment_order_id = set()
 137         
 138        self.handled_async_cancel_order_stock_order_id = set()
 139        self.handled_async_cancel_order_stock_order_sys_id = set()
 140        self.handled_sync_cancel_order_stock_order_id = set()
 141        self.handled_sync_cancel_order_stock_order_sys_id = set()
 142        self.queuing_cancel_errors_by_order_id = {}
 143        self.queuing_cancel_errors_by_order_sys_id = {}
 144        
 145        
 146    #########################
 147        #push
 148        def on_common_push_callback_wrapper(argc, callback):
 149            if argc == 0:
 150                def on_push_data():
 151                    self.executor.submit(callback)
 152                return on_push_data
 153            elif argc == 1:
 154                def on_push_data(data):
 155                    self.executor.submit(callback, data)
 156                return on_push_data
 157            elif argc == 2:
 158                def on_push_data(data1, data2):
 159                    self.executor.submit(callback, data1, data2)
 160                return on_push_data
 161            else:
 162                return None
 163        
 164        #response
 165        def on_common_resp_callback(seq, resp):
 166            callback = self.cbs.pop(seq, None)
 167            if callback:
 168                self.resp_executor.submit(callback, resp)
 169            return
 170        
 171        self.async_client.bindOnSubscribeRespCallback(on_common_resp_callback)
 172        self.async_client.bindOnUnsubscribeRespCallback(on_common_resp_callback)
 173        self.async_client.bindOnQueryStockAssetCallback(on_common_resp_callback)
 174        self.async_client.bindOnQueryStockOrdersCallback(on_common_resp_callback)
 175        self.async_client.bindOnQueryStockTradesCallback(on_common_resp_callback)
 176        self.async_client.bindOnQueryStockPositionsCallback(on_common_resp_callback)
 177        self.async_client.bindOnQueryCreditDetailRespCallback(on_common_resp_callback)
 178        self.async_client.bindOnQueryStkCompactsRespCallback(on_common_resp_callback)
 179        self.async_client.bindOnQueryCreditSubjectsRespCallback(on_common_resp_callback)
 180        self.async_client.bindOnQueryCreditSloCodeRespCallback(on_common_resp_callback)
 181        self.async_client.bindOnQueryCreditAssureRespCallback(on_common_resp_callback)
 182        self.async_client.bindOnQueryNewPurchaseLimitCallback(on_common_resp_callback)
 183        self.async_client.bindOnQueryIPODataCallback(on_common_resp_callback)
 184        self.async_client.bindOnQueryAppointmentInfoRespCallback(on_common_resp_callback)
 185        self.async_client.bindOnQuerySMTSecuInfoRespCallback(on_common_resp_callback)
 186        self.async_client.bindOnQuerySMTSecuRateRespCallback(on_common_resp_callback)
 187        
 188        self.async_client.bindOnQueryAccountInfosCallback(on_common_resp_callback)
 189        self.async_client.bindOnQueryAccountStatusCallback(on_common_resp_callback)
 190    #########################
 191        
 192        enable_push = 1
 193        
 194        #order push
 195        
 196        def on_push_SmtAppointmentAsyncResponse(seq, resp):
 197            callback = self.cbs.pop(seq, None)
 198            if callback:
 199                resp = xttype.XtAppointmentResponse(resp.m_strAccountID, resp.m_nOrderID, resp.m_nErrorID, resp.m_strErrorMsg, seq)
 200                callback(resp)
 201                self.handled_async_smt_appointment_order_id.add(resp.order_id)
 202            return
 203        
 204        if enable_push:
 205            self.async_client.bindOnSmtAppointmentRespCallback(on_common_push_callback_wrapper(2, on_push_SmtAppointmentAsyncResponse))
 206        
 207        def on_push_OrderStockAsyncResponse(seq, resp):
 208            callback = self.cbs.pop(seq, None)
 209            if callback:
 210                resp = xttype.XtOrderResponse(resp.m_strAccountID, resp.m_nOrderID, resp.m_strStrategyName, resp.m_strOrderRemark, resp.m_strErrorMsg, seq)
 211                callback(resp)
 212                self.handled_async_order_stock_order_id.add(resp.order_id)
 213                e = self.queuing_order_errors.pop(resp.order_id, None)
 214                if e is not None:
 215                    self.callback.on_order_error(e)
 216                    self.handled_async_order_stock_order_id.discard(resp.order_id)
 217            return
 218        
 219        if enable_push:
 220            self.async_client.bindOnOrderStockRespCallback(on_common_push_callback_wrapper(2, on_push_OrderStockAsyncResponse))
 221        
 222        def on_push_CancelOrderStockAsyncResponse(seq, resp):
 223            callback = self.cbs.pop(seq, None)
 224            if callback:
 225                resp = xttype.XtCancelOrderResponse(resp.m_strAccountID, resp.m_nCancelResult, resp.m_nOrderID, resp.m_strOrderSysID, seq)
 226                callback(resp)
 227                
 228                if not resp.order_sysid:
 229                    self.handled_async_cancel_order_stock_order_id.add(resp.order_id)
 230                    e = self.queuing_cancel_errors_by_order_id.pop(resp.order_id, None)
 231                    if e is not None:
 232                        self.handled_async_cancel_order_stock_order_id.discard(resp.order_id)
 233                        self.callback.on_cancel_error(e)
 234                else:
 235                    self.handled_async_cancel_order_stock_order_sys_id.add(resp.order_sysid)
 236                    e = self.queuing_cancel_errors_by_order_sys_id.pop(resp.order_sysid, None)
 237                    if e is not None:
 238                        self.handled_async_cancel_order_stock_order_sys_id.discard(resp.order_sysid)
 239                        self.callback.on_cancel_error(e)
 240            return
 241        
 242        if enable_push:
 243            self.async_client.bindOnCancelOrderStockRespCallback(on_common_push_callback_wrapper(2, on_push_CancelOrderStockAsyncResponse))
 244            
 245        def on_push_disconnected():
 246            if self.callback:
 247                self.callback.on_disconnected()
 248
 249        if enable_push:
 250            self.async_client.bindOnDisconnectedCallback(on_common_push_callback_wrapper(0, on_push_disconnected))
 251
 252        def on_push_AccountStatus(data):
 253            data = xttype.XtAccountStatus(data.m_strAccountID, data.m_nAccountType, data.m_nStatus)
 254            self.callback.on_account_status(data)
 255
 256        if enable_push:
 257            self.async_client.bindOnUpdateAccountStatusCallback(on_common_push_callback_wrapper(1, on_push_AccountStatus))
 258
 259        def on_push_StockAsset(data):
 260            self.callback.on_stock_asset(data)
 261
 262        if enable_push:
 263            self.async_client.bindOnStockAssetCallback(on_common_push_callback_wrapper(1, on_push_StockAsset))
 264
 265        def on_push_OrderStock(data):
 266            self.callback.on_stock_order(data)
 267
 268        if enable_push:
 269            self.async_client.bindOnStockOrderCallback(on_common_push_callback_wrapper(1, on_push_OrderStock))
 270
 271        def on_push_StockTrade(data):
 272            self.callback.on_stock_trade(data)
 273
 274        if enable_push:
 275            self.async_client.bindOnStockTradeCallback(on_common_push_callback_wrapper(1, on_push_StockTrade))
 276
 277        def on_push_StockPosition(data):
 278            self.callback.on_stock_position(data)
 279
 280        if enable_push:
 281            self.async_client.bindOnStockPositionCallback(on_common_push_callback_wrapper(1, on_push_StockPosition))
 282
 283        def on_push_OrderError(data):
 284            if data.order_id in self.handled_async_order_stock_order_id or data.order_id in self.sync_order_stock_order_id:
 285                self.handled_async_order_stock_order_id.discard(data.order_id)
 286                self.sync_order_stock_order_id.discard(data.order_id)
 287                self.callback.on_order_error(data)
 288            else:
 289                self.queuing_order_errors[data.order_id] = data
 290
 291        if enable_push:
 292            self.async_client.bindOnOrderErrorCallback(on_common_push_callback_wrapper(1, on_push_OrderError))
 293
 294        def on_push_CancelError(data):
 295            if not data.order_sysid:
 296                if data.order_id in self.handled_async_cancel_order_stock_order_id or data.order_id in self.handled_sync_cancel_order_stock_order_id:
 297                    self.handled_async_cancel_order_stock_order_id.discard(data.order_id)
 298                    self.handled_sync_cancel_order_stock_order_id.discard(data.order_id)
 299                    self.callback.on_cancel_error(data)
 300                else:
 301                    self.queuing_cancel_errors_by_order_id[data.order_id] = data
 302            else:
 303                if data.order_sysid in self.handled_async_cancel_order_stock_order_sys_id or data.order_sysid in self.handled_sync_cancel_order_stock_order_sys_id:
 304                    self.handled_async_cancel_order_stock_order_sys_id.discard(data.order_sysid)
 305                    self.handled_sync_cancel_order_stock_order_sys_id.discard(data.order_sysid)
 306                    self.callback.on_cancel_error(data)
 307                else:
 308                    self.queuing_cancel_errors_by_order_sys_id[data.order_sysid] = data
 309
 310        if enable_push:
 311            self.async_client.bindOnCancelErrorCallback(on_common_push_callback_wrapper(1, on_push_CancelError))
 312        
 313    ########################
 314
 315    def common_op_async_with_seq(self, seq, callable, callback):
 316        self.cbs[seq] = callback
 317
 318        def apply(func, *args):
 319            return func(*args)
 320        apply(*callable)
 321
 322        return seq
 323
 324    def common_op_sync_with_seq(self, seq, callable):
 325        future = Future()
 326        self.cbs[seq] = lambda resp:future.set_result(resp)
 327
 328        def apply(func, *args):
 329            return func(*args)
 330        apply(*callable)
 331
 332        return future.result()
 333
 334    #########################
 335    
 336    
 337    def __del__(self):
 338        if hasattr(self, 'oldloop'):
 339            asyncio.set_event_loop(self.oldloop)
 340
 341    def register_callback(self, callback):
 342        self.callback = callback
 343
 344    def start(self):
 345        self.async_client.init()
 346        self.async_client.start()
 347        self.executor = ThreadPoolExecutor(max_workers = 1)
 348        self.relaxed_resp_executor = ThreadPoolExecutor(max_workers = 1)
 349        self.resp_executor = self.relaxed_resp_executor if self.relaxed_resp_order_enabled else self.executor
 350        return
 351
 352    def stop(self):
 353        self.async_client.stop()
 354        self.loop.call_soon_threadsafe(self.loop.stop)
 355        self.executor.shutdown(wait = True)
 356        self.relaxed_resp_executor.shutdown(wait = True)
 357        return
 358
 359    def connect(self):
 360        result = self.async_client.connect()
 361        self.connected = result == 0
 362        return result
 363
 364    def sleep(self, time):
 365        async def sleep_coroutine(time):
 366            await asyncio.sleep(time)
 367        asyncio.run_coroutine_threadsafe(sleep_coroutine(time), self.loop).result()
 368
 369    def run_forever(self):
 370        import time
 371        while True:
 372            time.sleep(0.2)
 373        return
 374
 375    def set_relaxed_response_order_enabled(self, enabled):
 376        self.relaxed_resp_order_enabled = enabled
 377        self.resp_executor = self.relaxed_resp_executor if self.relaxed_resp_order_enabled else self.executor
 378        return
 379
 380    def subscribe(self, account):
 381        req = XTQC.SubscribeReq()
 382        req.m_nAccountType = account.account_type
 383        req.m_strAccountID = account.account_id
 384        seq = self.async_client.nextSeq()
 385        return self.common_op_sync_with_seq(
 386            seq,
 387            (self.async_client.subscribeWithSeq, seq, req)
 388        )
 389
 390    def unsubscribe(self, account):
 391        req = XTQC.UnsubscribeReq()
 392        req.m_nAccountType = account.account_type
 393        req.m_strAccountID = account.account_id
 394        seq = self.async_client.nextSeq()
 395        return self.common_op_sync_with_seq(
 396            seq,
 397            (self.async_client.unsubscribeWithSeq, seq, req)
 398        )
 399
 400    def order_stock_async(self, account, stock_code, order_type, order_volume, price_type, price, strategy_name='',
 401                          order_remark=''):
 402        """
 403        :param account: 证券账号
 404        :param stock_code: 证券代码, 例如"600000.SH"
 405        :param order_type: 委托类型, 23:买, 24:卖
 406        :param order_volume: 委托数量, 股票以'股'为单位, 债券以'张'为单位
 407        :param price_type: 报价类型, 详见帮助手册
 408        :param price: 报价价格, 如果price_type为指定价, 那price为指定的价格, 否则填0
 409        :param strategy_name: 策略名称
 410        :param order_remark: 委托备注
 411        :return: 返回下单请求序号, 成功委托后的下单请求序号为大于0的正整数, 如果为-1表示委托失败
 412        """
 413        req = XTQC.OrderStockReq()
 414        req.m_nAccountType = account.account_type
 415        req.m_strAccountID = account.account_id
 416        req.m_strStockCode = stock_code
 417        req.m_nOrderType = order_type
 418        req.m_nOrderVolume = order_volume
 419        req.m_nPriceType = price_type
 420        req.m_dPrice = price
 421        req.m_strStrategyName = strategy_name
 422        req.m_strOrderRemark = order_remark
 423
 424        seq = self.async_client.nextSeq()
 425        self.cbs[seq] = self.callback.on_order_stock_async_response
 426        self.async_client.orderStockWithSeq(seq, req)
 427        return seq
 428
 429    def order_stock(self, account, stock_code, order_type, order_volume, price_type, price, strategy_name='',
 430                          order_remark=''):
 431        """
 432        :param account: 证券账号
 433        :param stock_code: 证券代码, 例如"600000.SH"
 434        :param order_type: 委托类型, 23:买, 24:卖
 435        :param order_volume: 委托数量, 股票以'股'为单位, 债券以'张'为单位
 436        :param price_type: 报价类型, 详见帮助手册
 437        :param price: 报价价格, 如果price_type为指定价, 那price为指定的价格, 否则填0
 438        :param strategy_name: 策略名称
 439        :param order_remark: 委托备注
 440        :return: 返回下单请求序号, 成功委托后的下单请求序号为大于0的正整数, 如果为-1表示委托失败
 441        """
 442        req = XTQC.OrderStockReq()
 443        req.m_nAccountType = account.account_type
 444        req.m_strAccountID = account.account_id
 445        req.m_strStockCode = stock_code
 446        req.m_nOrderType = order_type
 447        req.m_nOrderVolume = order_volume
 448        req.m_nPriceType = price_type
 449        req.m_dPrice = price
 450        req.m_strStrategyName = strategy_name
 451        req.m_strOrderRemark = order_remark
 452        
 453        seq = self.async_client.nextSeq()
 454        resp = self.common_op_sync_with_seq(
 455            seq,
 456            (self.async_client.orderStockWithSeq, seq, req)
 457        )
 458        self.sync_order_stock_order_id.add(resp.order_id)
 459        return resp.order_id
 460
 461    def cancel_order_stock(self, account, order_id):
 462        """
 463        :param account: 证券账号
 464        :param order_id: 委托编号, 报单时返回的编号
 465        :return: 返回撤单成功或者失败, 0:成功,  -1:委托已完成撤单失败, -2:未找到对应委托编号撤单失败, -3:账号未登陆撤单失败
 466        """
 467        req = XTQC.CancelOrderStockReq()
 468        req.m_nAccountType = account.account_type
 469        req.m_strAccountID = account.account_id
 470        req.m_nOrderID = order_id
 471        
 472        seq = self.async_client.nextSeq()
 473        resp = self.common_op_sync_with_seq(
 474            seq,
 475            (self.async_client.cancelOrderStockWithSeq, seq, req)
 476        )
 477        self.handled_sync_cancel_order_stock_order_id.add(resp.order_id)
 478        return resp.cancel_result
 479
 480    def cancel_order_stock_async(self, account, order_id):
 481        """
 482        :param account: 证券账号
 483        :param order_id: 委托编号, 报单时返回的编号
 484        :return: 返回撤单请求序号, 成功委托后的撤单请求序号为大于0的正整数, 如果为-1表示委托失败
 485        """
 486        req = XTQC.CancelOrderStockReq()
 487        req.m_nAccountType = account.account_type
 488        req.m_strAccountID = account.account_id
 489        req.m_nOrderID = order_id
 490        
 491        seq = self.async_client.nextSeq()
 492        self.cbs[seq] = self.callback.on_cancel_order_stock_async_response
 493        self.async_client.cancelOrderStockWithSeq(seq, req)
 494        return seq
 495
 496    def cancel_order_stock_sysid(self, account, market, sysid):
 497        """
 498        :param account:证券账号
 499        :param market: 交易市场 0:上海 1:深圳
 500        :param sysid: 柜台合同编号
 501        :return:返回撤单成功或者失败, 0:成功,  -1:撤单失败
 502        """
 503        req = XTQC.CancelOrderStockReq()
 504        req.m_nAccountType = account.account_type
 505        req.m_strAccountID = account.account_id
 506        req.m_nMarket = market
 507        req.m_strOrderSysID = sysid
 508        
 509        seq = self.async_client.nextSeq()
 510        resp = self.common_op_sync_with_seq(
 511            seq,
 512            (self.async_client.cancelOrderStockWithSeq, seq, req)
 513        )
 514        self.handled_sync_cancel_order_stock_order_sys_id.add(resp.order_sysid)
 515        return resp.cancel_result
 516
 517    def cancel_order_stock_sysid_async(self, account, market, sysid):
 518        """
 519        :param account:证券账号
 520        :param market: 交易市场 0:上海 1:深圳
 521        :param sysid: 柜台编号
 522        :return:返回撤单请求序号, 成功委托后的撤单请求序号为大于0的正整数, 如果为-1表示委托失败
 523        """
 524        req = XTQC.CancelOrderStockReq()
 525        req.m_nAccountType = account.account_type
 526        req.m_strAccountID = account.account_id
 527        req.m_nMarket = market
 528        req.m_strOrderSysID = sysid
 529        
 530        seq = self.async_client.nextSeq()
 531        self.cbs[seq] = self.callback.on_cancel_order_stock_async_response
 532        self.async_client.cancelOrderStockWithSeq(seq, req)
 533        return seq
 534
 535    def query_account_infos(self):
 536        """
 537        :return: 返回账号列表
 538        """
 539        req = XTQC.QueryAccountInfosReq()
 540        
 541        seq = self.async_client.nextSeq()
 542        return self.common_op_sync_with_seq(
 543            seq,
 544            (self.async_client.queryAccountInfosWithSeq, seq, req)
 545        )
 546        
 547    query_account_info = query_account_infos
 548    
 549    def query_account_infos_async(self, callback):
 550        """
 551        :return: 返回账号列表
 552        """
 553        req = XTQC.QueryAccountInfosReq()
 554        
 555        seq = self.async_client.nextSeq()
 556        return self.common_op_async_with_seq(
 557            seq,
 558            (self.async_client.queryAccountInfosWithSeq, seq, req)
 559            , callback
 560        )
 561        
 562    def query_account_status(self):
 563        """
 564        :return: 返回账号状态
 565        """
 566        req = XTQC.QueryAccountStatusReq()
 567        
 568        seq = self.async_client.nextSeq()
 569        return self.common_op_sync_with_seq(
 570            seq,
 571            (self.async_client.queryAccountStatusWithSeq, seq, req)
 572        )
 573    
 574    def query_account_status_async(self, callback):
 575        """
 576        :return: 返回账号状态
 577        """
 578        req = XTQC.QueryAccountStatusReq()
 579        
 580        seq = self.async_client.nextSeq()
 581        return self.common_op_async_with_seq(
 582            seq,
 583            (self.async_client.queryAccountStatusWithSeq, seq, req)
 584            , callback
 585        )
 586
 587    def query_stock_asset(self, account):
 588        """
 589        :param account: 证券账号
 590        :return: 返回当前证券账号的资产数据
 591        """
 592        req = XTQC.QueryStockAssetReq()
 593        req.m_nAccountType = account.account_type
 594        req.m_strAccountID = account.account_id
 595        
 596        seq = self.async_client.nextSeq()
 597        resp = self.common_op_sync_with_seq(
 598            seq,
 599            (self.async_client.queryStockAssetWithSeq, seq, req)
 600        )
 601
 602        if resp and len(resp):
 603            return resp[0]
 604        return None
 605    
 606    def query_stock_asset_async(self, account, callback):
 607        """
 608        :param account: 证券账号
 609        :return: 返回当前证券账号的资产数据
 610        """
 611        req = XTQC.QueryStockAssetReq()
 612        req.m_nAccountType = account.account_type
 613        req.m_strAccountID = account.account_id
 614        
 615        seq = self.async_client.nextSeq()
 616        def _cb(resp):
 617            callback(resp[0] if resp else None)
 618        resp = self.common_op_async_with_seq(
 619            seq,
 620            (self.async_client.queryStockAssetWithSeq, seq, req)
 621            , _cb
 622        )
 623        return
 624
 625    def query_stock_order(self, account, order_id):
 626        """
 627        :param account: 证券账号
 628        :param order_id:  订单编号,同步报单接口返回的编号
 629        :return: 返回订单编号对应的委托对象
 630        """
 631        req = XTQC.QueryStockOrdersReq()
 632        req.m_nAccountType = account.account_type
 633        req.m_strAccountID = account.account_id
 634        req.m_nOrderID = order_id
 635        
 636        seq = self.async_client.nextSeq()
 637        resp = self.common_op_sync_with_seq(
 638            seq,
 639            (self.async_client.queryStockOrdersWithSeq, seq, req)
 640        )
 641        if resp and len(resp):
 642            return resp[0]
 643        return None
 644
 645    def query_stock_orders(self, account, cancelable_only = False):
 646        """
 647        :param account: 证券账号
 648        :param cancelable_only: 仅查询可撤委托
 649        :return: 返回当日所有委托的委托对象组成的list
 650        """
 651        req = XTQC.QueryStockOrdersReq()
 652        req.m_nAccountType = account.account_type
 653        req.m_strAccountID = account.account_id
 654        req.m_bCanCancel = cancelable_only
 655        
 656        seq = self.async_client.nextSeq()
 657        return self.common_op_sync_with_seq(
 658            seq,
 659            (self.async_client.queryStockOrdersWithSeq, seq, req)
 660        )
 661    
 662    def query_stock_orders_async(self, account, callback, cancelable_only = False):
 663        """
 664        :param account: 证券账号
 665        :param cancelable_only: 仅查询可撤委托
 666        :return: 返回当日所有委托的委托对象组成的list
 667        """
 668        req = XTQC.QueryStockOrdersReq()
 669        req.m_nAccountType = account.account_type
 670        req.m_strAccountID = account.account_id
 671        req.m_bCanCancel = cancelable_only
 672        
 673        seq = self.async_client.nextSeq()
 674        return self.common_op_async_with_seq(
 675            seq,
 676            (self.async_client.queryStockOrdersWithSeq, seq, req)
 677            , callback
 678        )
 679    
 680    def query_stock_trades(self, account):
 681        """
 682        :param account:  证券账号
 683        :return:  返回当日所有成交的成交对象组成的list
 684        """
 685        req = XTQC.QueryStockTradesReq()
 686        req.m_nAccountType = account.account_type
 687        req.m_strAccountID = account.account_id
 688        
 689        seq = self.async_client.nextSeq()
 690        return self.common_op_sync_with_seq(
 691            seq,
 692            (self.async_client.queryStockTradesWithSeq, seq, req)
 693        )
 694    
 695    def query_stock_trades_async(self, account, callback):
 696        """
 697        :param account:  证券账号
 698        :return:  返回当日所有成交的成交对象组成的list
 699        """
 700        req = XTQC.QueryStockTradesReq()
 701        req.m_nAccountType = account.account_type
 702        req.m_strAccountID = account.account_id
 703        
 704        seq = self.async_client.nextSeq()
 705        return self.common_op_async_with_seq(
 706            seq,
 707            (self.async_client.queryStockTradesWithSeq, seq, req)
 708            , callback
 709        )
 710
 711    def query_stock_position(self, account, stock_code):
 712        """
 713        :param account: 证券账号
 714        :param stock_code: 证券代码, 例如"600000.SH"
 715        :return: 返回证券代码对应的持仓对象
 716        """
 717        req = XTQC.QueryStockPositionsReq()
 718        req.m_nAccountType = account.account_type
 719        req.m_strAccountID = account.account_id
 720        req.m_strStockCode = stock_code
 721        
 722        seq = self.async_client.nextSeq()
 723        resp = self.common_op_sync_with_seq(
 724            seq,
 725            (self.async_client.queryStockPositionsWithSeq, seq, req)
 726        )
 727        if resp and len(resp):
 728            return resp[0]
 729        return None
 730
 731    def query_stock_positions(self, account):
 732        """
 733        :param account: 证券账号
 734        :return: 返回当日所有持仓的持仓对象组成的list
 735        """
 736        req = XTQC.QueryStockPositionsReq()
 737        req.m_nAccountType = account.account_type
 738        req.m_strAccountID = account.account_id
 739        
 740        seq = self.async_client.nextSeq()
 741        return self.common_op_sync_with_seq(
 742            seq,
 743            (self.async_client.queryStockPositionsWithSeq, seq, req)
 744        )
 745    
 746    def query_stock_positions_async(self, account, callback):
 747        """
 748        :param account: 证券账号
 749        :return: 返回当日所有持仓的持仓对象组成的list
 750        """
 751        req = XTQC.QueryStockPositionsReq()
 752        req.m_nAccountType = account.account_type
 753        req.m_strAccountID = account.account_id
 754        
 755        seq = self.async_client.nextSeq()
 756        return self.common_op_async_with_seq(
 757            seq
 758            , (self.async_client.queryStockPositionsWithSeq, seq, req)
 759            , callback
 760        )
 761
 762    def query_credit_detail(self, account):
 763        """
 764        :param account: 证券账号
 765        :return: 返回当前证券账号的资产数据
 766        """
 767        req = XTQC.QueryCreditDetailReq()
 768        req.m_nAccountType = account.account_type
 769        req.m_strAccountID = account.account_id
 770        
 771        seq = self.async_client.nextSeq()
 772        return self.common_op_sync_with_seq(
 773            seq,
 774            (self.async_client.queryCreditDetailWithSeq, seq, req)
 775        )
 776    
 777    def query_credit_detail_async(self, account, callback):
 778        """
 779        :param account: 证券账号
 780        :return: 返回当前证券账号的资产数据
 781        """
 782        req = XTQC.QueryCreditDetailReq()
 783        req.m_nAccountType = account.account_type
 784        req.m_strAccountID = account.account_id
 785        
 786        seq = self.async_client.nextSeq()
 787        return self.common_op_async_with_seq(
 788            seq,
 789            (self.async_client.queryCreditDetailWithSeq, seq, req)
 790            , callback
 791        )
 792
 793    def query_stk_compacts(self, account):
 794        """
 795        :param account: 证券账号
 796        :return: 返回负债合约
 797        """
 798        req = XTQC.QueryStkCompactsReq()
 799        req.m_nAccountType = account.account_type
 800        req.m_strAccountID = account.account_id
 801        
 802        seq = self.async_client.nextSeq()
 803        return self.common_op_sync_with_seq(
 804            seq,
 805            (self.async_client.queryStkCompactsWithSeq, seq, req)
 806        )
 807    
 808    def query_stk_compacts_async(self, account, callback):
 809        """
 810        :param account: 证券账号
 811        :return: 返回负债合约
 812        """
 813        req = XTQC.QueryStkCompactsReq()
 814        req.m_nAccountType = account.account_type
 815        req.m_strAccountID = account.account_id
 816        
 817        seq = self.async_client.nextSeq()
 818        return self.common_op_async_with_seq(
 819            seq,
 820            (self.async_client.queryStkCompactsWithSeq, seq, req)
 821            , callback
 822        )
 823    
 824    def query_credit_subjects(self, account):
 825        """
 826        :param account: 证券账号
 827        :return: 返回融资融券标的
 828        """
 829        req = XTQC.QueryCreditSubjectsReq()
 830        req.m_nAccountType = account.account_type
 831        req.m_strAccountID = account.account_id
 832        
 833        seq = self.async_client.nextSeq()
 834        return self.common_op_sync_with_seq(
 835            seq,
 836            (self.async_client.queryCreditSubjectsWithSeq, seq, req)
 837        )
 838    
 839    def query_credit_subjects_async(self, account, callback):
 840        """
 841        :param account: 证券账号
 842        :return: 返回融资融券标的
 843        """
 844        req = XTQC.QueryCreditSubjectsReq()
 845        req.m_nAccountType = account.account_type
 846        req.m_strAccountID = account.account_id
 847        
 848        seq = self.async_client.nextSeq()
 849        return self.common_op_async_with_seq(
 850            seq,
 851            (self.async_client.queryCreditSubjectsWithSeq, seq, req)
 852            , callback
 853        )
 854    
 855    def query_credit_slo_code(self, account):
 856        """
 857        :param account: 证券账号
 858        :return: 返回可融券数据
 859        """
 860        req = XTQC.QueryCreditSloCodeReq()
 861        req.m_nAccountType = account.account_type
 862        req.m_strAccountID = account.account_id
 863        
 864        seq = self.async_client.nextSeq()
 865        return self.common_op_sync_with_seq(
 866            seq,
 867            (self.async_client.queryCreditSloCodeWithSeq, seq, req)
 868        )
 869    
 870    def query_credit_slo_code_async(self, account, callback):
 871        """
 872        :param account: 证券账号
 873        :return: 返回可融券数据
 874        """
 875        req = XTQC.QueryCreditSloCodeReq()
 876        req.m_nAccountType = account.account_type
 877        req.m_strAccountID = account.account_id
 878        
 879        seq = self.async_client.nextSeq()
 880        return self.common_op_async_with_seq(
 881            seq,
 882            (self.async_client.queryCreditSloCodeWithSeq, seq, req)
 883            , callback
 884        )
 885    
 886    def query_credit_assure(self, account):
 887        """
 888        :param account: 证券账号
 889        :return: 返回标的担保品
 890        """
 891        req = XTQC.QueryCreditAssureReq()
 892        req.m_nAccountType = account.account_type
 893        req.m_strAccountID = account.account_id
 894        
 895        seq = self.async_client.nextSeq()
 896        return self.common_op_sync_with_seq(
 897            seq,
 898            (self.async_client.queryCreditAssureWithSeq, seq, req)
 899        )
 900    
 901    def query_credit_assure_async(self, account, callback):
 902        """
 903        :param account: 证券账号
 904        :return: 返回标的担保品
 905        """
 906        req = XTQC.QueryCreditAssureReq()
 907        req.m_nAccountType = account.account_type
 908        req.m_strAccountID = account.account_id
 909        
 910        seq = self.async_client.nextSeq()
 911        return self.common_op_async_with_seq(
 912            seq,
 913            (self.async_client.queryCreditAssureWithSeq, seq, req)
 914            , callback
 915        )
 916    
 917    def query_new_purchase_limit(self, account):
 918        """
 919        :param account: 证券账号
 920        :return: 返回账户新股申购额度数据
 921        """
 922        req = XTQC.QueryNewPurchaseLimitReq()
 923        req.m_nAccountType = account.account_type
 924        req.m_strAccountID = account.account_id
 925        
 926        seq = self.async_client.nextSeq()
 927        new_purchase_limit_list = self.common_op_sync_with_seq(
 928            seq,
 929            (self.async_client.queryNewPurchaseLimitWithSeq, seq, req)
 930        )
 931        new_purchase_limit_result = dict()
 932        for item in new_purchase_limit_list:
 933            new_purchase_limit_result[item.m_strNewPurchaseLimitKey] = item.m_nNewPurchaseLimitValue
 934        return new_purchase_limit_result
 935        
 936    def query_new_purchase_limit_async(self, account, callback):
 937        """
 938        :param account: 证券账号
 939        :return: 返回账户新股申购额度数据
 940        """
 941        req = XTQC.QueryNewPurchaseLimitReq()
 942        req.m_nAccountType = account.account_type
 943        req.m_strAccountID = account.account_id
 944        
 945        seq = self.async_client.nextSeq()
 946        return self.common_op_async_with_seq(
 947            seq,
 948            (self.async_client.queryNewPurchaseLimitWithSeq, seq, req)
 949            , callback
 950        )
 951    
 952    def query_ipo_data(self):
 953        """
 954        :return: 返回新股新债信息
 955        """
 956        req = XTQC.QueryIPODataReq()
 957        req.m_strIPOType = ''
 958        
 959        seq = self.async_client.nextSeq()
 960        ipo_data_list = self.common_op_sync_with_seq(
 961            seq,
 962            (self.async_client.queryIPODataWithSeq, seq, req)
 963        )
 964        ipo_data_result = dict()
 965        for item in ipo_data_list:
 966            ipo_data_result[item.m_strIPOCode] = {
 967                'name': item.m_strIPOName, 
 968                'type':  item.m_strIPOType, 
 969                'maxPurchaseNum':  item.m_nMaxPurchaseNum, 
 970                'minPurchaseNum':  item.m_nMinPurchaseNum, 
 971                'purchaseDate':  item.m_strPurchaseDate, 
 972                'issuePrice': item.m_dIssuePrice,
 973            }
 974        return ipo_data_result
 975        
 976    def query_ipo_data_async(self, callback):
 977        """
 978        :return: 返回新股新债信息
 979        """
 980        req = XTQC.QueryIPODataReq()
 981        req.m_strIPOType = ''
 982        
 983        seq = self.async_client.nextSeq()
 984        return self.common_op_async_with_seq(
 985            seq,
 986            (self.async_client.queryIPODataWithSeq, seq, req)
 987            , callback
 988        )
 989    
 990    def query_appointment_info(self, account):
 991        """
 992        :param account: 证券账号
 993        :return: 返回约券合约信息
 994        """
 995        req = XTQC.QueryAppointmentInfoReq()
 996        req.m_nAccountType = 3
 997        req.m_strAccountID = account.account_id
 998        
 999        seq = self.async_client.nextSeq()
1000        appointment_info_list = self.common_op_sync_with_seq(
1001            seq,
1002            (self.async_client.queryAppointmentInfoWithSeq, seq, req)
1003        )      
1004        appointment_info_result = dict()
1005        for item in appointment_info_list:
1006            appointment_info_result[item.m_strCompactId] = {
1007                'success': item.m_bSuccess,
1008                'error': item.m_strError,
1009                'fundAccount': item.m_strFundAccount,
1010                'origCompactId': item.m_strOrigCompactId,
1011                'exchangeType': item.m_strExchangeType,
1012                'stockCode': item.m_strStockCode,
1013                'stockName': item.m_strStockName,
1014                'contractEndDate': item.m_nContractEndDate,
1015                'feeRatio': item.m_dFeeRatio,
1016                'compactTerm': item.m_nCompactTerm,
1017                'compactAmount': item.m_nCompactAmount,
1018                'compactRepayDate': item.m_nCompactRepayDate,
1019                'compactStatus': item.m_strCompactStatus,
1020                'positionStr': item.m_strPositionStr,
1021            }
1022        return appointment_info_result
1023    
1024    def query_appointment_info_async(self, account, callback):
1025        """
1026        :param account: 证券账号
1027        :return: 返回约券合约信息
1028        """
1029        req = XTQC.QueryAppointmentInfoReq()
1030        req.m_nAccountType = account.account_type
1031        req.m_strAccountID = account.account_id
1032        
1033        seq = self.async_client.nextSeq()
1034        return self.common_op_async_with_seq(
1035            seq,
1036            (self.async_client.queryAppointmentInfoWithSeq, seq, req)
1037            , callback
1038        )
1039
1040    def smt_appointment_async(self, account, stock_code, apt_days, apt_volume, fare_ratio, sub_rare_ratio, fine_ratio,
1041                          begin_date):
1042        """
1043        :param account: 证券账号
1044        :param stock_code: 证券代码, 例如"600000.SH"
1045        :param apt_days: 约定期限
1046        :param apt_volume: 约定数量
1047        :param fare_ratio: 约券费率
1048        :param sub_rare_ratio: 提前归还费率
1049        :param fine_ratio: 违约金率
1050        :param begin_date: 约定日期
1051        :return: 返回下单请求序号
1052        """
1053        req = XTQC.SmtAppointmentReq()
1054        req.m_strAccountID = account.account_id
1055        req.m_strStockCode = stock_code
1056        req.m_nAptDays = apt_days
1057        req.m_nVolume = apt_volume
1058        req.m_dFareRatio = fare_ratio
1059        req.m_dSubRareRatio = sub_rare_ratio
1060        req.m_dFineRatio = fine_ratio
1061        req.m_strBeginDate = begin_date
1062        
1063        
1064        seq = self.async_client.nextSeq()
1065        self.cbs[seq] = self.callback.on_smt_appointment_async_response
1066        self.async_client.smtAppointmentWithSeq(seq, req)
1067        return seq
1068       
1069    def query_smt_secu_info(self, account):
1070        """
1071        :param account: 证券账号
1072        :return: 返回券源券单信息
1073        """
1074        req = XTQC.QuerySMTSecuInfoReq()
1075        req.m_nAccountType = 3
1076        req.m_strAccountID = account.account_id
1077
1078        seq = self.async_client.nextSeq()
1079        smt_secu_info_list = self.common_op_sync_with_seq(
1080            seq,
1081            (self.async_client.querySMTSecuInfoWithSeq, seq, req)
1082        )
1083        smt_secu_info_result = dict()
1084        for item in smt_secu_info_list:
1085            stock = item.m_strStockCode + '.' +item.m_strExchangeType
1086            smt_secu_info_result[stock] = {
1087                'success': item.m_bSuccess, 
1088                'error':  item.m_strError, 
1089                'stockName': item.m_strStockName,
1090                'creditType':  item.m_strCreditType, 
1091                'tradeType': item.m_strTradeType,
1092                'compactTerm': item.m_nCompactTerm,
1093                'maxTerm': item.m_nMaxTerm,
1094                'lendAmount': item.m_nLendAmount,
1095                'remark': item.m_strRemark,
1096                'fareWay': item.m_strFareWay,
1097                'fareRateNew': item.m_dFareRateNew,
1098            }
1099        return smt_secu_info_result
1100    
1101    def query_smt_secu_rate(self, account, stock_code, max_term, fare_way, credit_type, trade_type):
1102        """
1103        :param account: 证券账号
1104        :param stock_code: 证券代码, 例如"600000.SH"
1105        :param max_term: 最大约定期限
1106        :param fare_way: 折扣标志
1107        :param credit_type: 资券类型
1108        :param trade_type: 业务类型
1109        :return: 返回券源费率信息
1110        """
1111        req = XTQC.QuerySMTSecuRateReq()
1112        req.m_nAccountType = 3
1113        req.m_strAccountID = account.account_id
1114        req.m_strStockCode = stock_code
1115        req.m_nMaxTerm = max_term
1116        req.m_strFareWay = fare_way
1117        req.m_strCreditType = credit_type
1118        req.m_strTradeType = trade_type
1119        
1120        seq = self.async_client.nextSeq()
1121        smt_secu_rate_list = self.common_op_sync_with_seq(
1122            seq,
1123            (self.async_client.querySMTSecuRateWithSeq, seq, req)
1124        )
1125        smt_secu_rate_result = dict()
1126        if smt_secu_rate_list:
1127            item = smt_secu_rate_list[0]
1128            smt_secu_rate_result = {
1129                'success': item.m_bSuccess, 
1130                'error':  item.m_strError, 
1131                'fareRatio': item.m_dFareRatio,
1132                'subRareRatio': item.m_dSubRareRatio,
1133                'fineRatio': item.m_dFineRatio,
1134        }
1135        return smt_secu_rate_result
XtQuantTrader(path, session, callback=None)
109    def __init__(self, path, session, callback=None):
110        """
111        :param path: mini版迅投极速交易客户端安装路径下,userdata文件夹具体路径
112        :param session: 当前任务执行所属的会话id
113        :param callback: 回调方法
114        """
115        self.async_client = XTQC.XtQuantAsyncClient(path.encode('gb18030'), 'xtquant', session)
116        self.callback = callback
117
118        self.connected = False
119
120        self.oldloop = asyncio.get_event_loop()
121        self.loop = asyncio.new_event_loop()
122        asyncio.set_event_loop(self.loop)
123        self.cbs = {}
124
125        self.executor = None
126        self.resp_executor = None
127
128        self.relaxed_resp_order_enabled = False
129        self.relaxed_resp_executor = None
130
131        self.handled_async_order_stock_order_id = set()
132        self.sync_order_stock_order_id = set()
133        self.queuing_order_errors = {}
134
135        self.handled_async_smt_appointment_order_id = set()
136        self.sync_smt_appointment_order_id = set()
137         
138        self.handled_async_cancel_order_stock_order_id = set()
139        self.handled_async_cancel_order_stock_order_sys_id = set()
140        self.handled_sync_cancel_order_stock_order_id = set()
141        self.handled_sync_cancel_order_stock_order_sys_id = set()
142        self.queuing_cancel_errors_by_order_id = {}
143        self.queuing_cancel_errors_by_order_sys_id = {}
144        
145        
146    #########################
147        #push
148        def on_common_push_callback_wrapper(argc, callback):
149            if argc == 0:
150                def on_push_data():
151                    self.executor.submit(callback)
152                return on_push_data
153            elif argc == 1:
154                def on_push_data(data):
155                    self.executor.submit(callback, data)
156                return on_push_data
157            elif argc == 2:
158                def on_push_data(data1, data2):
159                    self.executor.submit(callback, data1, data2)
160                return on_push_data
161            else:
162                return None
163        
164        #response
165        def on_common_resp_callback(seq, resp):
166            callback = self.cbs.pop(seq, None)
167            if callback:
168                self.resp_executor.submit(callback, resp)
169            return
170        
171        self.async_client.bindOnSubscribeRespCallback(on_common_resp_callback)
172        self.async_client.bindOnUnsubscribeRespCallback(on_common_resp_callback)
173        self.async_client.bindOnQueryStockAssetCallback(on_common_resp_callback)
174        self.async_client.bindOnQueryStockOrdersCallback(on_common_resp_callback)
175        self.async_client.bindOnQueryStockTradesCallback(on_common_resp_callback)
176        self.async_client.bindOnQueryStockPositionsCallback(on_common_resp_callback)
177        self.async_client.bindOnQueryCreditDetailRespCallback(on_common_resp_callback)
178        self.async_client.bindOnQueryStkCompactsRespCallback(on_common_resp_callback)
179        self.async_client.bindOnQueryCreditSubjectsRespCallback(on_common_resp_callback)
180        self.async_client.bindOnQueryCreditSloCodeRespCallback(on_common_resp_callback)
181        self.async_client.bindOnQueryCreditAssureRespCallback(on_common_resp_callback)
182        self.async_client.bindOnQueryNewPurchaseLimitCallback(on_common_resp_callback)
183        self.async_client.bindOnQueryIPODataCallback(on_common_resp_callback)
184        self.async_client.bindOnQueryAppointmentInfoRespCallback(on_common_resp_callback)
185        self.async_client.bindOnQuerySMTSecuInfoRespCallback(on_common_resp_callback)
186        self.async_client.bindOnQuerySMTSecuRateRespCallback(on_common_resp_callback)
187        
188        self.async_client.bindOnQueryAccountInfosCallback(on_common_resp_callback)
189        self.async_client.bindOnQueryAccountStatusCallback(on_common_resp_callback)
190    #########################
191        
192        enable_push = 1
193        
194        #order push
195        
196        def on_push_SmtAppointmentAsyncResponse(seq, resp):
197            callback = self.cbs.pop(seq, None)
198            if callback:
199                resp = xttype.XtAppointmentResponse(resp.m_strAccountID, resp.m_nOrderID, resp.m_nErrorID, resp.m_strErrorMsg, seq)
200                callback(resp)
201                self.handled_async_smt_appointment_order_id.add(resp.order_id)
202            return
203        
204        if enable_push:
205            self.async_client.bindOnSmtAppointmentRespCallback(on_common_push_callback_wrapper(2, on_push_SmtAppointmentAsyncResponse))
206        
207        def on_push_OrderStockAsyncResponse(seq, resp):
208            callback = self.cbs.pop(seq, None)
209            if callback:
210                resp = xttype.XtOrderResponse(resp.m_strAccountID, resp.m_nOrderID, resp.m_strStrategyName, resp.m_strOrderRemark, resp.m_strErrorMsg, seq)
211                callback(resp)
212                self.handled_async_order_stock_order_id.add(resp.order_id)
213                e = self.queuing_order_errors.pop(resp.order_id, None)
214                if e is not None:
215                    self.callback.on_order_error(e)
216                    self.handled_async_order_stock_order_id.discard(resp.order_id)
217            return
218        
219        if enable_push:
220            self.async_client.bindOnOrderStockRespCallback(on_common_push_callback_wrapper(2, on_push_OrderStockAsyncResponse))
221        
222        def on_push_CancelOrderStockAsyncResponse(seq, resp):
223            callback = self.cbs.pop(seq, None)
224            if callback:
225                resp = xttype.XtCancelOrderResponse(resp.m_strAccountID, resp.m_nCancelResult, resp.m_nOrderID, resp.m_strOrderSysID, seq)
226                callback(resp)
227                
228                if not resp.order_sysid:
229                    self.handled_async_cancel_order_stock_order_id.add(resp.order_id)
230                    e = self.queuing_cancel_errors_by_order_id.pop(resp.order_id, None)
231                    if e is not None:
232                        self.handled_async_cancel_order_stock_order_id.discard(resp.order_id)
233                        self.callback.on_cancel_error(e)
234                else:
235                    self.handled_async_cancel_order_stock_order_sys_id.add(resp.order_sysid)
236                    e = self.queuing_cancel_errors_by_order_sys_id.pop(resp.order_sysid, None)
237                    if e is not None:
238                        self.handled_async_cancel_order_stock_order_sys_id.discard(resp.order_sysid)
239                        self.callback.on_cancel_error(e)
240            return
241        
242        if enable_push:
243            self.async_client.bindOnCancelOrderStockRespCallback(on_common_push_callback_wrapper(2, on_push_CancelOrderStockAsyncResponse))
244            
245        def on_push_disconnected():
246            if self.callback:
247                self.callback.on_disconnected()
248
249        if enable_push:
250            self.async_client.bindOnDisconnectedCallback(on_common_push_callback_wrapper(0, on_push_disconnected))
251
252        def on_push_AccountStatus(data):
253            data = xttype.XtAccountStatus(data.m_strAccountID, data.m_nAccountType, data.m_nStatus)
254            self.callback.on_account_status(data)
255
256        if enable_push:
257            self.async_client.bindOnUpdateAccountStatusCallback(on_common_push_callback_wrapper(1, on_push_AccountStatus))
258
259        def on_push_StockAsset(data):
260            self.callback.on_stock_asset(data)
261
262        if enable_push:
263            self.async_client.bindOnStockAssetCallback(on_common_push_callback_wrapper(1, on_push_StockAsset))
264
265        def on_push_OrderStock(data):
266            self.callback.on_stock_order(data)
267
268        if enable_push:
269            self.async_client.bindOnStockOrderCallback(on_common_push_callback_wrapper(1, on_push_OrderStock))
270
271        def on_push_StockTrade(data):
272            self.callback.on_stock_trade(data)
273
274        if enable_push:
275            self.async_client.bindOnStockTradeCallback(on_common_push_callback_wrapper(1, on_push_StockTrade))
276
277        def on_push_StockPosition(data):
278            self.callback.on_stock_position(data)
279
280        if enable_push:
281            self.async_client.bindOnStockPositionCallback(on_common_push_callback_wrapper(1, on_push_StockPosition))
282
283        def on_push_OrderError(data):
284            if data.order_id in self.handled_async_order_stock_order_id or data.order_id in self.sync_order_stock_order_id:
285                self.handled_async_order_stock_order_id.discard(data.order_id)
286                self.sync_order_stock_order_id.discard(data.order_id)
287                self.callback.on_order_error(data)
288            else:
289                self.queuing_order_errors[data.order_id] = data
290
291        if enable_push:
292            self.async_client.bindOnOrderErrorCallback(on_common_push_callback_wrapper(1, on_push_OrderError))
293
294        def on_push_CancelError(data):
295            if not data.order_sysid:
296                if data.order_id in self.handled_async_cancel_order_stock_order_id or data.order_id in self.handled_sync_cancel_order_stock_order_id:
297                    self.handled_async_cancel_order_stock_order_id.discard(data.order_id)
298                    self.handled_sync_cancel_order_stock_order_id.discard(data.order_id)
299                    self.callback.on_cancel_error(data)
300                else:
301                    self.queuing_cancel_errors_by_order_id[data.order_id] = data
302            else:
303                if data.order_sysid in self.handled_async_cancel_order_stock_order_sys_id or data.order_sysid in self.handled_sync_cancel_order_stock_order_sys_id:
304                    self.handled_async_cancel_order_stock_order_sys_id.discard(data.order_sysid)
305                    self.handled_sync_cancel_order_stock_order_sys_id.discard(data.order_sysid)
306                    self.callback.on_cancel_error(data)
307                else:
308                    self.queuing_cancel_errors_by_order_sys_id[data.order_sysid] = data
309
310        if enable_push:
311            self.async_client.bindOnCancelErrorCallback(on_common_push_callback_wrapper(1, on_push_CancelError))
Parameters
  • path: mini版迅投极速交易客户端安装路径下,userdata文件夹具体路径
  • session: 当前任务执行所属的会话id
  • callback: 回调方法
async_client
callback
connected
oldloop
loop
cbs
executor
resp_executor
relaxed_resp_order_enabled
relaxed_resp_executor
handled_async_order_stock_order_id
sync_order_stock_order_id
queuing_order_errors
handled_async_smt_appointment_order_id
sync_smt_appointment_order_id
handled_async_cancel_order_stock_order_id
handled_async_cancel_order_stock_order_sys_id
handled_sync_cancel_order_stock_order_id
handled_sync_cancel_order_stock_order_sys_id
queuing_cancel_errors_by_order_id
queuing_cancel_errors_by_order_sys_id
def common_op_async_with_seq(self, seq, callable, callback):
315    def common_op_async_with_seq(self, seq, callable, callback):
316        self.cbs[seq] = callback
317
318        def apply(func, *args):
319            return func(*args)
320        apply(*callable)
321
322        return seq
def common_op_sync_with_seq(self, seq, callable):
324    def common_op_sync_with_seq(self, seq, callable):
325        future = Future()
326        self.cbs[seq] = lambda resp:future.set_result(resp)
327
328        def apply(func, *args):
329            return func(*args)
330        apply(*callable)
331
332        return future.result()
def register_callback(self, callback):
341    def register_callback(self, callback):
342        self.callback = callback
def start(self):
344    def start(self):
345        self.async_client.init()
346        self.async_client.start()
347        self.executor = ThreadPoolExecutor(max_workers = 1)
348        self.relaxed_resp_executor = ThreadPoolExecutor(max_workers = 1)
349        self.resp_executor = self.relaxed_resp_executor if self.relaxed_resp_order_enabled else self.executor
350        return
def stop(self):
352    def stop(self):
353        self.async_client.stop()
354        self.loop.call_soon_threadsafe(self.loop.stop)
355        self.executor.shutdown(wait = True)
356        self.relaxed_resp_executor.shutdown(wait = True)
357        return
def connect(self):
359    def connect(self):
360        result = self.async_client.connect()
361        self.connected = result == 0
362        return result
def sleep(self, time):
364    def sleep(self, time):
365        async def sleep_coroutine(time):
366            await asyncio.sleep(time)
367        asyncio.run_coroutine_threadsafe(sleep_coroutine(time), self.loop).result()
def run_forever(self):
369    def run_forever(self):
370        import time
371        while True:
372            time.sleep(0.2)
373        return
def set_relaxed_response_order_enabled(self, enabled):
375    def set_relaxed_response_order_enabled(self, enabled):
376        self.relaxed_resp_order_enabled = enabled
377        self.resp_executor = self.relaxed_resp_executor if self.relaxed_resp_order_enabled else self.executor
378        return
def subscribe(self, account):
380    def subscribe(self, account):
381        req = XTQC.SubscribeReq()
382        req.m_nAccountType = account.account_type
383        req.m_strAccountID = account.account_id
384        seq = self.async_client.nextSeq()
385        return self.common_op_sync_with_seq(
386            seq,
387            (self.async_client.subscribeWithSeq, seq, req)
388        )
def unsubscribe(self, account):
390    def unsubscribe(self, account):
391        req = XTQC.UnsubscribeReq()
392        req.m_nAccountType = account.account_type
393        req.m_strAccountID = account.account_id
394        seq = self.async_client.nextSeq()
395        return self.common_op_sync_with_seq(
396            seq,
397            (self.async_client.unsubscribeWithSeq, seq, req)
398        )
def order_stock_async( self, account, stock_code, order_type, order_volume, price_type, price, strategy_name='', order_remark=''):
400    def order_stock_async(self, account, stock_code, order_type, order_volume, price_type, price, strategy_name='',
401                          order_remark=''):
402        """
403        :param account: 证券账号
404        :param stock_code: 证券代码, 例如"600000.SH"
405        :param order_type: 委托类型, 23:买, 24:卖
406        :param order_volume: 委托数量, 股票以'股'为单位, 债券以'张'为单位
407        :param price_type: 报价类型, 详见帮助手册
408        :param price: 报价价格, 如果price_type为指定价, 那price为指定的价格, 否则填0
409        :param strategy_name: 策略名称
410        :param order_remark: 委托备注
411        :return: 返回下单请求序号, 成功委托后的下单请求序号为大于0的正整数, 如果为-1表示委托失败
412        """
413        req = XTQC.OrderStockReq()
414        req.m_nAccountType = account.account_type
415        req.m_strAccountID = account.account_id
416        req.m_strStockCode = stock_code
417        req.m_nOrderType = order_type
418        req.m_nOrderVolume = order_volume
419        req.m_nPriceType = price_type
420        req.m_dPrice = price
421        req.m_strStrategyName = strategy_name
422        req.m_strOrderRemark = order_remark
423
424        seq = self.async_client.nextSeq()
425        self.cbs[seq] = self.callback.on_order_stock_async_response
426        self.async_client.orderStockWithSeq(seq, req)
427        return seq
Parameters
  • account: 证券账号
  • stock_code: 证券代码, 例如"600000.SH"
  • order_type: 委托类型, 23:买, 24: 卖
  • order_volume: 委托数量, 股票以'股'为单位, 债券以'张'为单位
  • price_type: 报价类型, 详见帮助手册
  • price: 报价价格, 如果price_type为指定价, 那price为指定的价格, 否则填0
  • strategy_name: 策略名称
  • order_remark: 委托备注
Returns

返回下单请求序号, 成功委托后的下单请求序号为大于0的正整数, 如果为-1表示委托失败

def order_stock( self, account, stock_code, order_type, order_volume, price_type, price, strategy_name='', order_remark=''):
429    def order_stock(self, account, stock_code, order_type, order_volume, price_type, price, strategy_name='',
430                          order_remark=''):
431        """
432        :param account: 证券账号
433        :param stock_code: 证券代码, 例如"600000.SH"
434        :param order_type: 委托类型, 23:买, 24:卖
435        :param order_volume: 委托数量, 股票以'股'为单位, 债券以'张'为单位
436        :param price_type: 报价类型, 详见帮助手册
437        :param price: 报价价格, 如果price_type为指定价, 那price为指定的价格, 否则填0
438        :param strategy_name: 策略名称
439        :param order_remark: 委托备注
440        :return: 返回下单请求序号, 成功委托后的下单请求序号为大于0的正整数, 如果为-1表示委托失败
441        """
442        req = XTQC.OrderStockReq()
443        req.m_nAccountType = account.account_type
444        req.m_strAccountID = account.account_id
445        req.m_strStockCode = stock_code
446        req.m_nOrderType = order_type
447        req.m_nOrderVolume = order_volume
448        req.m_nPriceType = price_type
449        req.m_dPrice = price
450        req.m_strStrategyName = strategy_name
451        req.m_strOrderRemark = order_remark
452        
453        seq = self.async_client.nextSeq()
454        resp = self.common_op_sync_with_seq(
455            seq,
456            (self.async_client.orderStockWithSeq, seq, req)
457        )
458        self.sync_order_stock_order_id.add(resp.order_id)
459        return resp.order_id
Parameters
  • account: 证券账号
  • stock_code: 证券代码, 例如"600000.SH"
  • order_type: 委托类型, 23:买, 24: 卖
  • order_volume: 委托数量, 股票以'股'为单位, 债券以'张'为单位
  • price_type: 报价类型, 详见帮助手册
  • price: 报价价格, 如果price_type为指定价, 那price为指定的价格, 否则填0
  • strategy_name: 策略名称
  • order_remark: 委托备注
Returns

返回下单请求序号, 成功委托后的下单请求序号为大于0的正整数, 如果为-1表示委托失败

def cancel_order_stock(self, account, order_id):
461    def cancel_order_stock(self, account, order_id):
462        """
463        :param account: 证券账号
464        :param order_id: 委托编号, 报单时返回的编号
465        :return: 返回撤单成功或者失败, 0:成功,  -1:委托已完成撤单失败, -2:未找到对应委托编号撤单失败, -3:账号未登陆撤单失败
466        """
467        req = XTQC.CancelOrderStockReq()
468        req.m_nAccountType = account.account_type
469        req.m_strAccountID = account.account_id
470        req.m_nOrderID = order_id
471        
472        seq = self.async_client.nextSeq()
473        resp = self.common_op_sync_with_seq(
474            seq,
475            (self.async_client.cancelOrderStockWithSeq, seq, req)
476        )
477        self.handled_sync_cancel_order_stock_order_id.add(resp.order_id)
478        return resp.cancel_result
Parameters
  • account: 证券账号
  • order_id: 委托编号, 报单时返回的编号
Returns

返回撤单成功或者失败, 0:成功, -1:委托已完成撤单失败, -2:未找到对应委托编号撤单失败, -3:账号未登陆撤单失败

def cancel_order_stock_async(self, account, order_id):
480    def cancel_order_stock_async(self, account, order_id):
481        """
482        :param account: 证券账号
483        :param order_id: 委托编号, 报单时返回的编号
484        :return: 返回撤单请求序号, 成功委托后的撤单请求序号为大于0的正整数, 如果为-1表示委托失败
485        """
486        req = XTQC.CancelOrderStockReq()
487        req.m_nAccountType = account.account_type
488        req.m_strAccountID = account.account_id
489        req.m_nOrderID = order_id
490        
491        seq = self.async_client.nextSeq()
492        self.cbs[seq] = self.callback.on_cancel_order_stock_async_response
493        self.async_client.cancelOrderStockWithSeq(seq, req)
494        return seq
Parameters
  • account: 证券账号
  • order_id: 委托编号, 报单时返回的编号
Returns

返回撤单请求序号, 成功委托后的撤单请求序号为大于0的正整数, 如果为-1表示委托失败

def cancel_order_stock_sysid(self, account, market, sysid):
496    def cancel_order_stock_sysid(self, account, market, sysid):
497        """
498        :param account:证券账号
499        :param market: 交易市场 0:上海 1:深圳
500        :param sysid: 柜台合同编号
501        :return:返回撤单成功或者失败, 0:成功,  -1:撤单失败
502        """
503        req = XTQC.CancelOrderStockReq()
504        req.m_nAccountType = account.account_type
505        req.m_strAccountID = account.account_id
506        req.m_nMarket = market
507        req.m_strOrderSysID = sysid
508        
509        seq = self.async_client.nextSeq()
510        resp = self.common_op_sync_with_seq(
511            seq,
512            (self.async_client.cancelOrderStockWithSeq, seq, req)
513        )
514        self.handled_sync_cancel_order_stock_order_sys_id.add(resp.order_sysid)
515        return resp.cancel_result
Parameters
  • account: 证券账号
  • market: 交易市场 0:上海 1: 深圳
  • sysid: 柜台合同编号
Returns

返回撤单成功或者失败, 0:成功, -1:撤单失败

def cancel_order_stock_sysid_async(self, account, market, sysid):
517    def cancel_order_stock_sysid_async(self, account, market, sysid):
518        """
519        :param account:证券账号
520        :param market: 交易市场 0:上海 1:深圳
521        :param sysid: 柜台编号
522        :return:返回撤单请求序号, 成功委托后的撤单请求序号为大于0的正整数, 如果为-1表示委托失败
523        """
524        req = XTQC.CancelOrderStockReq()
525        req.m_nAccountType = account.account_type
526        req.m_strAccountID = account.account_id
527        req.m_nMarket = market
528        req.m_strOrderSysID = sysid
529        
530        seq = self.async_client.nextSeq()
531        self.cbs[seq] = self.callback.on_cancel_order_stock_async_response
532        self.async_client.cancelOrderStockWithSeq(seq, req)
533        return seq
Parameters
  • account: 证券账号
  • market: 交易市场 0:上海 1: 深圳
  • sysid: 柜台编号
Returns

返回撤单请求序号, 成功委托后的撤单请求序号为大于0的正整数, 如果为-1表示委托失败

def query_account_infos(self):
535    def query_account_infos(self):
536        """
537        :return: 返回账号列表
538        """
539        req = XTQC.QueryAccountInfosReq()
540        
541        seq = self.async_client.nextSeq()
542        return self.common_op_sync_with_seq(
543            seq,
544            (self.async_client.queryAccountInfosWithSeq, seq, req)
545        )
Returns

返回账号列表

def query_account_info(self):
535    def query_account_infos(self):
536        """
537        :return: 返回账号列表
538        """
539        req = XTQC.QueryAccountInfosReq()
540        
541        seq = self.async_client.nextSeq()
542        return self.common_op_sync_with_seq(
543            seq,
544            (self.async_client.queryAccountInfosWithSeq, seq, req)
545        )
Returns

返回账号列表

def query_account_infos_async(self, callback):
549    def query_account_infos_async(self, callback):
550        """
551        :return: 返回账号列表
552        """
553        req = XTQC.QueryAccountInfosReq()
554        
555        seq = self.async_client.nextSeq()
556        return self.common_op_async_with_seq(
557            seq,
558            (self.async_client.queryAccountInfosWithSeq, seq, req)
559            , callback
560        )
Returns

返回账号列表

def query_account_status(self):
562    def query_account_status(self):
563        """
564        :return: 返回账号状态
565        """
566        req = XTQC.QueryAccountStatusReq()
567        
568        seq = self.async_client.nextSeq()
569        return self.common_op_sync_with_seq(
570            seq,
571            (self.async_client.queryAccountStatusWithSeq, seq, req)
572        )
Returns

返回账号状态

def query_account_status_async(self, callback):
574    def query_account_status_async(self, callback):
575        """
576        :return: 返回账号状态
577        """
578        req = XTQC.QueryAccountStatusReq()
579        
580        seq = self.async_client.nextSeq()
581        return self.common_op_async_with_seq(
582            seq,
583            (self.async_client.queryAccountStatusWithSeq, seq, req)
584            , callback
585        )
Returns

返回账号状态

def query_stock_asset(self, account):
587    def query_stock_asset(self, account):
588        """
589        :param account: 证券账号
590        :return: 返回当前证券账号的资产数据
591        """
592        req = XTQC.QueryStockAssetReq()
593        req.m_nAccountType = account.account_type
594        req.m_strAccountID = account.account_id
595        
596        seq = self.async_client.nextSeq()
597        resp = self.common_op_sync_with_seq(
598            seq,
599            (self.async_client.queryStockAssetWithSeq, seq, req)
600        )
601
602        if resp and len(resp):
603            return resp[0]
604        return None
Parameters
  • account: 证券账号
Returns

返回当前证券账号的资产数据

def query_stock_asset_async(self, account, callback):
606    def query_stock_asset_async(self, account, callback):
607        """
608        :param account: 证券账号
609        :return: 返回当前证券账号的资产数据
610        """
611        req = XTQC.QueryStockAssetReq()
612        req.m_nAccountType = account.account_type
613        req.m_strAccountID = account.account_id
614        
615        seq = self.async_client.nextSeq()
616        def _cb(resp):
617            callback(resp[0] if resp else None)
618        resp = self.common_op_async_with_seq(
619            seq,
620            (self.async_client.queryStockAssetWithSeq, seq, req)
621            , _cb
622        )
623        return
Parameters
  • account: 证券账号
Returns

返回当前证券账号的资产数据

def query_stock_order(self, account, order_id):
625    def query_stock_order(self, account, order_id):
626        """
627        :param account: 证券账号
628        :param order_id:  订单编号,同步报单接口返回的编号
629        :return: 返回订单编号对应的委托对象
630        """
631        req = XTQC.QueryStockOrdersReq()
632        req.m_nAccountType = account.account_type
633        req.m_strAccountID = account.account_id
634        req.m_nOrderID = order_id
635        
636        seq = self.async_client.nextSeq()
637        resp = self.common_op_sync_with_seq(
638            seq,
639            (self.async_client.queryStockOrdersWithSeq, seq, req)
640        )
641        if resp and len(resp):
642            return resp[0]
643        return None
Parameters
  • account: 证券账号
  • order_id: 订单编号,同步报单接口返回的编号
Returns

返回订单编号对应的委托对象

def query_stock_orders(self, account, cancelable_only=False):
645    def query_stock_orders(self, account, cancelable_only = False):
646        """
647        :param account: 证券账号
648        :param cancelable_only: 仅查询可撤委托
649        :return: 返回当日所有委托的委托对象组成的list
650        """
651        req = XTQC.QueryStockOrdersReq()
652        req.m_nAccountType = account.account_type
653        req.m_strAccountID = account.account_id
654        req.m_bCanCancel = cancelable_only
655        
656        seq = self.async_client.nextSeq()
657        return self.common_op_sync_with_seq(
658            seq,
659            (self.async_client.queryStockOrdersWithSeq, seq, req)
660        )
Parameters
  • account: 证券账号
  • cancelable_only: 仅查询可撤委托
Returns

返回当日所有委托的委托对象组成的list

def query_stock_orders_async(self, account, callback, cancelable_only=False):
662    def query_stock_orders_async(self, account, callback, cancelable_only = False):
663        """
664        :param account: 证券账号
665        :param cancelable_only: 仅查询可撤委托
666        :return: 返回当日所有委托的委托对象组成的list
667        """
668        req = XTQC.QueryStockOrdersReq()
669        req.m_nAccountType = account.account_type
670        req.m_strAccountID = account.account_id
671        req.m_bCanCancel = cancelable_only
672        
673        seq = self.async_client.nextSeq()
674        return self.common_op_async_with_seq(
675            seq,
676            (self.async_client.queryStockOrdersWithSeq, seq, req)
677            , callback
678        )
Parameters
  • account: 证券账号
  • cancelable_only: 仅查询可撤委托
Returns

返回当日所有委托的委托对象组成的list

def query_stock_trades(self, account):
680    def query_stock_trades(self, account):
681        """
682        :param account:  证券账号
683        :return:  返回当日所有成交的成交对象组成的list
684        """
685        req = XTQC.QueryStockTradesReq()
686        req.m_nAccountType = account.account_type
687        req.m_strAccountID = account.account_id
688        
689        seq = self.async_client.nextSeq()
690        return self.common_op_sync_with_seq(
691            seq,
692            (self.async_client.queryStockTradesWithSeq, seq, req)
693        )
Parameters
  • account: 证券账号
Returns

返回当日所有成交的成交对象组成的list

def query_stock_trades_async(self, account, callback):
695    def query_stock_trades_async(self, account, callback):
696        """
697        :param account:  证券账号
698        :return:  返回当日所有成交的成交对象组成的list
699        """
700        req = XTQC.QueryStockTradesReq()
701        req.m_nAccountType = account.account_type
702        req.m_strAccountID = account.account_id
703        
704        seq = self.async_client.nextSeq()
705        return self.common_op_async_with_seq(
706            seq,
707            (self.async_client.queryStockTradesWithSeq, seq, req)
708            , callback
709        )
Parameters
  • account: 证券账号
Returns

返回当日所有成交的成交对象组成的list

def query_stock_position(self, account, stock_code):
711    def query_stock_position(self, account, stock_code):
712        """
713        :param account: 证券账号
714        :param stock_code: 证券代码, 例如"600000.SH"
715        :return: 返回证券代码对应的持仓对象
716        """
717        req = XTQC.QueryStockPositionsReq()
718        req.m_nAccountType = account.account_type
719        req.m_strAccountID = account.account_id
720        req.m_strStockCode = stock_code
721        
722        seq = self.async_client.nextSeq()
723        resp = self.common_op_sync_with_seq(
724            seq,
725            (self.async_client.queryStockPositionsWithSeq, seq, req)
726        )
727        if resp and len(resp):
728            return resp[0]
729        return None
Parameters
  • account: 证券账号
  • stock_code: 证券代码, 例如"600000.SH"
Returns

返回证券代码对应的持仓对象

def query_stock_positions(self, account):
731    def query_stock_positions(self, account):
732        """
733        :param account: 证券账号
734        :return: 返回当日所有持仓的持仓对象组成的list
735        """
736        req = XTQC.QueryStockPositionsReq()
737        req.m_nAccountType = account.account_type
738        req.m_strAccountID = account.account_id
739        
740        seq = self.async_client.nextSeq()
741        return self.common_op_sync_with_seq(
742            seq,
743            (self.async_client.queryStockPositionsWithSeq, seq, req)
744        )
Parameters
  • account: 证券账号
Returns

返回当日所有持仓的持仓对象组成的list

def query_stock_positions_async(self, account, callback):
746    def query_stock_positions_async(self, account, callback):
747        """
748        :param account: 证券账号
749        :return: 返回当日所有持仓的持仓对象组成的list
750        """
751        req = XTQC.QueryStockPositionsReq()
752        req.m_nAccountType = account.account_type
753        req.m_strAccountID = account.account_id
754        
755        seq = self.async_client.nextSeq()
756        return self.common_op_async_with_seq(
757            seq
758            , (self.async_client.queryStockPositionsWithSeq, seq, req)
759            , callback
760        )
Parameters
  • account: 证券账号
Returns

返回当日所有持仓的持仓对象组成的list

def query_credit_detail(self, account):
762    def query_credit_detail(self, account):
763        """
764        :param account: 证券账号
765        :return: 返回当前证券账号的资产数据
766        """
767        req = XTQC.QueryCreditDetailReq()
768        req.m_nAccountType = account.account_type
769        req.m_strAccountID = account.account_id
770        
771        seq = self.async_client.nextSeq()
772        return self.common_op_sync_with_seq(
773            seq,
774            (self.async_client.queryCreditDetailWithSeq, seq, req)
775        )
Parameters
  • account: 证券账号
Returns

返回当前证券账号的资产数据

def query_credit_detail_async(self, account, callback):
777    def query_credit_detail_async(self, account, callback):
778        """
779        :param account: 证券账号
780        :return: 返回当前证券账号的资产数据
781        """
782        req = XTQC.QueryCreditDetailReq()
783        req.m_nAccountType = account.account_type
784        req.m_strAccountID = account.account_id
785        
786        seq = self.async_client.nextSeq()
787        return self.common_op_async_with_seq(
788            seq,
789            (self.async_client.queryCreditDetailWithSeq, seq, req)
790            , callback
791        )
Parameters
  • account: 证券账号
Returns

返回当前证券账号的资产数据

def query_stk_compacts(self, account):
793    def query_stk_compacts(self, account):
794        """
795        :param account: 证券账号
796        :return: 返回负债合约
797        """
798        req = XTQC.QueryStkCompactsReq()
799        req.m_nAccountType = account.account_type
800        req.m_strAccountID = account.account_id
801        
802        seq = self.async_client.nextSeq()
803        return self.common_op_sync_with_seq(
804            seq,
805            (self.async_client.queryStkCompactsWithSeq, seq, req)
806        )
Parameters
  • account: 证券账号
Returns

返回负债合约

def query_stk_compacts_async(self, account, callback):
808    def query_stk_compacts_async(self, account, callback):
809        """
810        :param account: 证券账号
811        :return: 返回负债合约
812        """
813        req = XTQC.QueryStkCompactsReq()
814        req.m_nAccountType = account.account_type
815        req.m_strAccountID = account.account_id
816        
817        seq = self.async_client.nextSeq()
818        return self.common_op_async_with_seq(
819            seq,
820            (self.async_client.queryStkCompactsWithSeq, seq, req)
821            , callback
822        )
Parameters
  • account: 证券账号
Returns

返回负债合约

def query_credit_subjects(self, account):
824    def query_credit_subjects(self, account):
825        """
826        :param account: 证券账号
827        :return: 返回融资融券标的
828        """
829        req = XTQC.QueryCreditSubjectsReq()
830        req.m_nAccountType = account.account_type
831        req.m_strAccountID = account.account_id
832        
833        seq = self.async_client.nextSeq()
834        return self.common_op_sync_with_seq(
835            seq,
836            (self.async_client.queryCreditSubjectsWithSeq, seq, req)
837        )
Parameters
  • account: 证券账号
Returns

返回融资融券标的

def query_credit_subjects_async(self, account, callback):
839    def query_credit_subjects_async(self, account, callback):
840        """
841        :param account: 证券账号
842        :return: 返回融资融券标的
843        """
844        req = XTQC.QueryCreditSubjectsReq()
845        req.m_nAccountType = account.account_type
846        req.m_strAccountID = account.account_id
847        
848        seq = self.async_client.nextSeq()
849        return self.common_op_async_with_seq(
850            seq,
851            (self.async_client.queryCreditSubjectsWithSeq, seq, req)
852            , callback
853        )
Parameters
  • account: 证券账号
Returns

返回融资融券标的

def query_credit_slo_code(self, account):
855    def query_credit_slo_code(self, account):
856        """
857        :param account: 证券账号
858        :return: 返回可融券数据
859        """
860        req = XTQC.QueryCreditSloCodeReq()
861        req.m_nAccountType = account.account_type
862        req.m_strAccountID = account.account_id
863        
864        seq = self.async_client.nextSeq()
865        return self.common_op_sync_with_seq(
866            seq,
867            (self.async_client.queryCreditSloCodeWithSeq, seq, req)
868        )
Parameters
  • account: 证券账号
Returns

返回可融券数据

def query_credit_slo_code_async(self, account, callback):
870    def query_credit_slo_code_async(self, account, callback):
871        """
872        :param account: 证券账号
873        :return: 返回可融券数据
874        """
875        req = XTQC.QueryCreditSloCodeReq()
876        req.m_nAccountType = account.account_type
877        req.m_strAccountID = account.account_id
878        
879        seq = self.async_client.nextSeq()
880        return self.common_op_async_with_seq(
881            seq,
882            (self.async_client.queryCreditSloCodeWithSeq, seq, req)
883            , callback
884        )
Parameters
  • account: 证券账号
Returns

返回可融券数据

def query_credit_assure(self, account):
886    def query_credit_assure(self, account):
887        """
888        :param account: 证券账号
889        :return: 返回标的担保品
890        """
891        req = XTQC.QueryCreditAssureReq()
892        req.m_nAccountType = account.account_type
893        req.m_strAccountID = account.account_id
894        
895        seq = self.async_client.nextSeq()
896        return self.common_op_sync_with_seq(
897            seq,
898            (self.async_client.queryCreditAssureWithSeq, seq, req)
899        )
Parameters
  • account: 证券账号
Returns

返回标的担保品

def query_credit_assure_async(self, account, callback):
901    def query_credit_assure_async(self, account, callback):
902        """
903        :param account: 证券账号
904        :return: 返回标的担保品
905        """
906        req = XTQC.QueryCreditAssureReq()
907        req.m_nAccountType = account.account_type
908        req.m_strAccountID = account.account_id
909        
910        seq = self.async_client.nextSeq()
911        return self.common_op_async_with_seq(
912            seq,
913            (self.async_client.queryCreditAssureWithSeq, seq, req)
914            , callback
915        )
Parameters
  • account: 证券账号
Returns

返回标的担保品

def query_new_purchase_limit(self, account):
917    def query_new_purchase_limit(self, account):
918        """
919        :param account: 证券账号
920        :return: 返回账户新股申购额度数据
921        """
922        req = XTQC.QueryNewPurchaseLimitReq()
923        req.m_nAccountType = account.account_type
924        req.m_strAccountID = account.account_id
925        
926        seq = self.async_client.nextSeq()
927        new_purchase_limit_list = self.common_op_sync_with_seq(
928            seq,
929            (self.async_client.queryNewPurchaseLimitWithSeq, seq, req)
930        )
931        new_purchase_limit_result = dict()
932        for item in new_purchase_limit_list:
933            new_purchase_limit_result[item.m_strNewPurchaseLimitKey] = item.m_nNewPurchaseLimitValue
934        return new_purchase_limit_result
Parameters
  • account: 证券账号
Returns

返回账户新股申购额度数据

def query_new_purchase_limit_async(self, account, callback):
936    def query_new_purchase_limit_async(self, account, callback):
937        """
938        :param account: 证券账号
939        :return: 返回账户新股申购额度数据
940        """
941        req = XTQC.QueryNewPurchaseLimitReq()
942        req.m_nAccountType = account.account_type
943        req.m_strAccountID = account.account_id
944        
945        seq = self.async_client.nextSeq()
946        return self.common_op_async_with_seq(
947            seq,
948            (self.async_client.queryNewPurchaseLimitWithSeq, seq, req)
949            , callback
950        )
Parameters
  • account: 证券账号
Returns

返回账户新股申购额度数据

def query_ipo_data(self):
952    def query_ipo_data(self):
953        """
954        :return: 返回新股新债信息
955        """
956        req = XTQC.QueryIPODataReq()
957        req.m_strIPOType = ''
958        
959        seq = self.async_client.nextSeq()
960        ipo_data_list = self.common_op_sync_with_seq(
961            seq,
962            (self.async_client.queryIPODataWithSeq, seq, req)
963        )
964        ipo_data_result = dict()
965        for item in ipo_data_list:
966            ipo_data_result[item.m_strIPOCode] = {
967                'name': item.m_strIPOName, 
968                'type':  item.m_strIPOType, 
969                'maxPurchaseNum':  item.m_nMaxPurchaseNum, 
970                'minPurchaseNum':  item.m_nMinPurchaseNum, 
971                'purchaseDate':  item.m_strPurchaseDate, 
972                'issuePrice': item.m_dIssuePrice,
973            }
974        return ipo_data_result
Returns

返回新股新债信息

def query_ipo_data_async(self, callback):
976    def query_ipo_data_async(self, callback):
977        """
978        :return: 返回新股新债信息
979        """
980        req = XTQC.QueryIPODataReq()
981        req.m_strIPOType = ''
982        
983        seq = self.async_client.nextSeq()
984        return self.common_op_async_with_seq(
985            seq,
986            (self.async_client.queryIPODataWithSeq, seq, req)
987            , callback
988        )
Returns

返回新股新债信息

def query_appointment_info(self, account):
 990    def query_appointment_info(self, account):
 991        """
 992        :param account: 证券账号
 993        :return: 返回约券合约信息
 994        """
 995        req = XTQC.QueryAppointmentInfoReq()
 996        req.m_nAccountType = 3
 997        req.m_strAccountID = account.account_id
 998        
 999        seq = self.async_client.nextSeq()
1000        appointment_info_list = self.common_op_sync_with_seq(
1001            seq,
1002            (self.async_client.queryAppointmentInfoWithSeq, seq, req)
1003        )      
1004        appointment_info_result = dict()
1005        for item in appointment_info_list:
1006            appointment_info_result[item.m_strCompactId] = {
1007                'success': item.m_bSuccess,
1008                'error': item.m_strError,
1009                'fundAccount': item.m_strFundAccount,
1010                'origCompactId': item.m_strOrigCompactId,
1011                'exchangeType': item.m_strExchangeType,
1012                'stockCode': item.m_strStockCode,
1013                'stockName': item.m_strStockName,
1014                'contractEndDate': item.m_nContractEndDate,
1015                'feeRatio': item.m_dFeeRatio,
1016                'compactTerm': item.m_nCompactTerm,
1017                'compactAmount': item.m_nCompactAmount,
1018                'compactRepayDate': item.m_nCompactRepayDate,
1019                'compactStatus': item.m_strCompactStatus,
1020                'positionStr': item.m_strPositionStr,
1021            }
1022        return appointment_info_result
Parameters
  • account: 证券账号
Returns

返回约券合约信息

def query_appointment_info_async(self, account, callback):
1024    def query_appointment_info_async(self, account, callback):
1025        """
1026        :param account: 证券账号
1027        :return: 返回约券合约信息
1028        """
1029        req = XTQC.QueryAppointmentInfoReq()
1030        req.m_nAccountType = account.account_type
1031        req.m_strAccountID = account.account_id
1032        
1033        seq = self.async_client.nextSeq()
1034        return self.common_op_async_with_seq(
1035            seq,
1036            (self.async_client.queryAppointmentInfoWithSeq, seq, req)
1037            , callback
1038        )
Parameters
  • account: 证券账号
Returns

返回约券合约信息

def smt_appointment_async( self, account, stock_code, apt_days, apt_volume, fare_ratio, sub_rare_ratio, fine_ratio, begin_date):
1040    def smt_appointment_async(self, account, stock_code, apt_days, apt_volume, fare_ratio, sub_rare_ratio, fine_ratio,
1041                          begin_date):
1042        """
1043        :param account: 证券账号
1044        :param stock_code: 证券代码, 例如"600000.SH"
1045        :param apt_days: 约定期限
1046        :param apt_volume: 约定数量
1047        :param fare_ratio: 约券费率
1048        :param sub_rare_ratio: 提前归还费率
1049        :param fine_ratio: 违约金率
1050        :param begin_date: 约定日期
1051        :return: 返回下单请求序号
1052        """
1053        req = XTQC.SmtAppointmentReq()
1054        req.m_strAccountID = account.account_id
1055        req.m_strStockCode = stock_code
1056        req.m_nAptDays = apt_days
1057        req.m_nVolume = apt_volume
1058        req.m_dFareRatio = fare_ratio
1059        req.m_dSubRareRatio = sub_rare_ratio
1060        req.m_dFineRatio = fine_ratio
1061        req.m_strBeginDate = begin_date
1062        
1063        
1064        seq = self.async_client.nextSeq()
1065        self.cbs[seq] = self.callback.on_smt_appointment_async_response
1066        self.async_client.smtAppointmentWithSeq(seq, req)
1067        return seq
Parameters
  • account: 证券账号
  • stock_code: 证券代码, 例如"600000.SH"
  • apt_days: 约定期限
  • apt_volume: 约定数量
  • fare_ratio: 约券费率
  • sub_rare_ratio: 提前归还费率
  • fine_ratio: 违约金率
  • begin_date: 约定日期
Returns

返回下单请求序号

def query_smt_secu_info(self, account):
1069    def query_smt_secu_info(self, account):
1070        """
1071        :param account: 证券账号
1072        :return: 返回券源券单信息
1073        """
1074        req = XTQC.QuerySMTSecuInfoReq()
1075        req.m_nAccountType = 3
1076        req.m_strAccountID = account.account_id
1077
1078        seq = self.async_client.nextSeq()
1079        smt_secu_info_list = self.common_op_sync_with_seq(
1080            seq,
1081            (self.async_client.querySMTSecuInfoWithSeq, seq, req)
1082        )
1083        smt_secu_info_result = dict()
1084        for item in smt_secu_info_list:
1085            stock = item.m_strStockCode + '.' +item.m_strExchangeType
1086            smt_secu_info_result[stock] = {
1087                'success': item.m_bSuccess, 
1088                'error':  item.m_strError, 
1089                'stockName': item.m_strStockName,
1090                'creditType':  item.m_strCreditType, 
1091                'tradeType': item.m_strTradeType,
1092                'compactTerm': item.m_nCompactTerm,
1093                'maxTerm': item.m_nMaxTerm,
1094                'lendAmount': item.m_nLendAmount,
1095                'remark': item.m_strRemark,
1096                'fareWay': item.m_strFareWay,
1097                'fareRateNew': item.m_dFareRateNew,
1098            }
1099        return smt_secu_info_result
Parameters
  • account: 证券账号
Returns

返回券源券单信息

def query_smt_secu_rate( self, account, stock_code, max_term, fare_way, credit_type, trade_type):
1101    def query_smt_secu_rate(self, account, stock_code, max_term, fare_way, credit_type, trade_type):
1102        """
1103        :param account: 证券账号
1104        :param stock_code: 证券代码, 例如"600000.SH"
1105        :param max_term: 最大约定期限
1106        :param fare_way: 折扣标志
1107        :param credit_type: 资券类型
1108        :param trade_type: 业务类型
1109        :return: 返回券源费率信息
1110        """
1111        req = XTQC.QuerySMTSecuRateReq()
1112        req.m_nAccountType = 3
1113        req.m_strAccountID = account.account_id
1114        req.m_strStockCode = stock_code
1115        req.m_nMaxTerm = max_term
1116        req.m_strFareWay = fare_way
1117        req.m_strCreditType = credit_type
1118        req.m_strTradeType = trade_type
1119        
1120        seq = self.async_client.nextSeq()
1121        smt_secu_rate_list = self.common_op_sync_with_seq(
1122            seq,
1123            (self.async_client.querySMTSecuRateWithSeq, seq, req)
1124        )
1125        smt_secu_rate_result = dict()
1126        if smt_secu_rate_list:
1127            item = smt_secu_rate_list[0]
1128            smt_secu_rate_result = {
1129                'success': item.m_bSuccess, 
1130                'error':  item.m_strError, 
1131                'fareRatio': item.m_dFareRatio,
1132                'subRareRatio': item.m_dSubRareRatio,
1133                'fineRatio': item.m_dFineRatio,
1134        }
1135        return smt_secu_rate_result
Parameters
  • account: 证券账号
  • stock_code: 证券代码, 例如"600000.SH"
  • max_term: 最大约定期限
  • fare_way: 折扣标志
  • credit_type: 资券类型
  • trade_type: 业务类型
Returns

返回券源费率信息