├── .gitattributes ├── .github └── workflows │ └── run-tqsdk.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── MANIFEST.in ├── PKG-INFO ├── README.md ├── doc ├── Makefile ├── _static │ ├── baidu.js │ ├── demo_t10.png │ ├── faq1.png │ └── trading_system.svg ├── advanced │ ├── backtest.rst │ ├── dingding.rst │ ├── entry.rst │ ├── evolution.rst │ ├── for_ctp_user.rst │ ├── for_vnpy_user.rst │ ├── gui.rst │ ├── index.rst │ ├── multi_strategy.rst │ ├── order.rst │ ├── pandas.rst │ ├── processing.rst │ ├── scheduler.rst │ ├── targetpostask2.rst │ ├── timer.rst │ ├── tq_trading_unit.rst │ ├── tqsdk2ctptest.rst │ └── unanttended.rst ├── arch.svg ├── conf.py ├── demo │ ├── algorithm.rst │ ├── base.rst │ ├── index.rst │ ├── jupyter.rst │ ├── notebooks │ │ ├── demo.ipynb │ │ └── factor.ipynb │ ├── option_base.rst │ └── strategy.rst ├── dev │ ├── async_tool.rst │ ├── backtest.rst │ ├── dataflow.drawio │ ├── diff.drawio │ ├── framework.rst │ ├── general.rst │ ├── gui.rst │ ├── index.rst │ ├── unittest.rst │ └── workflow.drawio ├── devtools │ ├── drawindex.rst │ ├── index.rst │ ├── tq │ │ ├── index.rst │ │ ├── quickstart.rst │ │ ├── strategybacktest.rst │ │ ├── strategyrun.rst │ │ └── tqreplay.rst │ └── vscode.rst ├── enterprise.rst ├── images │ ├── backtest_click.png │ ├── backtest_ready.png │ ├── change_speed_replay.png │ ├── choose_broke.png │ ├── click_backtest.png │ ├── complete_config.png │ ├── config_ide_python.png │ ├── create_strategy.png │ ├── custom_settings.png │ ├── dialog_param_backtest.png │ ├── dialog_param_run.png │ ├── draw_index.png │ ├── foreign01.png │ ├── how-grafana04.gif │ ├── indicate_index.png │ ├── input_backtest_date.png │ ├── input_parameter.png │ ├── llm_pic1.png │ ├── llm_pic2.png │ ├── llm_pic3.png │ ├── llm_pic4.png │ ├── llm_pic5.png │ ├── llm_pic6.png │ ├── llm_pic7.png │ ├── mdreplay.png │ ├── page_backtest_intro.png │ ├── page_run_intro.png │ ├── pycharm_edit_configuration.png │ ├── pycharm_edit_configuration_entry.png │ ├── pycharm_open_directory.png │ ├── pycharm_process_console.png │ ├── pycharm_run.png │ ├── pycharm_run_configuration.png │ ├── qa_pic.png │ ├── replay.png │ ├── save_strategy.png │ ├── strategy_backtest_report.png │ ├── strategy_output.png │ ├── strategy_ready_run.png │ ├── strategy_run.png │ ├── strategy_symbol_image.png │ ├── strategybacktest_begin.png │ ├── strategybacktest_ready.png │ ├── system.drawio │ ├── tianqin-vscode-demo.gif │ ├── tianqin_chart_trade.png │ ├── tianqin_list_trade.png │ ├── tianqin_login_real.png │ ├── tq_breif.png │ ├── tq_loging.png │ ├── tq_mdreplay.png │ ├── tq_register.png │ ├── tq_zq_assign.png │ ├── tq_zq_backen.png │ ├── tq_zq_broker.png │ ├── tq_zq_config.png │ ├── tq_zq_config2.png │ ├── tq_zq_front.png │ ├── tq_zq_init.png │ ├── tq_zq_strategy.png │ ├── tq_zq_unclear_order.png │ ├── tqsdk_new_logo.png │ ├── user_login.png │ ├── user_web_management.png │ ├── user_web_management_new.png │ ├── vscode_backtest_report.png │ ├── vscode_backtest_report_detail.png │ ├── vscode_backtest_setting_finished.png │ ├── vscode_click.png │ ├── vscode_click_tianqinlianghua.png │ ├── vscode_gui_performance.png │ ├── vscode_install.png │ ├── vscode_kill_terminal.png │ ├── vscode_repaly.png │ ├── vscode_repaly_steps.png │ ├── vscode_replay_speed.png │ ├── vscode_run_replay.png │ ├── vscode_save_exe.png │ ├── vscode_setting_account.png │ ├── vscode_setting_backtesttime.png │ ├── vscode_setting_config.png │ ├── vscode_strategy_picture.png │ ├── wait_update.png │ ├── web_gui_backtest.png │ ├── web_gui_backtest_report.png │ ├── web_gui_demo.png │ ├── web_gui_klines.png │ ├── web_gui_real.png │ ├── win10_start_scheduled_task.png │ ├── win10_start_scheduled_task_create.png │ ├── win10_start_scheduled_task_python.png │ ├── win10_start_scheduled_task_taskkill.png │ ├── win2008_scheduled_task_kill.png │ ├── win2008_scheduled_task_python.png │ └── win2008_start_scheduled_task.png ├── index.rst ├── intro.rst ├── logo.png ├── make.bat ├── profession.rst ├── qa.rst ├── quickstart.rst ├── reference │ ├── index.rst │ ├── tqsdk.account.rst │ ├── tqsdk.algorithm.rst │ ├── tqsdk.api.rst │ ├── tqsdk.auth.rst │ ├── tqsdk.backtest.rst │ ├── tqsdk.exceptions.rst │ ├── tqsdk.lib.rst │ ├── tqsdk.multiaccount.rst │ ├── tqsdk.objs.rst │ ├── tqsdk.risk_rule.rst │ ├── tqsdk.sim.rst │ ├── tqsdk.ta.rst │ ├── tqsdk.tafunc.rst │ ├── tqsdk.tools.download.rst │ ├── tqsdk.tqctp.rst │ ├── tqsdk.tqjees.rst │ ├── tqsdk.tqkq.rst │ ├── tqsdk.tqrohon.rst │ ├── tqsdk.tqyida.rst │ └── tqsdk.tqzq.rst ├── tq_trading_unit.rst ├── tqsdk_llm.rst ├── usage │ ├── backtest.rst │ ├── framework.rst │ ├── index.rst │ ├── jupyter.rst │ ├── kqd_symbol.rst │ ├── mddatas.rst │ ├── option_trade.rst │ ├── replay.rst │ ├── shinny_account.rst │ ├── ta.rst │ ├── targetpostask.rst │ ├── trade.rst │ └── web_gui.rst └── version.rst ├── requirements.txt ├── setup.cfg ├── setup.py └── tqsdk ├── __init__.py ├── __pyinstaller ├── __init__.py └── hook-tqsdk.py ├── __version__.py ├── account.py ├── algorithm ├── __init__.py ├── time_table_generater.py └── twap.py ├── api.py ├── auth.py ├── backtest.py ├── backtest ├── __init__.py ├── backtest.py ├── replay.py └── utils.py ├── baseApi.py ├── baseModule.py ├── calendar.py ├── channel.py ├── connect.py ├── constants.py ├── data_extension.py ├── data_series.py ├── datetime.py ├── datetime_state.py ├── demo ├── __init__.py ├── download_orders.py ├── example │ ├── __init__.py │ ├── aberration.py │ ├── doublema.py │ ├── dualthrust.py │ ├── escalator.py │ ├── fairy_four_price.py │ ├── gridtrading.py │ ├── gridtrading_async.py │ ├── momentum.py │ ├── random_forest.py │ ├── rbreaker.py │ ├── rbreaker2.py │ ├── turtle.py │ └── vwap.py ├── multiaccount.py ├── option_tutorial │ ├── __init__.py │ ├── o10.py │ ├── o20.py │ ├── o30.py │ ├── o40.py │ ├── o41.py │ ├── o60.py │ ├── o70.py │ ├── o71.py │ ├── o72.py │ ├── o73.py │ └── o74.py ├── ta.py ├── ta_option.py └── tutorial │ ├── __init__.py │ ├── backtest.py │ ├── downloader.py │ ├── replay.py │ ├── replay2.py │ ├── t10.py │ ├── t20.py │ ├── t30.py │ ├── t40.py │ ├── t41.py │ ├── t50.py │ ├── t51.py │ ├── t52.py │ ├── t53.py │ ├── t54.py │ ├── t55.py │ ├── t56.py │ ├── t57.py │ ├── t58.py │ ├── t59.py │ ├── t60.py │ ├── t70.py │ ├── t71.py │ ├── t72.py │ ├── t80.py │ ├── t90.py │ ├── t91.py │ ├── t92.py │ ├── t93.py │ ├── t94.py │ ├── t95.py │ ├── t96.py │ └── underlying_symbol.py ├── diff.py ├── entity.py ├── exceptions.py ├── expired_quotes.json.lzma ├── ins_schema.py ├── lib ├── __init__.py ├── notify.py ├── target_pos_scheduler.py ├── target_pos_task.py ├── time_table.py └── utils.py ├── log.py ├── multiaccount.py ├── objs.py ├── objs_not_entity.py ├── rangeset.py ├── report.py ├── risk_manager.py ├── risk_rule.py ├── sim ├── __init__.py ├── trade.py ├── trade_base.py └── utils.py ├── sm.py ├── stockprofit.py ├── symbols.py ├── ta.py ├── tafunc.py ├── tools ├── __init__.py ├── dead_ins.lzma └── downloader.py ├── tqwebhelper.py ├── trade_extension.py ├── tradeable ├── __init__.py ├── interface.py ├── mixin.py ├── otg │ ├── __init__.py │ ├── base_otg.py │ ├── tqaccount.py │ ├── tqctp.py │ ├── tqjees.py │ ├── tqkq.py │ ├── tqrohon.py │ ├── tqtradingunit.py │ ├── tqyida.py │ └── tqzq.py ├── sim │ ├── __init__.py │ ├── basesim.py │ ├── tqsim.py │ ├── tqsim_stock.py │ ├── trade.py │ ├── trade_base.py │ ├── trade_future.py │ ├── trade_stock.py │ └── utils.py └── tradeable.py ├── trading_status.py ├── utils.py ├── utils_symbols.py ├── web ├── css │ ├── app.d72d8978.css │ ├── chunk-vendors.1f44729d.css │ └── chunk-vendors.c93e9127.css ├── d3.min.js ├── favicon.ico ├── fonts │ ├── ionicons.143146fa.woff2 │ ├── ionicons.99ac3308.woff │ └── ionicons.d535a25a.ttf ├── img │ ├── icons │ │ ├── android-chrome-192x192.png │ │ ├── android-icon-144x144.png │ │ ├── android-icon-192x192.png │ │ ├── android-icon-36x36.png │ │ ├── android-icon-48x48.png │ │ ├── android-icon-72x72.png │ │ ├── android-icon-96x96.png │ │ ├── apple-touch-icon-114x114.png │ │ ├── apple-touch-icon-120x120.png │ │ ├── apple-touch-icon-144x144.png │ │ ├── apple-touch-icon-152x152.png │ │ ├── apple-touch-icon-180x180.png │ │ ├── apple-touch-icon-57x57.png │ │ ├── apple-touch-icon-60x60.png │ │ ├── apple-touch-icon-72x72.png │ │ ├── apple-touch-icon-76x76.png │ │ ├── apple-touch-icon-precomposed.png │ │ ├── apple-touch-icon.png │ │ ├── browserconfig.xml │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── favicon-96x96.png │ │ ├── favicon.ico │ │ ├── manifest.json │ │ ├── ms-icon-150x150.png │ │ ├── ms-icon-310x310.png │ │ ├── ms-icon-70x70.png │ │ ├── msapplication-icon-144x144.png.png │ │ ├── mstile-150x150.png │ │ └── notes │ └── ionicons.a2c4a261.svg ├── index.html ├── js │ ├── app.2c843c86.js │ ├── app.5a494932.js │ ├── app.5eb857be.js │ ├── app.93328858.js │ ├── app.c1424daf.js │ ├── app.fc01ac28.js │ ├── chunk-vendors.d7fceff6.js │ └── chunk-vendors.fc3d6c6c.js ├── manifest.json ├── precache-manifest.1f4dd8e7baba14f0858de9c5a10cb57c.js ├── precache-manifest.53e7f698ae4f429b303bb209afaae23f.js ├── precache-manifest.5663715a1857b4046348697243e71707.js ├── precache-manifest.6648e5db468eb9b65c97bc6d385e4143.js ├── precache-manifest.771b3896014acd43a3cb89b93a2134ea.js ├── precache-manifest.7ed60b69dab01cdb0c64836489ab6e0d.js ├── robots.txt └── service-worker.js ├── zq.py └── zq_otg.py /.gitattributes: -------------------------------------------------------------------------------- 1 | *.script filter=lfs diff=lfs merge=lfs -text 2 | -------------------------------------------------------------------------------- /.github/workflows/run-tqsdk.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Release 2 | 3 | on: 4 | push: 5 | branches: 6 | - 'master' 7 | 8 | jobs: 9 | 10 | deploy: 11 | strategy: 12 | matrix: 13 | python-version: [3.6.x] 14 | python-arch: [x64] 15 | 16 | env: 17 | PYTHONIOENCODING: "utf-8" 18 | 19 | runs-on: ubuntu-latest 20 | 21 | steps: 22 | - name: Dump GitHub context 23 | env: 24 | GITHUB_CONTEXT: ${{ toJson(github) }} 25 | run: echo "$GITHUB_CONTEXT" 26 | 27 | - name: Format ci info on tag 28 | if: startsWith(github.event.head_commit.message, 'Update Version') 29 | run: | 30 | echo "TAG_NAME=$(echo ${{ github.event.head_commit.message }} | cut -c15-)" >> $GITHUB_ENV 31 | 32 | - name: Checkout 33 | uses: actions/checkout@v2 34 | 35 | - name: Add tag 36 | if: startsWith(github.event.head_commit.message, 'Update Version') 37 | uses: mathieudutour/github-tag-action@v5.6 38 | with: 39 | github_token: ${{ secrets.GITHUB_TOKEN }} 40 | custom_tag: ${{ env.TAG_NAME }} 41 | create_annotated_tag: true 42 | tag_prefix: '' 43 | 44 | - name: Install ghr 45 | if: startsWith(github.event.head_commit.message, 'Update Version') 46 | env: 47 | GHR_FORK: tcnksm/ghr 48 | GHR_VERSION: 0.14.0 49 | run: | 50 | curl --silent -L https://github.com/${{env.GHR_FORK}}/releases/download/v${{env.GHR_VERSION}}/ghr_v${{env.GHR_VERSION}}_linux_amd64.tar.gz > ghr_v${{env.GHR_VERSION}}_linux_amd64.tar.gz 51 | tar xvzf ghr_v${{env.GHR_VERSION}}_linux_amd64.tar.gz 52 | mv ghr_v${{env.GHR_VERSION}}_linux_amd64/ghr /usr/local/bin/ 53 | rm -rf ghr_v${{env.GHR_VERSION}}_linux_amd64 ghr_v${{env.GHR_VERSION}}_linux_amd64.tar.gz 54 | 55 | - name: Publish to github release 56 | if: startsWith(github.event.head_commit.message, 'Update Version') 57 | run: | 58 | ghr -u shinny-yangyang -t ${{ secrets.GITHUB_USER_TOKEN }} ${{ env.TAG_NAME }} 59 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | !tqsdk/lib/ 20 | lib64/ 21 | parts/ 22 | sdist/ 23 | var/ 24 | wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | 29 | # PyInstaller 30 | # Usually these files are written by a python script from a template 31 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 32 | *.manifest 33 | *.spec 34 | 35 | # Installer logs 36 | pip-log.txt 37 | pip-delete-this-directory.txt 38 | 39 | # Unit test / coverage reports 40 | htmlcov/ 41 | .tox/ 42 | .coverage 43 | .coverage.* 44 | .cache 45 | nosetests.xml 46 | coverage.xml 47 | *.cover 48 | .hypothesis/ 49 | chromedriver 50 | geckodriver 51 | 52 | # Translations 53 | *.mo 54 | *.pot 55 | 56 | # Django stuff: 57 | *.log 58 | local_settings.py 59 | 60 | # Flask stuff: 61 | instance/ 62 | .webassets-cache 63 | 64 | # Scrapy stuff: 65 | .scrapy 66 | 67 | # Sphinx documentation 68 | doc/_build/ 69 | 70 | # PyBuilder 71 | target/ 72 | 73 | # Jupyter Notebook 74 | .ipynb_checkpoints 75 | 76 | # pyenv 77 | .python-version 78 | 79 | # celery beat schedule file 80 | celerybeat-schedule 81 | 82 | # SageMath parsed files 83 | *.sage.py 84 | 85 | # dotenv 86 | .env 87 | 88 | # virtualenv 89 | .venv 90 | venv/ 91 | ENV/ 92 | 93 | # Spyder project settings 94 | .spyderproject 95 | .spyproject 96 | 97 | # Rope project settings 98 | .ropeproject 99 | 100 | # mkdocs documentation 101 | /site 102 | 103 | # mypy 104 | .mypy_cache/ 105 | 106 | .idea/ 107 | .vscode/ 108 | .reports/ 109 | .DS_Store 110 | 111 | #node js dir 112 | node_modules/ 113 | web/tests/e2e/reports/ 114 | 115 | # local env files 116 | .env.local 117 | .env.*.local 118 | 119 | # Log files 120 | npm-debug.log* 121 | yarn-debug.log* 122 | yarn-error.log* 123 | selenium-debug.log 124 | chromedriver.log 125 | geckodriver.log 126 | 127 | # Editor directories and files 128 | *.suo 129 | *.ntvs* 130 | *.njsproj 131 | *.sln 132 | *.sw? 133 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | recursive-exclude * __pycache__ 2 | recursive-exclude tqsdk/test * 3 | recursive-include tqsdk/web * 4 | exclude tqsdk/*.c tqsdk/tools/*.c 5 | include tqsdk/tools/dead_ins.lzma 6 | include tqsdk/expired_quotes.json.lzma 7 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = TianQin 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | livehtml: 16 | sphinx-autobuild -b html $(SOURCEDIR) $(BUILDDIR)/html 17 | 18 | .PHONY: help Makefile 19 | 20 | # Catch-all target: route all unknown targets to Sphinx using the new 21 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 22 | %: Makefile 23 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 24 | -------------------------------------------------------------------------------- /doc/_static/baidu.js: -------------------------------------------------------------------------------- 1 | var _hmt = _hmt || []; 2 | (function() { 3 | var hm = document.createElement("script"); 4 | hm.src = "https://hm.baidu.com/hm.js?f7292fcf4a7be122de798d24f80e32f6"; 5 | var s = document.getElementsByTagName("script")[0]; 6 | s.parentNode.insertBefore(hm, s); 7 | })(); -------------------------------------------------------------------------------- /doc/_static/demo_t10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/_static/demo_t10.png -------------------------------------------------------------------------------- /doc/_static/faq1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/_static/faq1.png -------------------------------------------------------------------------------- /doc/advanced/dingding.rst: -------------------------------------------------------------------------------- 1 | .. _dingding: 2 | 3 | 将程序信息推送到手机端 4 | ================================================= 5 | TqSdk 并不提供专门的服务器来推送消息,但是你可以通过其他 SDK 来做到这个效果,在发生成交或者条件满足时,进行消息推送,以钉钉为例:: 6 | 7 | from datetime import datetime, time, timedelta 8 | import requests 9 | from json import dumps 10 | from tqsdk import TqApi, TqAuth, TargetPosTask 11 | 12 | 13 | def send_msg(content): 14 | """钉钉消息提醒模块""" 15 | webhook = "设置自己的钉钉 webhook" 16 | 17 | # 钉钉安全规则将 天勤量化 设为关键字 18 | msg = {"msgtype": "text", 19 | "text": {"content": "{}\n{}\n".format("天勤量化\n" + content, 20 | datetime.now().strftime("%Y-%m-%d %H:%M:%S"))}, } 21 | headers = {"content-type": "application/json;charset=utf-8"} 22 | body = dumps(msg) 23 | requests.post(webhook, data=body, headers=headers) 24 | print(content) 25 | 26 | 27 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 28 | quote = api.get_quote("SHFE.rb2109") 29 | target_pos = TargetPosTask(api, "SHFE.rb2110") 30 | send_msg("策略开始运行") 31 | a = 0 32 | while True: 33 | api.wait_update() 34 | # 通过本地变量 a 来避免多次发送钉钉消息触发流控 35 | if quote.last_price > 5110 and a == 0: 36 | send_msg("行情满足条件,开多头5手") 37 | target_pos.set_target_volume(5) 38 | a = 1 39 | 40 | 41 | 具体说明,请参考 `钉钉操作手册 `_ 42 | -------------------------------------------------------------------------------- /doc/advanced/evolution.rst: -------------------------------------------------------------------------------- 1 | 使用逐步完善的方式构建交易策略 2 | ================================================= 3 | `TqSdk`_ 的目标是能尽可能减少编码环节引入的坑,而交易逻辑本身的坑则需要用户自己填,如果每次调整交易逻辑都需要大规模的代码重构会严重阻碍交易系统的演化。 4 | 5 | `TqSdk`_ 鼓励使用线性的编码风格,因此可以做到小调交易逻辑只需小改,只有大调交易逻辑时才需要大改。以 `R-Breaker`_ 策略为例, 6 | 第一版是留仓过夜,回测下来可能发现留仓过夜引入了很大的风险,却没有获得与风险对应的收益,因此修改交易策略,收盘前清仓离场, 7 | 对应代码的修改只需在主循环中加入判断是否接近收盘并平仓:: 8 | 9 | if api.is_changing(quote, "datetime"): 10 | now = datetime.strptime(quote.datetime, "%Y-%m-%d %H:%M:%S.%f") 11 | if now.hour == close_hour and now.minute >= close_minute: # 到达平仓时间: 平仓 12 | print("临近本交易日收盘: 平仓") 13 | target_pos.set_target_volume(0) # 平仓 14 | deadline = time.time() + 60 15 | while api.wait_update(deadline=deadline): # 等待60秒 16 | pass 17 | api.close() 18 | break 19 | 20 | 上述代码在行情时间变化时判断是否接近收盘,如果是的话则将目标持仓设为0(即空仓)。由于下单之后不一定能立即成交,价格变化后可能还需撤单重下, 21 | 因此等待一分钟后再退出,通常交易的合约不是太冷门的话一分钟应该足够了,如果不放心的话可以改为判断持仓手数是否为0。 22 | 23 | 更多的用例可以参见: https://doc.shinnytech.com/pysdk/latest/demo.html 24 | 25 | 26 | 27 | 28 | .. _TqSdk: https://doc.shinnytech.com/pysdk/latest/index.html 29 | .. _TqSim: https://doc.shinnytech.com/pysdk/latest/reference.html#tqsdk.sim.TqSim 30 | .. _get_kline_serial: https://doc.shinnytech.com/pysdk/latest/reference.html#tqsdk.api.TqApi.get_kline_serial 31 | .. _TargetPosTask: https://doc.shinnytech.com/pysdk/latest/reference.html#tqsdk.lib.TargetPosTask 32 | .. _wait_update: https://doc.shinnytech.com/pysdk/latest/reference.html#tqsdk.api.TqApi.wait_update 33 | .. _DIFF: https://doc.shinnytech.com/diff/latest/index.html 34 | .. _get_account: https://doc.shinnytech.com/pysdk/latest/reference.html#tqsdk.api.TqApi.get_account 35 | .. _get_quote: https://doc.shinnytech.com/pysdk/latest/reference.html#tqsdk.api.TqApi.get_quote 36 | .. _is_changing: https://doc.shinnytech.com/pysdk/latest/reference.html#tqsdk.api.TqApi.is_changing 37 | .. _TqBacktest: https://doc.shinnytech.com/pysdk/latest/reference.html#tqsdk.backtest.TqBacktest 38 | .. _R-Breaker: https://github.com/shinnytech/tqsdk-python/blob/master/tqsdk/demo/example/rbreaker.py 39 | -------------------------------------------------------------------------------- /doc/advanced/gui.rst: -------------------------------------------------------------------------------- 1 | .. _gui: 2 | 3 | 与Gui库共同工作 4 | ================================================= 5 | 某些情况下, 我们可能需要在一个 Python GUI 程序中使用TqSdk库. TqSdk 可以与Tkinter, PyQt, WxPython, PySimpleGui 等大多数常见 Python Gui 库配合工作. 6 | 7 | 下面以 PySimpleGui 为例, 介绍 Gui 库与 TqSdk 组合使用的方式. 8 | 9 | 10 | 先后使用GUI库和TqSdk 11 | ------------------------------------------------- 12 | 参见示例程序 param_input.py. 这个程序先使用 PySimpleGui 创建一个参数输入对话框, 用户输入参数后, 关闭对话框, 开始使用 TqSdk: 13 | 14 | .. literalinclude:: ../../tqsdk/demo/gui/param_input.py 15 | :language: python 16 | 17 | 18 | 在两个线程中分别运行Gui和TqSdk 19 | ------------------------------------------------- 20 | 参见示例程序 multi_thread.py. 21 | 22 | .. literalinclude:: ../../tqsdk/demo/gui/multi_thread.py 23 | :language: python 24 | 25 | 26 | 在TqSdk任务中驱动Gui消息循环 27 | ------------------------------------------------- 28 | 参见示例程序 loop_integrate.py. 29 | 30 | .. literalinclude:: ../../tqsdk/demo/gui/loop_integrate.py 31 | :language: python 32 | 33 | -------------------------------------------------------------------------------- /doc/advanced/index.rst: -------------------------------------------------------------------------------- 1 | .. _advanced: 2 | 3 | 进阶主题 4 | ======================================== 5 | 这一部分内容提供给有经验的 TqSdk 用户, 主要讲解将 TqSdk 用于实际工作时的一些重要问题的处理方案和最佳实践. 6 | 7 | .. toctree:: 8 | :maxdepth: 2 9 | 10 | order.rst 11 | backtest.rst 12 | multi_strategy.rst 13 | gui.rst 14 | dingding.rst 15 | for_vnpy_user.rst 16 | for_ctp_user.rst 17 | unanttended.rst 18 | targetpostask2.rst 19 | scheduler.rst 20 | -------------------------------------------------------------------------------- /doc/advanced/order.rst: -------------------------------------------------------------------------------- 1 | .. _advanced_order: 2 | 3 | 高级委托指令 4 | ================================================= 5 | 6 | 在实盘交易中, 除常见的限价委托指令外, tqsdk 提供了 FAK / FOK 两种高级市价指令。 7 | 8 | insert_order 为用户提供了 limit_price,advanced 两个参数指定下单指令,两个参数支持的值的组合为: 9 | 10 | =========== ======== ==================================== 11 | limit_price advanced memo 12 | =========== ======== ==================================== 13 | 指定价格 None 限价指令,即时成交,当日有效 14 | 指定价格 FAK 限价指令,即时成交剩余撤销 15 | 指定价格 FOK 限价指令,即时全部成交或撤销 16 | None None 市价指令,即时成交剩余撤销 17 | None FAK 市价指令,即时成交剩余撤销 18 | None FOK 市价指令,即时全部成交或撤销 19 | BEST None 最优一档即时成交剩余撤销指令 20 | BEST FAK 最优一档即时成交剩余撤销指令 21 | FIVELEVEL None 最优五档即时成交剩余撤销指令 22 | FIVELEVEL FAK 最优五档即时成交剩余撤销指令 23 | =========== ======== ==================================== 24 | 25 | * limit_price 默认值为 ``None`` 26 | * advance 默认值为 ``None`` 27 | * 对于市价单、BEST、FIVELEVEL,``advanced="FAK"`` 与默认参数 ``None`` 的实际报单请求一样。 28 | 29 | 30 | 例如:: 31 | 32 | from tqsdk import TqApi, TqAuth 33 | 34 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 35 | # 当日有效限价单 36 | api.insert_order("SHFE.cu2009", "BUY", "OPEN", 3, limit_price=14200) 37 | # FAK 限价单 38 | api.insert_order("SHFE.cu2009", "BUY", "OPEN", 3, limit_price=14200, advanced="FAK") 39 | # FOK 限价单 40 | api.insert_order("SHFE.cu2009", "BUY", "OPEN", 3, limit_price=14200, advanced="FOK") 41 | 42 | # 市价单 43 | api.insert_order("DCE.m2009", "BUY", "OPEN", 3) 44 | # FOK 市价单 45 | api.insert_order("DCE.m2009", "BUY", "OPEN", 3, advanced="FOK") 46 | 47 | # BEST 48 | api.insert_order("CFFEX.T2003", "BUY", "OPEN", 3, limit_price="BEST") 49 | # FIVELEVEL 50 | api.insert_order("CFFEX.T2003", "BUY", "OPEN", 3, limit_price="FIVELEVEL") 51 | 52 | 53 | 不同交易所支持的高级指令参数组合: 54 | 55 | ======== ============== ==================== ==================== 56 | 交易所 品种 limit_price advance 57 | ======== ============== ==================== ==================== 58 | 郑商所 期货 指定价格 / None None / FAK 59 | 郑商所 期权 指定价格 / None None / FAK / FOK 60 | 大商所 期货 指定价格 / None None / FAK / FOK 61 | 大商所 期权 指定价格 None / FAK / FOK 62 | 上期所 期货/期权 指定价格 None / FAK / FOK 63 | 中金所 期货/期权 指定价格 None / FAK / FOK 64 | 中金所 期货/期权 BEST / FIVELEVEL None / FAK 65 | 上交所 ETF期权 指定价格 None / FOK 66 | 深交所 ETF期权 指定价格 None / FOK 67 | ======== ============== ==================== ==================== 68 | -------------------------------------------------------------------------------- /doc/advanced/pandas.rst: -------------------------------------------------------------------------------- 1 | 与 pandas 配合使用 2 | ================================================= 3 | This part of the documentation covers the installation of Requests. The first step to using any software package is getting it properly installed. 4 | 5 | -------------------------------------------------------------------------------- /doc/advanced/processing.rst: -------------------------------------------------------------------------------- 1 | 业务数据处理 2 | ================================================= 3 | This part of the documentation covers the installation of Requests. The first step to using any software package is getting it properly installed. 4 | 5 | -------------------------------------------------------------------------------- /doc/advanced/targetpostask2.rst: -------------------------------------------------------------------------------- 1 | .. _targetpostask2: 2 | 3 | TargetPosTask 高级功能 4 | ==================================================== 5 | 6 | 本篇文档假设您已经了解 :py:class:`~tqsdk.TargetPosTask` 的用法,文档参考 :ref:`targetpostask`。 7 | 8 | 本篇文档主要介绍 :py:class:`~tqsdk.TargetPosTask` 的高级用法。如何使用\ 9 | :py:meth:`~tqsdk.TargetPosTask.cancel` 和 :py:meth:`~tqsdk.TargetPosTask.is_finished` 方法。 10 | 11 | 12 | 应用情景说明 13 | ---------------------------------------------------- 14 | 15 | 任何时刻,每个账户下一个合约只能有一个 :py:class:`~tqsdk.TargetPosTask` 实例,并且其构造参数不能修改。 16 | 17 | 但是在某些情况下,用户会希望可以管理 :py:class:`~tqsdk.TargetPosTask` 实例。 18 | 19 | 比如说,用户使用 :py:class:`~tqsdk.TargetPosTask` 的 **PASSIVE** 模式进行下单,希望在收盘前取消所有挂单(包含 :py:class:`~tqsdk.TargetPosTask` 实例的未成委托单),并平仓。 20 | 21 | 如何实现这样的功能 22 | ---------------------------------------------------- 23 | 24 | :py:class:`~tqsdk.TargetPosTask` 类提供了 :py:meth:`~tqsdk.TargetPosTask.cancel` 和 :py:meth:`~tqsdk.TargetPosTask.is_finished` 方法。 25 | 26 | + :py:meth:`~tqsdk.TargetPosTask.cancel` 方法会取消当前 :py:class:`~tqsdk.TargetPosTask` 实例,会将该实例已经发出但还未成交的委托单撤单此实例的 set_target_volume 函数不会再生效,并且此实例的 set_target_volume 函数不会再生效。 27 | + :py:meth:`~tqsdk.TargetPosTask.is_finished` 方法可以获取当前 :py:class:`~tqsdk.TargetPosTask` 实例是否已经结束。已经结束实例的 set_target_volume 函数不会再接受参数,此实例不会再下单或者撤单。 28 | 29 | 下面是一个例子:: 30 | 31 | from datetime import datetime, time 32 | from tqsdk import TqApi, TargetPosTask 33 | 34 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 35 | quote = api.get_quote("SHFE.rb2110") 36 | target_pos_passive = TargetPosTask(api, "SHFE.rb2110", price="PASSIVE") 37 | 38 | while datetime.strptime(quote.datetime, "%Y-%m-%d %H:%M:%S.%f").time() < time(14, 50): 39 | api.wait_update() 40 | # ... 策略代码 ... 41 | 42 | # 取消 TargetPosTask 实例 43 | target_pos_passive.cancel() 44 | 45 | while not target_pos_passive.is_finished(): # 此循环等待 target_pos_passive 处理 cancel 结束 46 | api.wait_update() # 调用wait_update(),会对已经发出但还是未成交的委托单撤单 47 | 48 | # 创建新的 TargetPosTask 实例 49 | target_pos_active = TargetPosTask(api, "SHFE.rb2110", price="ACTIVE") 50 | target_pos_active.set_target_volume(0) # 平所有仓位 51 | 52 | while True: 53 | api.wait_update() 54 | # ... 策略代码 ... 55 | 56 | api.close() 57 | 58 | -------------------------------------------------------------------------------- /doc/advanced/timer.rst: -------------------------------------------------------------------------------- 1 | 定时器 2 | ================================================= 3 | This part of the documentation covers the installation of Requests. The first step to using any software package is getting it properly installed. 4 | 5 | -------------------------------------------------------------------------------- /doc/advanced/tq_trading_unit.rst: -------------------------------------------------------------------------------- 1 | .. _tq_trading_unit: 2 | 3 | ============================ 4 | tqsdk 多策略使用手册 5 | ============================ 6 | 7 | 概述 8 | ==== 9 | `tqsdk` 提供了 `TqTradingUnit` 账户类型,支持一个实盘账号在多个策略中交易,每个策略交易数据相互隔离 10 | 11 | 系统配置要求 12 | ============ 13 | - **Windows**: >= Windows 10 14 | - **Linux**: >= Ubuntu 22.04 15 | 16 | 安装 17 | ==== 18 | 使用 `TqTradingUnit` 账户类型需要安装 `tqsdk-zq` 包,用来初始化本地环境:: 19 | 20 | pip install tqsdk-zq 21 | 22 | 对于 Windows 用户,还需要安装 Microsoft Visual C++ Redistributable,下载地址: 23 | `Microsoft Redistributable `_ 24 | 25 | 使用流程 26 | ======== 27 | 28 | 1. **初始化本地环境**:: 29 | 30 | tqsdk-zq init --kq-name=xx --kq-password=xx --web-port=xx 31 | 32 | - 初始化完成后,控制台会输出多策略管理页的账户、密码以及网址 33 | - 打开浏览器,访问控制台输出的网址 34 | 35 | 2. **打印多策略控制台地址**:: 36 | 37 | tqsdk-zq web 38 | 39 | - 如果机器重启或者网页打不开了,请执行以上命令 40 | - 进程重新拉起后,控制台会输出管理页网址 41 | 42 | 3. **访问多策略管理页**: 43 | 44 | - 在多策略管理页添加策略组 45 | - 在策略组中添加后端账号 46 | - 在策略组中添加前端号并入金 47 | 48 | 4. **使用 TqTradingUnit 登录前端账户**:: 49 | 50 | from tqsdk import TqApi, TqTradingUnit, TqAuth 51 | 52 | account = TqTradingUnit(account_id="前端账户", tags=["铜品种策略", "套利策略"]) 53 | api = TqApi(account, auth=TqAuth("快期账户", "账户密码")) 54 | 55 | -------------------------------------------------------------------------------- /doc/advanced/tqsdk2ctptest.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk2ctptest: 2 | 3 | 在 TqSdk 中调用 TqSdk2 查询保证金 4 | ================================================= 5 | TqSdk 没有直接提供查询保证金的接口,但是你可以通过使用 TqSdk2 的直连功能来做到这个效果。tqsdk和tqsdk2可以在一个py文件中同时运行。 6 | 7 | 该方法仅支持 TqSdk2 中直连CTP 柜台时使用。受限制于 CTP 柜台的流控机制(每秒 1 笔), 短时间发送大量查询指令后, 后续查询指令将会排队等待。 8 | 为了避免盘中的查询等待时间, 建议盘前启动程序, 对标的合约提前进行查询:: 9 | 10 | from tqsdk import TqApi, TqAuth, TqAccount 11 | import tqsdk2 12 | 13 | account = tqsdk2.TqCtp(front_url, front_broker, app_id, auth_code, account_id, password) 14 | api_margin = tqsdk2.TqApi(account = account, auth=tqsdk2.TqAuth("快期账户", "账户密码")) 15 | rate = api_margin.get_margin_rates("SHFE.cu2201") 16 | print(rate) 17 | api = TqApi(TqAccount("期货公司","账号","密码"),auth=TqAuth("快期账户", "账户密码")) 18 | quote = api.get_quote("SHFE.cu2201") 19 | while True: 20 | api.wait_update() 21 | print(quote.datetime) 22 | # 正常和tqsdk一样执行策略 23 | 24 | 25 | TqSdk2 的直连功能需要企业版权限,有关企业版的具体费用和功能,请参考 `天勤官方网站 `_ 26 | 如果想了解更多关于 TqSdk2 的直连功能TqCtp,请参考 `tqsdk2官方文档 `_ 27 | -------------------------------------------------------------------------------- /doc/demo/algorithm.rst: -------------------------------------------------------------------------------- 1 | .. _demo_algorithm: 2 | 3 | 算法模块示例 4 | ==================================================== 5 | 6 | .. contents:: 目录 7 | 8 | 9 | .. _demo-algorithm-twap: 10 | 11 | twap_table - 时间平均加权算法 12 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 13 | 14 | .. literalinclude:: ../../tqsdk/demo/algorithm/twap.py 15 | :language: python 16 | 17 | 18 | .. _demo-algorithm-vwap: 19 | 20 | vwap_table - 交易量平均加权算法 21 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 22 | 23 | .. literalinclude:: ../../tqsdk/demo/algorithm/vwap.py 24 | :language: python -------------------------------------------------------------------------------- /doc/demo/index.rst: -------------------------------------------------------------------------------- 1 | .. _demo: 2 | 3 | 示例程序 4 | ==================================================== 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | base.rst 10 | option_base.rst 11 | algorithm.rst 12 | strategy.rst 13 | jupyter.rst 14 | 15 | -------------------------------------------------------------------------------- /doc/demo/jupyter.rst: -------------------------------------------------------------------------------- 1 | .. _demo_jupyter: 2 | 3 | Jupyter 示例 4 | ==================================================== 5 | 6 | .. contents:: 目录 7 | 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: 目录: 12 | 13 | notebooks/demo 14 | notebooks/factor 15 | -------------------------------------------------------------------------------- /doc/demo/notebooks/demo.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "metadata": {}, 5 | "cell_type": "markdown", 6 | "source": "## 获取实时行情", 7 | "id": "cf67a7321f3bb1f9" 8 | }, 9 | { 10 | "cell_type": "code", 11 | "id": "initial_id", 12 | "metadata": { 13 | "collapsed": true, 14 | "ExecuteTime": { 15 | "end_time": "2024-06-19T02:43:38.474676Z", 16 | "start_time": "2024-06-19T02:43:37.562702Z" 17 | } 18 | }, 19 | "source": [ 20 | "from tqsdk import TqApi, TqSim, TqAuth\n", 21 | "auth = TqAuth('快期账户', '快期密码')" 22 | ], 23 | "outputs": [ 24 | { 25 | "name": "stderr", 26 | "output_type": "stream", 27 | "text": [ 28 | "在使用天勤量化之前,默认您已经知晓并同意以下免责条款,如果不同意请立即停止使用:https://www.shinnytech.com/blog/disclaimer/\n" 29 | ] 30 | } 31 | ], 32 | "execution_count": 1 33 | }, 34 | { 35 | "metadata": { 36 | "ExecuteTime": { 37 | "end_time": "2024-06-19T02:43:40.994847Z", 38 | "start_time": "2024-06-19T02:43:38.476915Z" 39 | } 40 | }, 41 | "cell_type": "code", 42 | "source": "api = TqApi(TqSim(), auth=auth)", 43 | "id": "1e9889a79d1712c6", 44 | "outputs": [], 45 | "execution_count": 2 46 | }, 47 | { 48 | "metadata": { 49 | "ExecuteTime": { 50 | "end_time": "2024-06-19T02:43:41.019471Z", 51 | "start_time": "2024-06-19T02:43:40.996711Z" 52 | } 53 | }, 54 | "cell_type": "code", 55 | "source": "q = api.get_quote('SHFE.rb2410')", 56 | "id": "2882551c574b0eb", 57 | "outputs": [], 58 | "execution_count": 3 59 | }, 60 | { 61 | "metadata": { 62 | "ExecuteTime": { 63 | "end_time": "2024-06-19T02:43:41.025745Z", 64 | "start_time": "2024-06-19T02:43:41.021628Z" 65 | } 66 | }, 67 | "cell_type": "code", 68 | "source": "print(q.datetime, q.last_price)", 69 | "id": "61778b7e63c12fd7", 70 | "outputs": [ 71 | { 72 | "name": "stdout", 73 | "output_type": "stream", 74 | "text": [ 75 | "2024-06-19 10:43:40.500000 3639\n" 76 | ] 77 | } 78 | ], 79 | "execution_count": 4 80 | }, 81 | { 82 | "metadata": { 83 | "ExecuteTime": { 84 | "end_time": "2024-06-19T02:43:41.051300Z", 85 | "start_time": "2024-06-19T02:43:41.027038Z" 86 | } 87 | }, 88 | "cell_type": "code", 89 | "source": "api.close()", 90 | "id": "d399ddff6ba9fc70", 91 | "outputs": [], 92 | "execution_count": 5 93 | } 94 | ], 95 | "metadata": { 96 | "kernelspec": { 97 | "display_name": "Python 3", 98 | "language": "python", 99 | "name": "python3" 100 | }, 101 | "language_info": { 102 | "codemirror_mode": { 103 | "name": "ipython", 104 | "version": 2 105 | }, 106 | "file_extension": ".py", 107 | "mimetype": "text/x-python", 108 | "name": "python", 109 | "nbconvert_exporter": "python", 110 | "pygments_lexer": "ipython2", 111 | "version": "2.7.6" 112 | } 113 | }, 114 | "nbformat": 4, 115 | "nbformat_minor": 5 116 | } 117 | -------------------------------------------------------------------------------- /doc/demo/option_base.rst: -------------------------------------------------------------------------------- 1 | .. _demo_options: 2 | 3 | 期权基本使用 4 | ==================================================== 5 | 6 | .. contents:: 目录 7 | 8 | 9 | .. _option_tutorial-t10: 10 | 11 | o10 - 获取期权实时行情 12 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 13 | 14 | .. literalinclude:: ../../tqsdk/demo/option_tutorial/o10.py 15 | :language: python 16 | 17 | 18 | .. _option_tutorial-t20: 19 | 20 | o20 - 查询符合要求的期权 21 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 22 | 23 | .. literalinclude:: ../../tqsdk/demo/option_tutorial/o20.py 24 | :language: python 25 | 26 | 27 | .. _option_tutorial-t30: 28 | 29 | o30 - 查询平值/虚值/实值期权 30 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 31 | 32 | .. literalinclude:: ../../tqsdk/demo/option_tutorial/o30.py 33 | :language: python 34 | 35 | 36 | .. _option_tutorial-t40: 37 | 38 | o40 - 计算期权的希腊字母 39 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 40 | 41 | .. literalinclude:: ../../tqsdk/demo/option_tutorial/o40.py 42 | :language: python 43 | 44 | 45 | .. _option_tutorial-t41: 46 | 47 | o41 - 计算期权隐含波动率和历史波动率 48 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 49 | 50 | .. literalinclude:: ../../tqsdk/demo/option_tutorial/o41.py 51 | :language: python 52 | 53 | 54 | .. _option_tutorial-t60: 55 | 56 | o60 - 获取期权波动率曲面 57 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 58 | 59 | .. literalinclude:: ../../tqsdk/demo/option_tutorial/o60.py 60 | :language: python 61 | 62 | .. _option_tutorial-t70: 63 | 64 | o70 - 期权套利策略 65 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 66 | 67 | .. literalinclude:: ../../tqsdk/demo/option_tutorial/o70.py 68 | :language: python 69 | 70 | o71 - 获取一组期权和其对应行权价 71 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 72 | 73 | .. literalinclude:: ../../tqsdk/demo/option_tutorial/o71.py 74 | :language: python 75 | 76 | o72 - 查询标的对应期权按虚值平值实值分类方法一 77 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 78 | 79 | .. literalinclude:: ../../tqsdk/demo/option_tutorial/o72.py 80 | :language: python 81 | 82 | o73 - 查询标的对应期权按虚值平值实值分类方法二 83 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 84 | 85 | .. literalinclude:: ../../tqsdk/demo/option_tutorial/o73.py 86 | :language: python 87 | 88 | o74 - 本地计算ETF期权卖方开仓保证金 89 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 90 | 91 | .. literalinclude:: ../../tqsdk/demo/option_tutorial/o74.py 92 | :language: python -------------------------------------------------------------------------------- /doc/dev/async_tool.rst: -------------------------------------------------------------------------------- 1 | .. _dev_async_tool: 2 | 3 | 异步工具 4 | ==================================================== 5 | @todo: 待写 6 | -------------------------------------------------------------------------------- /doc/dev/backtest.rst: -------------------------------------------------------------------------------- 1 | .. _dev_backtest: 2 | 3 | 策略回测框架 4 | ================================================= 5 | @todo: 待写 6 | -------------------------------------------------------------------------------- /doc/dev/diff.drawio: -------------------------------------------------------------------------------- 1 | 7ZpJc9owFMc/DcdkbHnBHFNCmmaSTFMOpb1kNFix1QiLyjJLPn1lLONFwLhhkZPhBPpLsq333k97x+pPFl8ZnIYP1EekAwx/0bGuOwCYNjDFT6osM6XngkwIGPZloUIY4jckRUOqCfZRXCnIKSUcT6vimEYRGvOKBhmj82qxF0qqb53CACnCcAyJqv7EPg8z1QPdQr9FOAjzN5tuL8uZwLywbEkcQp/OS5I16Fh9RinP/k0WfURS4+V2yerdbMldfxhDEW9SATw9zvBblHwL+N1Tf4SDix/XF9IZMV/mDUa+aL9MUsZDGtAIkkGhfmE0iXyUPtUQqaLMPaVTIZpC/IM4X0pnwoRTIYV8QmQuWmA+SqtfOjL1q5RzvZBPXiWWeSLyr1J3imREI5QpN5gQmZ+1I/34reaRUkwTNpalru7h8uWO/n5cuM929/HB5tb8wlw7R0Q1ohPE2VLUY4hAjmfV50MZXsG63Lrqd4rFm4GRo5DHwTIPcMOoPoNDFiAuqxWOFH9K31FIK/dudvX2ZgFjBkki25C+ou7+qnPnIeZoOIUre80F4VVHbrXxDDGOFiVJNafM9WpWya00L8EmpbDEmW1st3/FcDustBEISysQJRwKOE4JxEabnAaIdUd5eB42t6r7cfo+0dJROVEKkDRZVFuldIWIGJpXLttRzt4zlPZiW+0B/yaUi9nFATpBpcfbYMetnaBZ6wWBobkXNL0zGwdjw27IhqOTDVthY3h7M7gcJ2bPMJVgODUg9WkCcDUD4ijmIjDmz1OGhRF0W8uqWctqOKmqD8CH605651mVYhT3KLMqqzarso63ytjeqgoYM0qSSQuhaNiFHA2K9b7AB4AiH2OLYXU9MrdjjPUajrH7LmX28ri3Y4xVN2J0j7G27kkoUOcdZ0DeC0hPBeQom197ebynAPJKcNTCBZrt6WZD78bt52IjP2toNxz5V5bo4Hj82j44HFs3HB9oE7f9cGzY2mshHOreHmfQ17/sqMPhap9V2Wc4DgcHUOHYEZ/a6AAKHUmMWPv29Vzd+3rAOdNxODqspnQArXRYCh1TGmOOaaR/clXfturqPiAH7pmQwxHS9Gwoi1FthLT7dMiuM6J9da73asEnY8RpyojeywXqkaAYRZ4JjQLtgDg1QLyGK/TjnX3ovV/wX4CcLtCPcyLo1E4EvVPfs1KPBFMw4lB4sH1kNBw63kGGSBaXfTPjFlemrcE/7ZpLc5swEIB/jY/JIIHBHBvHaZJpZppxH+kpozEqKAVEhIjt/PoKI8xDaYJDCTDjk63VA7S732q1w0SfB5vPDEXeDXWwP4Gas5no5xMIgQGB+Ekl20ximzATuIw4clAhWJJnLIWalCbEwXFlIKfU5ySqClc0DPGKV2SIMbquDvtN/epTI+RiRbBcIV+V/iQO96QUmHbRcYmJ68lHz6CVdQQoHyx3EnvIoeuSSF9M9DmjlGf/gs0c+6nycr1cbfDqITJ/sOvb7bNx8+fRtOyTbLGLQ6bst8BwyN+99FlIbgMzugwX8+uT+Na+uvn+7STfGt/m+sKOUJ9sUsY96tIQ+YtCesZoEjo4XVUTrWLMF0ojIQRC+IA530pfQAmnQuTxwJe9eEP4XTr9dCpbv0o95xu58q6xzRuh8yn1BtEMaYgzyQXxfdmf7SN9+ZrZ39CZHBfThK3wK4oCe4MLUjANMGdbMY9hH3HyVH0oki7r7sftp36lRLwO1CReM6l/yZZlatUVOGIu5nJSYVvxp/QWhWhn8QOsL9/3CfmJ3EH6iLpHVO299gjHywjttLUWMaNqW7kiZhxv3mEJVcNyFaOqqVxx6wLpXOSVYDa0f1ukosxDNQd75aZETcHQMLkxPoIbMPtYbvTxRE2x0btyo+QzabOYtmsNymtEorAz4yvjzJbe1SoGGEr0fEwoF7nOIAMoqEVQYPYcQqdHiLqFyGwIkdUnRKYC0fLyYnG6SoCtAcVDBkFSPRfZXxD6IslSdOijmN9HjAjNDFKFel2FDfM52JUKZ8d8rllQsTvJ5+oJHfzgi5CtEPRE/SQYCT16wwDUGT2g3zLCQfjkZ3lxfO8zgAGf5SAvnb11mLe9b7XzA7WgUJzm6pV5EDDVT3O977wYmEeYOobJaghT26JfOz9Q0zrOkDPQM6l+vTT6TorBiFK6kWJkN8Wo1xsmUJO7JMZsJJdLo/dK9zG365gj2DS3A20vX+0cQU3uIhoTTmg40JJn/Z40NfpmSc2Bjyz9X5b0hizBXnO7/DXHVPY0ajSZWt80GUeaOqZp2pQmvVeapi+dTPc+Dd1hojSto9Sw5tBZAQ+OqObQMxJt7zIvF8CNWgHcrEfNjgvgUC02pAjFnjDrOBiyGh5H72BINIuv/DKNF99K6ou/ -------------------------------------------------------------------------------- /doc/dev/general.rst: -------------------------------------------------------------------------------- 1 | .. _dev_general: 2 | 3 | 原则与规范 4 | ==================================================== 5 | 6 | TqSdk设计原则 7 | ---------------------------------------------------- 8 | 9 | 不预设用户策略模型 10 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11 | 我们深刻认识到, 量化交易是一个充满竞争与创新的领域,成功的用户总是在不断构思和尝试全新的理念与模型. 在这方面, 用户比我们知道得更多, 走得也更快. 因此, 我们在设计TqSdk时, 总是尽力避免对用户的模型结构做限定, 而是专注于为用户提供通用性的资源和能力. 12 | 13 | 我们的以下设计决策遵循了此原则: 14 | 15 | * 不提供策略类模板, 只以示例程序方式展示各类策略应用 16 | * 一个策略程序中可以任意获取数据和发出指令 17 | * 允许用户在一个程序中使用任意多个TqApi实例 18 | 19 | 20 | 保持用户代码简单 21 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 22 | 我们对TqSdk的一个设计目标是尽量让用户的代码与需求方案保持一致(顺序相同, 篇幅相当). 23 | 24 | 我们的以下设计决策遵循了此原则: 25 | 26 | * 不使用多线程, 避免用户处理线程同步问题 27 | * 不使用回调模型, 避免用户维护状态机状态变量 28 | * 提供专门的调仓工具 29 | * 实盘/模拟/回测/复盘 几种不同运行模式切换, 只需要在代码中做单点修改 30 | 31 | 32 | 行为可验证 33 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 34 | 作为TqSdk库质量管控的关键措施, 我们要求 TqSdk 在运行时可以记录完整的输入信息, 以确保发生问题时可以稳定重现问题和定位原因. 我们做了这些决定: 35 | 36 | * 以数据流衔接库中的各组件 37 | * TqSdk 的日志文件完整记录收到的全部数据包 38 | * 专门构建了一个单元测试框架, 可以直接用日志作为测试用例输入 39 | 40 | 41 | 相关知识与技能 42 | ---------------------------------------------------- 43 | TqSdk 的开发涉及以下知识点,您可能需要先学习它们,才能更好的理解和改进TqSdk的代码 44 | 45 | * 金融相关业务知识 46 | 47 | TqSdk是用于金融交易领域的专用软件包。我们假定用户和开发者都已经具备相应的基础知识,在TqSdk的文档中不再详加解释。 48 | 49 | * python asyncio 50 | 51 | TqSdk 的代码大量依赖 python asyncio 机制. asyncio 的编程模型与传统 python 程序差异很大. 我们对于TqSdk的使用者尽量隐藏了 asyncio 相关概念, 允许用户在不了解 asyncio 的情况下实现绝大多数业务需求. 但是对于开发者, 若不了解 asyncio, 在理解 TqSdk 内部代码实现时会非常困难。 52 | 53 | * Diff协议 54 | 55 | TqSdk 并不是一个 all-in-one 的包, 它的能力有赖于一系列后台服务的支持. DIFF协议是 TqSdk 与后台服务间通讯的主要协议, 开发者需对 DIFF 有所理解, 才能掌握 TqSdk 的内部实现 56 | 57 | * Pandas/Numpy 58 | 59 | Pandas/Numpy 是非常优秀的 python 数值计算库. TqSdk 利用这些库完成K线序列数据的存储和操作. 60 | 61 | 62 | 代码风格 63 | ---------------------------------------------------- 64 | TqSdk的代码风格遵循 PEP8 规范. 65 | 66 | 67 | 日志规范 68 | ---------------------------------------------------- 69 | @todo: 待写 70 | 71 | 72 | -------------------------------------------------------------------------------- /doc/dev/gui.rst: -------------------------------------------------------------------------------- 1 | .. _dev_gui: 2 | 3 | Web Gui 4 | ==================================================== 5 | @todo: 待写 6 | -------------------------------------------------------------------------------- /doc/dev/index.rst: -------------------------------------------------------------------------------- 1 | .. _dev: 2 | 3 | 参与TqSdk开发 4 | ======================================== 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | general.rst 10 | framework.rst 11 | async_tool.rst 12 | gui.rst 13 | backtest.rst 14 | unittest.rst 15 | 16 | -------------------------------------------------------------------------------- /doc/dev/unittest.rst: -------------------------------------------------------------------------------- 1 | .. _dev_unittest: 2 | 3 | 单元测试 4 | ==================================================== 5 | @todo: 待写 6 | -------------------------------------------------------------------------------- /doc/dev/workflow.drawio: -------------------------------------------------------------------------------- 1 | 7VrLcpswFP0aLZsBiecSEtIu0k6n6UybVUcxqqHGyBFybPfrK4EwYMUOSZvI6Xhl3asXOrpHOhcD0Pl8/Z7hRfaRpqQA0ErXAF0ACG0H2uJHejaNJ/Rg45iyPFWNOsd1/psop6W8yzwl1aAhp7Tg+WLonNCyJBM+8GHG6GrY7CcthrMu8JRojusJLnTvtzzlWeMNoN/5P5B8mrUz217Y1Mxx21itpMpwSlc9F0oAOmeU8qY0X5+TQoLX4tL0u9xTu30wRko+psPyS3X/6Wqd3pINms+yG9e34ne2Gqbim3bFJBUAKJMyntEpLXGRdN6Y0WWZEjmsJayuzRWlC+G0hfMX4XyjdhMvORWujM8LVUvWOf8uu5+5yrrp1Vys1ci1sWmNkrNNr5M0b/p1Xbfaavs165OL2otbiwFdsgk5BJaKP8ymhB9oB7e7K2hB6JyI5xH9GCkwz++Hz4FVfE637botFAW1i0/Z0Wbce1ws1Uwg8UHogCgAiQeCAMQ+SBwQxyBCsiqyQKBHwXCPV1nOyfUC1/CsBNOH+6mmJIyT9WGUdVRUh0CxZDM0Vx3n7JZIWY9vjvVSMMITMUYTA44kBjJJDKgRAy/ysxXO+Y/lIsWcHBsHbM84CdCJBKNJgEaSwDFJAvRf3A7biDfHDP/EjNHMcEYyw3ZNUsN5a/cDgqZZ4GqQrchtRSczsc0iJStyuTDoFeI54lsmSlNZAokLgksQ2iAJQdCcLyI4qplxgJG3c84Yv4G9ZyIsjvIERK4siMM99o4VYWSZRtgfdSO6shDWoSuuxjiq20QgcOoqVyIsClECAnScOBtPqAIN56931+nsALT8rkqPEEnj2iPUI1bTImUayZdfwippKbVHiqusRs3ekRSdPLCEqOkLhDPLdx8RCbX1mbBcrIywJyuHRxXBHkHQg959APnWN1o3qBk+01yepu3OQ2vPfdsO0Qgf1av/5m13IHfnWvF3Bmpw0Aaqo2O77L8Qq9Y/jRglQu02YMbJUGE8P1DGSUxTgbKjy5zwmXGye9Q4dvC6ceLoYXFKag4mK2OyGu/h2Hyl18G6Rn+LGb9jXCdCHZMTOQ7H/BhyhEbJoadXR57zO8Z1fHsnnXgwhgfhSB70/hE2wYMHUoo3eEm4xl/XQF1pH/mB4r1gOivM7vOGRqR2H4mg5A8= -------------------------------------------------------------------------------- /doc/devtools/drawindex.rst: -------------------------------------------------------------------------------- 1 | .. _draw_indicator: 2 | 3 | 技术指标绘图和使用示例 4 | ========================================================================= 5 | 在TqSdk中我们提供了非常丰富的 :ref:`tqsdk.ta` ,下面我们以真实波幅均值(ATR average true range)为例,来讲解这个指标在策略中如何使用并在天勤终端和VS code插件版中进行画图 6 | 7 | ATR的计算比较简单,首先我们要算出当前真实的波幅.这里不单单考虑当前的价格波动,同时也要考虑到前一个时间点收盘价和当前开盘价之间的价格缺口.而ATR则是真实波幅一段时间窗口(一般取14天)的简单移动平均.计算公式如下: 8 | 9 | 1.真实波幅(TR): TR = MAX(∣最高价-最低价∣,∣最高价-昨收∣,∣昨收-最低价∣) 10 | 11 | 2.真实波幅均值(ATR): ATR = TR的N日简单移动平均 12 | 13 | 在天勤中我们可以很方便的计算出以上两个数据:: 14 | 15 | # 获取 SHFE.au1912 合约的平均真实波幅,导入TqApi和对应的技术指标函数ATR 16 | from tqsdk import TqApi, TqAuth 17 | from tqsdk.ta import ATR 18 | 19 | api = TqApi(TqAuth("快期账户", "账户密码")) 20 | klines = api.get_kline_serial("SHFE.au1912", 24 * 60 * 60) 21 | atr = ATR(klines, 14) 22 | print(atr.tr) # 真实波幅 23 | print(atr.atr) # 真实波幅均值 24 | # 预计的输出是这样的: 25 | [..., 143.0, 48.0, 80.0, ...] 26 | [..., 95.20000000000005, 92.0571428571429, 95.21428571428575, ...] 27 | # 通过api.wait_update()将vs code信息发送给天勤终端 28 | api.wait_update() 29 | api.close() 30 | 31 | 如何在天勤终端和外部天勤IDE插件进行绘图? 32 | -------------------------------------------------------------------------- 33 | 在得到这两个数据之后,我们可使用天勤终端内配置的IDE或 Vs Code插件版来进行绘图:: 34 | 35 | # 创建副图以折线显示art.art数据 36 | klines["ATR_atr"] = atr.atr 37 | # ATR_atr.board为选择图版,可选,缺省为"MAIN"表示绘制在主图 38 | klines["ATR_atr.board"] = "ATR_atr" 39 | # 通过api.wait_update()将vs code信息发送给天勤终端 40 | api.wait_update() 41 | api.close() 42 | 43 | 以上代码运行之后,会在天勤内部绘制额外atr.atr副图 44 | 45 | .. figure:: ../images/draw_index.png 46 | 47 | 设定color和width对应可选参数即可更改副图图像颜色和宽度属性:: 48 | 49 | # 在副图以折线形态显示atr.tr数据 50 | klines["ATR_tr"] = atr.tr 51 | # ATR_tr.board为选择图版,可选,缺省为"MAIN"表示绘制在主图 52 | klines["ATR_tr.board"] = "ATR_tr" 53 | # ATR_tr.color为文本颜色,可选,缺省为红色 54 | klines["ATR_tr.color"] = 0xFF00FF00 55 | # ATR_tr.width 为折线宽度,可选 56 | klines["ATR_tr.width"] = 3 57 | # 创建另外副图显示art.art数据 58 | klines["ATR_atr"] = atr.atr 59 | klines["ATR_atr.board"] = "ATR_atr" 60 | # 通过api.wait_update()将vs code信息发送给天勤终端 61 | api.wait_update() 62 | api.close() 63 | 64 | 运行代码显示如下: 65 | 66 | .. figure:: ../images/indicate_index.png 67 | 68 | 更多的画图示例在示例程序 t90 - t95 : :ref:`demo` -------------------------------------------------------------------------------- /doc/devtools/index.rst: -------------------------------------------------------------------------------- 1 | .. _devtools: 2 | 3 | 开发支持工具 4 | ========================================================================= 5 | TqSdk并不需要依赖任何IDE即可工作。对于习惯使用vscode/pycharm等IDE进行python开发的用户,我们通过IDE插件的方式提供了一些有用的附加功能。包括: 6 | 7 | * 复盘支持 8 | * 交易监控及报告 9 | * 在行情图上绘制指标和其它图形 10 | 11 | .. toctree:: 12 | :maxdepth: 2 13 | 14 | vscode.rst 15 | -------------------------------------------------------------------------------- /doc/devtools/tq/index.rst: -------------------------------------------------------------------------------- 1 | .. _tq: 2 | 3 | 天勤终端 4 | ========================================================================= 5 | 天勤终端是一款基于TqSdk开发的外部GUI,TqSdk并不需要依赖天勤终端即可运行。 6 | 7 | .. toctree:: 8 | :maxdepth: 2 9 | 10 | quickstart.rst 11 | strategybacktest.rst 12 | strategyrun.rst 13 | tqreplay.rst 14 | 15 | 16 | -------------------------------------------------------------------------------- /doc/devtools/tq/quickstart.rst: -------------------------------------------------------------------------------- 1 | .. _tq_quickstart: 2 | 3 | 下载天勤终端 4 | ========================================================================= 5 | 天勤终端目前只支持 Windows 操作系统。要安装天勤软件,请点击 `天勤终端 `_ 下载 6 | 7 | 下载完毕后,双击安装包进行安装。 8 | 9 | 在安装过程中可以根据您的需求选择【最小安装】,【完整安装】或【自定义安装】 10 | 11 | .. figure:: ../../images/custom_settings.png 12 | 13 | 最小安装 14 | -------------------------------------------------------------------------- 15 | 【最小安装】为使用天勤终端的推荐方案 16 | 17 | 安装完成之后,建议配置天勤终端的python环境和IDE,方便终端使用,其中python环境需要安装TqSdk安装包 18 | 19 | 具体配置步骤如下 20 | 21 | ● 点击终端【选项】按钮 22 | 23 | ● 配置对应的python路径和IDE路径,注意配置为pythonw.exe文件 24 | 25 | .. figure:: ../../images/config_ide_python.png 26 | 27 | 完整安装 28 | -------------------------------------------------------------------------- 29 | 【完全安装】仅推荐用户电脑上无python环境下选择,存在python环境后选择该方案可能干扰之前的配置环境 30 | 31 | 选择【完整安装】,会默认帮助用户配置python环境,安装TqSdk开发包等,配置Nodepad++, 32 | 33 | 此方案下的天勤终端无需再额外配置即可进行策略编辑, 34 | 35 | .. figure:: ../../images/complete_config.png 36 | 37 | 38 | 注册模拟账号 39 | -------------------------------------------------------------------------- 40 | 点击 `【申请模拟账号】 `_ 后,会自动打开【天勤量化】注册页,填写以下对应信息之后,并点击激活邮件,即可用【邮箱地址】登录天勤终端【快期模拟】和用户论坛 41 | 42 | .. figure:: ../../images/tq_register.png 43 | 44 | 同时【快期模拟】,也可以在TqSdk中通过TqAccount函数进行登录,具体请参照 :ref:`real_trading` 45 | -------------------------------------------------------------------------------- /doc/devtools/tq/strategybacktest.rst: -------------------------------------------------------------------------------- 1 | .. _strategybacktest: 2 | 3 | 终端策略回测 4 | ========================================================================= 5 | 在天勤终端,我们提供了便捷的方法让大家能够便捷的进行回测,【首页】左侧为回测运行管理区 6 | 7 | .. figure:: ../../images/strategybacktest_begin.png 8 | 9 | 点击【回测】后,会出现一个弹出框, 让你填写具体回测区间 10 | 11 | .. figure:: ../../images/input_backtest_date.png 12 | 13 | 回测时间输入完毕,然后点击【确定】做到这一步, 策略程序就正式执行回测了 14 | 15 | 要停止一个执行中的回测, 只需双击它. 再次双击, 会从头开始重新回测   16 | 17 | 回测结果 18 | ------------------------------------------------------------------------- 19 | 天勤的回测报告, 是在整个回测过程中不断更新的 20 | 21 | 策略报告 22 | ------------------------------------------------------------------------- 23 | 策略报告展示策略程序回测的收益情况和资金曲线, 如下 24 | 25 | .. figure:: ../../images/strategy_backtest_report.png 26 | 27 | 策略日志 28 | ------------------------------------------------------------------------- 29 | 策略程序中用 print 或 logging 输出的信息, 都会出现在这里 30 | 31 | .. figure:: ../../images/strategy_output.png 32 | 33 | 策略交易图 34 | ------------------------------------------------------------------------- 35 | 策略交易图展示一个合约的交易和持仓情况 36 | 37 | .. figure:: ../../images/strategy_symbol_image.png 38 | 39 | 它包含了这些内容 40 | 41 | ● 成交记录: 图上用红色和绿色的箭头标注实际发生的成交时间和成交价格 42 | 43 | ● 持仓记录: 当策略在一段时间内有持仓时, 图上会用红绿色矩形框表示. 红色框表示这段时间的持仓方向与行情方向一致(盈利), 反之为绿色 44 | 45 | ● 当前挂单: 如果策略当前还有挂单, 将在图上以横线虚线的形式显示 46 | 47 | ● 当前持仓: 如果策略当前还有持仓, 将在图上以横线实线的形式显示 48 | 49 | ● 成交记录定位: 如果你在策略日志中选中任意一条日志记录, 图上会用紫色竖条标出这条日志记录的具体时间 50 | 51 | 如果策略程序交易涉及多个合约, 可以在策略日志中选择一条, 策略交易图将切换到选中的合约 52 | 53 | 要改变图表K线周期, 请点击菜单右上方对应时间周期 54 | 55 | 如有需要, 你可以在策略交易图上添加技术指标或者手工画线 56 | 57 | 再次回测 58 | ------------------------------------------------------------------------- 59 | 所有运行过的回测结果都会自动保存, 随时可以点击查看 60 | 61 | 当策略程序修改以后, 如需再次运行回测, 只需对回测任务再次双击即可, 再次回测依然使用前次回测的参数 62 | 63 | 回测与真实运行有哪些差别 64 | ------------------------------------------------------------------------- 65 | 我们在设计复盘功能时, 已尽量模仿真实交易的场景. 但由于种种限制, 与实盘运行相比, 回测时在行情和交易方面依然有一些重要的差别 66 | 67 | 由于回测时使用模拟交易, 成交情况与实盘交易不可避免地存在一些区别 68 | ● 模拟交易要求报单价格大于等于对手盘价格才会成交, 例如下买单, 要求价格大于等于卖一价才会成交, 如果不能立即成交则会等到下次行情更新再重新判断 69 | 70 | 回测模式下 quote 的更新频率由所订阅的 tick 和 k线周期确定 71 | ● 只要策略程序订阅了tick, 则对应合约的 quote 就会使用 tick 生成, 更新频率也和 tick 一致, 但只有这些字段: datetime/ask&bid_price1/ask&bid_volume1/last_price/highest/lowest/average/volume/amount/open_interest/ price_tick/price_decs/volume_multiple/max&min_limit&market_order_volume/underlying_symbol/strike_price 72 | 73 | ● 如果策略程序没有订阅tick, 但是订阅了 k线, 则对应合约的 quote 会使用 k线生成, 更新频率和 k线的周期一致. 如果订阅了某个合约的多个周期的 k线, 则任一个周期的 k线有更新时, quote 都会更新. 使用 k线生成的 quote 的盘口由收盘价分别加/减一个最小变动单位, 并且 highest/lowest/average/amount 始终为 nan, volume 始终为0 74 | 75 | ● 如果策略程序既没有订阅tick, 也没有订阅 k线或订阅的k线周期大于分钟线, 则 TqBacktest 会自动订阅分钟线来生成 quote 76 | 77 | 回测模式下k线会在刚创建出来时和结束时分别更新一次, 在这之间 k线是不会更新的 78 | 79 | 回测模式下 wait_update 每次最多推进一个行情时间 80 | 81 | 用复盘模式测试策略程序 82 | ------------------------------------------------------------------------- 83 | 除了回测以外, 你还可以选择用 :ref:`tqreplay` 下的模拟交易来测试你的策略程序 84 | 85 | 启动天勤复盘模式, 回到过去的某个时间. 详见 :ref:`tqreplay` 86 | 按照 :ref:`strategyrun` 的说明, 启动策略运行 87 | 88 | 89 | -------------------------------------------------------------------------------- /doc/devtools/tq/strategyrun.rst: -------------------------------------------------------------------------------- 1 | .. _strategyrun: 2 | 3 | 终端策略运行 4 | ========================================================================= 5 | 在天勤终端中运行和停止一个策略 6 | ------------------------------------------------------------------------- 7 | 页面左侧为策略运行管理区 8 | 9 | .. figure:: ../../images/strategy_ready_run.png 10 | 11 | 要创建新策略, 点击 【创建新策略】 按钮. 然后输入新策略文件的文件名: 12 | 13 | .. figure:: ../../images/create_strategy.png 14 | 15 | 点击【保存】后,如果您当时选择的是天勤终端全即可在天勤内置的VS Code保存该策略 16 | 17 | .. figure:: ../../images/save_strategy.png 18 | 19 | 编辑策略参数 20 | ------------------------------------------------------------------------- 21 | 22 | 如果需要对指定策略进行参数修改,则右键点击需要修改策略,即可修改对应参数,如合约代码等,修改完毕之后点击保存,该策略即可以新参数运行 23 | 24 | .. figure:: ../../images/input_parameter.png 25 | 26 | 策略运行监控 27 | ------------------------------------------------------------------------- 28 | 天勤为策略运行提供全面监控. 在策略运行表中选中任一个策略, 页面会立即显示所选策略的运行情况 29 | 30 | 策略日志 31 | ------------------------------------------------------------------------- 32 | 策略程序中用 print 或 logging 输出的信息, 都会出现在这里 33 | 34 | .. figure:: ../../images/strategy_output.png 35 | 36 | 策略交易图 37 | ------------------------------------------------------------------------- 38 | 策略交易图展示一个合约的交易和持仓情况 39 | 40 | .. figure:: ../../images/strategy_symbol_image.png 41 | 42 | 它包含了这些内容 43 | 44 | ● 成交记录: 图上用红色和绿色的箭头标注实际发生的成交时间和成交价格 45 | 46 | ● 持仓记录: 当策略在一段时间内有持仓时, 图上会用红绿色矩形框表示. 红色框表示这段时间的持仓方向与行情方向一致(盈利), 反之为绿色 47 | 48 | ● 当前挂单: 如果策略当前还有挂单, 将在图上以横线虚线的形式显示 49 | 50 | ● 当前持仓: 如果策略当前还有持仓, 将在图上以横线实线的形式显示 51 | 52 | ● 成交记录定位: 如果你在策略日志中选中任意一条日志记录, 图上会用紫色竖条标出这条日志记录的具体时间 53 | 54 | 如果策略程序交易涉及多个合约, 可以在策略日志中选择一条, 策略交易图将切换到选中的合约 55 | 56 | 要改变图表K线周期, 请点击菜单右上方对应时间周期 57 | 58 | 如有需要, 你可以在策略交易图上添加技术指标或者手工画线 -------------------------------------------------------------------------------- /doc/devtools/tq/tqreplay.rst: -------------------------------------------------------------------------------- 1 | .. _tqreplay: 2 | 3 | 终端历史复盘 4 | ========================================================================= 5 | 天勤终端支持全面历史复盘. 您只需指定任一交易日,天勤终端将回到那一天,并完整重演全天的行情变化.在此过程中,您可以如常使用软件全部功能及扩展接口,一切都有如真正回到那天一样,您在回放过程中可以任意暂停或加减速. 6 | 7 | 使用历史复盘功能 8 | ------------------------------------------------------------------------- 9 | 欲使用历史复盘功能, 请按以下步骤操作: 10 | 11 | ● 点击桌面上的 天勤终端-复盘 图标 启动 12 | 13 | ● 在软件启动时, 先选择一个日期, 然后点击 【开始历史复盘】 14 | 15 | .. figure:: ../../images/tq_mdreplay.png 16 | 17 | ● 软件将会以指定的交易日启动, 您可以如常使用软件功能. 复盘状态下默认登录一个 初始资金 100万 的模拟交易账户, 可以进行交易练习. 18 | 19 | ● 在复盘状态下, 屏幕上将始终有一个悬浮控制框, 可以调整行情回放速度 20 | 21 | .. figure:: ../../images/change_speed_replay.png 22 | 23 | ● 要从复盘状态回到正常使用状态, 请退出软件, 重新启动 24 | 25 | -------------------------------------------------------------------------------- /doc/enterprise.rst: -------------------------------------------------------------------------------- 1 | .. _enterprise: 2 | 3 | TqSdk 企业版 4 | ================================================= 5 | 除了 TqSdk 专业版以外,我们还提供 TqSdk 企业版本 6 | 7 | 企业版和专业版相比的主要区别是柜台支持上的区别,企业版支持直连 CTP/融航/杰宜斯等柜台,专业版只能通过中继的方式去进行连接 8 | 9 | 如果想使用 TqSdk 企业版功能,可以点击 `个人中心 `_ 申请15天试用或购买 10 | 11 | TqSdk 本地多策略功能 12 | ------------------------------------------------- 13 | 随着对收益曲线稳定的追求,较多用户需求在一个账户下去运行多个策略,当多个策略交易同一标的时,则面临着不同策略的持仓管理,绩效归因等问题 14 | 15 | 为了解决该问题, `tqsdk` 在企业版中提供了本地众期多策略系统,支持用户在本地将一个实盘账户拆分为多个策略(多个前端账户),每个策略交易数据相互隔离,且跨日有效 16 | 17 | 同时该方案会提供多策略的管理界面,支持可视化观察各个多策略的持仓,委托,资金和盈亏情况 18 | 19 | TqSdk 本地多策略功能的详细介绍,请点击 :ref:`tq_trading_unit` 20 | 21 | 22 | TqSdk 直连功能 23 | ------------------------------------------------- 24 | 在 TqSdk 企业版支持用户通过直连模式接入任意一家指定期货公司 25 | 26 | 除了接入指定期货公司的优点以外,直连模式还带来了一下好处: 27 | 28 | * 交易指令直达期货公司,省去中继服务器路径,交易延迟平均减少10ms左右 29 | * 减少了交易服务器依赖,程序运行稳定性提升 30 | 31 | TqSdk 直连CTP模式的详细介绍,请点击 :py:class:`~tqsdk.TqCtp` 32 | 33 | 34 | .. _tqjees: 35 | 36 | TqSdk 连接平台功能 37 | ------------------------------------------------- 38 | TqSdk 提供了资管平台的对接支持,支持用户连接到指定资管平台,例如杰宜斯或者融航资管系统等 39 | 40 | 以连融航的模拟服务器为例:: 41 | 42 | from tqsdk import TqApi, TqRohon, TqAuth 43 | 44 | account = TqRohon(account_id="融航账户", password="融航密码", front_broker="融航柜台代码", front_url="融航柜台地址", app_id="融航 AppID", auth_code="融航 AuthCode") 45 | api = TqApi(account, auth=TqAuth("快期账户", "账户密码")) 46 | 47 | 其中融航的 **模拟账户** 、 **模拟账户密码** 、 **app_id** 和 **auth_code** 需要自行和融航联系获取,其他参数在融航模拟下为 48 | 49 | front_url="tcp://129.211.138.170:10001" 50 | 51 | front_broker="RohonDemo" 52 | 53 | 融航实盘情况下将对应信息换成实盘信息即可 54 | 55 | 融航资管平台连接模式的详细介绍,请点击 :py:class:`~tqsdk.TqRohon` 56 | -------------------------------------------------------------------------------- /doc/images/backtest_click.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/backtest_click.png -------------------------------------------------------------------------------- /doc/images/backtest_ready.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/backtest_ready.png -------------------------------------------------------------------------------- /doc/images/change_speed_replay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/change_speed_replay.png -------------------------------------------------------------------------------- /doc/images/choose_broke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/choose_broke.png -------------------------------------------------------------------------------- /doc/images/click_backtest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/click_backtest.png -------------------------------------------------------------------------------- /doc/images/complete_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/complete_config.png -------------------------------------------------------------------------------- /doc/images/config_ide_python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/config_ide_python.png -------------------------------------------------------------------------------- /doc/images/create_strategy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/create_strategy.png -------------------------------------------------------------------------------- /doc/images/custom_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/custom_settings.png -------------------------------------------------------------------------------- /doc/images/dialog_param_backtest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/dialog_param_backtest.png -------------------------------------------------------------------------------- /doc/images/dialog_param_run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/dialog_param_run.png -------------------------------------------------------------------------------- /doc/images/draw_index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/draw_index.png -------------------------------------------------------------------------------- /doc/images/foreign01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/foreign01.png -------------------------------------------------------------------------------- /doc/images/how-grafana04.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/how-grafana04.gif -------------------------------------------------------------------------------- /doc/images/indicate_index.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/indicate_index.png -------------------------------------------------------------------------------- /doc/images/input_backtest_date.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/input_backtest_date.png -------------------------------------------------------------------------------- /doc/images/input_parameter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/input_parameter.png -------------------------------------------------------------------------------- /doc/images/llm_pic1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/llm_pic1.png -------------------------------------------------------------------------------- /doc/images/llm_pic2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/llm_pic2.png -------------------------------------------------------------------------------- /doc/images/llm_pic3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/llm_pic3.png -------------------------------------------------------------------------------- /doc/images/llm_pic4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/llm_pic4.png -------------------------------------------------------------------------------- /doc/images/llm_pic5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/llm_pic5.png -------------------------------------------------------------------------------- /doc/images/llm_pic6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/llm_pic6.png -------------------------------------------------------------------------------- /doc/images/llm_pic7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/llm_pic7.png -------------------------------------------------------------------------------- /doc/images/mdreplay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/mdreplay.png -------------------------------------------------------------------------------- /doc/images/page_backtest_intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/page_backtest_intro.png -------------------------------------------------------------------------------- /doc/images/page_run_intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/page_run_intro.png -------------------------------------------------------------------------------- /doc/images/pycharm_edit_configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/pycharm_edit_configuration.png -------------------------------------------------------------------------------- /doc/images/pycharm_edit_configuration_entry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/pycharm_edit_configuration_entry.png -------------------------------------------------------------------------------- /doc/images/pycharm_open_directory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/pycharm_open_directory.png -------------------------------------------------------------------------------- /doc/images/pycharm_process_console.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/pycharm_process_console.png -------------------------------------------------------------------------------- /doc/images/pycharm_run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/pycharm_run.png -------------------------------------------------------------------------------- /doc/images/pycharm_run_configuration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/pycharm_run_configuration.png -------------------------------------------------------------------------------- /doc/images/qa_pic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/qa_pic.png -------------------------------------------------------------------------------- /doc/images/replay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/replay.png -------------------------------------------------------------------------------- /doc/images/save_strategy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/save_strategy.png -------------------------------------------------------------------------------- /doc/images/strategy_backtest_report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/strategy_backtest_report.png -------------------------------------------------------------------------------- /doc/images/strategy_output.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/strategy_output.png -------------------------------------------------------------------------------- /doc/images/strategy_ready_run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/strategy_ready_run.png -------------------------------------------------------------------------------- /doc/images/strategy_run.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/strategy_run.png -------------------------------------------------------------------------------- /doc/images/strategy_symbol_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/strategy_symbol_image.png -------------------------------------------------------------------------------- /doc/images/strategybacktest_begin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/strategybacktest_begin.png -------------------------------------------------------------------------------- /doc/images/strategybacktest_ready.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/strategybacktest_ready.png -------------------------------------------------------------------------------- /doc/images/tianqin-vscode-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tianqin-vscode-demo.gif -------------------------------------------------------------------------------- /doc/images/tianqin_chart_trade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tianqin_chart_trade.png -------------------------------------------------------------------------------- /doc/images/tianqin_list_trade.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tianqin_list_trade.png -------------------------------------------------------------------------------- /doc/images/tianqin_login_real.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tianqin_login_real.png -------------------------------------------------------------------------------- /doc/images/tq_breif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tq_breif.png -------------------------------------------------------------------------------- /doc/images/tq_loging.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tq_loging.png -------------------------------------------------------------------------------- /doc/images/tq_mdreplay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tq_mdreplay.png -------------------------------------------------------------------------------- /doc/images/tq_register.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tq_register.png -------------------------------------------------------------------------------- /doc/images/tq_zq_assign.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tq_zq_assign.png -------------------------------------------------------------------------------- /doc/images/tq_zq_backen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tq_zq_backen.png -------------------------------------------------------------------------------- /doc/images/tq_zq_broker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tq_zq_broker.png -------------------------------------------------------------------------------- /doc/images/tq_zq_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tq_zq_config.png -------------------------------------------------------------------------------- /doc/images/tq_zq_config2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tq_zq_config2.png -------------------------------------------------------------------------------- /doc/images/tq_zq_front.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tq_zq_front.png -------------------------------------------------------------------------------- /doc/images/tq_zq_init.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tq_zq_init.png -------------------------------------------------------------------------------- /doc/images/tq_zq_strategy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tq_zq_strategy.png -------------------------------------------------------------------------------- /doc/images/tq_zq_unclear_order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tq_zq_unclear_order.png -------------------------------------------------------------------------------- /doc/images/tqsdk_new_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/tqsdk_new_logo.png -------------------------------------------------------------------------------- /doc/images/user_login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/user_login.png -------------------------------------------------------------------------------- /doc/images/user_web_management.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/user_web_management.png -------------------------------------------------------------------------------- /doc/images/user_web_management_new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/user_web_management_new.png -------------------------------------------------------------------------------- /doc/images/vscode_backtest_report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/vscode_backtest_report.png -------------------------------------------------------------------------------- /doc/images/vscode_backtest_report_detail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/vscode_backtest_report_detail.png -------------------------------------------------------------------------------- /doc/images/vscode_backtest_setting_finished.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/vscode_backtest_setting_finished.png -------------------------------------------------------------------------------- /doc/images/vscode_click.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/vscode_click.png -------------------------------------------------------------------------------- /doc/images/vscode_click_tianqinlianghua.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/vscode_click_tianqinlianghua.png -------------------------------------------------------------------------------- /doc/images/vscode_gui_performance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/vscode_gui_performance.png -------------------------------------------------------------------------------- /doc/images/vscode_install.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/vscode_install.png -------------------------------------------------------------------------------- /doc/images/vscode_kill_terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/vscode_kill_terminal.png -------------------------------------------------------------------------------- /doc/images/vscode_repaly.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/vscode_repaly.png -------------------------------------------------------------------------------- /doc/images/vscode_repaly_steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/vscode_repaly_steps.png -------------------------------------------------------------------------------- /doc/images/vscode_replay_speed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/vscode_replay_speed.png -------------------------------------------------------------------------------- /doc/images/vscode_run_replay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/vscode_run_replay.png -------------------------------------------------------------------------------- /doc/images/vscode_save_exe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/vscode_save_exe.png -------------------------------------------------------------------------------- /doc/images/vscode_setting_account.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/vscode_setting_account.png -------------------------------------------------------------------------------- /doc/images/vscode_setting_backtesttime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/vscode_setting_backtesttime.png -------------------------------------------------------------------------------- /doc/images/vscode_setting_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/vscode_setting_config.png -------------------------------------------------------------------------------- /doc/images/vscode_strategy_picture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/vscode_strategy_picture.png -------------------------------------------------------------------------------- /doc/images/wait_update.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/wait_update.png -------------------------------------------------------------------------------- /doc/images/web_gui_backtest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/web_gui_backtest.png -------------------------------------------------------------------------------- /doc/images/web_gui_backtest_report.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/web_gui_backtest_report.png -------------------------------------------------------------------------------- /doc/images/web_gui_demo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/web_gui_demo.png -------------------------------------------------------------------------------- /doc/images/web_gui_klines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/web_gui_klines.png -------------------------------------------------------------------------------- /doc/images/web_gui_real.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/web_gui_real.png -------------------------------------------------------------------------------- /doc/images/win10_start_scheduled_task.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/win10_start_scheduled_task.png -------------------------------------------------------------------------------- /doc/images/win10_start_scheduled_task_create.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/win10_start_scheduled_task_create.png -------------------------------------------------------------------------------- /doc/images/win10_start_scheduled_task_python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/win10_start_scheduled_task_python.png -------------------------------------------------------------------------------- /doc/images/win10_start_scheduled_task_taskkill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/win10_start_scheduled_task_taskkill.png -------------------------------------------------------------------------------- /doc/images/win2008_scheduled_task_kill.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/win2008_scheduled_task_kill.png -------------------------------------------------------------------------------- /doc/images/win2008_scheduled_task_python.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/win2008_scheduled_task_python.png -------------------------------------------------------------------------------- /doc/images/win2008_start_scheduled_task.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/images/win2008_start_scheduled_task.png -------------------------------------------------------------------------------- /doc/index.rst: -------------------------------------------------------------------------------- 1 | .. image:: logo.png 2 | :width: 600 px 3 | :align: center 4 | 5 | | 6 | 7 | .. _pysdk: 8 | 9 | TianQin Python Sdk User Guide 10 | ======================================== 11 | 12 | 本文档是 TqSdk 的使用说明. 从 TqSdk 中的一些关键概念开始, 逐步介绍如何充分利用 TqSdk 全部功能。 13 | 14 | .. toctree:: 15 | :maxdepth: 2 16 | 17 | intro.rst 18 | quickstart.rst 19 | usage/index.rst 20 | demo/index.rst 21 | reference/index.rst 22 | tq_trading_unit.rst 23 | advanced/index.rst 24 | dev/index.rst 25 | profession.rst 26 | enterprise.rst 27 | tqsdk_llm.rst 28 | qa.rst 29 | version.rst 30 | 31 | -------------------------------------------------------------------------------- /doc/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/doc/logo.png -------------------------------------------------------------------------------- /doc/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | set SPHINXPROJ=TianQinPythonSDK 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 20 | echo.installed, then set the SPHINXBUILD environment variable to point 21 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 22 | echo.may add the Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /doc/qa.rst: -------------------------------------------------------------------------------- 1 | 天勤用户论坛 2 | ------------------------------------------------- 3 | 在学习TqSdk的过程中可能会碰到一些疑惑,我们相信用户论坛能够帮助到你。 4 | 5 | 在用户论坛中你可以: 6 | 7 | * 根据关键词搜索已解决问题 8 | * 查看热门问题及其解决方案 9 | * 提出待解决的新问题 10 | * 回答/讨论他人提出的问题 11 | 12 | 点击进入 `用户论坛 `_ ,加入讨论. 13 | 14 | .. figure:: images/qa_pic.png -------------------------------------------------------------------------------- /doc/reference/index.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk_apis: 2 | 3 | TqSdk 模块参考 4 | ==================================================================== 5 | 6 | .. toctree:: 7 | :maxdepth: 1 8 | 9 | tqsdk.api.rst 10 | tqsdk.auth.rst 11 | tqsdk.account.rst 12 | tqsdk.tqkq.rst 13 | tqsdk.tqzq.rst 14 | tqsdk.tqctp.rst 15 | tqsdk.tqrohon.rst 16 | tqsdk.tqjees.rst 17 | tqsdk.tqyida.rst 18 | tqsdk.sim.rst 19 | tqsdk.multiaccount.rst 20 | tqsdk.objs.rst 21 | tqsdk.lib.rst 22 | tqsdk.ta.rst 23 | tqsdk.tafunc.rst 24 | tqsdk.backtest.rst 25 | tqsdk.algorithm.rst 26 | tqsdk.risk_rule.rst 27 | tqsdk.tools.download.rst 28 | tqsdk.exceptions.rst 29 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.account.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.account: 2 | 3 | tqsdk.TqAccount - 实盘账户类 4 | ------------------------------------------------------------------ 5 | .. autoclass:: tqsdk.TqAccount 6 | :members: 7 | :inherited-members: 8 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.algorithm.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.algorithm: 2 | 3 | tqsdk.algorithm - 算法模块 4 | ------------------------------------------------------------------ 5 | 6 | 7 | .. _tqsdk.algorithm.twap: 8 | 9 | tqsdk.algorithm.twap - Twap 算法 10 | ================================================================== 11 | .. automodule:: tqsdk.algorithm.twap 12 | :members: 13 | 14 | 15 | .. _tqsdk.algorithm.time_table_generater: 16 | 17 | tqsdk.algorithm.time_table_generater - 生成 time_table 辅助函数 18 | ================================================================== 19 | .. automodule:: tqsdk.algorithm.time_table_generater 20 | :members: 21 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.api.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.api: 2 | 3 | tqsdk.TqApi - 框架及核心业务 4 | ------------------------------------------------------------------ 5 | .. autoclass:: tqsdk.TqApi 6 | :members: 7 | 8 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.auth.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.auth: 2 | 3 | tqsdk.TqAuth - 用户认证类 4 | ------------------------------------------------------------------ 5 | .. autoclass:: tqsdk.TqAuth 6 | :members: 7 | 8 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.backtest.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.backtest: 2 | 3 | tqsdk.TqBacktest - 策略回测 4 | ------------------------------------------------------------------ 5 | .. autoclass:: tqsdk.TqBacktest 6 | :members: 7 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.exceptions.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.exceptions: 2 | 3 | tqsdk.exceptions - 抛出例外 4 | ------------------------------------------------------------------ 5 | .. automodule:: tqsdk.exceptions 6 | :members: 7 | 8 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.lib.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.lib: 2 | 3 | tqsdk.lib - 业务工具库 4 | ------------------------------------------------------------------ 5 | 6 | 7 | .. _tqsdk.lib.notify: 8 | 9 | tqsdk.TqNotify - 收集通知信息工具 10 | ================================================================== 11 | .. autoclass:: tqsdk.TqNotify 12 | :members: 13 | 14 | 15 | .. _tqsdk.target_pos_task: 16 | 17 | tqsdk.TargetPosTask - 目标持仓工具 18 | ================================================================== 19 | .. autoclass:: tqsdk.TargetPosTask 20 | :members: 21 | 22 | .. autoclass:: tqsdk.InsertOrderUntilAllTradedTask 23 | :members: 24 | 25 | .. autoclass:: tqsdk.InsertOrderTask 26 | :members: 27 | 28 | 29 | .. _tqsdk.lib.target_pos_scheduler: 30 | 31 | tqsdk.TargetPosScheduler - 基于时间维度的目标持仓工具 32 | ================================================================== 33 | .. autoclass:: tqsdk.TargetPosScheduler 34 | :members: 35 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.multiaccount.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.multiaccount: 2 | 3 | tqsdk.TqMultiAccount - 多账户 4 | ------------------------------------------------------------------ 5 | .. autoclass:: tqsdk.TqMultiAccount 6 | :members: 7 | 8 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.objs.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.objs: 2 | 3 | tqsdk.objs - 业务对象 4 | ------------------------------------------------------------------ 5 | .. automodule:: tqsdk.objs 6 | :members: 7 | 8 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.risk_rule.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.risk_rule: 2 | 3 | tqsdk.risk_rule - 风控类模块 4 | ------------------------------------------------------------------ 5 | .. automodule:: tqsdk.risk_rule 6 | :members: 7 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.sim.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.sim: 2 | 3 | tqsdk.TqSim - 本地模拟交易 4 | ------------------------------------------------------------------ 5 | .. autoclass:: tqsdk.TqSim 6 | :members: 7 | :inherited-members: 8 | 9 | 10 | .. _tqsdk.sim_stock: 11 | 12 | tqsdk.TqSimStock - 本地股票模拟交易 13 | ------------------------------------------------------------------ 14 | .. autoclass:: tqsdk.TqSimStock 15 | :members: 16 | :inherited-members: 17 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.ta.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.ta: 2 | 3 | tqsdk.ta - 技术指标计算函数 4 | ------------------------------------------------------------------ 5 | .. automodule:: tqsdk.ta 6 | :members: 7 | :autosummary: -------------------------------------------------------------------------------- /doc/reference/tqsdk.tafunc.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.tafunc: 2 | 3 | tqsdk.tafunc - 序列计算函数 4 | ------------------------------------------------------------------ 5 | .. automodule:: tqsdk.tafunc 6 | :members: 7 | :autosummary: -------------------------------------------------------------------------------- /doc/reference/tqsdk.tools.download.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.tools.downloader: 2 | 3 | tqsdk.tools.DataDownloader - 数据下载工具 4 | ------------------------------------------------------------------ 5 | .. autoclass:: tqsdk.tools.DataDownloader 6 | :members: 7 | 8 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.tqctp.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.tqctp: 2 | 3 | tqsdk.TqCtp - 直连 CTP 交易类 4 | ------------------------------------------------------------------ 5 | .. autoclass:: tqsdk.TqCtp 6 | :members: 7 | :inherited-members: 8 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.tqjees.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.tqjees: 2 | 3 | tqsdk.TqJees - 杰宜斯资管交易类 4 | ------------------------------------------------------------------ 5 | .. autoclass:: tqsdk.TqJees 6 | :members: 7 | :inherited-members: 8 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.tqkq.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.tqkq: 2 | 3 | tqsdk.TqKq - 快期模拟交易类 4 | ------------------------------------------------------------------ 5 | .. autoclass:: tqsdk.TqKq 6 | :members: 7 | :inherited-members: 8 | 9 | 10 | .. _tqsdk.tqkq_stock: 11 | 12 | tqsdk.TqKqStock - 快期股票模拟交易类 13 | ------------------------------------------------------------------ 14 | .. autoclass:: tqsdk.TqKqStock 15 | :members: 16 | :inherited-members: 17 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.tqrohon.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.tqrohon: 2 | 3 | tqsdk.TqRohon - 融航资管交易类 4 | ------------------------------------------------------------------ 5 | .. autoclass:: tqsdk.TqRohon 6 | :members: 7 | :inherited-members: 8 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.tqyida.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.tqyida: 2 | 3 | tqsdk.TqYida - 易达交易类 4 | ------------------------------------------------------------------ 5 | .. autoclass:: tqsdk.TqYida 6 | :members: 7 | :inherited-members: 8 | -------------------------------------------------------------------------------- /doc/reference/tqsdk.tqzq.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk.tqzq: 2 | 3 | tqsdk.TqZq - 众期交易类 4 | ------------------------------------------------------------------ 5 | .. autoclass:: tqsdk.TqZq 6 | :members: 7 | :inherited-members: 8 | -------------------------------------------------------------------------------- /doc/tqsdk_llm.rst: -------------------------------------------------------------------------------- 1 | .. _tqsdk_llm: 2 | 3 | 天勤量化 AI 助手 4 | ----------------------------------------------- 5 | 点击使用 `使用天勤 AI 助手! `_ 6 | 在使用天勤的过程中,用户往往会遇到各种问题,尤其是初学者,他们可能会关心以下几点: 7 | 8 | * 天勤量化可以实现哪些功能? 9 | * 如何编写实现这些功能的大致代码? 10 | * 文档中某些函数的具体参数是什么意思? 11 | 12 | 当度过初学者的阶段后,用户可能会遇到以下情况: 13 | 14 | * 如何解决天勤或 Python 报错? 15 | * 如何优化策略代码逻辑? 16 | * 某个特定功能在天勤中如何实现? 17 | 18 | 这些问题都会成为用户使用天勤量化时的障碍。 19 | 20 | 为了帮助用户解决这些问题,我们结合了国内先进的大语言模型,推出了专门的智能机器人助手,旨在解答以下问题: 21 | 22 | * 具体函数的详细介绍 23 | * 根据具体需求或策略提供天勤实现的示例 24 | * 天勤或 Python 报错的可能解决方案 25 | 26 | 点击即刻尝试 `使用天勤 AI 助手! `_ 27 | 28 | 下图是具体的使用示例 demo 29 | 30 | .. figure:: images/llm_pic1.png 31 | .. figure:: images/llm_pic2.png 32 | .. figure:: images/llm_pic3.png 33 | .. figure:: images/llm_pic4.png 34 | .. figure:: images/llm_pic5.png 35 | .. figure:: images/llm_pic6.png 36 | .. figure:: images/llm_pic7.png 37 | 38 | 39 | -------------------------------------------------------------------------------- /doc/usage/index.rst: -------------------------------------------------------------------------------- 1 | .. _usage: 2 | 3 | 使用TqSdk 4 | ======================================== 5 | 6 | .. toctree:: 7 | :maxdepth: 2 8 | 9 | framework.rst 10 | shinny_account.rst 11 | mddatas.rst 12 | kqd_symbol.rst 13 | ta.rst 14 | trade.rst 15 | option_trade.rst 16 | targetpostask.rst 17 | backtest.rst 18 | web_gui.rst 19 | jupyter.rst 20 | -------------------------------------------------------------------------------- /doc/usage/jupyter.rst: -------------------------------------------------------------------------------- 1 | .. _jupyter: 2 | 3 | 在 Jupyter Notebook 中使用 TqSdk 4 | ==================================================== 5 | 本文档将介绍如何在 Jupyter Notebook 中使用 TqSdk。 6 | 7 | 当您的主要是希望使用 TqSdk 来进行行情分析和研究,并不涉及到交易时使用 Jupyter Notebook 可以带来一些潜在优势 8 | 9 | 1. 交互式编程 10 | Jupyter Notebook 提供了一个交互式的环境,可以逐步执行代码块并立即查看输出结果。这种特性特别适合数据分析和探索性编程,使得用户可以实时查看数据处理和可视化的效果。 11 | 12 | 2. 内嵌可视化 13 | Jupyter Notebook 支持在单元格中嵌入图表和图像,使得数据可视化变得非常方便。用户可以在一个文档中同时编写代码、生成图表和撰写分析报告,无需切换到其他工具或窗口。 14 | 15 | 安装 Jupyter Notebook 16 | ---------------------------------------------------- 17 | 18 | Jupyter Notebook 是一个开源项目,能够在交互式编程环境中提供丰富的可视化表达,可以创建和共享代码和文档。 19 | 20 | 可以使用以下命令安装 Jupyter Notebook: 21 | 22 | ```bash 23 | pip install jupyter 24 | ``` 25 | 26 | 更多 Jupyter Notebook 安装文档请参考 27 | 28 | `Jupyter Notebook 安装文档 `_ :: 29 | `Jupyter Notebook 文档 `_ :: 30 | 31 | 32 | 安装 TqSdk 33 | ---------------------------------------------------- 34 | 35 | 请参考 :ref:`安装文档 ` 。 36 | 37 | 38 | 在 Jupyter Notebook 中使用 TqSdk 39 | ---------------------------------------------------- 40 | 41 | 请参考 :ref:`示例 ` 。 42 | 43 | 44 | 注意事项 45 | ---------------------------------------------------- 46 | 47 | * **不建议用户在 jupyter 里使用 tqsdk 的交易功能,因为 TqSdk 行情只有在调用 wait_update() 之后才会更新,但是在 jupyter 交互运行的环境中,无法及时调用 wait_update(),可能会导致行情延时** 48 | 49 | * **不能在 jupyter 中异步的使用 tqsdk,jupyter 只能用 TqSdk 的同步代码的写法** 50 | 51 | * **在 jupyter 中使用 wait_update() 时,建议增加 deadline 参数在函数里,避免长时间的阻塞** 52 | 53 | -------------------------------------------------------------------------------- /doc/usage/option_trade.rst: -------------------------------------------------------------------------------- 1 | .. _option_trade: 2 | 3 | 期权交易 & 交易所官方组合 4 | ==================================================== 5 | TqSdk 中期权合和交易所官方组合的约代码格式参考如下:: 6 | 7 | DCE.m1807-C-2450 - 大商所豆粕期权 8 | CZCE.CF003C11000 - 郑商所棉花期权 9 | SHFE.au2004C308 - 上期所黄金期权 10 | CFFEX.IO2002-C-3550 - 中金所沪深300股指期权 11 | SSE.10002513 - 上交所上证50etf期权 12 | SSE.10002504 - 上交所沪深300etf期权 13 | SZSE.90000097 - 深交所沪深300etf期权 14 | CZCE.SPD SR901&SR903 - 郑商所 SR901&SR903 跨期合约 15 | DCE.SP a1709&a1801 - 大商所 a1709&a1801 跨期合约 16 | 17 | 18 | 19 | 对于交易所官方组合,目前 TqSdk 中只支持交易所官方组合进行实盘交易,不支持在模拟中进行交易所官方组合交易 20 | 21 | 22 | 期权指标计算&序列计算函数 23 | ---------------------------------------------------- 24 | TqSdk 内提供了丰富的期权指标计算&序列计算函数,参考如下: 25 | 26 | * :py:meth:`~tqsdk.ta.OPTION_GREEKS` - 计算期权希腊指标 27 | * :py:meth:`~tqsdk.ta.OPTION_IMPV` - 计算期权隐含波动率 28 | * :py:meth:`~tqsdk.ta.BS_VALUE` - 计算期权 BS 模型理论价格 29 | * :py:meth:`~tqsdk.ta.OPTION_VALUE` - 计算期权内在价值,期权时间价值 30 | * :py:meth:`~tqsdk.tafunc.get_bs_price` - 计算期权 BS 模型理论价格 31 | * :py:meth:`~tqsdk.tafunc.get_delta` - 计算期权希腊指标 delta 值 32 | * :py:meth:`~tqsdk.tafunc.get_gamma` - 计算期权希腊指标 gamma 值 33 | * :py:meth:`~tqsdk.tafunc.get_rho` - 计算期权希腊指标 rho 值 34 | * :py:meth:`~tqsdk.tafunc.get_theta` - 计算期权希腊指标 theta 值 35 | * :py:meth:`~tqsdk.tafunc.get_vega` - 计算期权希腊指标 vega 值 36 | * :py:meth:`~tqsdk.tafunc.get_his_volatility` - 计算某个合约的历史波动率 37 | * :py:meth:`~tqsdk.tafunc.get_t` - 计算 K 线序列对应的年化到期时间,主要用于计算期权相关希腊指标时,需要得到计算出序列对应的年化到期时间 38 | 39 | 期权查询函数 40 | ---------------------------------------------------- 41 | TqSdk 内提供了完善的期权查询函数 :py:meth:`~tqsdk.TqApi.query_options` 和对应平值虚值期权查询函数 :py:meth:`~tqsdk.TqApi.query_atm_options` ,供用户搜索符合自己需求的期权:: 42 | 43 | 44 | 45 | from tqsdk import TqApi, TqAuth 46 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 47 | 48 | ls = api.query_options("SHFE.au2012") 49 | print(ls) # 标的为 "SHFE.au2012" 的所有期权 50 | 51 | ls = api.query_options("SHFE.au2012", option_class="PUT") 52 | print(ls) # 标的为 "SHFE.au2012" 的看跌期权 53 | 54 | ls = api.query_options("SHFE.au2012", option_class="PUT", expired=False) 55 | print(ls) # 标的为 "SHFE.au2012" 的看跌期权, 未下市的 56 | 57 | ls = api.query_options("SHFE.au2012", strike_price=340) 58 | print(ls) # 标的为 "SHFE.au2012" 、行权价为 340 的期权 59 | 60 | ls = api.query_options("SSE.510300") 61 | print(ls) # 中金所沪深300股指期权 62 | 63 | ls = api.query_options("SSE.510300") 64 | print(ls) # 上交所沪深300etf期权 65 | 66 | ls = api.query_options("SSE.510300", exercise_year=2020, exercise_month=12) 67 | print(ls) # 上交所沪深300etf期权, 限制条件 2020 年 12 月份行权 68 | 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /doc/usage/replay.rst: -------------------------------------------------------------------------------- 1 | .. _replay: 2 | 3 | 策略程序复盘 4 | ================================================= 5 | 6 | 执行策略复盘 7 | ------------------------------------------------- 8 | 除了传统的回测模式以外,TqSdk 提供独具特色的复盘模式,它与回测模式有以下区别 9 | 10 | 1.复盘模式为时间驱动,回测模式为事件驱动 11 | 12 | 复盘模式下,你可以指定任意一天交易日,后端行情服务器会传输用户订阅合约的当天的所有历史行情数据,重演当天行情,而在回测模式下,我们采用 :ref:`backtest_rule` ,根据用户订阅的合约周期数据来进行推送 13 | 14 | 因此在复盘模式下K线更新和实盘一模一样,而回测模式下就算订阅了 Tick 数据,回测中任意周期 K 线最后一根的 close 和其他数据也不会随着 Tick 更新而更新,而是随着K线频率生成和结束时更新一次 15 | 16 | 2.复盘和回测的行情速度 17 | 18 | 因为两者的驱动机制不同,回测会更快,但是我们在复盘模式下也提供行情速度调节功能,可以结合 :ref:`web_gui_replay` 来实现 19 | 20 | 3.复盘目前只支持单日复盘 21 | 22 | 因为复盘提供对应合约全部的当日历史行情数据,对后端服务器会有较大压力,目前只支持复盘模式下选择单日进行复盘 23 | 24 | 25 | 使用 TqSdk 编写的策略程序,不需要修改策略代码,只需要在创建 api 实例时给 backtest 参数传入 :py:class:`~tqsdk.backtest.TqReplay` 指定复盘日期, 策略就会进入复盘模式:: 26 | 27 | from datetime import date 28 | from tqsdk import TqApi, TqReplay 29 | 30 | api = TqApi(backtest = TqReplay(date(2019,12,23)), auth=TqAuth("快期账户", "账户密码")) 31 | 32 | 33 | 此外我们认为复盘模式结合图形化界面会有更好的体验,可以参考 :ref:`web_gui` 34 | 35 | 同时在图形化界面下,你可以通过点击复盘速度控制按钮对复盘行情速度进行控制 36 | 37 | .. figure:: ../images/replay.png 38 | 39 | 40 | **使用复盘模式时需要注意:** 41 | 42 | 1.指定复盘日期需要有行情,否则提示无法创建复盘服务器 43 | 44 | 2.订阅合约在复盘日期时已经上市或还未下市 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /doc/usage/shinny_account.rst: -------------------------------------------------------------------------------- 1 | .. _shinny_account: 2 | 3 | 快期账户 4 | ================================================= 5 | 在使用 TqSdk 之前,用户需要先注册自己的 **快期账户** ,传入快期账户是使用任何 TqSdk 程序的前提 6 | 7 | 如需注册,请点击 `注册快期账户 `_ :: 8 | 9 | from tqsdk import TqApi, TqAuth 10 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 11 | 12 | 用快期账户来模拟交易 13 | ------------------------------------------------- 14 | 注册完成的快期账户的【手机号】/【邮箱地址】/【用户名】和【密码】可以作为 快期模拟 账号,通过 :py:class:`~tqsdk.api.TqKq` 对 auth 传入参数进行登录,这个 快期模拟 账户在快期APP、快期专业版 和天勤量化上是互通的:: 15 | 16 | from tqsdk import TqApi, TqAuth, TqKq 17 | api = TqApi(TqKq(), auth=TqAuth("快期账户", "账户密码")) 18 | 19 | 20 | 用快期账户来实盘交易 21 | ------------------------------------------------- 22 | 对于 TqSdk 免费版,每个快期账户支持最多绑定一个实盘账户,而天勤量化专业版支持一个快期账户绑定任意多个实盘账户 23 | 24 | 快期账户会在用户使用实盘账户时自动进行绑定,直到该快期账户没有能绑定实盘账户的名额:: 25 | 26 | from tqsdk import TqApi, TqAccount, TqAuth, TqKq 27 | api = TqApi(TqAccount("H海通期货", "320102", "123456"), auth=TqAuth("快期账户", "账户密码")) 28 | 29 | 如果需要注册快期账户或者修改您的快期账户绑定的实盘账户请参见 :ref:`user_center` 30 | 31 | 32 | .. _user_center: 33 | 34 | 登录用户管理中心 35 | ------------------------------------------------- 36 | 点击 `登录用户管理中心 `_ ,可以注册快期账户或者修改您的快期账户绑定的实盘账户 37 | 38 | 登录成功后显示如下,在下方红框处,用户可以自行解绑/绑定实盘账户,其中解绑操作每天限定一次 39 | 40 | .. figure:: ../images/user_web_management.png 41 | 42 | 如需一个快期账户支持更多的实盘账户,请联系工作人员进行批量购买 `天勤量化专业版 `_ 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /doc/usage/ta.rst: -------------------------------------------------------------------------------- 1 | .. _ta: 2 | 3 | 技术指标与序列计算函数 4 | ==================================================== 5 | 6 | 技术指标 7 | ---------------------------------------------------- 8 | tqsdk.ta 模块中包含了大量技术指标. 每个技术指标是一个函数, 函数名为全大写, 第一参数总是K线序列, 以pandas.DataFrame格式返回计算结果. 以MACD为例:: 9 | 10 | from tqsdk.ta import MACD 11 | 12 | klines = api.get_kline_serial("SHFE.cu1812", 60) # 提取SHFE.cu1812的分钟线 13 | result = MACD(klines, 12, 26, 9) # 计算MACD指标 14 | print(result["diff"]) # MACD指标中的diff序列 15 | 16 | tqsdk.ta 中目前提供的技术指标详表,请见 :ref:`tqsdk.ta` 17 | 18 | 19 | 序列计算函数 20 | ---------------------------------------------------- 21 | tqsdk.tafunc 模块中包含了一批序列计算函数. 它们是构成技术指标的基础. 在某些情况下, 您也可以直接使用这些序列计算函数以获取更大的灵活性. 22 | 23 | 例如, 技术指标MA(均线)总是按K线的收盘价来计算, 如果你需要计算最高价的均线, 可以使用ma函数:: 24 | 25 | from tqsdk.tafunc import ma 26 | 27 | klines = api.get_kline_serial("SHFE.cu1812", 60) # 提取SHFE.cu1812的分钟线 28 | result = ma(klines.high, 9) # 按K线的最高价序列做9分钟的移动平均 29 | print(result) # 移动平均结果 30 | 31 | tqsdk.tafunc 中目前提供的序列计算函数详表,请见 :ref:`tqsdk.tafunc` 32 | 33 | -------------------------------------------------------------------------------- /doc/usage/web_gui.rst: -------------------------------------------------------------------------------- 1 | .. _web_gui: 2 | 3 | 策略程序图形化界面 4 | ==================================================== 5 | 6 | 要在 TqSdk 中实现图形化界面非常简单,在 :py:class:`~tqsdk.TqApi` 中传入参数 web_gui = True即可,一套方案满足实盘/回测需求 7 | 8 | 对于需要固定web_gui网址的同学,可以传入本机IP端口 web_gui = "http://192.168.143.0:9876"(需填写本机IP端口) 来进行固定网址 9 | 10 | 实盘情况下的图形化界面 11 | ---------------------------------------------------- 12 | 实盘下的示例代码:: 13 | 14 | # 引入TqSdk模块 15 | from tqsdk import TqApi, TqAuth 16 | # 创建api实例,设置web_gui=True生成图形化界面 17 | api = TqApi(web_gui=True, auth=TqAuth("快期账户", "账户密码")) 18 | # 订阅 cu2002 合约的10秒线 19 | klines = api.get_kline_serial("SHFE.cu2002", 10) 20 | while True: 21 | # 通过wait_update刷新数据 22 | api.wait_update() 23 | 24 | 当你运行该程序后,预期会显示如下两条信息:: 25 | 26 | 2019-12-13 10:45:26,468 - INFO - 您可以访问 http://127.0.0.1:62964 查看策略绘制出的 K 线图形。 27 | 2019-12-13 10:45:27,422 - INFO - 通知: 与 wss://openmd.shinnytech.com/t/md/front/mobile 的网络连接已建立 28 | 29 | 点击访问地址后,显示网址效果如下: 30 | 31 | .. figure:: ../images/web_gui_demo.png 32 | 33 | 34 | 回测情况下的图形化界面 35 | ---------------------------------------------------- 36 | 回测情况下,设置完回测区间参数后传入web_gui=True,也可以用同样的方法来生成图形化地址:: 37 | 38 | from datetime import date 39 | from tqsdk import TqApi, TqAuth, TqBacktest, TargetPosTask 40 | # 在创建 api 实例时传入 TqBacktest 就会进入回测模式,设置web_gui=True开启图形化界面 41 | api = TqApi(backtest=TqBacktest(start_dt=date(2018, 5, 2), end_dt=date(2018, 6, 2)),web_gui=True, auth=TqAuth("快期账户", "账户密码")) 42 | # 获得 m1901 5分钟K线的引用 43 | klines = api.get_kline_serial("DCE.m1901", 5 * 60, data_length=15) 44 | # 创建 m1901 的目标持仓 task,该 task 负责调整 m1901 的仓位到指定的目标仓位 45 | target_pos = TargetPosTask(api, "DCE.m1901") 46 | while True: 47 | api.wait_update() 48 | if api.is_changing(klines): 49 | ma = sum(klines.close.iloc[-15:]) / 15 50 | print("最新价", klines.close.iloc[-1], "MA", ma) 51 | if klines.close.iloc[-1] > ma: 52 | print("最新价大于MA: 目标多头5手") 53 | # 设置目标持仓为多头5手 54 | target_pos.set_target_volume(5) 55 | elif klines.close.iloc[-1] < ma: 56 | print("最新价小于MA: 目标空仓") 57 | # 设置目标持仓为空仓 58 | target_pos.set_target_volume(0) 59 | 60 | 点击访问地址后,显示网址效果如下: 61 | 62 | .. figure:: ../images/web_gui_klines.png 63 | 64 | 点击完整回测报告,显示更加详细的报告结果: 65 | 66 | .. figure:: ../images/web_gui_backtest_report.png 67 | 68 | 如何在 TqSdk 中进行回测可以参见 :ref:`backtest` 69 | 70 | .. _web_gui_replay: 71 | 72 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | certifi 2 | websockets>=8.1 3 | requests 4 | numpy 5 | pandas>=0.24.0 6 | aiohttp 7 | pysimplegui 8 | matplotlib 9 | mplcursors 10 | simplejson 11 | selenium 12 | scipy 13 | pyjwt 14 | Sphinx==2.3.1 15 | autodocsumm 16 | sphinx_rtd_theme 17 | jieba -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [options.entry_points] 2 | pyinstaller40 = 3 | hook-dirs = tqsdk.__pyinstaller:get_hook_dirs 4 | 5 | [egg_info] 6 | tag_build = 7 | tag_date = 0 8 | 9 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | __author__ = 'yangyang' 3 | 4 | import setuptools 5 | 6 | with open("README.md", mode="r", encoding='utf-8') as fh: 7 | long_description = fh.read() 8 | 9 | setuptools.setup( 10 | name='tqsdk', 11 | version="3.8.1", 12 | description='TianQin SDK', 13 | author='TianQin', 14 | author_email='tianqincn@gmail.com', 15 | long_description=long_description, 16 | long_description_content_type="text/markdown", 17 | url='https://www.shinnytech.com/tqsdk', 18 | packages=setuptools.find_packages(exclude=["tqsdk.test", "tqsdk.test.*"]), 19 | python_requires='>=3.7', 20 | install_requires=["websockets>=8.1", "requests", "numpy", "pandas>=1.1.0", "scipy", "simplejson", "aiohttp", 21 | "certifi", "pyjwt", "psutil>=5.9.6", "shinny_structlog", "sgqlc", "filelock", "tqsdk_ctpse", "tqsdk_sm", 22 | "packaging"], 23 | classifiers=[ 24 | "Programming Language :: Python :: 3", 25 | "License :: OSI Approved :: Apache Software License", 26 | "Operating System :: OS Independent", 27 | ], 28 | include_package_data=True 29 | ) 30 | -------------------------------------------------------------------------------- /tqsdk/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chengzhi' 4 | name = "tqsdk" 5 | 6 | from tqsdk.api import TqApi 7 | from tqsdk.tradeable import TqAccount, TqZq, TqKq, TqKqStock, TqSim, TqSimStock, TqCtp, TqRohon, TqJees, TqYida, TqTradingUnit 8 | from tqsdk.auth import TqAuth 9 | from tqsdk.channel import TqChan 10 | from tqsdk.backtest import TqBacktest, TqReplay 11 | from tqsdk.exceptions import BacktestFinished, TqBacktestPermissionError, TqTimeoutError, TqRiskRuleError 12 | from tqsdk.lib import TargetPosScheduler, TargetPosTask, InsertOrderUntilAllTradedTask, InsertOrderTask, TqNotify 13 | from tqsdk.multiaccount import TqMultiAccount 14 | from .__version__ import __version__ 15 | -------------------------------------------------------------------------------- /tqsdk/__pyinstaller/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | def get_hook_dirs(): 4 | return [os.path.dirname(__file__)] 5 | -------------------------------------------------------------------------------- /tqsdk/__pyinstaller/hook-tqsdk.py: -------------------------------------------------------------------------------- 1 | from PyInstaller.utils.hooks import collect_data_files, collect_submodules 2 | datas = collect_data_files('tqsdk', includes=['web', 'expired_quotes.json.lzma']) 3 | hiddenimports = collect_submodules('tqsdk_ctpse') 4 | -------------------------------------------------------------------------------- /tqsdk/__version__.py: -------------------------------------------------------------------------------- 1 | __version__ = '3.8.1' 2 | -------------------------------------------------------------------------------- /tqsdk/algorithm/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'yanqiong' 4 | 5 | from tqsdk.algorithm.twap import Twap 6 | from tqsdk.algorithm.time_table_generater import twap_table, vwap_table 7 | 8 | -------------------------------------------------------------------------------- /tqsdk/backtest/__init__.py: -------------------------------------------------------------------------------- 1 | #!usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | 4 | __author__ = 'mayanqiong' 5 | 6 | from tqsdk.backtest.backtest import TqBacktest 7 | from tqsdk.backtest.replay import TqReplay -------------------------------------------------------------------------------- /tqsdk/constants.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'mayanqiong' 4 | 5 | """ 6 | 定义常量 7 | """ 8 | 9 | FUTURE_EXCHANGES = ["CFFEX", "SHFE", "DCE", "CZCE", "INE", "GFEX"] 10 | STOCK_EXCHANGES = ["SSE", "SZSE"] 11 | SPOT_EXCHANGES = ["SSWE"] 12 | KQ_EXCHANGES = ["KQ"] 13 | KQD_EXCHANGES = ["KQD"] 14 | -------------------------------------------------------------------------------- /tqsdk/datetime_state.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'mayanqiong' 4 | 5 | 6 | """ 7 | 时间帮助函数,根据回测/实盘获取不同的当前时间 8 | 9 | 模块内部创建使用 10 | """ 11 | 12 | import time 13 | 14 | 15 | class TqDatetimeState: 16 | 17 | def __init__(self): 18 | self.data_ready = False # 是否收到了第一个 mdhis_more_data 19 | self.tqsdk_backtest = {} 20 | 21 | def get_current_dt(self): 22 | """返回当前 nano timestamp""" 23 | if self.tqsdk_backtest: 24 | return self.tqsdk_backtest.get('current_dt') 25 | else: 26 | return int(time.time() * 1000000) * 1000 27 | 28 | def update_state(self, diff): 29 | self.tqsdk_backtest.update(diff.get('_tqsdk_backtest', {})) 30 | if not self.data_ready and diff.get('mdhis_more_data', True) is False: 31 | self.data_ready = True 32 | 33 | -------------------------------------------------------------------------------- /tqsdk/demo/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/demo/__init__.py -------------------------------------------------------------------------------- /tqsdk/demo/download_orders.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'yanqiong' 4 | 5 | import csv 6 | import os 7 | from datetime import datetime 8 | 9 | from tqsdk import TqApi, TqAuth, TqKq 10 | 11 | 12 | """ 13 | 本示例用于下载账户当前交易日到目前位置的全部委托单、成交记录分别到 orders.csv、trades.csv 文件。 14 | 15 | 如果文件已经存在,会将记录追加到文件末尾。 16 | 17 | 用户可以在交易日结束之后,运行本示例,可以将当日的委托单、成交记录保存到本地。 18 | """ 19 | 20 | 21 | order_cols = ["order_id", "exchange_order_id", "exchange_id", "instrument_id", "direction", "offset", "status", "volume_orign", "volume_left", "limit_price", "price_type", "volume_condition", "time_condition", "insert_date_time", "last_msg"] 22 | trade_cols = ["trade_id", "order_id", "exchange_trade_id", "exchange_id", "instrument_id", "direction", "offset", "price", "volume", "trade_date_time"] 23 | 24 | 25 | def write_csv(file_name, cols, datas): 26 | file_exists = os.path.exists(file_name) and os.path.getsize(file_name) > 0 27 | with open(file_name, 'a', newline='') as csvfile: 28 | csv_writer = csv.writer(csvfile, dialect='excel') 29 | if not file_exists: 30 | csv_writer.writerow(['datetime'] + cols) 31 | for item in datas.values(): 32 | if 'insert_date_time' in cols: 33 | dt = datetime.fromtimestamp(item['insert_date_time'] / 1e9).strftime('%Y-%m-%d %H:%M:%S.%f') 34 | elif 'trade_date_time' in cols: 35 | dt = datetime.fromtimestamp(item['trade_date_time'] / 1e9).strftime('%Y-%m-%d %H:%M:%S.%f') 36 | else: 37 | dt = None 38 | row = [dt] + [item[k] for k in cols] 39 | csv_writer.writerow(row) 40 | 41 | 42 | with TqApi(TqKq(), auth=TqAuth("快期账户", "账户密码")) as api: 43 | # 将当前账户下全部委托单、成交信息写入 csv 文件中 44 | write_csv("orders.csv", order_cols, api.get_order()) 45 | write_csv("trades.csv", trade_cols, api.get_trade()) 46 | -------------------------------------------------------------------------------- /tqsdk/demo/example/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/demo/example/__init__.py -------------------------------------------------------------------------------- /tqsdk/demo/example/aberration.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = "Ringo" 4 | 5 | ''' 6 | Aberration策略 (难度:初级) 7 | 参考: https://www.shinnytech.com/blog/aberration/ 8 | 注: 该示例策略仅用于功能示范, 实盘时请根据自己的策略/经验进行修改 9 | ''' 10 | 11 | from tqsdk import TqApi, TqAuth, TargetPosTask 12 | from tqsdk.ta import BOLL 13 | 14 | # 设置合约代码 15 | SYMBOL = "DCE.m2105" 16 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 17 | quote = api.get_quote(SYMBOL) 18 | klines = api.get_kline_serial(SYMBOL, 60 * 60 * 24) 19 | position = api.get_position(SYMBOL) 20 | target_pos = TargetPosTask(api, SYMBOL) 21 | 22 | 23 | # 使用BOLL指标计算中轨、上轨和下轨,其中26为周期N ,2为参数p 24 | def boll_line(klines): 25 | boll = BOLL(klines, 26, 2) 26 | midline = boll["mid"].iloc[-1] 27 | topline = boll["top"].iloc[-1] 28 | bottomline = boll["bottom"].iloc[-1] 29 | print("策略运行,中轨:%.2f,上轨为:%.2f,下轨为:%.2f" % (midline, topline, bottomline)) 30 | return midline, topline, bottomline 31 | 32 | 33 | midline, topline, bottomline = boll_line(klines) 34 | 35 | while True: 36 | api.wait_update() 37 | # 每次生成新的K线时重新计算BOLL指标 38 | if api.is_changing(klines.iloc[-1], "datetime"): 39 | midline, topline, bottomline = boll_line(klines) 40 | 41 | # 每次最新价发生变化时进行判断 42 | if api.is_changing(quote, "last_price"): 43 | # 判断开仓条件 44 | if position.pos_long == 0 and position.pos_short == 0: 45 | # 如果最新价大于上轨,K线上穿上轨,开多仓 46 | if quote.last_price > topline: 47 | print("K线上穿上轨,开多仓") 48 | target_pos.set_target_volume(20) 49 | # 如果最新价小于轨,K线下穿下轨,开空仓 50 | elif quote.last_price < bottomline: 51 | print("K线下穿下轨,开空仓") 52 | target_pos.set_target_volume(-20) 53 | else: 54 | print("当前最新价%.2f,未穿上轨或下轨,不开仓" % quote.last_price) 55 | 56 | # 在多头情况下,空仓条件 57 | elif position.pos_long > 0: 58 | # 如果最新价低于中线,多头清仓离场 59 | if quote.last_price < midline: 60 | print("最新价低于中线,多头清仓离场") 61 | target_pos.set_target_volume(0) 62 | else: 63 | print("当前多仓,未穿越中线,仓位无变化") 64 | 65 | # 在空头情况下,空仓条件 66 | elif position.pos_short > 0: 67 | # 如果最新价高于中线,空头清仓离场 68 | if quote.last_price > midline: 69 | print("最新价高于中线,空头清仓离场") 70 | target_pos.set_target_volume(0) 71 | else: 72 | print("当前空仓,未穿越中线,仓位无变化") 73 | -------------------------------------------------------------------------------- /tqsdk/demo/example/doublema.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'limin' 4 | 5 | ''' 6 | 双均线策略 7 | 注: 该示例策略仅用于功能示范, 实盘时请根据自己的策略/经验进行修改 8 | ''' 9 | from tqsdk import TqApi, TqAuth, TargetPosTask 10 | from tqsdk.tafunc import ma 11 | 12 | SHORT = 30 # 短周期 13 | LONG = 60 # 长周期 14 | SYMBOL = "SHFE.bu2012" # 合约代码 15 | 16 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 17 | print("策略开始运行") 18 | 19 | data_length = LONG + 2 # k线数据长度 20 | # "duration_seconds=60"为一分钟线, 日线的duration_seconds参数为: 24*60*60 21 | klines = api.get_kline_serial(SYMBOL, duration_seconds=60, data_length=data_length) 22 | target_pos = TargetPosTask(api, SYMBOL) 23 | 24 | while True: 25 | api.wait_update() 26 | 27 | if api.is_changing(klines.iloc[-1], "datetime"): # 产生新k线:重新计算SMA 28 | short_avg = ma(klines["close"], SHORT) # 短周期 29 | long_avg = ma(klines["close"], LONG) # 长周期 30 | 31 | # 均线下穿,做空 32 | if long_avg.iloc[-2] < short_avg.iloc[-2] and long_avg.iloc[-1] > short_avg.iloc[-1]: 33 | target_pos.set_target_volume(-3) 34 | print("均线下穿,做空") 35 | 36 | # 均线上穿,做多 37 | if short_avg.iloc[-2] < long_avg.iloc[-2] and short_avg.iloc[-1] > long_avg.iloc[-1]: 38 | target_pos.set_target_volume(3) 39 | print("均线上穿,做多") 40 | -------------------------------------------------------------------------------- /tqsdk/demo/example/dualthrust.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'limin' 4 | 5 | ''' 6 | Dual Thrust策略 (难度:中级) 7 | 参考: https://www.shinnytech.com/blog/dual-thrust 8 | 注: 该示例策略仅用于功能示范, 实盘时请根据自己的策略/经验进行修改 9 | ''' 10 | 11 | from tqsdk import TqApi, TqAuth, TargetPosTask 12 | 13 | SYMBOL = "DCE.jd2011" # 合约代码 14 | NDAY = 5 # 天数 15 | K1 = 0.2 # 上轨K值 16 | K2 = 0.2 # 下轨K值 17 | 18 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 19 | print("策略开始运行") 20 | 21 | quote = api.get_quote(SYMBOL) 22 | klines = api.get_kline_serial(SYMBOL, 24 * 60 * 60) # 86400使用日线 23 | target_pos = TargetPosTask(api, SYMBOL) 24 | 25 | 26 | def dual_thrust(quote, klines): 27 | current_open = klines.iloc[-1]["open"] 28 | HH = max(klines.high.iloc[-NDAY - 1:-1]) # N日最高价的最高价 29 | HC = max(klines.close.iloc[-NDAY - 1:-1]) # N日收盘价的最高价 30 | LC = min(klines.close.iloc[-NDAY - 1:-1]) # N日收盘价的最低价 31 | LL = min(klines.low.iloc[-NDAY - 1:-1]) # N日最低价的最低价 32 | range = max(HH - LC, HC - LL) 33 | buy_line = current_open + range * K1 # 上轨 34 | sell_line = current_open - range * K2 # 下轨 35 | print("当前开盘价: %f, 上轨: %f, 下轨: %f" % (current_open, buy_line, sell_line)) 36 | return buy_line, sell_line 37 | 38 | 39 | buy_line, sell_line = dual_thrust(quote, klines) # 获取上下轨 40 | 41 | while True: 42 | api.wait_update() 43 | if api.is_changing(klines.iloc[-1], ["datetime", "open"]): # 新产生一根日线或开盘价发生变化: 重新计算上下轨 44 | buy_line, sell_line = dual_thrust(quote, klines) 45 | 46 | if api.is_changing(quote, "last_price"): 47 | if quote.last_price > buy_line: # 高于上轨 48 | print("高于上轨,目标持仓 多头3手") 49 | target_pos.set_target_volume(3) # 交易 50 | elif quote.last_price < sell_line: # 低于下轨 51 | print("低于下轨,目标持仓 空头3手") 52 | target_pos.set_target_volume(-3) # 交易 53 | else: 54 | print('未穿越上下轨,不调整持仓') 55 | -------------------------------------------------------------------------------- /tqsdk/demo/example/fairy_four_price.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'limin' 4 | 5 | ''' 6 | 菲阿里四价 策略(日内突破策略, 在每日收盘前对所持合约进行平仓) 7 | 参考: https://www.shinnytech.com/blog/fairy-four-price/ 8 | 注: 该示例策略仅用于功能示范, 实盘时请根据自己的策略/经验进行修改 9 | ''' 10 | 11 | from tqsdk import TqApi, TqAuth, TargetPosTask 12 | from datetime import datetime 13 | import time 14 | 15 | symbol = "SHFE.ni2012" # 合约代码 16 | close_hour, close_minute = 14, 50 # 平仓时间 17 | 18 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) # 使用模拟帐号直连行情和交易服务器 19 | quote = api.get_quote(symbol) # 获取指定合约的盘口行情 20 | klines = api.get_kline_serial(symbol, 24 * 60 * 60) # 获取日线 21 | position = api.get_position(symbol) # 持仓信息 22 | target_pos = TargetPosTask(api, symbol) # 目标持仓 23 | 24 | top_rail = klines.high.iloc[-2] # 上轨: 昨日高点 25 | bottom_rail = klines.low.iloc[-2] # 下轨: 昨日低点 26 | print("上轨:", top_rail, ",下轨:", bottom_rail, ",昨日收盘价:", klines.close.iloc[-2], ",今日开盘价:", klines.open.iloc[-1]) 27 | 28 | while True: 29 | api.wait_update() 30 | if api.is_changing(klines.iloc[-1], "datetime"): # 如果产生一根新日线 (即到达下一个交易日): 重新获取上下轨 31 | top_rail = klines.high.iloc[-2] 32 | bottom_rail = klines.low.iloc[-2] 33 | print("上轨:", top_rail, ",下轨:", bottom_rail, ",昨日收盘价:", klines.close.iloc[-2], ",今日开盘价:", klines.open.iloc[-1]) 34 | 35 | if api.is_changing(quote, "last_price"): # 如果行情最新价发生变化 36 | print("当前最新价", quote.last_price) 37 | # 开仓突破 38 | if quote.last_price > top_rail and position.pos_long == 0: # 如果价格突破上轨: 买入开仓 39 | print("最新价:", quote.last_price, ", 价格突破上轨,买入开仓") 40 | target_pos.set_target_volume(3) # 设置目标持仓手数,将指定合约调整到目标头寸 41 | elif quote.last_price < bottom_rail and position.pos_short == 0: # 如果价格跌破下轨: 卖出开仓 42 | print("最新价:", quote.last_price, ", 价格跌破下轨, 卖出开仓") 43 | target_pos.set_target_volume(-3) 44 | 45 | # 平仓止损: 当价格 向上突破上轨 或 向下突破下轨 后, 再次回破当日开盘价 46 | if (quote.highest > top_rail and quote.last_price <= quote.open) or ( 47 | quote.lowest < bottom_rail and quote.last_price >= quote.open): 48 | print("平仓止损") 49 | target_pos.set_target_volume(0) 50 | 51 | if api.is_changing(quote, "datetime"): 52 | now_time = datetime.strptime(quote.datetime, "%Y-%m-%d %H:%M:%S.%f") # 获取当前的行情时间 53 | if now_time.hour == close_hour and now_time.minute >= close_minute: # 到达平仓时间: 平仓 54 | print("临近本交易日收盘: 平仓") 55 | target_pos.set_target_volume(0) 56 | deadline = time.time() + 60 # 设置截止时间为当前时间的60秒以后 57 | while api.wait_update(deadline=deadline): # 等待60秒 58 | pass 59 | api.close() # 关闭api 60 | break # 退出while循环 61 | -------------------------------------------------------------------------------- /tqsdk/demo/example/gridtrading_async.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chengzhi' 4 | 5 | """ 6 | 网格交易策略 7 | 参考: https://www.shinnytech.com/blog/grid-trading/ 8 | 注: 该示例策略仅用于功能示范, 实盘时请根据自己的策略/经验进行修改 9 | """ 10 | 11 | from functools import reduce 12 | from contextlib import closing 13 | from tqsdk import TqApi, TqAuth, TargetPosTask 14 | 15 | # 网格计划参数: 16 | symbol = "DCE.jd2011" # 合约代码 17 | start_price = 4247 # 起始价位 18 | grid_amount = 10 # 网格在多头、空头方向的格子(档位)数量 19 | grid_region_long = [0.005] * grid_amount # 多头每格价格跌幅(网格密度) 20 | grid_region_short = [0.005] * grid_amount # 空头每格价格涨幅(网格密度) 21 | grid_volume_long = [1] * grid_amount # 多头每格交易手数 22 | grid_volume_short = [-1] * grid_amount # 空头每格交易手数 23 | grid_prices_long = [reduce(lambda p, r: p*(1-r), grid_region_long[:i], start_price) for i in range(grid_amount + 1)] # 多头每格的触发价位列表, 第一个元素为起始价位 24 | grid_prices_short = [reduce(lambda p, r: p*(1+r), grid_region_short[:i], start_price) for i in range(grid_amount + 1)] # 空头每格的触发价位列表, 第一个元素为起始价位 25 | 26 | print("起始价位:", start_price) 27 | print("多头每格交易量:", grid_volume_long) 28 | print("多头每格的价位:", grid_prices_long) 29 | print("空头每格的价位:", grid_prices_short) 30 | 31 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 32 | quote = api.get_quote(symbol) # 行情数据 33 | target_pos = TargetPosTask(api, symbol) 34 | target_volume = 0 # 目标持仓手数 35 | 36 | 37 | async def price_watcher(open_price, close_price, volume): 38 | """该task在价格触发开仓价时开仓,触发平仓价时平仓""" 39 | global target_volume 40 | async with api.register_update_notify(quote) as update_chan: # 当 quote 有更新时会发送通知到 update_chan 上 41 | while True: 42 | async for _ in update_chan: # 当从 update_chan 上收到行情更新通知时判断是否触发开仓条件 43 | if (volume > 0 and quote.last_price <= open_price) or (volume < 0 and quote.last_price >= open_price): 44 | break 45 | target_volume += volume 46 | target_pos.set_target_volume(target_volume) 47 | print("时间:", quote.datetime, "最新价:", quote.last_price, "开仓", volume, "手", "总仓位:", target_volume, "手") 48 | async for _ in update_chan: # 当从 update_chan 上收到行情更新通知时判断是否触发平仓条件 49 | if (volume > 0 and quote.last_price > close_price) or (volume < 0 and quote.last_price < close_price): 50 | break 51 | target_volume -= volume 52 | target_pos.set_target_volume(target_volume) 53 | print("时间:", quote.datetime, "最新价:", quote.last_price, "平仓", volume, "手", "总仓位:", target_volume, "手") 54 | 55 | 56 | for i in range(grid_amount): 57 | api.create_task(price_watcher(grid_prices_long[i+1], grid_prices_long[i], grid_volume_long[i])) 58 | api.create_task(price_watcher(grid_prices_short[i+1], grid_prices_short[i], grid_volume_short[i])) 59 | 60 | with closing(api): 61 | while True: 62 | api.wait_update() 63 | -------------------------------------------------------------------------------- /tqsdk/demo/example/momentum.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = "Ringo" 4 | 5 | ''' 6 | 价格动量 策略 (难度:初级) 7 | 参考: https://www.shinnytech.com/blog/momentum-strategy/ 8 | 注: 该示例策略仅用于功能示范, 实盘时请根据自己的策略/经验进行修改 9 | ''' 10 | 11 | from tqsdk import TqApi, TqAuth, TargetPosTask 12 | 13 | # 设置指定合约,获取N条K线计算价格动量 14 | SYMBOL = "SHFE.au2012" 15 | N = 15 16 | 17 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 18 | klines = api.get_kline_serial(SYMBOL, 60 * 60 * 24, N) 19 | quote = api.get_quote(SYMBOL) 20 | target_pos = TargetPosTask(api, SYMBOL) 21 | position = api.get_position(SYMBOL) 22 | 23 | 24 | def AR(kline1): 25 | """价格动量函数AR,以前N-1日K线计算价格动量ar""" 26 | spread_ho = sum(kline1.high[:-1] - kline1.open[:-1]) 27 | spread_oc = sum(kline1.open[:-1] - kline1.low[:-1]) 28 | # spread_oc 为0时,设置为最小价格跳动值 29 | if spread_oc == 0: 30 | spread_oc = quote.price_tick 31 | ar = (spread_ho / spread_oc) * 100 32 | return ar 33 | 34 | 35 | ar = AR(klines) 36 | print("策略开始启动") 37 | 38 | while True: 39 | api.wait_update() 40 | # 生成新K线时,重新计算价格动量值ar 41 | if api.is_changing(klines.iloc[-1], "datetime"): 42 | ar = AR(klines) 43 | print("价格动量是:", ar) 44 | # 每次最新价发生变动时,重新进行判断 45 | if api.is_changing(quote, "last_price"): 46 | # 开仓策略 47 | if position.pos_long == 0 and position.pos_short == 0: 48 | # 如果ar大于110并且小于150,开多仓 49 | if 110 < ar < 150: 50 | print("价值动量超过110,小于150,做多") 51 | target_pos.set_target_volume(100) 52 | # 如果ar大于50,小于90,开空仓 53 | elif 50 < ar < 90: 54 | print("价值动量大于50,小于90,做空") 55 | target_pos.set_target_volume(-100) 56 | 57 | # 止损策略,多头下当前ar值小于90则平仓止损,空头下当前ar值大于110则平仓止损 58 | elif (position.pos_long > 0 and ar < 90) or (position.pos_short > 0 and ar > 110): 59 | print("止损平仓") 60 | target_pos.set_target_volume(0) 61 | -------------------------------------------------------------------------------- /tqsdk/demo/multiaccount.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'hongyan' 4 | 5 | from tqsdk import TqApi, TqAuth, TqAccount, TqKq, TqSim, TqMultiAccount 6 | # 多账户模式下, 同时操作实盘、模拟交易和快期模拟账户交易 7 | tqact = TqAccount("H海通期货", "123456", "123456") 8 | sim = TqSim() 9 | kq = TqKq() 10 | 11 | with TqApi(TqMultiAccount([tqact, sim, kq]), auth=TqAuth("快期账户", "账户密码")) as api: 12 | order1 = api.insert_order(symbol="DCE.m2101", direction="BUY", offset="OPEN", volume=5, account=tqact) 13 | order2 = api.insert_order(symbol="SHFE.au2012C308", direction="BUY", offset="OPEN", volume=5, limit_price=78.1, account=sim) 14 | order3 = api.insert_order(symbol="SHFE.cu2101", direction="Sell", offset="OPEN", volume=10, limit_price=51610, account=kq) 15 | api.cancel_order(order3, kq) 16 | while order1.status != "FINISHED" or order2.status != "FINISHED": 17 | api.wait_update() 18 | # 分别获取账户资金信息 19 | account_info1 = tqact.get_account() 20 | account_info2 = sim.get_account() 21 | account_info3 = kq.get_account() 22 | # 分别获取账户持仓信息 23 | position1 = tqact.get_position("DCE.m2101", ) 24 | position2 = sim.get_position() 25 | position3 = kq.get_position() 26 | # 分别获取账户委托数据 27 | orders1 = tqact.get_order(order_id=order1.order_id, ) 28 | orders2 = sim.get_position() 29 | orders3 = kq.get_position() 30 | # 分别获取账户成交数据 31 | trades1 = tqact.get_trade() 32 | trades2 = sim.get_trade() 33 | trades3 = kq.get_trade() -------------------------------------------------------------------------------- /tqsdk/demo/option_tutorial/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/demo/option_tutorial/__init__.py -------------------------------------------------------------------------------- /tqsdk/demo/option_tutorial/o10.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'ringo' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | # 创建API实例,传入自己的快期账户 8 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 9 | 10 | # 获取大商所豆粕期权行情 11 | quote_m = api.get_quote("DCE.m1807-C-2450") 12 | 13 | # 获取中金所股指期权行情 14 | quote_IO = api.get_quote("CFFEX.IO2002-C-3550") 15 | 16 | # 输出 m1807-C-2450 的最新行情时间和最新价 17 | print(quote_m.datetime, quote_m.last_price) 18 | 19 | # 关闭api,释放资源 20 | api.close() 21 | -------------------------------------------------------------------------------- /tqsdk/demo/option_tutorial/o20.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'ringo' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 8 | 9 | ls = api.query_options("SHFE.au2012") 10 | print(ls) # 标的为 "SHFE.au2012" 的所有期权 11 | 12 | ls = api.query_options("SHFE.au2012", option_class="PUT") 13 | print(ls) # 标的为 "SHFE.au2012" 的看跌期权 14 | 15 | ls = api.query_options("SHFE.au2012", option_class="PUT", expired=False) 16 | print(ls) # 标的为 "SHFE.au2012" 的看跌期权, 未下市的 17 | 18 | ls = api.query_options("SHFE.au2012", strike_price=340) 19 | print(ls) # 标的为 "SHFE.au2012" 、行权价为 340 的期权 20 | 21 | ls = api.query_options("SSE.000300", exchange_id="CFFEX") 22 | print(ls) # 中金所沪深300股指期权 23 | 24 | ls = api.query_options("SSE.510300", exchange_id="SSE") 25 | print(ls) # 上交所沪深300etf期权 26 | 27 | ls = api.query_options("SSE.510300", exchange_id="SSE", exercise_year=2020, exercise_month=12) 28 | print(ls) # 上交所沪深300etf期权, 限制条件 2020 年 12 月份行权 29 | 30 | api.close() -------------------------------------------------------------------------------- /tqsdk/demo/option_tutorial/o30.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'ringo' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 8 | 9 | quote = api.get_quote("SHFE.au2012") 10 | 11 | # 预计输出的为以au2012现在最新价来比对的认购的平值期权,当没有符合的平值期权时返回为空,如果有返回则格式为 ["SHFE.au2012C30000"] 12 | ls = api.query_atm_options("SHFE.au2012", quote.last_price, 0, "CALL") 13 | 14 | # 预计输出的为au2012,以开盘价来比对的认购的实值3档,实值2档,实值1档期权,如果没有符合要求的期权则对应栏返回为None,如果有则返回格式例如 [None,None,"SHFE.au2012C30000"] 15 | ls = api.query_atm_options("SHFE.au2012", quote.open, [3, 2, 1], "CALL") 16 | 17 | # 预计输出的为au2012,以开盘价来比对的认购的实值1档,平值期权,虚值1档,如果没有符合要求的期权则对应栏返回为None,如果有则返回格式例如 18 | ls = api.query_atm_options("SHFE.au2012", quote.open, [1, 0, -1], "CALL") 19 | 20 | # 预计输出的为au2012,以现在最新价来比对的认购的虚值1档期权 21 | ls = api.query_atm_options("SHFE.au2012", quote.last_price, -1, "CALL") 22 | 23 | # 预计输出沪深300股指期权,2020年12月的虚值1档期权 24 | ls = api.query_atm_options("SSE.000300", quote.last_price, -1, "CALL", exercise_year=2020, exercise_month=12) 25 | 26 | # 预计输出 上交所 沪深300股指ETF期权,2020年12月的虚值1档期权 27 | ls = api.query_atm_options("SSE.510300", quote.last_price, -1, "CALL", exercise_year=2020, exercise_month=12) 28 | 29 | api.close() 30 | -------------------------------------------------------------------------------- /tqsdk/demo/option_tutorial/o40.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'ringo' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | from tqsdk.ta import OPTION_GREEKS 7 | 8 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 9 | 10 | # 获取指定期权行情 11 | quote = api.get_quote("SHFE.cu2006C44000") 12 | 13 | # 获取期权和其对应标的的多合约的 kline 数据 14 | klines = api.get_kline_serial(["SHFE.cu2006C44000", "SHFE.cu2006"], 24 * 60 * 60, 30) 15 | 16 | # 运行 OPTION_GREEKS 希腊值计算函数 17 | greeks = OPTION_GREEKS(klines, quote, 0.025) 18 | 19 | # 输出希腊字母 20 | print(list(greeks["delta"])) 21 | print(list(greeks["theta"])) 22 | print(list(greeks["gamma"])) 23 | print(list(greeks["vega"])) 24 | print(list(greeks["rho"])) 25 | 26 | api.close() 27 | -------------------------------------------------------------------------------- /tqsdk/demo/option_tutorial/o41.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'ringo' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | from tqsdk.ta import OPTION_IMPV 7 | 8 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 9 | 10 | # 获取指定期权行情 11 | quote = api.get_quote("SHFE.cu2006C50000") 12 | 13 | # 获取期权和对应标的的多合约 kline 14 | klines = api.get_kline_serial(["SHFE.cu2006C50000", "SHFE.cu2006"], 24 * 60 * 60, 20) 15 | 16 | # 通过 OPTION_IMPV 函数计算隐含波动率,设置无风险利率为 0.025 17 | impv = OPTION_IMPV(klines, quote, 0.025) 18 | 19 | print(list(impv["impv"] * 100)) 20 | 21 | api.close() 22 | -------------------------------------------------------------------------------- /tqsdk/demo/option_tutorial/o60.py: -------------------------------------------------------------------------------- 1 | from tqsdk import TqApi, TqAuth 2 | from tqsdk.ta import VOLATILITY_CURVE 3 | 4 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 5 | 6 | # 获取 m2112 的看跌期权 7 | underlying = "DCE.m2101" 8 | options = api.query_options(underlying_symbol=underlying, option_class="PUT", expired=False) 9 | 10 | # 批量获取合约的行情信息, 存储结构必须为 dict, key 为合约, value 为行情数据 11 | quote = {} 12 | for symbol in options: 13 | quote[symbol] = api.get_quote(symbol) 14 | options.append(underlying) 15 | 16 | klines = api.get_kline_serial(options, 24 * 60 * 60, 20) 17 | 18 | # 使用 VOLATILITY_CURVE 函数计算波动率曲面 19 | vc = VOLATILITY_CURVE(klines, quote, underlying, r=0.025) 20 | 21 | print(vc) 22 | 23 | api.close() 24 | -------------------------------------------------------------------------------- /tqsdk/demo/option_tutorial/o70.py: -------------------------------------------------------------------------------- 1 | from tqsdk import TqApi, TqAuth 2 | 3 | ''' 4 | 如果买入看涨期权构建多头期货的价格小于卖出期货价格 5 | 存在套利机会则发出双边挂单 6 | ''' 7 | api = TqApi(auth=TqAuth("快期账户", "账号密码")) 8 | 9 | # 获取行权价为2950的MA109看涨期权的quote数据 10 | quote_option = api.get_quote('CZCE.MA109C2950') 11 | 12 | # 获取期权对应标的期货,即MA109的quote数据 13 | quote = api.get_quote(quote_option.underlying_symbol) 14 | 15 | # 套利机会尝试次数 16 | times = 0 17 | 18 | while True: 19 | api.wait_update() 20 | # 以对手价来计算买入看涨期权然后行权后的期货成本价格 21 | option_buy = quote_option.strike_price + quote_option.ask_price1 22 | # 判断当期货的买入1档,即卖出期货价格大于买入看涨期权的期货成本价格,形成套利空间时进行限价下单 23 | if quote.bid_price1 > option_buy and times == 0: 24 | times += 1 25 | # 以现在卖1档价格买入看涨期权 26 | order_opiton = api.insert_order('CZCE.MA109C2950', "BUY", "OPEN", 1, quote_option.ask_price1) 27 | # 以现在买1档的价格卖出期货 28 | order_future = api.insert_order(quote.underlying_symbol, "SELL", "OPEN", 1, quote.bid_price1) 29 | print("存在期货,期权套利空间尝试买入") 30 | -------------------------------------------------------------------------------- /tqsdk/demo/option_tutorial/o71.py: -------------------------------------------------------------------------------- 1 | from tqsdk import TqApi, TqAuth 2 | 3 | ''' 4 | 获取标的对应看涨期权的期权和行权价对应列表 5 | ''' 6 | api = TqApi(auth=TqAuth("快期账户", "账号密码")) 7 | 8 | # 获取沪深300股指期权的认购在市合约 9 | ls = api.query_options("SSE.000300", "CALL", expired=False) 10 | 11 | # 批量获取这些合约的quote合约信息 12 | quote_ls = api.get_quote_list(ls) 13 | 14 | option_ls = {} 15 | 16 | # 遍历quote合约信息,将合约和其对应行权价组装成字典 17 | for i in quote_ls: 18 | option_ls[i.instrument_id] = i.strike_price 19 | 20 | print(option_ls) 21 | 22 | api.close() -------------------------------------------------------------------------------- /tqsdk/demo/option_tutorial/o72.py: -------------------------------------------------------------------------------- 1 | from tqsdk import TqApi, TqAuth 2 | from datetime import datetime 3 | from tqsdk.tafunc import time_to_datetime 4 | 5 | ''' 6 | 查询标的对应期权按虚值平值实值分类 7 | ''' 8 | from tqsdk import TqApi, TqAuth 9 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 10 | quote = api.get_quote("SHFE.au2112") 11 | in_money_options, at_money_options, out_of_money_options = api.query_all_level_options("SHFE.au2112", quote.last_price, "CALL") 12 | print(in_money_options) # 实值期权列表 13 | print(at_money_options) # 平值期权列表 14 | print(out_of_money_options) # 虚值期权列表 15 | 16 | api.close() 17 | -------------------------------------------------------------------------------- /tqsdk/demo/option_tutorial/o73.py: -------------------------------------------------------------------------------- 1 | from tqsdk import TqApi, TqAuth 2 | from datetime import datetime 3 | from tqsdk.tafunc import time_to_datetime 4 | 5 | ''' 6 | 查询标的对应期权按虚值平值实值分类 7 | ''' 8 | from tqsdk import TqApi, TqAuth 9 | 10 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 11 | 12 | quote = api.get_quote("SSE.510300") 13 | 14 | # 获取下月的上交所看涨300etf期权 15 | in_money_options, at_money_options, out_of_money_options = api.query_all_level_finance_options("SSE.510300", quote.last_price, "CALL", nearbys = 1) 16 | 17 | print(in_money_options) # 实值期权列表 18 | print(at_money_options) # 平值期权列表 19 | print(out_of_money_options) # 虚值期权列表 20 | 21 | api.close() 22 | -------------------------------------------------------------------------------- /tqsdk/demo/option_tutorial/o74.py: -------------------------------------------------------------------------------- 1 | from tqsdk import TqApi, TqAuth 2 | 3 | ''' 4 | 根据输入的ETF期权来查询该期权的交易所规则下的理论卖方保证金,实际情况请以期货公司收取的一手保证金为准 5 | ''' 6 | 7 | def etf_margin_cal(symbol): 8 | quote_etf = api.get_quote(symbol) 9 | # 判断期权标的是不是ETF 10 | if quote_etf.underlying_symbol in ["SSE.510050", "SSE.510300", "SZSE.159919"]: 11 | if quote_etf.option_class == "CALL": 12 | # 认购期权虚值=Max(行权价-合约标的前收盘价,0) 13 | call_out_value = max(quote_etf.strike_price - quote_etf.underlying_quote.pre_close, 0) 14 | # 认购期权义务仓开仓保证金=[合约前结算价+Max(12%×合约标的前收盘价-认购期权虚值,7%×合约标的前收盘价)]×合约单位 15 | call_margin = (quote_etf.pre_settlement + max(0.12 * quote_etf.underlying_quote.pre_close - call_out_value, 16 | 0.07 * quote_etf.underlying_quote.pre_close)) * quote_etf.volume_multiple 17 | return round(call_margin, 2) 18 | elif quote_etf.option_class == "PUT": 19 | # 认沽期权虚值=Max(合约标的前收盘价-行权价,0) 20 | put_out_value = max(quote_etf.underlying_quote.pre_close - quote_etf.strike_price, 0) 21 | # 认沽期权义务仓开仓保证金=Min[合约前结算价+Max(12%×合约标的前收盘价-认沽期权虚值,7%×行权价),行权价]×合约单位。 22 | put_margin = min(quote_etf.pre_settlement + max(0.12 * quote_etf.underlying_quote.pre_close - put_out_value, 23 | 0.07 * quote_etf.strike_price), 24 | quote_etf.strike_price) * quote_etf.volume_multiple 25 | return round(put_margin, 2) 26 | else: 27 | print("输入的不是ETF期权合约") 28 | return None 29 | 30 | 31 | # 创建api 32 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 33 | 34 | # 深交所300etf期权 35 | symbol = "SZSE.90000833" 36 | 37 | print(etf_margin_cal(symbol)) 38 | 39 | api.close() 40 | -------------------------------------------------------------------------------- /tqsdk/demo/ta.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chengzhi' 4 | 5 | import datetime 6 | from tqsdk import TqApi, TqAuth 7 | from tqsdk.ta import * 8 | 9 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 10 | # 获得 cu1909 10秒K线的引用 11 | klines = api.get_kline_serial("SHFE.cu1910", 10, data_length=3000) 12 | 13 | print("K线时间", datetime.datetime.fromtimestamp(klines.iloc[-1]["datetime"] / 1e9)) 14 | print(klines) 15 | 16 | print("ATR", ATR(klines, 26)) 17 | print("BIAS", BIAS(klines, 6)) 18 | print("BOLL", BOLL(klines, 3, 5)) 19 | print("DMI", DMI(klines, 14, 6)) 20 | print("KDJ", KDJ(klines, 9, 3, 3)) 21 | print("MA", MA(klines, 3)) 22 | print("MACD", MACD(klines, 20, 35, 10)) 23 | print("SAR", SAR(klines, 4, 0.02, 0.2)) 24 | 25 | api.close() 26 | -------------------------------------------------------------------------------- /tqsdk/demo/ta_option.py: -------------------------------------------------------------------------------- 1 | #!usr/bin/env python3 2 | #-*- coding:utf-8 -*- 3 | 4 | from tqsdk import TqApi, TqAuth, tafunc 5 | from tqsdk.ta import * 6 | 7 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 8 | 9 | underlying_quote = api.get_quote("SHFE.cu2009") 10 | klines = api.get_kline_serial('SHFE.cu2009', 24 * 60 * 60, 20) 11 | v = tafunc.get_his_volatility(klines, underlying_quote) 12 | print("历史波动率:", v) 13 | 14 | quote = api.get_quote("SHFE.cu2009C44000") 15 | bs_serise = BS_VALUE(klines, quote, 0.025) 16 | print("理论价:", list(round(bs_serise['bs_price'], 2))) 17 | 18 | 19 | klines2 = api.get_kline_serial(["SHFE.cu2009C44000", "SHFE.cu2009"], 24 * 60 * 60, 20) 20 | 21 | values = OPTION_VALUE(klines2, quote) 22 | print("内在价值:", list(values["intrins"])) 23 | print("时间价值:", list(values["time"])) 24 | 25 | impv = OPTION_IMPV(klines2, quote, 0.025) 26 | print("隐含波动率:", list(round(impv['impv'] * 100, 2))) 27 | 28 | greeks = OPTION_GREEKS(klines2, quote, 0.025, impv['impv']) 29 | print("delta:", list(greeks["delta"])) 30 | print("theta:", list(greeks["theta"])) 31 | print("gamma:", list(greeks["gamma"])) 32 | print("vega:", list(greeks["vega"])) 33 | print("rho:", list(greeks["rho"])) 34 | 35 | api.close() 36 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/demo/tutorial/__init__.py -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/backtest.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chengzhi' 4 | 5 | from datetime import date 6 | from tqsdk import TqApi, TqAuth, TqBacktest, TargetPosTask 7 | 8 | ''' 9 | 如果当前价格大于5分钟K线的MA15则开多仓 10 | 如果小于则平仓 11 | 回测从 2018-05-01 到 2018-10-01 12 | ''' 13 | # 在创建 api 实例时传入 TqBacktest 就会进入回测模式 14 | api = TqApi(backtest=TqBacktest(start_dt=date(2018, 5, 1), end_dt=date(2018, 10, 1)), auth=TqAuth("快期账户", "账户密码")) 15 | # 获得 m1901 5分钟K线的引用 16 | klines = api.get_kline_serial("DCE.m1901", 5 * 60, data_length=15) 17 | # 创建 m1901 的目标持仓 task,该 task 负责调整 m1901 的仓位到指定的目标仓位 18 | target_pos = TargetPosTask(api, "DCE.m1901") 19 | 20 | while True: 21 | api.wait_update() 22 | if api.is_changing(klines): 23 | ma = sum(klines.close.iloc[-15:]) / 15 24 | print("最新价", klines.close.iloc[-1], "MA", ma) 25 | if klines.close.iloc[-1] > ma: 26 | print("最新价大于MA: 目标多头5手") 27 | # 设置目标持仓为多头5手 28 | target_pos.set_target_volume(5) 29 | elif klines.close.iloc[-1] < ma: 30 | print("最新价小于MA: 目标空仓") 31 | # 设置目标持仓为空仓 32 | target_pos.set_target_volume(0) 33 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/downloader.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chengzhi' 4 | 5 | from datetime import datetime 6 | from contextlib import closing 7 | from tqsdk import TqApi, TqAuth 8 | from tqsdk.tools import DataDownloader 9 | 10 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 11 | # 下载从 2018-01-01凌晨6点 到 2018-06-01下午4点 的 cu1805 分钟线数据 12 | kd = DataDownloader(api, symbol_list="SHFE.cu1805", dur_sec=60, 13 | start_dt=datetime(2018, 1, 1, 6, 0 ,0), end_dt=datetime(2018, 6, 1, 16, 0, 0), csv_file_name="kline.csv") 14 | # 下载从 2018-05-01凌晨0点 到 2018-07-01凌晨0点 的 T1809 盘口Tick数据 15 | td = DataDownloader(api, symbol_list="CFFEX.T1809", dur_sec=0, 16 | start_dt=datetime(2018, 5, 1), end_dt=datetime(2018, 7, 1), csv_file_name="tick.csv") 17 | # 使用with closing机制确保下载完成后释放对应的资源 18 | with closing(api): 19 | while not kd.is_finished() or not td.is_finished(): 20 | api.wait_update() 21 | print("progress: kline: %.2f%% tick:%.2f%%" % (kd.get_progress(), td.get_progress())) 22 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/replay.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'mayanqiong' 4 | 5 | from datetime import date 6 | from tqsdk import TqApi, TqAuth, TqReplay 7 | 8 | ''' 9 | 复盘模式示例: 指定日期行情完全复盘 10 | 复盘 2020-05-26 行情 11 | ''' 12 | # 在创建 api 实例时传入 TqReplay 就会进入复盘模式 13 | api = TqApi(backtest=TqReplay(date(2020, 5, 26)), auth=TqAuth("快期账户", "账户密码")) 14 | quote = api.get_quote("SHFE.cu2009") 15 | 16 | while True: 17 | api.wait_update() 18 | if api.is_changing(quote): 19 | print("最新价", quote.datetime, quote.last_price) 20 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/replay2.py: -------------------------------------------------------------------------------- 1 | #!usr/bin/env python3 2 | #-*- coding:utf-8 -*- 3 | #!/usr/bin/env python 4 | # -*- coding: utf-8 -*- 5 | __author__ = 'chengzhi' 6 | 7 | from datetime import date 8 | from tqsdk import TqApi, TqAuth, TqReplay, TargetPosTask 9 | 10 | ''' 11 | 复盘 2020-05-26 12 | 如果当前价格大于5分钟K线的MA15则开多仓,如果小于则平仓 13 | ''' 14 | # 在创建 api 实例时传入 TqReplay 就会进入复盘模式, 同时打开 web_gui 15 | api = TqApi(backtest=TqReplay(date(2020, 5, 26)), web_gui=True, auth=TqAuth("快期账户", "账户密码")) 16 | # 获得 cu2009 5分钟K线的引用 17 | klines = api.get_kline_serial("SHFE.cu2009", 5 * 60, data_length=15) 18 | # 创建 cu2009 的目标持仓 task,该 task 负责调整 m1901 的仓位到指定的目标仓位 19 | target_pos = TargetPosTask(api, "SHFE.cu2009") 20 | 21 | while True: 22 | api.wait_update() 23 | if api.is_changing(klines): 24 | ma = sum(klines.close.iloc[-15:]) / 15 25 | print("最新价", klines.close.iloc[-1], "MA", ma) 26 | if klines.close.iloc[-1] > ma: 27 | print("最新价大于MA: 目标多头5手") 28 | # 设置目标持仓为多头5手 29 | target_pos.set_target_volume(5) 30 | elif klines.close.iloc[-1] < ma: 31 | print("最新价小于MA: 目标空仓") 32 | # 设置目标持仓为空仓 33 | target_pos.set_target_volume(0) 34 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t10.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chengzhi' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | # 创建API实例,传入自己的快期账户 8 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 9 | # 获得上期所 ni2206 的行情引用,当行情有变化时 quote 中的字段会对应更新 10 | quote = api.get_quote("SHFE.ni2206") 11 | 12 | # 输出 ni2206 的最新行情时间和最新价 13 | print(quote.datetime, quote.last_price) 14 | 15 | # 关闭api,释放资源 16 | api.close() 17 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t20.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chengzhi' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | # 可以指定debug选项将调试信息写入指定的文件中 8 | api = TqApi(debug="debug.log", auth=TqAuth("快期账户", "账户密码")) 9 | quote = api.get_quote("CZCE.FG209") 10 | print(quote.datetime, quote.last_price, quote.ask_price1, quote.ask_price2) 11 | 12 | while True: 13 | # 调用 wait_update 等待业务信息发生变化,例如: 行情发生变化, 委托单状态变化, 发生成交等等 14 | # 注意:其他合约的行情的更新也会触发业务信息变化,因此下面使用 is_changing 判断 FG209 的行情是否有变化 15 | api.wait_update() 16 | # 如果 FG209 的任何字段有变化,is_changing就会返回 True 17 | if api.is_changing(quote): 18 | print("行情变化", quote) 19 | # 只有当 FG209 的最新价有变化,is_changing才会返回 True 20 | if api.is_changing(quote, "last_price"): 21 | print("最新价变化", quote.last_price) 22 | # 当 FG209 的买1价/买1量/卖1价/卖1量中任何一个有变化,is_changing都会返回 True 23 | if api.is_changing(quote, ["ask_price1", "ask_volume1", "bid_price1", "bid_volume1"]): 24 | print("盘口变化", quote.ask_price1, quote.ask_volume1, quote.bid_price1, quote.bid_volume1) 25 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t30.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chengzhi' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | import datetime 7 | 8 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 9 | # 获得 i2209 tick序列的引用 10 | ticks = api.get_tick_serial("DCE.i2209") 11 | # 获得 i2209 10秒K线的引用 12 | klines = api.get_kline_serial("DCE.i2209", 10) 13 | print(datetime.datetime.fromtimestamp(klines.iloc[-1]["datetime"] / 1e9)) 14 | 15 | while True: 16 | api.wait_update() 17 | # 判断整个tick序列是否有变化 18 | if api.is_changing(ticks): 19 | # ticks.iloc[-1]返回序列中最后一个tick 20 | print("tick变化", ticks.iloc[-1]) 21 | # 判断最后一根K线的时间是否有变化,如果发生变化则表示新产生了一根K线 22 | if api.is_changing(klines.iloc[-1], "datetime"): 23 | # datetime: 自unix epoch(1970-01-01 00:00:00 GMT)以来的纳秒数 24 | print("新K线", datetime.datetime.fromtimestamp(klines.iloc[-1]["datetime"] / 1e9)) 25 | # 判断最后一根K线的收盘价是否有变化 26 | if api.is_changing(klines.iloc[-1], "close"): 27 | # klines.close返回收盘价序列 28 | print("K线变化", datetime.datetime.fromtimestamp(klines.iloc[-1]["datetime"] / 1e9), klines.close.iloc[-1]) 29 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t40.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chengzhi' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 8 | # 获得 m2105 的持仓引用,当持仓有变化时 position 中的字段会对应更新 9 | position = api.get_position("DCE.m2105") 10 | # 获得资金账户引用,当账户有变化时 account 中的字段会对应更新 11 | account = api.get_account() 12 | # 下单并返回委托单的引用,当该委托单有变化时 order 中的字段会对应更新 13 | order = api.insert_order(symbol="DCE.m2105", direction="BUY", offset="OPEN", volume=5, limit_price=2750) 14 | 15 | while True: 16 | api.wait_update() 17 | if api.is_changing(order, ["status", "volume_orign", "volume_left"]): 18 | print("单状态: %s, 已成交: %d 手" % (order.status, order.volume_orign - order.volume_left)) 19 | if api.is_changing(position, "pos_long_today"): 20 | print("今多头: %d 手" % (position.pos_long_today)) 21 | if api.is_changing(account, "available"): 22 | print("可用资金: %.2f" % (account.available)) 23 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t41.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | from tqsdk import TqApi, TqAuth 5 | 6 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 7 | quote = api.get_quote("SHFE.ni2206") 8 | # 开仓两手并等待完成 9 | order = api.insert_order(symbol="SHFE.ni2206", direction="BUY", offset="OPEN", limit_price=quote.ask_price1, volume=2) 10 | while order.status != "FINISHED": 11 | api.wait_update() 12 | print("已开仓") 13 | # 平今两手并等待完成 14 | order = api.insert_order(symbol="SHFE.ni2206", direction="SELL", offset="CLOSETODAY", limit_price=quote.bid_price1, 15 | volume=2) 16 | while order.status != "FINISHED": 17 | api.wait_update() 18 | print("已平今") 19 | # 关闭api,释放相应资源 20 | api.close() 21 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t50.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chaos' 4 | 5 | from datetime import datetime 6 | from tqsdk import TqApi, TqAuth 7 | 8 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 9 | # 注意:该函数返回的对象不会更新,不建议在循环内调用该方法 10 | 11 | # 最近3天结算价信息 12 | df = api.query_symbol_settlement("SHFE.ag2504", days=3) 13 | print(df.to_string()) 14 | 15 | # 查询从2025年2月10日开始两天的结算价信息 16 | df = api.query_symbol_settlement("SHFE.ag2504", days=2, start_dt=datetime(2025,2,10).date()) 17 | print(df.to_string()) 18 | 19 | # 关闭api,释放相应资源 20 | api.close() -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t51.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chaos' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 8 | # 注意:该函数返回的对象不会更新,不建议在循环内调用该方法 9 | 10 | # 最近 1 天持仓排名信息,以成交量排序 11 | df = api.query_symbol_ranking("SHFE.ag2504", ranking_type="VOLUME") 12 | print(df.to_string()) 13 | 14 | # 最近 3 天持仓排名信息,以多头持仓量排序 15 | df = api.query_symbol_ranking("SHFE.ag2504", ranking_type="LONG",days=3) 16 | print(df.to_string()) 17 | 18 | # 关闭api,释放相应资源 19 | api.close() -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t52.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chaos' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 8 | 9 | # 不推荐使用以下方式获取符合某种条件的合约列表,推荐使用接口来完成此功能。 10 | # ls = [k for k,v in api._data["quotes"].items() if k.startswith("KQ.m")] 11 | # print(ls) 12 | 13 | # au 品种的全部合约,包括已下市以及未下市合约 14 | ls = api.query_quotes(ins_class="FUTURE", product_id="au") 15 | print(ls) 16 | 17 | # au、cu 品种的全部未下市合约合约 18 | ls = api.query_quotes(ins_class=["FUTURE"], product_id=["au", "cu"], expired=False) 19 | print(ls) 20 | 21 | # au 品种指数合约 22 | ls = api.query_quotes(ins_class="INDEX", product_id="au") 23 | print(ls) 24 | 25 | # 全部主连合约 26 | ls = api.query_quotes(ins_class="CONT") 27 | print(ls) 28 | 29 | # au 品种主连合约 30 | ls = api.query_quotes(ins_class="CONT", product_id="au") 31 | print(ls) 32 | 33 | # 上期所带夜盘的期货合约列表 34 | ls = api.query_quotes(ins_class="FUTURE", exchange_id="SHFE", has_night=True) 35 | print(ls) 36 | 37 | # au 品种的全部未下市合约、指数、主连 38 | ls = api.query_quotes(product_id="au", expired=False) 39 | print(ls) 40 | 41 | # 上海交易所股票代码列表 42 | ls = api.query_quotes(ins_class="STOCK", exchange_id="SSE", expired=False) 43 | print(ls) 44 | 45 | # 上海交易所基金代码列表 46 | ls = api.query_quotes(ins_class="FUND", exchange_id="SSE", expired=False) 47 | print(ls) 48 | 49 | # 关闭api,释放相应资源 50 | api.close() -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t53.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chaos' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 8 | 9 | # 全部主连合约对应的标的合约 10 | ls = api.query_cont_quotes() 11 | print(ls) 12 | 13 | # 大商所主连合约对应的标的合约 14 | ls = api.query_cont_quotes(exchange_id="DCE") 15 | print(ls) 16 | 17 | # jd 品种主连合约对应的标的合约 18 | ls = api.query_cont_quotes(product_id="jd") 19 | print(ls) 20 | 21 | # 关闭api,释放相应资源 22 | api.close() 23 | 24 | # 预期输出如下 25 | # ['SHFE.cu2503', 'SHFE.ni2503', 'CFFEX.TS2503', 'SHFE.br2503', 'CZCE.OI505', 'DCE.c2505', 'GFEX.lc2505', 'INE.bc2503', 'CZCE.CJ505', 'CFFEX.TF2503', 'SHFE.hc2505', 'SHFE.ru2505', 'DCE.lg2507', 'DCE.a2505', 'DCE.b2505', 'GFEX.ps2506', 'SHFE.ss2505', 'CZCE.CF505', 'DCE.m2505', 'CFFEX.T2503', 'DCE.pg2503', 'CZCE.SR505', 'CZCE.PF504', 'SHFE.pb2503', 'CZCE.UR505', 'CZCE.MA505', 'CZCE.PX505', 'SHFE.sn2503', 'GFEX.si2505', 'CZCE.FG505', 'CFFEX.IM2503', 'CZCE.ZC505', 'CFFEX.IC2503', 'INE.nr2504', 'INE.lu2505', 'DCE.fb2505', 'CZCE.RM505', 'CFFEX.TL2503', 'CZCE.SA505', 'CZCE.AP505', 'CZCE.PK505', 'CZCE.SF505', 'SHFE.ao2505', 'CZCE.TA505', 'SHFE.bu2504', 'SHFE.zn2503', 'DCE.jm2505', 'DCE.jd2505', 'INE.sc2504', 'INE.ec2504', 'CZCE.PM505', 'DCE.lh2505', 'CZCE.WH505', 'CZCE.RI505', 'DCE.l2505', 'CZCE.PR503', 'CZCE.CY505', 'DCE.eg2505', 'DCE.pp2505', 'SHFE.fu2505', 'DCE.v2505', 'DCE.p2505', 'SHFE.rb2505', 'CZCE.JR505', 'SHFE.sp2505', 'CZCE.SM505', 'CFFEX.IF2503', 'DCE.rr2503', 'SHFE.au2504', 'DCE.bb2509', 'SHFE.ag2504', 'SHFE.al2504', 'DCE.j2505', 'CZCE.RS507', 'DCE.y2505', 'DCE.i2505', 'CZCE.SH505', 'CZCE.LR505', 'DCE.cs2503', 'SHFE.wr2505', 'CFFEX.IH2503', 'DCE.eb2503'] 26 | # ['DCE.c2505', 'DCE.lg2507', 'DCE.a2505', 'DCE.b2505', 'DCE.m2505', 'DCE.pg2503', 'DCE.fb2505', 'DCE.jm2505', 'DCE.jd2505', 'DCE.lh2505', 'DCE.l2505', 'DCE.eg2505', 'DCE.pp2505', 'DCE.v2505', 'DCE.p2505', 'DCE.rr2503', 'DCE.bb2509', 'DCE.j2505', 'DCE.y2505', 'DCE.i2505', 'DCE.cs2503', 'DCE.eb2503'] 27 | # ['DCE.jd2505'] 28 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t54.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chaos' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 8 | 9 | ls = api.query_options("SSE.510050", option_class="CALL", expired=False) # 所有未下市上交所上证50etf期权 10 | df = api.query_symbol_info(ls) 11 | print(df.to_string()) 12 | 13 | # 关闭api,释放相应资源 14 | api.close() -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t55.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chaos' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 8 | 9 | # 标的为 "SHFE.au2504" 的所有期权 10 | ls = api.query_options("SHFE.au2504") 11 | print(ls) 12 | 13 | # 标的为 "SHFE.au2504" 的看跌期权 14 | ls = api.query_options("SHFE.au2504", option_class="PUT") 15 | print(ls) 16 | 17 | # 标的为 "SHFE.au2504" 的看跌期权, 未下市的 18 | ls = api.query_options("SHFE.au2504", option_class="PUT", expired=False) 19 | print(ls) 20 | 21 | # 标的为 "SHFE.au2504" 、行权价为 340 的期权 22 | ls = api.query_options("SHFE.au2504", strike_price=340) 23 | print(ls) 24 | 25 | # 中金所沪深300股指期权 26 | ls = api.query_options("SSE.000300") 27 | print(ls) 28 | 29 | # 上交所沪深300etf期权 30 | ls = api.query_options("SSE.510300") 31 | print(ls) 32 | 33 | # 上交所沪深300etf期权, 限制条件 2020 年 12 月份行权 34 | ls = api.query_options("SSE.510300", exercise_year=2020, exercise_month=12) 35 | print(ls) 36 | 37 | # 关闭api,释放相应资源 38 | api.close() -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t56.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chaos' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 8 | quote = api.get_quote("SHFE.au2504") 9 | 10 | # 预计输出的为以au2504现在最新价来比对的认购的平值期权,当没有符合的平值期权时返回为空 11 | # ['SHFE.au2504C680'] 12 | ls = api.query_atm_options("SHFE.au2504", quote.last_price, 0, "CALL") 13 | print(ls) 14 | 15 | # 预计输出的为以au2504开盘价来比对的认购的实值1档,平值期权,虚值1档,如果没有符合要求的期权则对应栏返回为None,如果有则返回格式例如 16 | # ['SHFE.au2504C680', 'SHFE.au2504C688', 'SHFE.au2504C696'] 17 | ls = api.query_atm_options("SHFE.au2504", quote.open, [1,0,-1], "CALL") 18 | print(ls) 19 | 20 | # 预计输出沪深300股指期权,2025年12月的虚值1档期权 21 | ls = api.query_atm_options("SSE.000300", quote.last_price, -1, "CALL", exercise_year=2025, exercise_month=12) 22 | print(ls) 23 | 24 | # 关闭api,释放相应资源 25 | api.close() 26 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t57.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chaos' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 8 | 9 | quote = api.get_quote("SHFE.au2504") 10 | in_money_options, at_money_options, out_of_money_options = api.query_all_level_options("SHFE.au2504", quote.last_price, "CALL") 11 | # 实值期权列表 12 | print(in_money_options) 13 | # 平值期权列表 14 | print(at_money_options) 15 | # 虚值期权列表 16 | print(out_of_money_options) 17 | 18 | # 关闭api,释放相应资源 19 | api.close() 20 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t58.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chaos' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 8 | 9 | quote = api.get_quote("SSE.510050") 10 | in_money_options, at_money_options, out_of_money_options = api.query_all_level_finance_options("SSE.510300", quote.last_price, "CALL", nearbys = 1) 11 | print(in_money_options) # 实值期权列表 12 | print(at_money_options) # 平值期权列表 13 | print(out_of_money_options) # 虚值期权列表 14 | 15 | # 关闭api,释放相应资源 16 | api.close() 17 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t59.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chaos' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 8 | 9 | quote = api.get_quote("SSE.510300") 10 | in_money_options, at_money_options, out_of_money_options = api.query_all_level_finance_options("SSE.510300", quote.last_price, "CALL", nearbys = 1) 11 | ls = in_money_options + at_money_options + out_of_money_options # 期权列表 12 | df = api.query_option_greeks(ls) 13 | print(df.to_string()) # 显示期权希腊指标 14 | 15 | # 关闭api,释放相应资源 16 | api.close() 17 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t60.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chengzhi' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | ''' 8 | 如果当前价格大于10秒K线的MA15则开多仓 (使用 insert_order() 函数) 9 | 如果小于则平仓 10 | ''' 11 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 12 | # 获得 m2207 10秒K线的引用 13 | klines = api.get_kline_serial("DCE.m2207", 10) 14 | 15 | # 判断开仓条件 16 | while True: 17 | api.wait_update() 18 | if api.is_changing(klines): 19 | ma = sum(klines.close.iloc[-15:]) / 15 20 | print("最新价", klines.close.iloc[-1], "MA", ma) 21 | if klines.close.iloc[-1] > ma: 22 | print("最新价大于MA: 市价开仓") 23 | api.insert_order(symbol="DCE.m2207", direction="BUY", offset="OPEN", volume=5) 24 | break 25 | # 判断平仓条件 26 | while True: 27 | api.wait_update() 28 | if api.is_changing(klines): 29 | ma = sum(klines.close.iloc[-15:]) / 15 30 | print("最新价", klines.close.iloc[-1], "MA", ma) 31 | if klines.close.iloc[-1] < ma: 32 | print("最新价小于MA: 市价平仓") 33 | api.insert_order(symbol="DCE.m2207", direction="SELL", offset="CLOSE", volume=5) 34 | break 35 | # 关闭api,释放相应资源 36 | api.close() 37 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t70.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chengzhi' 4 | 5 | from tqsdk import TqApi, TqAuth, TargetPosTask 6 | 7 | ''' 8 | 如果当前价格大于10秒K线的MA15则开多仓 (使用 TargetPosTask 调仓工具) 9 | 如果小于则平仓 10 | ''' 11 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 12 | # 获得 m2207 10秒K线的引用 13 | klines = api.get_kline_serial("DCE.m2207", 10) 14 | # 创建 m2207 的目标持仓 task,该 task 负责调整 m2207 的仓位到指定的目标仓位 15 | target_pos = TargetPosTask(api, "DCE.m2207") 16 | 17 | while True: 18 | api.wait_update() 19 | if api.is_changing(klines): 20 | ma = sum(klines.close.iloc[-15:]) / 15 21 | print("最新价", klines.close.iloc[-1], "MA", ma) 22 | if klines.close.iloc[-1] > ma: 23 | print("最新价大于MA: 目标多头5手") 24 | # 设置目标持仓为多头5手 25 | target_pos.set_target_volume(5) 26 | elif klines.close.iloc[-1] < ma: 27 | print("最新价小于MA: 目标空仓") 28 | # 设置目标持仓为空仓 29 | target_pos.set_target_volume(0) 30 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t71.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'yanqiong' 4 | 5 | from tqsdk import TqApi, TqAuth, TargetPosTask 6 | 7 | ''' 8 | 连续3根阴线就做空,连续3根阳线就做多,否则空仓 9 | ''' 10 | 11 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 12 | # 设定连续多少根阳线/阴线 13 | length = 3 14 | # 获得 ni2205 10秒K线的引用, 长度为 length+1 15 | klines = api.get_kline_serial("SHFE.ni2205", 10, data_length=length + 1) 16 | # 创建 ni2205 的目标持仓 task,该 task 负责调整 ni2105 的仓位到指定的目标仓位, offset_priority的用法详见文档 17 | target_pos = TargetPosTask(api, "SHFE.ni2205", offset_priority="今昨开") 18 | 19 | while True: 20 | api.wait_update() 21 | # 只有在新创建出K线时才判断开平仓条件 22 | if api.is_changing(klines.iloc[-1], "datetime"): 23 | # 跳过最后一根刚生成的K线 24 | df = klines.iloc[:-1] 25 | # 比较收盘价和开盘价,判断是阳线还是阴线 26 | # df.close 为收盘价序列, df.open 为开盘价序列, ">"(pandas.Series.gt) 返回收盘价是否大于开盘价的一个新序列 27 | up = df.close > df.open 28 | down = df.close < df.open 29 | if all(up): 30 | print("连续阳线: 目标持仓 多头1手") 31 | # 设置目标持仓为正数表示多头,负数表示空头,0表示空仓 32 | target_pos.set_target_volume(1) 33 | elif all(down): 34 | print("连续阴线: 目标持仓 空头1手") 35 | target_pos.set_target_volume(-1) 36 | else: 37 | print("目标持仓: 空仓") 38 | target_pos.set_target_volume(0) 39 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t72.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'ringo' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | from tqsdk.tafunc import time_to_datetime 7 | 8 | ''' 9 | 使用get_trading_status来判断合约是否进入交易状态来进行下单,该接口需要有天勤量化专业版资格才可使用 10 | ''' 11 | 12 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 13 | ts = api.get_trading_status("SHFE.cu2201") 14 | print(ts.trade_status) 15 | 16 | while True: 17 | api.wait_update() 18 | # 如果处于集合竞价状态则进行下单 19 | if ts.trade_status == "AUCTIONORDERING": 20 | order = api.insert_order("SHFE.cu2201", "BUY", "OPEN", 1, 71400) 21 | break 22 | # insert_order指令会在下一次wait_update()发出 23 | api.wait_update() 24 | 25 | api.close() 26 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t80.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chengzhi' 4 | 5 | from tqsdk import TqApi, TqAuth, TargetPosTask 6 | 7 | ''' 8 | 价差回归 9 | 当近月-远月的价差大于250时做空近月,做多远月 10 | 当价差小于200时平仓 11 | ''' 12 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 13 | quote_near = api.get_quote("SHFE.rb2104") 14 | quote_deferred = api.get_quote("SHFE.rb2105") 15 | # 创建 rb2104 的目标持仓 task,该 task 负责调整 rb2104 的仓位到指定的目标仓位 16 | target_pos_near = TargetPosTask(api, "SHFE.rb2104") 17 | # 创建 rb2105 的目标持仓 task,该 task 负责调整 rb2105 的仓位到指定的目标仓位 18 | target_pos_deferred = TargetPosTask(api, "SHFE.rb2105") 19 | 20 | while True: 21 | api.wait_update() 22 | if api.is_changing(quote_near) or api.is_changing(quote_deferred): 23 | spread = quote_near.last_price - quote_deferred.last_price 24 | print("当前价差:", spread) 25 | if spread > 250: 26 | print("目标持仓: 空近月,多远月") 27 | # 设置目标持仓为正数表示多头,负数表示空头,0表示空仓 28 | target_pos_near.set_target_volume(-1) 29 | target_pos_deferred.set_target_volume(1) 30 | elif spread < 200: 31 | print("目标持仓: 空仓") 32 | target_pos_near.set_target_volume(0) 33 | target_pos_deferred.set_target_volume(0) 34 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t90.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'limin' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | from tqsdk.ta import MA 7 | 8 | ''' 9 | 画图示例: 在主图中画指标线 10 | 注意: 画图示例中用到的数据不含有实际意义,请根据自己的实际策略情况进行修改 11 | ''' 12 | 13 | api = TqApi(web_gui=True, auth=TqAuth("快期账户", "账户密码")) # web_gui=True, 开启使用 web 界面查看绘图结果的功能 14 | klines = api.get_kline_serial("SHFE.rb2105", 5) 15 | 16 | # 画一次指标线 17 | ma = MA(klines, 30) # 使用 tqsdk 自带指标函数计算均线 18 | klines["ma_MAIN"] = ma.ma # 在主图中画一根默认颜色(红色)的 ma 指标线 19 | 20 | # 由于需要在浏览器中查看绘图结果,因此程序不能退出 21 | while True: 22 | api.wait_update() 23 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t91.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'limin' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | from tqsdk.ta import MA 7 | 8 | ''' 9 | 画图示例: 在附图中画指标线 10 | (将画图代码放在循环中即可使图像随着行情推进而更新) 11 | 注意: 画图示例中用到的数据不含有实际意义,请根据自己的实际策略情况进行修改 12 | ''' 13 | 14 | api = TqApi(web_gui=":9878", auth=TqAuth("快期账户", "账户密码")) # web_gui="[ip]:port", 指定 web 界面地址的 ip 和 port 15 | klines = api.get_kline_serial("SHFE.rb2105", 24 * 60 * 60) 16 | 17 | while True: 18 | # 将画图代码放在循环中即可使图像随着行情推进而更新 19 | ma = MA(klines, 30) # 使用tqsdk自带指标函数计算均线 20 | 21 | # 示例1: 在附图中画一根绿色的ma指标线 22 | klines["ma_B2"] = ma.ma 23 | klines["ma_B2.board"] = "B2" # 设置附图: 可以设置任意字符串,同一字符串表示同一副图 24 | klines["ma_B2.color"] = "green" # 设置为绿色. 以下设置颜色方式都可行: "green", "#00FF00", "rgb(0,255,0)", "rgba(0,125,0,0.5)" 25 | 26 | # 示例2: 在另一个附图画一根比ma小4的宽度为4的紫色指标线 27 | klines["ma_4"] = ma.ma - 4 28 | klines["ma_4.board"] = "MA4" # 设置为另一个附图 29 | klines["ma_4.color"] = 0xFF9933CC # 设置为紫色, 或者 "#9933FF" 30 | klines["ma_4.width"] = 4 # 设置宽度为4,默认为1 31 | 32 | api.wait_update() 33 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t92.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'limin' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | ''' 8 | 画图示例: 在主图中画信号线及文字标注 9 | 注意: 画图示例中用到的数据不含有实际意义,请根据自己的实际策略情况进行修改 10 | ''' 11 | 12 | api = TqApi(web_gui=True, auth=TqAuth("快期账户", "账户密码")) # web_gui=True, 开启使用 web 界面查看绘图结果的功能 13 | klines = api.get_kline_serial("SHFE.rb2105", 300) 14 | 15 | # 示例1: 在主图中最后一根K线上画射线以标注需要的信号 16 | api.draw_line(klines, -1, klines.iloc[-1].close, -1, klines.iloc[-1].high, line_type="SEG", color=0xFFFF9900, width=3) 17 | 18 | # 示例2: 绘制字符串 19 | api.draw_text(klines, "信号1", x=-1, y=klines.iloc[-1].high + 5, color=0xFFFF3333) 20 | 21 | # 示例3: 给主图最后5根K线加一个方框 22 | api.draw_box(klines, x1=-5, y1=klines.iloc[-5]["high"], x2=-1, y2=klines.iloc[-1]["low"], width=1, color=0xFF0000FF, 23 | bg_color=0x7000FF00) 24 | 25 | # 由于需要在浏览器中查看绘图结果,因此程序不能退出 26 | while True: 27 | api.wait_update() 28 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t93.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'limin' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | ''' 8 | 画图示例: 在主图中画线和方框 9 | 注意: 画图示例中用到的数据不含有实际意义,请根据自己的实际策略情况进行修改 10 | ''' 11 | 12 | api = TqApi(web_gui=True, auth=TqAuth("快期账户", "账户密码")) # web_gui=True, 开启使用 web 界面查看绘图结果的功能 13 | klines = api.get_kline_serial("SHFE.rb2105", 60) 14 | 15 | # 由于需要在浏览器中查看绘图结果,因此程序不能退出 16 | while True: 17 | api.wait_update() # 当有业务信息发生变化时执行 18 | # 当最后 1 根柱子最大最小值价差大于 0.05 时,在主图绘制信号 19 | high = klines.iloc[-1].high 20 | low = klines.iloc[-1].low 21 | if high - low > 0.05: 22 | # 绘制直线, 每一个 id 对应同一条直线 23 | api.draw_line(klines, -1, high, -1, low, id="box%.0f" % (klines.iloc[-1].id), color=0xaa662244, width=4) 24 | # 绘制字符串 25 | api.draw_text(klines, "信号1", x=-1, y=low, id="text%.0f" % (klines.iloc[-1].id), color=0xFFFF3333) 26 | 27 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t94.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'limin' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | ''' 8 | 画图示例: 在附图中画K线 9 | 注意: 画图示例中用到的数据不含有实际意义,请根据自己的实际策略情况进行修改 10 | ''' 11 | 12 | api = TqApi(web_gui=True, auth=TqAuth("快期账户", "账户密码")) 13 | klines = api.get_kline_serial("SHFE.rb2104", 86400) 14 | klines2 = api.get_kline_serial("SHFE.rb2105", 86400) 15 | 16 | while True: 17 | # 将画图代码放在循环中即可使图像随着行情推进而更新 18 | # 在附图画出 rb2105 的K线: 需要将open、high、log、close的数据都设置正确 19 | klines["rb2105.open"] = klines2["open"] 20 | klines["rb2105.high"] = klines2["high"] 21 | klines["rb2105.low"] = klines2["low"] 22 | klines["rb2105.close"] = klines2["close"] 23 | klines["rb2105.board"] = "B2" 24 | api.wait_update() 25 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t95.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'limin' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | from tqsdk.ta import MA 7 | 8 | ''' 9 | 画图示例: 在同一附图中画K线、线段和方框 10 | 注意: 画图示例中用到的数据不含有实际意义,请根据自己的实际策略情况进行修改 11 | ''' 12 | 13 | api = TqApi(web_gui=True, auth=TqAuth("快期账户", "账户密码")) 14 | klines = api.get_kline_serial("CFFEX.T2103", 10) 15 | klines2 = api.get_kline_serial("CFFEX.T2012", 10) 16 | 17 | # 示例1 : 在附图画出 T2012 的K线: 需要将open、high、log、close的数据都设置正确 18 | klines["T2012.open"] = klines2["open"] 19 | klines["T2012.high"] = klines2["high"] 20 | klines["T2012.low"] = klines2["low"] 21 | klines["T2012.close"] = klines2["close"] 22 | klines["T2012.board"] = "B2" 23 | ma = MA(klines, 30) 24 | klines["ma_MAIN"] = ma.ma 25 | 26 | # 示例2: 在附图中画线段(默认为红色) 27 | api.draw_line(klines, -10, klines2.iloc[-10].low, -3, klines2.iloc[-3].high, id="my_line", board="B2", line_type="SEG", 28 | color=0xFFFF00FF, width=3) 29 | 30 | # 示例3: 在附图K线上画黄色的方框: 需要设置画在附图时, 将board参数选择到对应的图板即可 31 | api.draw_box(klines, x1=-5, y1=klines2.iloc[-5]["high"], x2=-1, y2=klines2.iloc[-1]["low"], id="my_box", board="B2", 32 | width=1, color=0xFF0000FF, bg_color=0x70FFFF00) 33 | 34 | # 由于需要在浏览器中查看绘图结果,因此程序不能退出 35 | while True: 36 | api.wait_update() 37 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/t96.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'yanqiong' 4 | 5 | from tqsdk import TqApi, TqAuth 6 | from tqsdk.ta import MACD 7 | 8 | ''' 9 | 画图示例: 在附图中画 macd 指标示例 10 | 注意: 画图示例中用到的数据不含有实际意义,请根据自己的实际策略情况进行修改 11 | ''' 12 | 13 | def calc_macd_klines(klines): 14 | # 计算 macd 指标 15 | macd = MACD(klines, 12, 26, 9) 16 | # 用 K 线图模拟 MACD 指标柱状图 17 | klines["MACD.open"] = 0.0 18 | klines["MACD.close"] = macd["bar"] 19 | klines["MACD.high"] = klines["MACD.close"].where(klines["MACD.close"] > 0, 0) 20 | klines["MACD.low"] = klines["MACD.close"].where(klines["MACD.close"] < 0, 0) 21 | klines["MACD.board"] = "MACD" 22 | # 在 board=MACD 上添加 diff、dea 线 23 | klines["diff"] = macd["diff"] 24 | klines["diff.board"] = "MACD" 25 | klines["diff.color"] = "gray" 26 | klines["dea"] = macd["dea"] 27 | klines["dea.board"] = "MACD" 28 | klines["dea.color"] = "rgb(255,128,0)" 29 | 30 | 31 | api = TqApi(auth=TqAuth("快期账户", "账户密码"), web_gui=True) 32 | klines = api.get_kline_serial("SHFE.rb2105", 5*60, 200) 33 | while True: 34 | calc_macd_klines(klines) 35 | api.wait_update() 36 | -------------------------------------------------------------------------------- /tqsdk/demo/tutorial/underlying_symbol.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = "Ringo" 4 | 5 | from tqsdk import TqApi, TqAuth 6 | 7 | api = TqApi(auth=TqAuth("快期账户", "账户密码")) 8 | 9 | # 订阅螺纹钢主连 10 | quote = api.get_quote("KQ.m@SHFE.rb") 11 | # 打印现在螺纹钢主连的标的合约 12 | print(quote.underlying_symbol) 13 | 14 | api.close() -------------------------------------------------------------------------------- /tqsdk/entity.py: -------------------------------------------------------------------------------- 1 | #!usr/bin/env python3 2 | #-*- coding:utf-8 -*- 3 | __author__ = 'yanqiong' 4 | 5 | import copy 6 | import weakref 7 | from collections.abc import MutableMapping 8 | 9 | 10 | class Entity(MutableMapping): 11 | def _instance_entity(self, path): 12 | self._path = path 13 | self._listener = weakref.WeakSet() 14 | 15 | def __setitem__(self, key, value): 16 | return self.__dict__.__setitem__(key, value) 17 | 18 | def __delitem__(self, key): 19 | return self.__dict__.__delitem__(key) 20 | 21 | def __getitem__(self, key): 22 | return self.__dict__.__getitem__(key) 23 | 24 | def __iter__(self): 25 | return iter({k: v for k, v in self.__dict__.items() if not k.startswith("_")}) 26 | 27 | def __len__(self): 28 | return len({k: v for k, v in self.__dict__.items() if not k.startswith("_")}) 29 | 30 | def __str__(self): 31 | return str({k: v for k, v in self.__dict__.items() if not k.startswith("_")}) 32 | 33 | def __repr__(self): 34 | return '{}, D({})'.format(super(Entity, self).__repr__(), 35 | {k: v for k, v in self.__dict__.items() if not k.startswith("_")}) 36 | 37 | def copy(self): 38 | return copy.copy(self) 39 | -------------------------------------------------------------------------------- /tqsdk/expired_quotes.json.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/expired_quotes.json.lzma -------------------------------------------------------------------------------- /tqsdk/lib/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'mayanqiong' 4 | 5 | 6 | from tqsdk.lib.target_pos_task import TargetPosTask, InsertOrderUntilAllTradedTask, InsertOrderTask 7 | from tqsdk.lib.target_pos_scheduler import TargetPosScheduler 8 | from tqsdk.lib.notify import TqNotify 9 | -------------------------------------------------------------------------------- /tqsdk/lib/notify.py: -------------------------------------------------------------------------------- 1 | #!usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | __author__ = 'yanqiong' 4 | 5 | 6 | from tqsdk.api import TqApi 7 | from tqsdk.diff import _get_obj 8 | 9 | 10 | class TqNotify(object): 11 | """ 12 | 用于在同步代码中接受服务器通知 13 | """ 14 | 15 | def __init__(self, api: TqApi) -> None: 16 | """ 17 | 创建 TqNotify 实例 18 | 19 | Args: 20 | api (tqsdk.api.TqApi): TqApi 实例 21 | 22 | Example:: 23 | 24 | from tqsdk import TqApi, TqAuth, TqKq, TqNotify 25 | 26 | api = TqApi(account=TqKq(), auth=TqAuth("快期账户", "账户密码")) 27 | tqNotify = TqNotify(api) # 构造实例类 28 | while True: 29 | api.wait_update() 30 | # 每次调用返回距离上一次调用 tqNotify.get_notifies() 之后产生的通知列表,没有的话返回 [] 31 | notify_list = tqNotify.get_notifies() 32 | for notify in notify_list: 33 | print(notify) # 打印出通知内容 34 | # send_message(notify['content']) 可以发送通知到其他工具 35 | 36 | """ 37 | self._api = api 38 | self._notify = _get_obj(self._api._data, ["notify"]) 39 | # 用户未读取过的通知,用 list 类型尽量保证用户读到通知的顺序和进程收到的顺序一致,但是不能完全保证 40 | self._unread_notifies_list = [k for k in self._notify if not k.startswith("_")] 41 | # 已经添加到 _unread_notifies 的通知 42 | self._processed_notifies_set = {k for k in self._notify if not k.startswith("_")} 43 | self._task = self._api.create_task(self._run()) 44 | 45 | async def _run(self): 46 | async with self._api.register_update_notify(self._notify) as update_chan: 47 | async for _ in update_chan: 48 | all_notifies = {k for k in self._notify if not k.startswith("_")} 49 | notifies = all_notifies - self._processed_notifies_set # 最近更新的通知 50 | self._processed_notifies_set = all_notifies 51 | self._unread_notifies_list.extend([k for k in notifies]) 52 | 53 | def get_notifies(self): 54 | notifies = [self._notify[n] for n in self._unread_notifies_list] 55 | self._unread_notifies_list = [] 56 | return notifies 57 | -------------------------------------------------------------------------------- /tqsdk/lib/time_table.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'mayanqiong' 4 | 5 | 6 | from pandas import DataFrame 7 | 8 | 9 | class TqTimeTable(DataFrame): 10 | 11 | def __init__(self, account=None): 12 | self.__dict__["_account"] = account 13 | self.__dict__["_columns"] = ['interval', 'volume', 'price'] 14 | super(TqTimeTable, self).__init__(data=[], columns=self.__dict__["_columns"]) 15 | -------------------------------------------------------------------------------- /tqsdk/log.py: -------------------------------------------------------------------------------- 1 | # !usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | __author__ = 'yanqiong' 4 | 5 | import datetime 6 | import os 7 | 8 | import psutil 9 | 10 | DEBUG_DIR = os.path.join(os.path.expanduser('~'), ".tqsdk/logs") 11 | 12 | 13 | def _get_log_name(): 14 | """返回默认 debug 文件生成的位置""" 15 | if not os.path.exists(DEBUG_DIR): 16 | os.makedirs(os.path.join(os.path.expanduser('~'), ".tqsdk/logs"), exist_ok=True) 17 | return os.path.join(DEBUG_DIR, f"{datetime.datetime.now().strftime('%Y%m%d%H%M%S%f')}-{os.getpid()}.log") 18 | 19 | 20 | def _get_disk_free(): 21 | free = psutil.disk_usage(DEBUG_DIR).free 22 | return free / 1e9 23 | 24 | 25 | def _log_path_list(): 26 | # 获取所有日志文件路径,并按照修改时间递减排序 27 | path_list = [os.path.join(DEBUG_DIR, log) for log in os.listdir(DEBUG_DIR)] 28 | path_list.sort(key=lambda x: _stat_dt(x)) 29 | return path_list 30 | 31 | 32 | def _stat_dt(path): 33 | try: 34 | return datetime.datetime.fromtimestamp(os.stat(path).st_mtime) 35 | except: 36 | return datetime.datetime.now() 37 | 38 | 39 | def _remove_log(path): 40 | try: 41 | os.remove(path) 42 | except: 43 | pass # 忽略抛错 44 | 45 | 46 | def _clear_logs(): 47 | """清除最后修改时间是 n 天前的日志""" 48 | if not os.path.exists(DEBUG_DIR): 49 | return 50 | n = os.getenv("TQ_SAVE_LOG_DAYS", 30) 51 | # 清除最后修改时间是 n 天前的日志 52 | # 清空日志保证剩余空间大于 3G,但是最近 3 个自然日的一定不会清除,保证最近的一个交易日不会被清除日志 53 | dt30 = datetime.datetime.now() - datetime.timedelta(days=int(n)) 54 | dt3 = datetime.datetime.now() - datetime.timedelta(days=int(3)) 55 | for path in _log_path_list(): 56 | if _stat_dt(path) < dt30 or (_get_disk_free() < 3 and _stat_dt(path) < dt3): 57 | _remove_log(path) 58 | else: 59 | break 60 | -------------------------------------------------------------------------------- /tqsdk/risk_manager.py: -------------------------------------------------------------------------------- 1 | #!usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | 4 | __author__ = 'mayanqiong' 5 | 6 | from tqsdk.datetime import _get_trading_day_from_timestamp, _get_trading_day_end_time 7 | from tqsdk.datetime_state import TqDatetimeState 8 | from tqsdk.exceptions import TqRiskRuleError 9 | 10 | 11 | class TqRiskManager(list): 12 | 13 | def __init__(self): 14 | self._datetime_state = TqDatetimeState() 15 | self._trading_day_end = 0 16 | super(TqRiskManager, self).__init__() 17 | 18 | def _on_recv_data(self, diffs): 19 | for d in diffs: 20 | self._datetime_state.update_state(d) 21 | 22 | current = self._datetime_state.get_current_dt() 23 | if current > self._trading_day_end: 24 | # 切换交易日 25 | self._trading_day_end = _get_trading_day_end_time(_get_trading_day_from_timestamp(current)) 26 | [r._on_settle() for r in self] 27 | 28 | def append(self, rule): 29 | if rule not in self: 30 | super(TqRiskManager, self).append(rule) 31 | 32 | def remove(self, rule): 33 | if rule in self: 34 | super(TqRiskManager, self).remove(rule) 35 | 36 | def _could_insert_order(self, pack): 37 | # 是否可以下单 38 | for r in self: 39 | is_valid, err_msg = r._could_insert_order(pack) 40 | if not is_valid: 41 | raise TqRiskRuleError(err_msg) 42 | return True 43 | 44 | def _on_insert_order(self, pack): 45 | # 需要更新风控对象内部统计值 46 | for r in self: 47 | r._on_insert_order(pack) 48 | -------------------------------------------------------------------------------- /tqsdk/sim/utils.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'mayanqiong' 4 | 5 | 6 | TRADING_DAYS_OF_YEAR = 250 7 | 8 | 9 | def _get_price_range(quote): 10 | """ 返回合约对应的买一卖一盘口价格""" 11 | ask_price = quote["ask_price1"] 12 | bid_price = quote["bid_price1"] 13 | if quote["ins_class"].endswith("INDEX"): 14 | # 在指数交易时,使用 tick 进行回测时,backtest 发的 quote 没有买一卖一价;或者在实时行情中,指数的 quote 也没有买一卖一价 15 | if ask_price != ask_price: 16 | ask_price = quote["last_price"] + quote["price_tick"] 17 | if bid_price != bid_price: 18 | bid_price = quote["last_price"] - quote["price_tick"] 19 | return ask_price, bid_price 20 | 21 | 22 | def _get_option_margin(quote, last_price, underlying_last_price): 23 | """返回每张期权占用保证金,只有空头持仓占用保证金""" 24 | # 期权保证金计算公式参考深交所文档 http://docs.static.szse.cn/www/disclosure/notice/general/W020191207433397366259.pdf 25 | if quote["option_class"] == "CALL": 26 | # 认购期权义务仓开仓保证金=[合约最新价 + Max(12% × 合约标的最新价 - 认购期权虚值, 7% × 合约标的最新价)] × 合约单位 27 | # 认购期权虚值=Max(行权价 - 合约标的最新价,0) 28 | out_value = max(quote["strike_price"] - underlying_last_price, 0) 29 | return (last_price + max(0.12 * underlying_last_price - out_value, 30 | 0.07 * underlying_last_price)) * quote["volume_multiple"] 31 | else: 32 | # 认沽期权义务仓开仓保证金=Min[合约最新价+ Max(12% × 合约标的最新价 - 认沽期权虚值,7% × 行权价),行权价] × 合约单位 33 | # 认沽期权虚值=Max(合约标的最新价 - 行权价,0) 34 | out_value = max(underlying_last_price - quote["strike_price"], 0) 35 | return min(quote["last_price"] + max(0.12 * underlying_last_price - out_value, 36 | 0.07 * quote["strike_price"]), 37 | quote["strike_price"]) * quote["volume_multiple"] 38 | 39 | 40 | def _get_premium(trade, quote): 41 | """返回成交导致的权利金变化""" 42 | if quote["ins_class"].endswith("OPTION"): 43 | premium = trade["price"] * trade["volume"] * quote["volume_multiple"] 44 | return -premium if trade["direction"] == "BUY" else premium 45 | else: 46 | return 0 47 | 48 | 49 | def _get_close_profit(trade, quote, position): 50 | """返回成交导致的平仓盈亏变化""" 51 | if quote["ins_class"].endswith("OPTION"): 52 | # 期权没有持仓盈亏没有持仓价,其平仓的盈亏体现在市价变化中 53 | return 0 54 | # 期货及其他使用持仓价计算 55 | elif trade["direction"] == "SELL": 56 | return (trade["price"] - position["position_price_long"]) * trade["volume"] * quote["volume_multiple"] 57 | else: 58 | return (position["position_price_short"] - trade["price"]) * trade["volume"] * quote["volume_multiple"] 59 | 60 | 61 | def _get_commission(quote={}): 62 | """返回每手手续费""" 63 | if quote.get("ins_class", "").endswith("OPTION"): 64 | return quote.get("user_commission", 10) # 期权quote没有commission字段, 设为固定10元一张, 优先采用用户设置的参数 65 | return quote.get("user_commission", quote.get('commission', float('nan'))) 66 | 67 | 68 | def _get_future_margin(quote={}): 69 | """返回期货每手保证金""" 70 | if quote.get("ins_class", "").endswith("OPTION"): 71 | return float('nan') 72 | return quote.get("user_margin", quote.get("margin", float('nan'))) 73 | -------------------------------------------------------------------------------- /tqsdk/tools/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chengzhi' 4 | 5 | from tqsdk.tools.downloader import DataDownloader 6 | -------------------------------------------------------------------------------- /tqsdk/tools/dead_ins.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/tools/dead_ins.lzma -------------------------------------------------------------------------------- /tqsdk/tradeable/__init__.py: -------------------------------------------------------------------------------- 1 | #!usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | 4 | __author__ = 'mayanqiong' 5 | 6 | 7 | from tqsdk.tradeable.otg.base_otg import BaseOtg 8 | from tqsdk.tradeable.otg import TqAccount, TqZq, TqKq, TqKqStock, TqCtp, TqRohon, TqJees, TqYida, TqTradingUnit 9 | from tqsdk.tradeable.sim.basesim import BaseSim 10 | from tqsdk.tradeable.sim import TqSim, TqSimStock 11 | -------------------------------------------------------------------------------- /tqsdk/tradeable/otg/__init__.py: -------------------------------------------------------------------------------- 1 | #!usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | 4 | __author__ = 'mayanqiong' 5 | 6 | from tqsdk.tradeable.otg.tqaccount import TqAccount 7 | from tqsdk.tradeable.otg.tqzq import TqZq 8 | from tqsdk.tradeable.otg.tqkq import TqKq, TqKqStock 9 | from tqsdk.tradeable.otg.tqctp import TqCtp 10 | from tqsdk.tradeable.otg.tqrohon import TqRohon 11 | from tqsdk.tradeable.otg.tqjees import TqJees 12 | from tqsdk.tradeable.otg.tqyida import TqYida 13 | from tqsdk.tradeable.otg.tqtradingunit import TqTradingUnit 14 | -------------------------------------------------------------------------------- /tqsdk/tradeable/otg/tqctp.py: -------------------------------------------------------------------------------- 1 | #!usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | __author__ = 'chenli' 4 | 5 | import hashlib 6 | 7 | from tqsdk.tradeable.otg.base_otg import BaseOtg 8 | from tqsdk.tradeable.mixin import FutureMixin 9 | 10 | 11 | class TqCtp(BaseOtg, FutureMixin): 12 | """直连 CTP 账户类""" 13 | 14 | def __init__(self, account_id: str, password: str, front_broker: str, front_url: str, app_id: str, auth_code: str) -> None: 15 | """ 16 | 创建直连 CTP 账户实例 17 | 18 | Args: 19 | account_id (str): 帐号 20 | 21 | password (str): 密码 22 | 23 | front_broker (str): CTP 柜台代码 24 | 25 | front_url (str): CTP 柜台地址,格式为 tcp://ip:port,如 tcp://129.211.138.170:10001 26 | 27 | app_id (str): CTP AppID 28 | 29 | auth_code (str): CTP AuthCode 30 | 31 | Example1:: 32 | 33 | from tqsdk import TqApi, TqCtp 34 | account = TqCtp(account_id="CTP 账户", password="CTP 密码", front_broker="CTP 柜台代码", front_url="CTP 柜台地址", app_id="CTP AppID", auth_code="CTP AuthCode") 35 | api = TqApi(account, auth=TqAuth("快期账户", "账户密码")) 36 | 37 | 注意: 38 | 1. 使用 TqCtp 账户需要安装 tqsdk_zq_otg 包: pip install -U tqsdk_zq_otg 39 | 2. front_broker, front_url, app_id 和 auth_code 信息需要向期货公司申请程序化外接后取得 40 | 41 | """ 42 | self._account_id = account_id 43 | self._front_broker = front_broker 44 | self._front_url = front_url 45 | self._app_id = app_id 46 | self._auth_code = auth_code 47 | super(TqCtp, self).__init__(broker_id="", account_id=account_id, password=password, td_url="zqotg://127.0.0.1:0/trade") 48 | 49 | @property 50 | def _account_auth(self): 51 | return { 52 | "feature": "tq_direct", 53 | "account_id": self._account_id, 54 | "auto_add": True, 55 | } 56 | 57 | def _get_account_key(self): 58 | s = self._broker_id + self._account_id 59 | s += self._front_broker if self._front_broker else "" 60 | s += self._front_url if self._front_url else "" 61 | return hashlib.md5(s.encode('utf-8')).hexdigest() 62 | 63 | async def _send_login_pack(self): 64 | req = { 65 | "aid": "req_login", 66 | "bid": "tqsdk_zq_otg", 67 | "user_name": self._account_id, 68 | "password": self._password, 69 | "broker_id": self._front_broker, 70 | "front": self._front_url, 71 | "app_id": self._app_id, 72 | "auth_code": self._auth_code, 73 | "backend": "ctp" 74 | } 75 | await self._td_send_chan.send(req) 76 | -------------------------------------------------------------------------------- /tqsdk/tradeable/otg/tqjees.py: -------------------------------------------------------------------------------- 1 | #!usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | __author__ = 'chenli' 4 | 5 | import hashlib 6 | 7 | from tqsdk.tradeable.otg.base_otg import BaseOtg 8 | from tqsdk.tradeable.mixin import FutureMixin 9 | 10 | 11 | class TqJees(BaseOtg, FutureMixin): 12 | """杰宜斯资管账户类""" 13 | 14 | def __init__(self, account_id: str, password: str, front_broker: str, front_url: str, app_id: str, auth_code: str) -> None: 15 | """ 16 | 创建杰宜斯资管账户实例 17 | 18 | Args: 19 | account_id (str): 帐号 20 | 21 | password (str): 密码 22 | 23 | front_broker (str): 杰宜斯柜台代码 24 | 25 | front_url (str): 杰宜斯柜台地址,格式为 tcp://ip:port,如 tcp://129.211.138.170:10001 26 | 27 | app_id (str): 杰宜斯 AppID 28 | 29 | auth_code (str): 杰宜斯 AuthCode 30 | 31 | Example1:: 32 | 33 | from tqsdk import TqApi, TqJees 34 | account = TqJees(account_id="杰宜斯账户", password="杰宜斯密码", front_broker="杰宜斯柜台代码", front_url="杰宜斯柜台地址", app_id="杰宜斯 AppID", auth_code="杰宜斯 AuthCode") 35 | api = TqApi(account, auth=TqAuth("快期账户", "账户密码")) 36 | 37 | 注意: 38 | 1. 使用 TqJees 账户需要安装 tqsdk_zq_otg 包: pip install -U tqsdk_zq_otg 39 | 2. front_broker, front_url, app_id 和 auth_code 信息需要向杰宜斯申请程序化外接后取得 40 | 41 | """ 42 | self._account_id = account_id 43 | self._front_broker = front_broker 44 | self._front_url = front_url 45 | self._app_id = app_id 46 | self._auth_code = auth_code 47 | super(TqJees, self).__init__(broker_id="", account_id=account_id, password=password, td_url="zqotg://127.0.0.1:0/trade") 48 | 49 | @property 50 | def _account_auth(self): 51 | return { 52 | "feature": "tq_direct", 53 | "account_id": self._account_id, 54 | "auto_add": True, 55 | } 56 | 57 | def _get_account_key(self): 58 | s = self._broker_id + self._account_id 59 | s += self._front_broker if self._front_broker else "" 60 | s += self._front_url if self._front_url else "" 61 | return hashlib.md5(s.encode('utf-8')).hexdigest() 62 | 63 | async def _send_login_pack(self): 64 | req = { 65 | "aid": "req_login", 66 | "bid": "tqsdk_zq_otg", 67 | "user_name": self._account_id, 68 | "password": self._password, 69 | "broker_id": self._front_broker, 70 | "front": self._front_url, 71 | "app_id": self._app_id, 72 | "auth_code": self._auth_code, 73 | "backend": "jees" 74 | } 75 | await self._td_send_chan.send(req) 76 | -------------------------------------------------------------------------------- /tqsdk/tradeable/otg/tqrohon.py: -------------------------------------------------------------------------------- 1 | #!usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | __author__ = 'chenli' 4 | 5 | import hashlib 6 | 7 | from tqsdk.tradeable.otg.base_otg import BaseOtg 8 | from tqsdk.tradeable.mixin import FutureMixin 9 | 10 | 11 | class TqRohon(BaseOtg, FutureMixin): 12 | """融航资管账户类""" 13 | 14 | def __init__(self, account_id: str, password: str, front_broker: str, front_url: str, app_id: str, auth_code: str) -> None: 15 | """ 16 | 创建融航账户实例 17 | 18 | Args: 19 | account_id (str): 帐号 20 | 21 | password (str): 密码 22 | 23 | front_broker (str): 融航柜台代码 24 | 25 | front_url (str): 融航柜台地址,格式为 tcp://ip:port,如 tcp://129.211.138.170:10001 26 | 27 | app_id (str): 融航 AppID 28 | 29 | auth_code (str): 融航 AuthCode 30 | 31 | Example1:: 32 | 33 | from tqsdk import TqApi, TqRohon 34 | account = TqRohon(account_id="融航账户", password="融航密码", front_broker="融航柜台代码", front_url="融航柜台地址", app_id="融航 AppID", auth_code="融航 AuthCode") 35 | api = TqApi(account, auth=TqAuth("快期账户", "账户密码")) 36 | 37 | 注意: 38 | 1. 使用 TqRohon 账户需要安装 tqsdk_zq_otg 包: pip install -U tqsdk_zq_otg 39 | 2. front_broker, front_url, app_id 和 auth_code 信息需要融航申请程序化外接后取得 40 | 41 | """ 42 | self._account_id = account_id 43 | self._front_broker = front_broker 44 | self._front_url = front_url 45 | self._app_id = app_id 46 | self._auth_code = auth_code 47 | super(TqRohon, self).__init__(broker_id="", account_id=account_id, password=password, td_url="zqotg://127.0.0.1:0/trade") 48 | 49 | @property 50 | def _account_auth(self): 51 | return { 52 | "feature": "tq_direct", 53 | "account_id": self._account_id, 54 | "auto_add": True, 55 | } 56 | 57 | def _get_account_key(self): 58 | s = self._broker_id + self._account_id 59 | s += self._front_broker if self._front_broker else "" 60 | s += self._front_url if self._front_url else "" 61 | return hashlib.md5(s.encode('utf-8')).hexdigest() 62 | 63 | async def _send_login_pack(self): 64 | req = { 65 | "aid": "req_login", 66 | "bid": "tqsdk_zq_otg", 67 | "user_name": self._account_id, 68 | "password": self._password, 69 | "broker_id": self._front_broker, 70 | "front": self._front_url, 71 | "app_id": self._app_id, 72 | "auth_code": self._auth_code, 73 | "backend": "rohon" 74 | } 75 | await self._td_send_chan.send(req) 76 | -------------------------------------------------------------------------------- /tqsdk/tradeable/otg/tqtradingunit.py: -------------------------------------------------------------------------------- 1 | #!usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | __author__ = 'chenli' 4 | 5 | import hashlib 6 | from typing import Optional, List 7 | import inspect 8 | 9 | from tqsdk.tradeable.otg.base_otg import BaseOtg 10 | from tqsdk.tradeable.mixin import FutureMixin 11 | 12 | 13 | class TqTradingUnit(BaseOtg, FutureMixin): 14 | """交易单元类""" 15 | 16 | def __init__(self, account_id: str, tags: Optional[List[str]]=None) -> None: 17 | """ 18 | 创建交易单元实例 19 | 20 | Args: 21 | account_id (str): 众期子账户 22 | 23 | tags (None/list of str): 策略标签, 默认为调用 TqTradingUnit 的文件名及 account_id 24 | 25 | Example1:: 26 | 27 | from tqsdk import TqApi, TqTradingUnit, TqAuth 28 | account = TqTradingUnit(account_id="众期子账户", tags=["铜品种策略", "套利策略"]) 29 | api = TqApi(account, auth=TqAuth("快期账户", "账户密码")) 30 | 31 | """ 32 | self._tags = self._convert_tags(tags, account_id) 33 | super(TqTradingUnit, self).__init__(broker_id="", account_id=account_id, password="tqsdk_zq", td_url="zq://localhost/") 34 | 35 | def _convert_tags(self, tags: Optional[List[str]], account_id: str) -> list: 36 | if tags is None: 37 | frame = inspect.stack()[1] 38 | filename = frame.filename 39 | strategy_set = {filename, account_id} 40 | else: 41 | strategy_set = set(tags) 42 | return list(strategy_set) 43 | 44 | @property 45 | def _account_auth(self): 46 | return { 47 | "feature": "tq_trading_unit", 48 | "account_id": None, 49 | "auto_add": False, 50 | } 51 | 52 | def _get_account_key(self): 53 | s = self._account_id + self._td_url 54 | return hashlib.md5(s.encode('utf-8')).hexdigest() 55 | 56 | async def _send_login_pack(self): 57 | req = { 58 | "aid": "req_login", 59 | "bid": "tqsdk_zq", 60 | "user_name": self._account_id, 61 | "password": "tqsdk_zq", 62 | "tags": self._tags 63 | } 64 | await self._td_send_chan.send(req) 65 | -------------------------------------------------------------------------------- /tqsdk/tradeable/otg/tqyida.py: -------------------------------------------------------------------------------- 1 | #!usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | __author__ = 'chenli' 4 | 5 | import hashlib 6 | 7 | from tqsdk.tradeable.otg.base_otg import BaseOtg 8 | from tqsdk.tradeable.mixin import FutureMixin 9 | 10 | 11 | class TqYida(BaseOtg, FutureMixin): 12 | """易达账户类""" 13 | 14 | def __init__(self, account_id: str, password: str, front_url: str, app_id: str, auth_code: str) -> None: 15 | """ 16 | 创建易达账户实例 17 | 18 | Args: 19 | account_id (str): 帐号 20 | 21 | password (str): 密码 22 | 23 | front_url (str): 易达柜台地址,格式为 tcp://ip:port,如 tcp://129.211.138.170:10001 24 | 25 | app_id (str): 易达 AppID 26 | 27 | auth_code (str): 易达 AuthCode 28 | 29 | Example1:: 30 | 31 | from tqsdk import TqApi, TqYida 32 | account = TqYida(account_id="易达账户", password="易达密码", front_url="易达柜台地址", app_id="易达 AppID", auth_code="易达 AuthCode") 33 | api = TqApi(account, auth=TqAuth("快期账户", "账户密码")) 34 | 35 | 注意: 36 | 1. 使用 TqYida 账户需要安装 tqsdk_zq_otg 包: pip install -U tqsdk_zq_otg 37 | 2. front_url, app_id 和 auth_code 信息需要向易达申请程序化外接后取得 38 | 39 | """ 40 | self._account_id = account_id 41 | self._front_url = front_url 42 | self._app_id = app_id 43 | self._auth_code = auth_code 44 | super(TqYida, self).__init__(broker_id="", account_id=account_id, password=password, td_url="zqotg://127.0.0.1:0/trade") 45 | 46 | @property 47 | def _account_auth(self): 48 | return { 49 | "feature": "tq_direct", 50 | "account_id": self._account_id, 51 | "auto_add": True, 52 | } 53 | 54 | def _get_account_key(self): 55 | s = self._broker_id + self._account_id 56 | s += self._front_url if self._front_url else "" 57 | return hashlib.md5(s.encode('utf-8')).hexdigest() 58 | 59 | async def _send_login_pack(self): 60 | req = { 61 | "aid": "req_login", 62 | "bid": "tqsdk_zq_otg", 63 | "user_name": self._account_id, 64 | "password": self._password, 65 | "broker_id": "", 66 | "front": self._front_url, 67 | "app_id": self._app_id, 68 | "auth_code": self._auth_code, 69 | "backend": "yida" 70 | } 71 | await self._td_send_chan.send(req) 72 | -------------------------------------------------------------------------------- /tqsdk/tradeable/otg/tqzq.py: -------------------------------------------------------------------------------- 1 | #!usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | __author__ = 'yanqiong' 4 | 5 | import hashlib 6 | 7 | from tqsdk.tradeable.otg.base_otg import BaseOtg 8 | from tqsdk.tradeable.mixin import FutureMixin 9 | 10 | 11 | class TqZq(BaseOtg, FutureMixin): 12 | """众期账户类""" 13 | 14 | def __init__(self, account_id: str, password: str, td_url: str) -> None: 15 | """ 16 | 创建众期账户实例 17 | 18 | Args: 19 | account_id (str): 帐号 20 | 21 | password (str): 密码 22 | 23 | td_url (str): 众期交易服务器地址, eg: "ws://1.2.3.4:8765/" 24 | 25 | Example1:: 26 | 27 | from tqsdk import TqApi, TqZq 28 | account = TqZq(account_id="众期账户", password="众期密码", td_url="众期柜台地址") 29 | api = TqApi(account, auth=TqAuth("快期账户", "账户密码")) 30 | 31 | """ 32 | super(TqZq, self).__init__(broker_id="", account_id=account_id, password=password, td_url=td_url) 33 | 34 | def _get_account_key(self): 35 | s = self._account_id + self._td_url 36 | return hashlib.md5(s.encode('utf-8')).hexdigest() 37 | -------------------------------------------------------------------------------- /tqsdk/tradeable/sim/__init__.py: -------------------------------------------------------------------------------- 1 | #!usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | 4 | __author__ = 'mayanqiong' 5 | 6 | from tqsdk.tradeable.sim.tqsim import TqSim 7 | from tqsdk.tradeable.sim.tqsim_stock import TqSimStock 8 | -------------------------------------------------------------------------------- /tqsdk/tradeable/tradeable.py: -------------------------------------------------------------------------------- 1 | #!usr/bin/env python3 2 | # -*- coding:utf-8 -*- 3 | 4 | __author__ = 'mayanqiong' 5 | 6 | from typing import Optional 7 | from abc import ABC, abstractmethod 8 | 9 | from tqsdk.baseModule import TqModule 10 | 11 | 12 | class Tradeable(ABC, TqModule): 13 | 14 | def __init__(self): 15 | self._account_key = self._get_account_key() # 每个账户的唯一标识,在账户初始化时就确定下来,后续只读不写 16 | 17 | def _get_account_key(self): 18 | return str(id(self)) 19 | 20 | @property 21 | @abstractmethod 22 | def _account_name(self): 23 | # 用于界面展示的用户信息 24 | raise NotImplementedError 25 | 26 | @property 27 | def _account_info(self): 28 | # 用于 web_helper 获取初始账户信息 29 | return { 30 | "account_key": self._account_key, 31 | "account_name": self._account_name 32 | } 33 | 34 | @property 35 | def _account_auth(self): 36 | # 使用该账户需要的授权信息 37 | return { 38 | "feature": None, 39 | "account_id": None, 40 | "auto_add": False, 41 | } 42 | 43 | def _is_self_trade_pack(self, pack): 44 | """是否是当前交易实例应该处理的交易包""" 45 | if pack["aid"] in ["insert_order", "cancel_order", "set_risk_management_rule"]: 46 | assert "account_key" in pack, "发给交易请求的包必须包含 account_key" 47 | if pack["account_key"] != self._account_key: 48 | return False 49 | else: 50 | pack.pop("account_key", None) 51 | return True 52 | return False 53 | 54 | def _connect_td(self, api, index: int) -> Optional[str]: 55 | # 用于建立交易连接 56 | return None 57 | -------------------------------------------------------------------------------- /tqsdk/web/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/favicon.ico -------------------------------------------------------------------------------- /tqsdk/web/fonts/ionicons.143146fa.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/fonts/ionicons.143146fa.woff2 -------------------------------------------------------------------------------- /tqsdk/web/fonts/ionicons.99ac3308.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/fonts/ionicons.99ac3308.woff -------------------------------------------------------------------------------- /tqsdk/web/fonts/ionicons.d535a25a.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/fonts/ionicons.d535a25a.ttf -------------------------------------------------------------------------------- /tqsdk/web/img/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/android-icon-144x144.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/android-icon-192x192.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/android-icon-36x36.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/android-icon-48x48.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/android-icon-72x72.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/android-icon-96x96.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/apple-touch-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/apple-touch-icon-114x114.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/apple-touch-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/apple-touch-icon-144x144.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/apple-touch-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/apple-touch-icon-57x57.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/apple-touch-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/apple-touch-icon-72x72.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/apple-touch-icon.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /tqsdk/web/img/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/favicon-16x16.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/favicon-32x32.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/favicon-96x96.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/favicon.ico -------------------------------------------------------------------------------- /tqsdk/web/img/icons/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "App", 3 | "icons": [ 4 | { 5 | "src": "\/android-icon-36x36.png", 6 | "sizes": "36x36", 7 | "type": "image\/png", 8 | "density": "0.75" 9 | }, 10 | { 11 | "src": "\/android-icon-48x48.png", 12 | "sizes": "48x48", 13 | "type": "image\/png", 14 | "density": "1.0" 15 | }, 16 | { 17 | "src": "\/android-icon-72x72.png", 18 | "sizes": "72x72", 19 | "type": "image\/png", 20 | "density": "1.5" 21 | }, 22 | { 23 | "src": "\/android-icon-96x96.png", 24 | "sizes": "96x96", 25 | "type": "image\/png", 26 | "density": "2.0" 27 | }, 28 | { 29 | "src": "\/android-icon-144x144.png", 30 | "sizes": "144x144", 31 | "type": "image\/png", 32 | "density": "3.0" 33 | }, 34 | { 35 | "src": "\/android-icon-192x192.png", 36 | "sizes": "192x192", 37 | "type": "image\/png", 38 | "density": "4.0" 39 | } 40 | ] 41 | } -------------------------------------------------------------------------------- /tqsdk/web/img/icons/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/ms-icon-150x150.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/ms-icon-310x310.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/ms-icon-70x70.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/msapplication-icon-144x144.png.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/msapplication-icon-144x144.png.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/shinnytech/tqsdk-python/62335b619dc589fc032eb2bf72c075794c9b538d/tqsdk/web/img/icons/mstile-150x150.png -------------------------------------------------------------------------------- /tqsdk/web/img/icons/notes: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /tqsdk/web/index.html: -------------------------------------------------------------------------------- 1 | tqsdk-python-web
-------------------------------------------------------------------------------- /tqsdk/web/manifest.json: -------------------------------------------------------------------------------- 1 | {"name":"tqsdk-python-web","short_name":"tqsdk-python-web","theme_color":"#4DBA87","icons":[{"src":"./img/icons/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"./img/icons/android-chrome-512x512.png","sizes":"512x512","type":"image/png"},{"src":"./img/icons/android-chrome-maskable-192x192.png","sizes":"192x192","type":"image/png","purpose":"maskable"},{"src":"./img/icons/android-chrome-maskable-512x512.png","sizes":"512x512","type":"image/png","purpose":"maskable"}],"start_url":".","display":"standalone","background_color":"#000000"} -------------------------------------------------------------------------------- /tqsdk/web/precache-manifest.1f4dd8e7baba14f0858de9c5a10cb57c.js: -------------------------------------------------------------------------------- 1 | self.__precacheManifest = (self.__precacheManifest || []).concat([ 2 | { 3 | "revision": "2d5af7f21b09666bed70", 4 | "url": "web/css/app.d72d8978.css" 5 | }, 6 | { 7 | "revision": "444d46da73e61093ed76", 8 | "url": "web/css/chunk-vendors.c93e9127.css" 9 | }, 10 | { 11 | "revision": "82cf43358c1d5de3b328f77464ef3d42", 12 | "url": "web/d3.min.js" 13 | }, 14 | { 15 | "revision": "143146fa24554ae2c5ac0a3982abb952", 16 | "url": "web/fonts/ionicons.143146fa.woff2" 17 | }, 18 | { 19 | "revision": "99ac3308dd8ee14f749f51538d0d5b9e", 20 | "url": "web/fonts/ionicons.99ac3308.woff" 21 | }, 22 | { 23 | "revision": "d535a25a79fb1365ae814b61e88fae71", 24 | "url": "web/fonts/ionicons.d535a25a.ttf" 25 | }, 26 | { 27 | "revision": "a2c4a261a239aa84463dc70e4bac9b9a", 28 | "url": "web/img/ionicons.a2c4a261.svg" 29 | }, 30 | { 31 | "revision": "cfc991fd3c84a514682ebd0873ecf3a6", 32 | "url": "web/index.html" 33 | }, 34 | { 35 | "revision": "2d5af7f21b09666bed70", 36 | "url": "web/js/app.c1424daf.js" 37 | }, 38 | { 39 | "revision": "444d46da73e61093ed76", 40 | "url": "web/js/chunk-vendors.d7fceff6.js" 41 | }, 42 | { 43 | "revision": "260485a0902e994592bfde307cd2874e", 44 | "url": "web/manifest.json" 45 | }, 46 | { 47 | "revision": "b6216d61c03e6ce0c9aea6ca7808f7ca", 48 | "url": "web/robots.txt" 49 | } 50 | ]); -------------------------------------------------------------------------------- /tqsdk/web/precache-manifest.53e7f698ae4f429b303bb209afaae23f.js: -------------------------------------------------------------------------------- 1 | self.__precacheManifest = (self.__precacheManifest || []).concat([ 2 | { 3 | "revision": "1084053643f61f877dd5", 4 | "url": "web/css/app.d72d8978.css" 5 | }, 6 | { 7 | "revision": "444d46da73e61093ed76", 8 | "url": "web/css/chunk-vendors.c93e9127.css" 9 | }, 10 | { 11 | "revision": "82cf43358c1d5de3b328f77464ef3d42", 12 | "url": "web/d3.min.js" 13 | }, 14 | { 15 | "revision": "143146fa24554ae2c5ac0a3982abb952", 16 | "url": "web/fonts/ionicons.143146fa.woff2" 17 | }, 18 | { 19 | "revision": "99ac3308dd8ee14f749f51538d0d5b9e", 20 | "url": "web/fonts/ionicons.99ac3308.woff" 21 | }, 22 | { 23 | "revision": "d535a25a79fb1365ae814b61e88fae71", 24 | "url": "web/fonts/ionicons.d535a25a.ttf" 25 | }, 26 | { 27 | "revision": "a2c4a261a239aa84463dc70e4bac9b9a", 28 | "url": "web/img/ionicons.a2c4a261.svg" 29 | }, 30 | { 31 | "revision": "214b6d0cc2b156d0e0ef0bdca809bc86", 32 | "url": "web/index.html" 33 | }, 34 | { 35 | "revision": "1084053643f61f877dd5", 36 | "url": "web/js/app.5a494932.js" 37 | }, 38 | { 39 | "revision": "444d46da73e61093ed76", 40 | "url": "web/js/chunk-vendors.d7fceff6.js" 41 | }, 42 | { 43 | "revision": "260485a0902e994592bfde307cd2874e", 44 | "url": "web/manifest.json" 45 | }, 46 | { 47 | "revision": "b6216d61c03e6ce0c9aea6ca7808f7ca", 48 | "url": "web/robots.txt" 49 | } 50 | ]); -------------------------------------------------------------------------------- /tqsdk/web/precache-manifest.5663715a1857b4046348697243e71707.js: -------------------------------------------------------------------------------- 1 | self.__precacheManifest = (self.__precacheManifest || []).concat([ 2 | { 3 | "revision": "919da4bc2f70a95e29ab", 4 | "url": "web/css/app.d72d8978.css" 5 | }, 6 | { 7 | "revision": "444d46da73e61093ed76", 8 | "url": "web/css/chunk-vendors.c93e9127.css" 9 | }, 10 | { 11 | "revision": "82cf43358c1d5de3b328f77464ef3d42", 12 | "url": "web/d3.min.js" 13 | }, 14 | { 15 | "revision": "143146fa24554ae2c5ac0a3982abb952", 16 | "url": "web/fonts/ionicons.143146fa.woff2" 17 | }, 18 | { 19 | "revision": "99ac3308dd8ee14f749f51538d0d5b9e", 20 | "url": "web/fonts/ionicons.99ac3308.woff" 21 | }, 22 | { 23 | "revision": "d535a25a79fb1365ae814b61e88fae71", 24 | "url": "web/fonts/ionicons.d535a25a.ttf" 25 | }, 26 | { 27 | "revision": "a2c4a261a239aa84463dc70e4bac9b9a", 28 | "url": "web/img/ionicons.a2c4a261.svg" 29 | }, 30 | { 31 | "revision": "6b70d9a005e2d62c2406629671866068", 32 | "url": "web/index.html" 33 | }, 34 | { 35 | "revision": "919da4bc2f70a95e29ab", 36 | "url": "web/js/app.93328858.js" 37 | }, 38 | { 39 | "revision": "444d46da73e61093ed76", 40 | "url": "web/js/chunk-vendors.d7fceff6.js" 41 | }, 42 | { 43 | "revision": "260485a0902e994592bfde307cd2874e", 44 | "url": "web/manifest.json" 45 | }, 46 | { 47 | "revision": "b6216d61c03e6ce0c9aea6ca7808f7ca", 48 | "url": "web/robots.txt" 49 | } 50 | ]); -------------------------------------------------------------------------------- /tqsdk/web/precache-manifest.6648e5db468eb9b65c97bc6d385e4143.js: -------------------------------------------------------------------------------- 1 | self.__precacheManifest = (self.__precacheManifest || []).concat([ 2 | { 3 | "revision": "9c8a19e054ff66ba9631", 4 | "url": "web/css/app.d72d8978.css" 5 | }, 6 | { 7 | "revision": "444d46da73e61093ed76", 8 | "url": "web/css/chunk-vendors.c93e9127.css" 9 | }, 10 | { 11 | "revision": "82cf43358c1d5de3b328f77464ef3d42", 12 | "url": "web/d3.min.js" 13 | }, 14 | { 15 | "revision": "143146fa24554ae2c5ac0a3982abb952", 16 | "url": "web/fonts/ionicons.143146fa.woff2" 17 | }, 18 | { 19 | "revision": "99ac3308dd8ee14f749f51538d0d5b9e", 20 | "url": "web/fonts/ionicons.99ac3308.woff" 21 | }, 22 | { 23 | "revision": "d535a25a79fb1365ae814b61e88fae71", 24 | "url": "web/fonts/ionicons.d535a25a.ttf" 25 | }, 26 | { 27 | "revision": "a2c4a261a239aa84463dc70e4bac9b9a", 28 | "url": "web/img/ionicons.a2c4a261.svg" 29 | }, 30 | { 31 | "revision": "b57f1ccb6d1c9c43702d6942a6af6d07", 32 | "url": "web/index.html" 33 | }, 34 | { 35 | "revision": "9c8a19e054ff66ba9631", 36 | "url": "web/js/app.fc01ac28.js" 37 | }, 38 | { 39 | "revision": "444d46da73e61093ed76", 40 | "url": "web/js/chunk-vendors.d7fceff6.js" 41 | }, 42 | { 43 | "revision": "260485a0902e994592bfde307cd2874e", 44 | "url": "web/manifest.json" 45 | }, 46 | { 47 | "revision": "b6216d61c03e6ce0c9aea6ca7808f7ca", 48 | "url": "web/robots.txt" 49 | } 50 | ]); -------------------------------------------------------------------------------- /tqsdk/web/precache-manifest.771b3896014acd43a3cb89b93a2134ea.js: -------------------------------------------------------------------------------- 1 | self.__precacheManifest = (self.__precacheManifest || []).concat([ 2 | { 3 | "revision": "9e87212e7997c6a3e6ff", 4 | "url": "web/css/app.d72d8978.css" 5 | }, 6 | { 7 | "revision": "d91a165d9320a5233a6d", 8 | "url": "web/css/chunk-vendors.1f44729d.css" 9 | }, 10 | { 11 | "revision": "82cf43358c1d5de3b328f77464ef3d42", 12 | "url": "web/d3.min.js" 13 | }, 14 | { 15 | "revision": "143146fa24554ae2c5ac0a3982abb952", 16 | "url": "web/fonts/ionicons.143146fa.woff2" 17 | }, 18 | { 19 | "revision": "99ac3308dd8ee14f749f51538d0d5b9e", 20 | "url": "web/fonts/ionicons.99ac3308.woff" 21 | }, 22 | { 23 | "revision": "d535a25a79fb1365ae814b61e88fae71", 24 | "url": "web/fonts/ionicons.d535a25a.ttf" 25 | }, 26 | { 27 | "revision": "a2c4a261a239aa84463dc70e4bac9b9a", 28 | "url": "web/img/ionicons.a2c4a261.svg" 29 | }, 30 | { 31 | "revision": "760d0976095136c746cc2592a5122cce", 32 | "url": "web/index.html" 33 | }, 34 | { 35 | "revision": "9e87212e7997c6a3e6ff", 36 | "url": "web/js/app.5eb857be.js" 37 | }, 38 | { 39 | "revision": "d91a165d9320a5233a6d", 40 | "url": "web/js/chunk-vendors.fc3d6c6c.js" 41 | }, 42 | { 43 | "revision": "260485a0902e994592bfde307cd2874e", 44 | "url": "web/manifest.json" 45 | }, 46 | { 47 | "revision": "b6216d61c03e6ce0c9aea6ca7808f7ca", 48 | "url": "web/robots.txt" 49 | } 50 | ]); -------------------------------------------------------------------------------- /tqsdk/web/precache-manifest.7ed60b69dab01cdb0c64836489ab6e0d.js: -------------------------------------------------------------------------------- 1 | self.__precacheManifest = (self.__precacheManifest || []).concat([ 2 | { 3 | "revision": "bdb3edcf9a8b75004898", 4 | "url": "web/css/app.d72d8978.css" 5 | }, 6 | { 7 | "revision": "444d46da73e61093ed76", 8 | "url": "web/css/chunk-vendors.c93e9127.css" 9 | }, 10 | { 11 | "revision": "82cf43358c1d5de3b328f77464ef3d42", 12 | "url": "web/d3.min.js" 13 | }, 14 | { 15 | "revision": "143146fa24554ae2c5ac0a3982abb952", 16 | "url": "web/fonts/ionicons.143146fa.woff2" 17 | }, 18 | { 19 | "revision": "99ac3308dd8ee14f749f51538d0d5b9e", 20 | "url": "web/fonts/ionicons.99ac3308.woff" 21 | }, 22 | { 23 | "revision": "d535a25a79fb1365ae814b61e88fae71", 24 | "url": "web/fonts/ionicons.d535a25a.ttf" 25 | }, 26 | { 27 | "revision": "a2c4a261a239aa84463dc70e4bac9b9a", 28 | "url": "web/img/ionicons.a2c4a261.svg" 29 | }, 30 | { 31 | "revision": "be353b15878098c0796b790ddb8d2977", 32 | "url": "web/index.html" 33 | }, 34 | { 35 | "revision": "bdb3edcf9a8b75004898", 36 | "url": "web/js/app.2c843c86.js" 37 | }, 38 | { 39 | "revision": "444d46da73e61093ed76", 40 | "url": "web/js/chunk-vendors.d7fceff6.js" 41 | }, 42 | { 43 | "revision": "260485a0902e994592bfde307cd2874e", 44 | "url": "web/manifest.json" 45 | }, 46 | { 47 | "revision": "b6216d61c03e6ce0c9aea6ca7808f7ca", 48 | "url": "web/robots.txt" 49 | } 50 | ]); -------------------------------------------------------------------------------- /tqsdk/web/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /tqsdk/web/service-worker.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Welcome to your Workbox-powered service worker! 3 | * 4 | * You'll need to register this file in your web app and you should 5 | * disable HTTP caching for this file too. 6 | * See https://goo.gl/nhQhGp 7 | * 8 | * The rest of the code is auto-generated. Please don't update this file 9 | * directly; instead, make changes to your Workbox build configuration 10 | * and re-run your build process. 11 | * See https://goo.gl/2aRDsh 12 | */ 13 | 14 | importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js"); 15 | 16 | importScripts( 17 | "web/precache-manifest.771b3896014acd43a3cb89b93a2134ea.js" 18 | ); 19 | 20 | workbox.core.setCacheNameDetails({prefix: "tqsdk-python-web"}); 21 | 22 | self.addEventListener('message', (event) => { 23 | if (event.data && event.data.type === 'SKIP_WAITING') { 24 | self.skipWaiting(); 25 | } 26 | }); 27 | 28 | /** 29 | * The workboxSW.precacheAndRoute() method efficiently caches and responds to 30 | * requests for URLs in the manifest. 31 | * See https://goo.gl/S9QRab 32 | */ 33 | self.__precacheManifest = [].concat(self.__precacheManifest || []); 34 | workbox.precaching.precacheAndRoute(self.__precacheManifest, {}); 35 | -------------------------------------------------------------------------------- /tqsdk/zq.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | __author__ = 'chenli' 4 | 5 | import asyncio 6 | import json 7 | import sys 8 | from pathlib import Path 9 | import subprocess 10 | 11 | from tqsdk.exceptions import TqContextManagerError 12 | 13 | 14 | class ZqContext(object): 15 | def __init__(self, api): 16 | self._api = api 17 | self._zq_config_path = Path.home() / ".tqsdk" / "zq" / "config" / "zq.json" 18 | 19 | async def __aenter__(self): 20 | return self 21 | 22 | async def get_url(self, url_info): 23 | """无法启动时抛出 TqContextManagerError 例外""" 24 | try: 25 | with open(self._zq_config_path, 'r') as file: 26 | config = json.load(file) 27 | td_url = config["td_url"] 28 | interpreter = config["interpreter"] 29 | if sys.platform.startswith("win"): 30 | zq_proc = subprocess.Popen([interpreter, "-m", "tqsdk_zq.cli", "start"], stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 31 | returncode = await self._api._loop.run_in_executor(None, lambda: zq_proc.wait()) 32 | else: 33 | zq_proc = await asyncio.create_subprocess_exec(interpreter, "-m", "tqsdk_zq.cli", "start", stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) 34 | returncode = await zq_proc.wait() 35 | if returncode != 0: 36 | raise TqContextManagerError(f"无法拉起 zq 进程, 返回码: {returncode}") 37 | return td_url 38 | except (OSError, KeyError, json.JSONDecodeError): 39 | raise Exception(f"加载配置文件失败: {self._zq_config_path}, 请尝试重新初始化: tqsdk-zq init") from None 40 | except: 41 | raise TqContextManagerError("获取交易服务地址失败") 42 | 43 | async def __aexit__(self, exc_type, exc, tb): 44 | pass 45 | --------------------------------------------------------------------------------