From 4b0fa9049d673aa8aba6d56e272c6f9d07f13949 Mon Sep 17 00:00:00 2001 From: shinny-pack Date: Tue, 8 Mar 2022 02:08:09 +0000 Subject: [PATCH] Update Version 3.2.4 --- PKG-INFO | 2 +- doc/advanced/index.rst | 1 + doc/advanced/tqsdk2ctptest.rst | 26 ++++++++++++++++++++++++++ doc/conf.py | 4 ++-- doc/version.rst | 8 ++++++++ setup.py | 2 +- tqsdk/__version__.py | 2 +- tqsdk/algorithm/twap.py | 2 ++ tqsdk/demo/option_tutorial/o70.py | 2 +- tqsdk/lib/target_pos_task.py | 2 ++ tqsdk/objs_not_entity.py | 1 + tqsdk/symbols.py | 9 +++++++-- tqsdk/tqwebhelper.py | 14 +++++++++----- tqsdk/tradeable/otg/tqkq.py | 25 +++++++++++++++++++++++++ 14 files changed, 87 insertions(+), 13 deletions(-) create mode 100644 doc/advanced/tqsdk2ctptest.rst diff --git a/PKG-INFO b/PKG-INFO index 54a93666..24bbfd54 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: tqsdk -Version: 3.2.3 +Version: 3.2.4 Summary: TianQin SDK Home-page: https://www.shinnytech.com/tqsdk Author: TianQin diff --git a/doc/advanced/index.rst b/doc/advanced/index.rst index 4f2e0a4e..5ec50c18 100644 --- a/doc/advanced/index.rst +++ b/doc/advanced/index.rst @@ -17,3 +17,4 @@ unanttended.rst targetpostask2.rst scheduler.rst + tqsdk2ctptest.rst diff --git a/doc/advanced/tqsdk2ctptest.rst b/doc/advanced/tqsdk2ctptest.rst new file mode 100644 index 00000000..6ee90a58 --- /dev/null +++ b/doc/advanced/tqsdk2ctptest.rst @@ -0,0 +1,26 @@ +.. _tqsdk2ctptest: + +在 tqsdk 中调用 tqsdk2 查询保证金 +================================================= +tqSdk 没有直接提供查询保证金的接口,但是你可以通过使用tqsdk2 的直连功能来做到这个效果。tqsdk和tqsdk2可以在一个py文件中同时运行。 + +该方法仅支持直连 CTP 柜台时使用。受限制于 CTP 柜台的流控机制(每秒 1 笔), 短时间发送大量查询指令后, 后续查询指令将会排队等待。 +为了避免盘中的查询等待时间, 建议盘前启动程序, 对标的合约提前进行查询:: + + from tqsdk import TqApi, TqAuth, TqAccount + import tqsdk2 + + account = tqsdk2.TqCtp(front_url, front_broker, app_id, auth_code, account_id, password) + api_margin = tqsdk2.TqApi(account = account, auth=tqsdk2.TqAuth("信易账户", "账户密码")) + rate = api_margin.get_margin_rates("SHFE.cu2201") + print(rate) + api = TqApi(TqAccount("期货公司","账号","密码"),auth=TqAuth("信易账户", "账户密码")) + quote = api.get_quote("SHFE.cu2201") + while True: + api.wait_update() + quote.datetime + # 正常和tqsdk一样执行策略 + + +tqsdk2的直连功能需要企业版权限,有关企业版的具体费用和功能,请参考 `天勤官方网站 `_ +如果想了解更多关于tqsdk2的直连功能TqCtp,请参考 `tqsdk2官方文档 `_ diff --git a/doc/conf.py b/doc/conf.py index 09519c8d..0b4e34f4 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -48,9 +48,9 @@ # built documents. # # The short X.Y version. -version = u'3.2.3' +version = u'3.2.4' # The full version, including alpha/beta/rc tags. -release = u'3.2.3' +release = u'3.2.4' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/version.rst b/doc/version.rst index 4908f4e0..3271301e 100644 --- a/doc/version.rst +++ b/doc/version.rst @@ -2,6 +2,14 @@ 版本变更 ============================= +3.2.4 (2022/03/07) + +* 优化:某些情况下启用 web_gui 后网页卡顿的问题 +* 修复:修正上交所 ETF 期权的昨结算(pre_settlement)字段 +* 修复::py:class:`~tqsdk.TargetPosTask` 及 :py:class:`~tqsdk.algorithm.twap` 添加动力煤期货暂不支持的提示 +* docs:修正文档,增加 tqkq() 的示例,增加 :ref:`tqsdk2ctptest` 文档 + + 3.2.3 (2022/02/16) * 修复:query_all_level_options 接口查询 ETF 期权可能报错的问题 diff --git a/setup.py b/setup.py index 8938a573..892cf74a 100644 --- a/setup.py +++ b/setup.py @@ -36,7 +36,7 @@ def get_tag(self): setuptools.setup( name='tqsdk', - version="3.2.3", + version="3.2.4", description='TianQin SDK', author='TianQin', author_email='tianqincn@gmail.com', diff --git a/tqsdk/__version__.py b/tqsdk/__version__.py index 32206102..cca48bd0 100644 --- a/tqsdk/__version__.py +++ b/tqsdk/__version__.py @@ -1 +1 @@ -__version__ = '3.2.3' +__version__ = '3.2.4' diff --git a/tqsdk/algorithm/twap.py b/tqsdk/algorithm/twap.py index 41616f45..ba231fad 100644 --- a/tqsdk/algorithm/twap.py +++ b/tqsdk/algorithm/twap.py @@ -119,6 +119,8 @@ def __init__(self, api: TqApi, symbol: str, direction: str, offset: str, volume: """ if symbol.startswith("CZCE.CJ"): raise Exception("红枣期货不支持创建 targetpostask、twap、vwap 任务,交易所规定该品种最小开仓手数为大于等于 4 手,这些函数还未支持该规则!") + if symbol.startswith("CZCE.ZC"): + raise Exception("动力煤期货不支持创建 targetpostask、twap、vwap 任务,交易所规定该品种最小开仓手数为大于等于 2 手,这些函数还未支持该规则!") self._api = api self._account = api._account._check_valid(account) if self._account is None: diff --git a/tqsdk/demo/option_tutorial/o70.py b/tqsdk/demo/option_tutorial/o70.py index 99f2069e..36f79c08 100644 --- a/tqsdk/demo/option_tutorial/o70.py +++ b/tqsdk/demo/option_tutorial/o70.py @@ -20,7 +20,7 @@ # 以对手价来计算买入看涨期权然后行权后的期货成本价格 option_buy = quote_option.strike_price + quote_option.ask_price1 # 判断当期货的买入1档,即卖出期货价格大于买入看涨期权的期货成本价格,形成套利空间时进行限价下单 - if quote.bid_price1 < option_buy and times == 0: + if quote.bid_price1 > option_buy and times == 0: times += 1 # 以现在卖1档价格买入看涨期权 order_opiton = api.insert_order('CZCE.MA109C2950', "BUY", "OPEN", 1, quote_option.ask_price1) diff --git a/tqsdk/lib/target_pos_task.py b/tqsdk/lib/target_pos_task.py index cd1969a8..ca730f90 100644 --- a/tqsdk/lib/target_pos_task.py +++ b/tqsdk/lib/target_pos_task.py @@ -197,6 +197,8 @@ def get_price(direction, quote): """ if symbol.startswith("CZCE.CJ"): raise Exception("红枣期货不支持创建 targetpostask、twap、vwap 任务,交易所规定该品种最小开仓手数为大于等于 4 手,这些函数还未支持该规则!") + if symbol.startswith("CZCE.ZC"): + raise Exception("动力煤期货不支持创建 targetpostask、twap、vwap 任务,交易所规定该品种最小开仓手数为大于等于 2 手,这些函数还未支持该规则!") super(TargetPosTask, self).__init__() self._api = api self._account = api._account._check_valid(account) diff --git a/tqsdk/objs_not_entity.py b/tqsdk/objs_not_entity.py index 161dce48..99e0b27e 100644 --- a/tqsdk/objs_not_entity.py +++ b/tqsdk/objs_not_entity.py @@ -342,6 +342,7 @@ async def _get_ranking_data(self, ranking_id): }) async def async_update(self): + await self.__dict__["_api"]._ensure_symbol_async(self.__dict__["_symbol"]) ranking_id = _generate_uuid("PYSDK_rank") self.__dict__["_api"].create_task(self._get_ranking_data(ranking_id), _caller_api=True) # 错误会抛给 api 处理 symbol_rankings = _get_obj(self.__dict__["_api"]._data, ["_symbol_rankings"]) diff --git a/tqsdk/symbols.py b/tqsdk/symbols.py index d83ed14a..6f937dc3 100644 --- a/tqsdk/symbols.py +++ b/tqsdk/symbols.py @@ -22,7 +22,7 @@ async def _run(self, api, sim_send_chan, sim_recv_chan, md_send_chan, md_recv_ch self._quotes_all_keys = set(Quote(None).keys()) self._quotes_all_keys = self._quotes_all_keys.union({'margin', 'commission'}) # 以下字段合约服务也会请求,但是不应该记在 quotes 中,quotes 中的这些字段应该有行情服务负责 - self._quotes_all_keys.difference_update({'pre_open_interest', 'pre_settlement', 'pre_close', 'upper_limit', 'lower_limit'}) + self._quotes_all_keys.difference_update({'pre_open_interest', 'pre_close', 'upper_limit', 'lower_limit'}) sim_task = self._api.create_task(self._sim_handler()) try: async for pack in self._md_recv_chan: @@ -36,8 +36,13 @@ async def _run(self, api, sim_send_chan, sim_recv_chan, md_send_chan, md_recv_ch if query_result.get("error", None): raise Exception(f"查询合约服务报错 {query_result['error']}") elif query_id.startswith("PYSDK_quote"): + quotes = self._api._symbols_to_quotes(query_result, self._quotes_all_keys) + for quote in quotes.values(): + if not (quote["ins_class"] == "OPTION" and quote["exchange_id"] == "SSE"): + # quotes 中的 pre_settlement 字段应该由行情服务负责,行情没有上交所期权的 pre_settlement,需要从合约服务取,其他合约不变 + quote.pop("pre_settlement", None) data.append( - {"quotes": self._api._symbols_to_quotes(query_result, self._quotes_all_keys)} + {"quotes": quotes} ) self._md_send_chan.send_nowait({ "aid": "ins_query", diff --git a/tqsdk/tqwebhelper.py b/tqsdk/tqwebhelper.py index de40539a..46e533b7 100644 --- a/tqsdk/tqwebhelper.py +++ b/tqsdk/tqwebhelper.py @@ -180,11 +180,15 @@ async def _data_handler(self, api_recv_chan, web_recv_chan): _simple_merge_diff(self._data["trade"], trade) web_diffs.append({"trade": trade}) # 账户是否有变化 - static_balance_changed = d.get("trade", {}).get(self._api._account._get_account_key(account=None), {}).\ - get("accounts", {}).get("CNY", {}).get('static_balance') - trades_changed = d.get("trade", {}).get(self._api._account._get_account_key(account=None), {}).get("trades", {}) - orders_changed = d.get("trade", {}).get(self._api._account._get_account_key(account=None), {}).get("orders", {}) - if static_balance_changed is not None or trades_changed != {} or orders_changed != {}: + # todo: 这里本来使用类似 is_changing 的做法,判断 diffs 中是否有 static_balance 字段;由于 _simple_merge_diff 去掉了默认参数 reduce_diff + # 现在修改为手动比较 diffs 中的 static_balance 和 self._data 中的 static_balance 是否一样 + account_key = self._api._account._get_account_key(account=None) + current_static_balance = self._data["trade"].get(account_key, {}).get("accounts", {}).get("CNY", {}).get('static_balance') + diff_static_balance = d.get("trade", {}).get(account_key, {}).get("accounts", {}).get("CNY", {}).get('static_balance', None) + static_balance_changed = diff_static_balance is not None and current_static_balance != diff_static_balance + trades_changed = d.get("trade", {}).get(account_key, {}).get("trades", {}) + orders_changed = d.get("trade", {}).get(account_key, {}).get("orders", {}) + if static_balance_changed is True or trades_changed != {} or orders_changed != {}: account_changed = True # 处理 backtest replay if d.get("_tqsdk_backtest") or d.get("_tqsdk_replay"): diff --git a/tqsdk/tradeable/otg/tqkq.py b/tqsdk/tradeable/otg/tqkq.py index a9b44a47..8edd4637 100644 --- a/tqsdk/tradeable/otg/tqkq.py +++ b/tqsdk/tradeable/otg/tqkq.py @@ -15,6 +15,31 @@ class TqKq(BaseOtg, FutureMixin): def __init__(self, td_url: Optional[str] = None): """ 创建快期模拟账户实例 + + 快期模拟的账户和交易信息可以在快期专业版查看,可以点击 `快期专业版 `_ 进行下载 + + Example:: + + from tqsdk import TqApi, TqAuth, TqKq + + tq_kq_stock = TqKq() + api = TqApi(account=tq_kq, auth=TqAuth("信易账户", "账户密码")) + quote = api.get_quote("SHFE.cu2206") + print(quote) + # 下单限价单 + order = api.insert_order(symbol="SHFE.cu2206", direction='BUY', offset='OPEN', limit_price=quote.last_price, volume=1) + while order.status == 'ALIVE': + api.wait_update() + print(order) # 打印委托单信息 + + print(tq_kq.get_account()) # 打印快期模拟账户信息 + + print(tq_kq.get_position("SHFE.cu2206")) # 打印持仓信息 + + for trade in order.trade_records.values(): + print(trade) # 打印委托单对应的成交信息 + api.close() + """ super().__init__("快期模拟", "", "", td_url=td_url)