├── .gitignore ├── CHANGELOG.md ├── MANIFEST.in ├── README.md ├── requirements.txt ├── setup.py ├── tests ├── __init__.py ├── test_client_config.py ├── test_push_client.py └── test_utils.py └── tigeropen ├── __init__.py ├── common ├── __init__.py ├── consts │ ├── __init__.py │ ├── filter_fields.py │ ├── fundamental_fields.py │ ├── params.py │ ├── push_destinations.py │ ├── push_subscriptions.py │ ├── push_types.py │ ├── quote_keys.py │ ├── service_types.py │ └── tick_constants.py ├── exceptions.py ├── model.py ├── request.py ├── response.py └── util │ ├── __init__.py │ ├── account_util.py │ ├── common_utils.py │ ├── contract_utils.py │ ├── order_utils.py │ ├── price_util.py │ ├── signature_utils.py │ ├── string_utils.py │ ├── tick_util.py │ └── web_utils.py ├── examples ├── __init__.py ├── client_config.py ├── financial_demo.py ├── nasdaq100.py ├── option_helpers │ ├── __init__.py │ └── helpers.py ├── push_client_demo.py ├── push_client_stomp_demo.py ├── quote_client_demo.py └── trade_client_demo.py ├── fundamental ├── __init__.py ├── domain │ └── __init__.py ├── request │ ├── __init__.py │ └── model.py └── response │ ├── __init__.py │ ├── corporate_dividend_response.py │ ├── corporate_earnings_calendar_response.py │ ├── corporate_split_response.py │ ├── dataframe_response.py │ ├── financial_daily_response.py │ ├── financial_exchange_rate_response.py │ ├── financial_report_response.py │ └── industry_response.py ├── push ├── __init__.py ├── network │ ├── __init__.py │ ├── connect.py │ ├── exception.py │ ├── listener.py │ ├── protocal.py │ ├── transport.py │ └── utils.py ├── pb │ ├── AssetData.proto │ ├── AssetData_pb2.py │ ├── AssetData_pb2.pyi │ ├── KlineData.proto │ ├── KlineData_pb2.py │ ├── KlineData_pb2.pyi │ ├── OptionTopData.proto │ ├── OptionTopData_pb2.py │ ├── OptionTopData_pb2.pyi │ ├── OrderStatusData.proto │ ├── OrderStatusData_pb2.py │ ├── OrderStatusData_pb2.pyi │ ├── OrderTransactionData.proto │ ├── OrderTransactionData_pb2.py │ ├── OrderTransactionData_pb2.pyi │ ├── PositionData.proto │ ├── PositionData_pb2.py │ ├── PositionData_pb2.pyi │ ├── PushData.proto │ ├── PushData_pb2.py │ ├── PushData_pb2.pyi │ ├── QuoteBBOData.proto │ ├── QuoteBBOData_pb2.py │ ├── QuoteBBOData_pb2.pyi │ ├── QuoteBasicData.proto │ ├── QuoteBasicData_pb2.py │ ├── QuoteBasicData_pb2.pyi │ ├── QuoteData.proto │ ├── QuoteData_pb2.py │ ├── QuoteData_pb2.pyi │ ├── QuoteDepthData.proto │ ├── QuoteDepthData_pb2.py │ ├── QuoteDepthData_pb2.pyi │ ├── Request.proto │ ├── Request_pb2.py │ ├── Request_pb2.pyi │ ├── Response.proto │ ├── Response_pb2.py │ ├── Response_pb2.pyi │ ├── SocketCommon.proto │ ├── SocketCommon_pb2.py │ ├── SocketCommon_pb2.pyi │ ├── StockTopData.proto │ ├── StockTopData_pb2.py │ ├── StockTopData_pb2.pyi │ ├── TickData.proto │ ├── TickData_pb2.py │ ├── TickData_pb2.pyi │ ├── TradeTickData.proto │ ├── TradeTickData_pb2.py │ ├── TradeTickData_pb2.pyi │ ├── __init__.py │ ├── readme.md │ ├── trade_tick.py │ └── util.py ├── protobuf_push_client.py ├── push_client.py └── stomp_push_client.py ├── quote ├── __init__.py ├── domain │ ├── __init__.py │ ├── bar.py │ ├── capital_distribution.py │ ├── filter.py │ ├── market_status.py │ ├── quote_brief.py │ ├── stock_broker.py │ ├── tick.py │ └── timeline.py ├── quote_client.py ├── request │ ├── __init__.py │ └── model.py └── response │ ├── __init__.py │ ├── capital_distribution_response.py │ ├── capital_flow_response.py │ ├── fund_contracts_response.py │ ├── future_briefs_response.py │ ├── future_contract_response.py │ ├── future_exchange_response.py │ ├── future_quote_bar_response.py │ ├── future_quote_ticks_response.py │ ├── future_trading_times_response.py │ ├── kline_quota_response.py │ ├── market_scanner_response.py │ ├── market_status_response.py │ ├── option_briefs_response.py │ ├── option_chains_response.py │ ├── option_depth_response.py │ ├── option_expirations_response.py │ ├── option_quote_bar_response.py │ ├── option_quote_ticks_response.py │ ├── option_symbols_response.py │ ├── quote_bar_response.py │ ├── quote_brief_response.py │ ├── quote_dataframe_response.py │ ├── quote_delay_briefs_response.py │ ├── quote_depth_response.py │ ├── quote_grab_permission_response.py │ ├── quote_hour_trading_timeline_response.py │ ├── quote_ticks_response.py │ ├── quote_timeline_response.py │ ├── stock_briefs_response.py │ ├── stock_broker_response.py │ ├── stock_details_response.py │ ├── stock_short_interest_response.py │ ├── stock_trade_meta_response.py │ ├── symbol_names_response.py │ ├── symbols_response.py │ ├── trade_rank_response.py │ ├── trading_calendar_response.py │ ├── warrant_briefs_response.py │ └── warrant_filter_response.py ├── tiger_open_client.py ├── tiger_open_config.py └── trade ├── __init__.py ├── domain ├── __init__.py ├── account.py ├── contract.py ├── order.py ├── position.py ├── prime_account.py └── profile.py ├── request ├── __init__.py └── model.py ├── response ├── __init__.py ├── account_profile_response.py ├── analytics_asset_response.py ├── assets_response.py ├── contracts_response.py ├── forex_order_response.py ├── funding_history_response.py ├── order_id_response.py ├── order_preview_response.py ├── orders_response.py ├── positions_response.py ├── prime_assets_response.py ├── segment_fund_response.py └── transactions_response.py └── trade_client.py /.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 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | share/python-wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | MANIFEST 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 | .nox/ 43 | .coverage 44 | .coverage.* 45 | .cache 46 | nosetests.xml 47 | coverage.xml 48 | *.cover 49 | *.py,cover 50 | .hypothesis/ 51 | .pytest_cache/ 52 | cover/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | .pybuilder/ 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # IPython 82 | profile_default/ 83 | ipython_config.py 84 | 85 | # pyenv 86 | # For a library or package, you might want to ignore these files since the code is 87 | # intended to run in multiple environments; otherwise, check them in: 88 | # .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 98 | __pypackages__/ 99 | 100 | # Celery stuff 101 | celerybeat-schedule 102 | celerybeat.pid 103 | 104 | # SageMath parsed files 105 | *.sage.py 106 | 107 | # Environments 108 | .env 109 | .venv 110 | env/ 111 | venv/ 112 | ENV/ 113 | env.bak/ 114 | venv.bak/ 115 | 116 | # Spyder project settings 117 | .spyderproject 118 | .spyproject 119 | 120 | # Rope project settings 121 | .ropeproject 122 | 123 | # mkdocs documentation 124 | /site 125 | 126 | # mypy 127 | .mypy_cache/ 128 | .dmypy.json 129 | dmypy.json 130 | 131 | # Pyre type checker 132 | .pyre/ 133 | 134 | # pytype static type analyzer 135 | .pytype/ 136 | 137 | # Cython debug symbols 138 | cython_debug/ 139 | 140 | .idea 141 | .DS_Store 142 | *.properties 143 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include requirements.txt 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | simplejson 2 | delorean 3 | pandas 4 | python-dateutil 5 | pytz 6 | pyasn1 7 | rsa 8 | stomp.py 9 | getmac 10 | cryptography 11 | backoff 12 | jproperties 13 | protobuf 14 | google-cloud 15 | urllib3 -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/9/16 4 | 5 | @author: gaoan 6 | """ 7 | from os import path 8 | from setuptools import find_packages, setup 9 | from tigeropen import __VERSION__ 10 | 11 | with open(path.join(path.abspath(path.dirname(__file__)), 'requirements.txt')) as f: 12 | install_requires = f.read() 13 | with open(path.join(path.abspath(path.dirname(__file__)), 'README.md'), encoding='utf-8') as f: 14 | long_description = f.read() 15 | 16 | setup( 17 | name='tigeropen', 18 | version=__VERSION__, 19 | description='TigerBrokers Open API', 20 | long_description=long_description, 21 | long_description_content_type='text/markdown', 22 | packages=find_packages(exclude=["tests"]), 23 | author='TigerBrokers', 24 | author_email='openapi@tigerbrokers.com', 25 | license='Apache License v2', 26 | package_data={'': ['*.*']}, 27 | url='https://github.com/tigerbrokers/openapi-python-sdk', 28 | platforms='any', 29 | install_requires=install_requires, 30 | classifiers=[ 31 | 'Programming Language :: Python', 32 | 'Operating System :: Microsoft :: Windows', 33 | 'Operating System :: Unix', 34 | 'Programming Language :: Python :: 3.6', 35 | 'Programming Language :: Python :: 3.7', 36 | 'Programming Language :: Python :: 3.8', 37 | 'Programming Language :: Python :: 3.9', 38 | 'Programming Language :: Python :: 3.10', 39 | 'Programming Language :: Python :: 3.11', 40 | ], 41 | ) 42 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2022/6/24 4 | # @Author : sukai 5 | -------------------------------------------------------------------------------- /tests/test_client_config.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2022/10/8 4 | # @Author : sukai 5 | import unittest 6 | from unittest.mock import MagicMock 7 | 8 | from tigeropen.common.consts import License 9 | from tigeropen.tiger_open_config import TigerOpenClientConfig, GATEWAY_SUFFIX 10 | 11 | 12 | class TestClientConfig(unittest.TestCase): 13 | 14 | def test_refresh_server_info(self): 15 | domain_map = { 16 | 'socket_port': 9883, 17 | 'port': 9887, 18 | 'TBSG-QUOTE': 'https://openapi.tigerfintech.com/sgp-quote', 19 | 'TBNZ-QUOTE': 'https://openapi.tigerfintech.com/hkg-quote', 20 | 'TBSG-PAPER': 'https://openapi-sandbox.tigerfintech.com/sgp', 21 | 'TBNZ-PAPER': 'https://openapi-sandbox.tigerfintech.com/hkg', 22 | 'TBSG': 'https://openapi.tigerfintech.com/sgp', 23 | 'TBNZ': 'https://openapi.tigerfintech.com/hkg', 24 | 'COMMON': 'https://openapi.tigerfintech.com', 25 | } 26 | config = TigerOpenClientConfig() 27 | config.query_domains = MagicMock(name='query_domains', return_value=domain_map) 28 | config.domain_conf = config.query_domains() 29 | 30 | self.assertEqual('https://openapi.tigerfintech.com' + GATEWAY_SUFFIX, config.server_url) 31 | self.assertEqual(('ssl', 'openapi.tigerfintech.com', 9883), config.socket_host_port) 32 | 33 | config.license = License.TBNZ 34 | config.refresh_server_info() 35 | self.assertEqual('https://openapi.tigerfintech.com/hkg' + GATEWAY_SUFFIX, config.server_url) 36 | self.assertEqual('https://openapi.tigerfintech.com/hkg-quote' + GATEWAY_SUFFIX, config.quote_server_url) 37 | 38 | config.license = 'TBSG' 39 | config.refresh_server_info() 40 | self.assertEqual('https://openapi.tigerfintech.com/sgp' + GATEWAY_SUFFIX, config.server_url) 41 | self.assertEqual('https://openapi.tigerfintech.com/sgp-quote' + GATEWAY_SUFFIX, config.quote_server_url) 42 | 43 | config.is_paper = True 44 | config.license = 'TBNZ' 45 | config.refresh_server_info() 46 | self.assertEqual('https://openapi-sandbox.tigerfintech.com/hkg' + GATEWAY_SUFFIX, config.server_url) 47 | self.assertEqual('https://openapi.tigerfintech.com/hkg-quote' + GATEWAY_SUFFIX, config.quote_server_url) 48 | 49 | config = TigerOpenClientConfig(enable_dynamic_domain=False) 50 | config.query_domains = MagicMock(name='query_domains', return_value=domain_map) 51 | config.domain_conf = config.query_domains() 52 | config.license = 'TBNZ' 53 | config.refresh_server_info() 54 | self.assertEqual('https://openapi.tigerfintech.com' + GATEWAY_SUFFIX, config.server_url) 55 | self.assertEqual(('ssl', 'openapi.tigerfintech.com', 9883), config.socket_host_port) -------------------------------------------------------------------------------- /tests/test_push_client.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2022/6/24 4 | # @Author : sukai 5 | import unittest 6 | 7 | from tigeropen.push.push_client import PushClient 8 | 9 | 10 | class TestPushClient(unittest.TestCase): 11 | 12 | def test_tick_convert(self): 13 | body = '{"symbol":"QQQ","tickType":"*****","serverTimestamp":1656062042242,"priceOffset":2,' \ 14 | '"volumes":[99,10,10,10,800],"partCode":["t","p","p","p","t"],"cond":"IIIIT","type":"TradeTick",' \ 15 | '"times":[1656062084833,11,0,0,31],"quoteLevel":"usStockQuote","priceBase":28770,"sn":878,' \ 16 | '"prices":[6,3,2,2,0],"timestamp":1656062085570}' 17 | 18 | expected = 'QQQ', [{'tick_type': '*', 'price': 287.76, 'volume': 99, 'part_code': 'NSDQ', 19 | 'part_code_name': 'NASDAQ Stock Market, LLC (NASDAQ)', 'cond': 'US_ODD_LOT_TRADE', 20 | 'time': 1656062084833, 'server_timestamp': 1656062042242, 'type': 'TradeTick', 21 | 'quote_level': 'usStockQuote', 'sn': 878, 'timestamp': 1656062085570}, 22 | {'tick_type': '*', 'price': 287.73, 'volume': 10, 'part_code': 'ARCA', 23 | 'part_code_name': 'NYSE Arca, Inc. (NYSE Arca)', 'cond': 'US_ODD_LOT_TRADE', 24 | 'time': 1656062084844, 'server_timestamp': 1656062042242, 'type': 'TradeTick', 25 | 'quote_level': 'usStockQuote', 'sn': 878, 'timestamp': 1656062085570}, 26 | {'tick_type': '*', 'price': 287.72, 'volume': 10, 'part_code': 'ARCA', 27 | 'part_code_name': 'NYSE Arca, Inc. (NYSE Arca)', 'cond': 'US_ODD_LOT_TRADE', 28 | 'time': 1656062084844, 'server_timestamp': 1656062042242, 'type': 'TradeTick', 29 | 'quote_level': 'usStockQuote', 'sn': 878, 'timestamp': 1656062085570}, 30 | {'tick_type': '*', 'price': 287.72, 'volume': 10, 'part_code': 'ARCA', 31 | 'part_code_name': 'NYSE Arca, Inc. (NYSE Arca)', 'cond': 'US_ODD_LOT_TRADE', 32 | 'time': 1656062084844, 'server_timestamp': 1656062042242, 'type': 'TradeTick', 33 | 'quote_level': 'usStockQuote', 'sn': 878, 'timestamp': 1656062085570}, 34 | {'tick_type': '*', 'price': 287.7, 'volume': 800, 'part_code': 'NSDQ', 35 | 'part_code_name': 'NASDAQ Stock Market, LLC (NASDAQ)', 'cond': 'US_FORM_T', 36 | 'time': 1656062084875, 'server_timestamp': 1656062042242, 'type': 'TradeTick', 37 | 'quote_level': 'usStockQuote', 'sn': 878, 'timestamp': 1656062085570}] 38 | self.assertEqual(expected, PushClient._convert_tick(body)) -------------------------------------------------------------------------------- /tests/test_utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2022/7/14 4 | # @Author : sukai 5 | import unittest 6 | 7 | from tigeropen.common.util.price_util import PriceUtil 8 | 9 | 10 | class TestUtils(unittest.TestCase): 11 | def test_price_util(self): 12 | delta = 1e-6 13 | tick_sizes = [{'begin': '0', 'end': '1', 'type': 'CLOSED', 'tick_size': 0.0001}, 14 | {'begin': '1', 'end': 'Infinity', 'type': 'OPEN', 'tick_size': 0.01}] 15 | self.assertFalse(PriceUtil.match_tick_size(None, None)) 16 | self.assertTrue(PriceUtil.match_tick_size(2.33, tick_sizes)) 17 | self.assertTrue(PriceUtil.match_tick_size(2.3, tick_sizes)) 18 | self.assertFalse(PriceUtil.match_tick_size(1.334, tick_sizes)) 19 | self.assertTrue(PriceUtil.match_tick_size(0.5, tick_sizes)) 20 | self.assertFalse(PriceUtil.match_tick_size(0.22223, tick_sizes)) 21 | self.assertAlmostEqual(PriceUtil.fix_price_by_tick_size(2.334, tick_sizes, True), 2.34, delta=delta) 22 | self.assertAlmostEqual(PriceUtil.fix_price_by_tick_size(2.334, tick_sizes, False), 2.33, delta=delta) 23 | self.assertAlmostEqual(PriceUtil.fix_price_by_tick_size(2.3345, None), 2.3345, delta=delta) 24 | 25 | tick_sizes = [{'begin': '0', 'end': '1', 'type': 'CLOSED', 'tick_size': 0.0005}, 26 | {'begin': '1', 'end': '100', 'type': 'OPEN_CLOSED', 'tick_size': 0.05}, 27 | {'begin': '100', 'end': '1000', 'type': 'OPEN_CLOSED', 'tick_size': 1.0}, 28 | {'begin': '1000', 'end': '10000', 'type': 'OPEN_CLOSED', 'tick_size': 2.0}, 29 | {'begin': '10000', 'end': 'Infinity', 'type': 'OPEN', 'tick_size': 5.0}] 30 | self.assertTrue(PriceUtil.match_tick_size(0.0005, tick_sizes)) 31 | self.assertTrue(PriceUtil.match_tick_size(1.15, tick_sizes)) 32 | self.assertFalse(PriceUtil.match_tick_size(0.0008, tick_sizes)) 33 | self.assertFalse(PriceUtil.match_tick_size(1.11, tick_sizes)) 34 | self.assertTrue(PriceUtil.match_tick_size(300, tick_sizes)) 35 | self.assertFalse(PriceUtil.match_tick_size(300.5, tick_sizes)) 36 | self.assertFalse(PriceUtil.match_tick_size(5001, tick_sizes)) 37 | self.assertAlmostEqual(PriceUtil.fix_price_by_tick_size(0.0021, tick_sizes), 0.002, delta=delta) 38 | self.assertAlmostEqual(PriceUtil.fix_price_by_tick_size(0.0021, tick_sizes, True), 0.0025, delta=delta) 39 | self.assertAlmostEqual(PriceUtil.fix_price_by_tick_size(3.027, tick_sizes), 3.0, delta=delta) 40 | self.assertAlmostEqual(PriceUtil.fix_price_by_tick_size(3.027, tick_sizes, True), 3.05, delta=delta) 41 | self.assertAlmostEqual(PriceUtil.fix_price_by_tick_size(200.5, tick_sizes), 200, delta=delta) 42 | self.assertAlmostEqual(PriceUtil.fix_price_by_tick_size(2001, tick_sizes, True), 2002, delta=delta) 43 | self.assertAlmostEqual(PriceUtil.fix_price_by_tick_size(20001, tick_sizes, True), 20005, delta=delta) 44 | -------------------------------------------------------------------------------- /tigeropen/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/9/16 4 | 5 | @author: gaoan 6 | """ 7 | __VERSION__ = '3.3.2' 8 | -------------------------------------------------------------------------------- /tigeropen/common/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/9/16 4 | 5 | @author: gaoan 6 | """ -------------------------------------------------------------------------------- /tigeropen/common/consts/params.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/9/20 4 | 5 | @author: gaoan 6 | """ 7 | 8 | P_TIGER_ID = "tiger_id" 9 | P_METHOD = "method" 10 | P_CHARSET = "charset" 11 | P_SIGN_TYPE = "sign_type" 12 | P_SIGN = "sign" 13 | P_TIMESTAMP = "timestamp" 14 | P_VERSION = "version" 15 | P_NOTIFY_URL = "notify_url" 16 | P_DEVICE_ID = "device_id" 17 | P_SDK_VERSION = "sdk-version" 18 | P_SDK_VERSION_PREFIX = "python-" 19 | 20 | COMMON_PARAM_KEYS = {P_TIGER_ID, P_METHOD, P_CHARSET, P_SIGN_TYPE, P_SIGN, P_TIMESTAMP, P_VERSION, P_NOTIFY_URL, 21 | P_DEVICE_ID} 22 | P_BIZ_CONTENT = "biz_content" 23 | -------------------------------------------------------------------------------- /tigeropen/common/consts/push_destinations.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | QUOTE = 'quote' 4 | QUOTE_DEPTH = 'quotedepth' 5 | QUOTE_FUTURE = 'future' 6 | QUOTE_OPTION = 'option' 7 | TRADE_TICK = 'tradetick' 8 | 9 | TRADE_ASSET = 'trade/asset' 10 | TRADE_POSITION = 'trade/position' 11 | TRADE_ORDER = 'trade/order' 12 | TRADE_TRANSACTION = 'trade/transaction' 13 | -------------------------------------------------------------------------------- /tigeropen/common/consts/push_subscriptions.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | SUBSCRIPTION_QUOTE = 'Quote' 4 | SUBSCRIPTION_QUOTE_DEPTH = 'QuoteDepth' 5 | SUBSCRIPTION_QUOTE_FUTURE = 'Future' 6 | SUBSCRIPTION_QUOTE_OPTION = 'Option' 7 | SUBSCRIPTION_TRADE_TICK = 'TradeTick' 8 | 9 | SUBSCRIPTION_TRADE_ASSET = 'Asset' 10 | SUBSCRIPTION_TRADE_POSITION = 'Position' 11 | SUBSCRIPTION_TRADE_ORDER = 'OrderStatus' 12 | SUBSCRIPTION_TRADE_TRANSACTION = 'TradeTransaction' 13 | -------------------------------------------------------------------------------- /tigeropen/common/consts/push_types.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/11/1 4 | 5 | @author: gaoan 6 | """ 7 | from enum import Enum 8 | 9 | 10 | class RequestType(Enum): 11 | # 交易 12 | ORDER_NO = 1 13 | PREVIEW_ORDER = 2 14 | PLACE_ORDER = 3 15 | CANCEL_ORDER = 4 16 | MODIFY_ORDER = 5 17 | REQ_OPEN_ORDERS = 6 18 | REQ_ASSETS = 7 19 | REQ_POSITIONS = 8 20 | REQ_ACCOUNT = 9 21 | 22 | # 行情 23 | REQ_MARKET_STATE = 101 24 | REQ_ALL_SYMBOLS = 102 25 | REQ_ALL_SYMBOL_NAMES = 103 26 | REQ_BRIEF_INFO = 104 27 | REQ_STOCK_DETAIL = 105 28 | REQ_TIME_LINE = 106 29 | REQ_HOUR_TRADING_TIME_LINE = 107 30 | REQ_KLINE = 108 31 | REQ_TRADE_TICK = 109 32 | REQ_SUB_SYMBOLS = 110 33 | 34 | 35 | class ResponseType(Enum): 36 | # 交易 37 | GET_ORDER_NO_END = 1 38 | PREVIEW_ORDER_END = 2 39 | PLACE_ORDER_END = 3 40 | CANCEL_ORDER_END = 4 41 | MODIFY_ORDER_END = 5 42 | GET_ASSET_END = 6 43 | GET_POSITION_END = 7 44 | GET_ACCOUNT_END = 8 45 | SUBSCRIBE_ORDER_STATUS = 9 46 | SUBSCRIBE_POSITION = 10 47 | SUBSCRIBE_ASSET = 11 48 | SUBSCRIBE_TRADE_EXECUTION = 12 49 | 50 | # 行情 51 | GET_MARKET_STATE_END = 101 52 | GET_ALL_SYMBOLS_END = 102 53 | GET_ALL_SYMBOL_NAMES_END = 103 54 | GET_BRIEF_INFO_END = 104 55 | GET_STOCK_DETAIL_END = 105 56 | GET_TIME_LINE_END = 106 57 | GET_HOUR_TRADING_TIME_LINE_END = 107 58 | GET_KLINE_END = 108 59 | GET_TRADING_TICK_END = 109 60 | GET_QUOTE_CHANGE_END = 110 61 | 62 | GET_SUB_SYMBOLS_END = 111 63 | GET_SUBSCRIBE_END = 112 64 | GET_CANCEL_SUBSCRIBE_END = 113 65 | 66 | ERROR_END = 200 67 | -------------------------------------------------------------------------------- /tigeropen/common/consts/quote_keys.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from enum import Enum, unique 3 | 4 | 5 | @unique 6 | class QuoteChangeKey(Enum): 7 | timestamp = 'timestamp' 8 | latest_price = 'latestPrice' 9 | prev_close = 'preClose' 10 | volume = 'volume' 11 | open = 'open' 12 | high = 'high' 13 | low = 'low' 14 | close = 'close' 15 | ask_price = 'askPrice' 16 | ask_size = 'askSize' 17 | bid_price = 'bidPrice' 18 | bid_size = 'bidSize' 19 | minute = 'mi' 20 | bid_depth = 'bidDepth' 21 | ask_depth = 'askDepth' 22 | 23 | 24 | @unique 25 | class QuoteKeyType(Enum): 26 | ALL = 'askPrice,askSize,bidPrice,bidSize,open,high,low,close,preClose,volume,latestPrice,mi' # 所有行情数据 27 | QUOTE = 'askPrice,askSize,bidPrice,bidSize' # 盘口数据 28 | TRADE = 'open,high,low,close,preClose,volume,latestPrice' # 成交数据 29 | TIMELINE = 'mi' # 分时数据 30 | -------------------------------------------------------------------------------- /tigeropen/common/exceptions.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/9/20 4 | 5 | @author: gaoan 6 | """ 7 | 8 | 9 | class ApiException(Exception): 10 | def __init__(self, code, msg): 11 | self.code = code 12 | self.msg = msg 13 | 14 | def __str__(self, *args, **kwargs): 15 | sb = "code=" + str(self.code) + \ 16 | " msg=" + self.msg 17 | return sb 18 | 19 | 20 | class RequestException(Exception): 21 | pass 22 | 23 | 24 | class ResponseException(Exception): 25 | pass 26 | -------------------------------------------------------------------------------- /tigeropen/common/model.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2021/11/12 4 | # @Author : sukai 5 | 6 | 7 | class BaseParams: 8 | def __init__(self): 9 | self._version = None # api版本 10 | self._lang = None # language 11 | 12 | @property 13 | def version(self): 14 | return self._version 15 | 16 | @version.setter 17 | def version(self, value): 18 | self._version = value 19 | 20 | @property 21 | def lang(self): 22 | return self._lang 23 | 24 | @lang.setter 25 | def lang(self, value): 26 | self._lang = value 27 | 28 | def to_openapi_dict(self): 29 | params = dict() 30 | if self.lang: 31 | params['lang'] = self.lang 32 | if self.version: 33 | params['version'] = self.version 34 | return params 35 | 36 | 37 | -------------------------------------------------------------------------------- /tigeropen/common/request.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2022/1/20 4 | # @Author : sukai 5 | import json 6 | 7 | from tigeropen.common.consts.params import P_METHOD, P_VERSION, P_BIZ_CONTENT 8 | 9 | 10 | class OpenApiRequest: 11 | def __init__(self, method, biz_model=None): 12 | self._method = method 13 | self._biz_model = biz_model 14 | 15 | @property 16 | def biz_model(self): 17 | return self._biz_model 18 | 19 | @biz_model.setter 20 | def biz_model(self, value): 21 | self._biz_model = value 22 | 23 | def get_params(self): 24 | params = dict() 25 | params[P_METHOD] = self._method 26 | params[P_VERSION] = getattr(self.biz_model, P_VERSION, None) 27 | 28 | if self.biz_model: 29 | params[P_BIZ_CONTENT] = json.dumps(obj=self.biz_model.to_openapi_dict(), ensure_ascii=False, sort_keys=True, 30 | separators=(',', ':')) 31 | 32 | return params -------------------------------------------------------------------------------- /tigeropen/common/response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/9/20 4 | 5 | @author: gaoan 6 | """ 7 | import json 8 | 9 | 10 | class TigerResponse: 11 | def __init__(self): 12 | self.code = None 13 | self.message = None 14 | self.data = None 15 | 16 | def is_success(self): 17 | return self.code == 0 18 | 19 | def parse_response_content(self, response): 20 | if 'code' in response: 21 | self.code = response['code'] 22 | if 'message' in response: 23 | self.message = response['message'] 24 | if 'data' in response: 25 | self.data = response['data'] 26 | if isinstance(self.data, str): 27 | self.data = json.loads(self.data) 28 | return response 29 | -------------------------------------------------------------------------------- /tigeropen/common/util/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/9/20 4 | 5 | @author: gaoan 6 | """ -------------------------------------------------------------------------------- /tigeropen/common/util/account_util.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | PAPER_ACCOUNT_DIGIT_LEN = 17 4 | 5 | 6 | class AccountUtil: 7 | 8 | @staticmethod 9 | def is_paper_account(account): 10 | try: 11 | if account: 12 | account = str(account) 13 | return account.isdigit() and len(account) >= PAPER_ACCOUNT_DIGIT_LEN 14 | except: 15 | pass 16 | return False 17 | 18 | -------------------------------------------------------------------------------- /tigeropen/common/util/common_utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/9/20 4 | 5 | @author: gaoan 6 | """ 7 | from enum import Enum 8 | 9 | import delorean 10 | import pytz 11 | 12 | eastern = pytz.timezone('US/Eastern') 13 | china = pytz.timezone('Asia/Shanghai') 14 | hongkong = pytz.timezone('Asia/Hong_Kong') 15 | 16 | 17 | def has_value(m, key): 18 | if not m: 19 | return False 20 | if key not in m: 21 | return False 22 | if not m[key]: 23 | return False 24 | return True 25 | 26 | 27 | def get_enum_value(e, enum_type=None): 28 | if enum_type is None: 29 | return e.value if isinstance(e, Enum) else e 30 | return e.value if isinstance(e, enum_type) else e 31 | 32 | 33 | def date_str_to_timestamp(dt, timezone): 34 | """ 35 | :param dt: date str. like "2019-01-01" or "2019-01-01 12:00:00" 36 | :param timezone: pytz timezone 37 | :return: timestamp in milliseconds 38 | """ 39 | try: 40 | if isinstance(dt, str) and timezone: 41 | return int(delorean.parse(dt, timezone=timezone, dayfirst=False).datetime.timestamp() * 1000) 42 | except Exception: 43 | pass 44 | return dt 45 | 46 | -------------------------------------------------------------------------------- /tigeropen/common/util/signature_utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/9/20 4 | 5 | @author: gaoan 6 | """ 7 | 8 | import base64 9 | import json 10 | from functools import lru_cache 11 | 12 | from cryptography.hazmat.backends import default_backend 13 | from cryptography.hazmat.primitives import hashes 14 | from cryptography.hazmat.primitives import serialization 15 | from cryptography.hazmat.primitives.asymmetric import padding 16 | 17 | from tigeropen.common.util.string_utils import add_start_end 18 | 19 | 20 | def get_sign_content(all_params): 21 | sign_content = "" 22 | for (k, v) in sorted(all_params.items()): 23 | value = v 24 | if not isinstance(value, str): 25 | value = json.dumps(value, ensure_ascii=False) 26 | sign_content += ("&" + k + "=" + value) 27 | sign_content = sign_content[1:] 28 | return sign_content 29 | 30 | 31 | def read_private_key(key_file): 32 | """ 33 | Pem key 34 | :param key_file: 35 | :return: 36 | """ 37 | key_str = open(key_file, 'r').read() 38 | return key_str.replace('-----BEGIN RSA PRIVATE KEY-----\n', '').replace( 39 | '\n-----END RSA PRIVATE KEY-----', '').strip() 40 | 41 | 42 | def read_public_key(key_file): 43 | """ 44 | Pem key 45 | :param key_file: 46 | :return: 47 | """ 48 | key_str = open(key_file, 'r').read() 49 | return key_str.replace('-----BEGIN PUBLIC KEY-----\n', '').replace('\n-----END PUBLIC KEY-----', '').strip() 50 | 51 | 52 | def fill_private_key_marker(private_key): 53 | return add_start_end(private_key, "-----BEGIN RSA PRIVATE KEY-----\n", "\n-----END RSA PRIVATE KEY-----") 54 | 55 | 56 | def fill_public_key_marker(public_key): 57 | return add_start_end(public_key, "-----BEGIN PUBLIC KEY-----\n", "\n-----END PUBLIC KEY-----") 58 | 59 | 60 | @lru_cache(maxsize=10) 61 | def load_private_key(private_key): 62 | return serialization.load_pem_private_key( 63 | fill_private_key_marker(private_key).encode(), 64 | password=None, 65 | backend=default_backend() 66 | ) 67 | 68 | 69 | @lru_cache(maxsize=10) 70 | def load_public_key(public_key): 71 | return serialization.load_pem_public_key( 72 | fill_public_key_marker(public_key).encode(), 73 | backend=default_backend() 74 | ) 75 | 76 | 77 | def sign_with_rsa(private_key_str, sign_content, charset): 78 | sign_content = sign_content.encode(charset) 79 | private_key = load_private_key(private_key_str) 80 | 81 | algorithm = hashes.SHA1() 82 | padding_data = padding.PKCS1v15() 83 | 84 | signature = private_key.sign(sign_content, padding_data, algorithm) 85 | sign = str(base64.b64encode(signature), encoding=charset) 86 | return sign 87 | 88 | 89 | def verify_with_rsa(public_key, message, sign): 90 | public_key = load_public_key(public_key) 91 | sign = base64.b64decode(sign) 92 | padding_data = padding.PKCS1v15() 93 | algorithm = hashes.SHA1() 94 | try: 95 | public_key.verify(sign, message, padding=padding_data, algorithm=algorithm) 96 | except Exception as e: 97 | raise e 98 | return True 99 | -------------------------------------------------------------------------------- /tigeropen/common/util/string_utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/9/20 4 | 5 | @author: gaoan 6 | """ 7 | import re 8 | 9 | CAMEL_PATTERN = re.compile(r'([a-z]|\d)([A-Z])') 10 | 11 | 12 | def add_start_end(key, start_marker, end_marker): 13 | if key.find(start_marker) < 0: 14 | key = start_marker + key 15 | if key.find(end_marker) < 0: 16 | key = key + end_marker 17 | return key 18 | 19 | 20 | def camel_to_underline(hunp_str): 21 | return re.sub(CAMEL_PATTERN, r'\1_\2', hunp_str).lower() 22 | 23 | 24 | def camel_to_underline_obj(d): 25 | if isinstance(d, list): 26 | return [camel_to_underline_obj(i) if isinstance(i, (dict, list)) else i for i in d] 27 | return {camel_to_underline(k): camel_to_underline_obj(v) if isinstance(v, (dict, list)) else v 28 | for k, v in d.items()} 29 | 30 | 31 | def underline_to_camel(underline_str): 32 | parts = underline_str.split('_') 33 | return parts[0] + ''.join(x.title() for x in parts[1:]) 34 | -------------------------------------------------------------------------------- /tigeropen/common/util/tick_util.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2022/6/24 4 | # @Author : sukai 5 | 6 | from tigeropen.common.consts.tick_constants import PART_CODE_MAP, PART_CODE_NAME_MAP, HK_QUOTE_LEVEL_PREFIX, \ 7 | HK_TRADE_COND_MAP, US_TRADE_COND_MAP 8 | 9 | 10 | def get_part_code(code): 11 | return PART_CODE_MAP.get(code) 12 | 13 | 14 | def get_part_code_name(code): 15 | return PART_CODE_NAME_MAP.get(code) 16 | 17 | 18 | def get_trade_condition_map(quote_level): 19 | if quote_level and quote_level.lower().startswith(HK_QUOTE_LEVEL_PREFIX): 20 | return HK_TRADE_COND_MAP 21 | return US_TRADE_COND_MAP 22 | 23 | 24 | def get_trade_condition(cond, cond_map): 25 | return cond_map.get(cond) 26 | 27 | 28 | -------------------------------------------------------------------------------- /tigeropen/common/util/web_utils.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/9/20 4 | 5 | @author: gaoan 6 | """ 7 | import json 8 | 9 | from tigeropen.common.consts import THREAD_LOCAL 10 | from tigeropen.common.exceptions import RequestException, ResponseException 11 | from urllib3 import PoolManager 12 | 13 | http_pool = PoolManager() 14 | 15 | 16 | def do_post(url, query_string=None, headers=None, params=None, timeout=15, charset=None): 17 | return do_request('POST', url=url, query_string=query_string, headers=headers, params=params, timeout=timeout, 18 | charset=charset) 19 | 20 | 21 | def do_get(url, query_string=None, headers=None, params=None, timeout=15, charset=None): 22 | return do_request('GET', url=url, query_string=query_string, headers=headers, params=params, timeout=timeout, 23 | charset=charset) 24 | 25 | 26 | def do_request(method, url, query_string=None, headers=None, params=None, timeout=15, charset=None): 27 | try: 28 | response = http_pool.request(method, url=url, fields=query_string, body=json.dumps(params), headers=headers, 29 | timeout=timeout, 30 | ) 31 | except Exception as e: 32 | raise RequestException('[' + THREAD_LOCAL.uuid + ']' + method + ' request failed. url: ' + url 33 | + ' headers: ' + str(headers) 34 | + ' params: ' + str(params) + ' detail: ' + str(e)) 35 | if response.status != 200: 36 | raise ResponseException('[' + THREAD_LOCAL.uuid + ']invalid http status ' + str(response.status) + 37 | ' headers: ' + str(headers) + 38 | ' detail body:' + str(response.data) + ' params: ' + str(params)) 39 | return response.data 40 | -------------------------------------------------------------------------------- /tigeropen/examples/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/9/20 4 | 5 | @author: gaoan 6 | """ -------------------------------------------------------------------------------- /tigeropen/examples/client_config.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | from tigeropen.common.consts import Language 8 | from tigeropen.tiger_open_config import TigerOpenClientConfig 9 | from tigeropen.common.util.signature_utils import read_private_key 10 | 11 | 12 | def get_client_config(): 13 | """ 14 | https://www.itiger.com/openapi/info 开发者信息获取 15 | :return: 16 | """ 17 | is_sandbox = False 18 | client_config = TigerOpenClientConfig(sandbox_debug=is_sandbox) 19 | client_config.private_key = read_private_key('your private key file path') 20 | client_config.tiger_id = 'your tiger id' 21 | client_config.account = 'your account' 22 | client_config.secret_key = None # 机构交易员专有密钥 (机构用户需要填写, 个人开发者无需填写) 23 | client_config.language = Language.en_US 24 | # client_config.timezone = 'US/Eastern' # 设置全局时区 25 | return client_config 26 | -------------------------------------------------------------------------------- /tigeropen/examples/option_helpers/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2022/4/15 4 | # @Author : sukai 5 | -------------------------------------------------------------------------------- /tigeropen/fundamental/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | -------------------------------------------------------------------------------- /tigeropen/fundamental/domain/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | -------------------------------------------------------------------------------- /tigeropen/fundamental/request/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- -------------------------------------------------------------------------------- /tigeropen/fundamental/response/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | -------------------------------------------------------------------------------- /tigeropen/fundamental/response/corporate_dividend_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import pandas as pd 4 | from tigeropen.common.response import TigerResponse 5 | 6 | COLUMNS = ['symbol', 'action_type', 'amount', 'currency', 'announced_date', 'execute_date', 7 | 'record_date', 'pay_date', 'market', 'exchange'] 8 | DIVIDEND_FIELD_MAPPINGS = {'actionType': 'action_type', 'announcedDate': 'announced_date', 9 | 'executeDate': 'execute_date', 'recordDate': 'record_date', 'payDate': 'pay_date', 10 | } 11 | 12 | 13 | class CorporateDividendResponse(TigerResponse): 14 | def __init__(self): 15 | super(CorporateDividendResponse, self).__init__() 16 | self.corporate_dividend = None 17 | self._is_success = None 18 | 19 | def parse_response_content(self, response_content): 20 | response = super(CorporateDividendResponse, self).parse_response_content(response_content) 21 | if 'is_success' in response: 22 | self._is_success = response['is_success'] 23 | 24 | if self.data: 25 | items = list() 26 | for symbol, dividend_items in self.data.items(): 27 | for item in dividend_items: 28 | item['symbol'] = symbol 29 | item['announcedDate'] = item.get('announcedDate', None) 30 | items.append(item) 31 | self.corporate_dividend = pd.DataFrame(items).rename(columns=DIVIDEND_FIELD_MAPPINGS) 32 | -------------------------------------------------------------------------------- /tigeropen/fundamental/response/corporate_earnings_calendar_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from itertools import chain 3 | 4 | import pandas as pd 5 | from tigeropen.common.response import TigerResponse 6 | 7 | COLUMNS = ['symbol', 'reportDate', 'reportTime', 'executeDate', 'expectedEps', 'actualEps', 8 | 'fiscalQuarterEnding', 'market', 'exchange', 'actionType'] 9 | EARNINGS_CALENDAR_FIELD_MAPPINGS = {'actionType': 'action_type', 'actualEps': 'actual_eps', 10 | 'expectedEps': 'expected_eps', 'executeDate': 'execute_date', 11 | 'fiscalQuarterEnding': 'fiscal_quarter_ending', 'reportDate': 'report_date', 12 | 'reportTime': 'report_time', 13 | } 14 | 15 | 16 | class EarningsCalendarResponse(TigerResponse): 17 | def __init__(self): 18 | super(EarningsCalendarResponse, self).__init__() 19 | self.earnings_calendar = None 20 | self._is_success = None 21 | 22 | def parse_response_content(self, response_content): 23 | response = super(EarningsCalendarResponse, self).parse_response_content(response_content) 24 | if 'is_success' in response: 25 | self._is_success = response['is_success'] 26 | 27 | if self.data: 28 | self.earnings_calendar = pd.DataFrame(chain.from_iterable(self.data.values()), columns=COLUMNS).rename( 29 | columns=EARNINGS_CALENDAR_FIELD_MAPPINGS).sort_values(by=['report_date']).reset_index(drop=True) 30 | -------------------------------------------------------------------------------- /tigeropen/fundamental/response/corporate_split_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import pandas as pd 4 | from tigeropen.common.response import TigerResponse 5 | 6 | COLUMNS = ['symbol', 'action_type', 'from_factor', 'to_factor', 'ratio', 'execute_date', 'market', 'exchange'] 7 | SPLIT_FIELD_MAPPINGS = {'actionType': 'action_type', 'fromFactor': 'from_factor', 'toFactor': 'to_factor', 8 | 'executeDate': 'execute_date'} 9 | 10 | 11 | class CorporateSplitResponse(TigerResponse): 12 | def __init__(self): 13 | super(CorporateSplitResponse, self).__init__() 14 | self.corporate_split = None 15 | self._is_success = None 16 | 17 | def parse_response_content(self, response_content): 18 | response = super(CorporateSplitResponse, self).parse_response_content(response_content) 19 | if 'is_success' in response: 20 | self._is_success = response['is_success'] 21 | 22 | if self.data: 23 | items = list() 24 | for symbol, split_items in self.data.items(): 25 | for item in split_items: 26 | item['symbol'] = symbol 27 | items.append(item) 28 | self.corporate_split = pd.DataFrame(items).rename(columns=SPLIT_FIELD_MAPPINGS)[COLUMNS] 29 | -------------------------------------------------------------------------------- /tigeropen/fundamental/response/dataframe_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2023/8/11 4 | # @Author : sukai 5 | 6 | import pandas as pd 7 | 8 | from tigeropen.common.response import TigerResponse 9 | from tigeropen.common.util.string_utils import camel_to_underline 10 | 11 | 12 | class DataframeResponse(TigerResponse): 13 | def __init__(self): 14 | super(DataframeResponse, self).__init__() 15 | self.result = None 16 | self._is_success = None 17 | 18 | def parse_response_content(self, response_content): 19 | response = super(DataframeResponse, self).parse_response_content(response_content) 20 | if 'is_success' in response: 21 | self._is_success = response['is_success'] 22 | 23 | if self.data and isinstance(self.data, list): 24 | fields = self.data[0].keys() 25 | fields_map = {origin: camel_to_underline(origin) for origin in fields} 26 | df = pd.DataFrame(self.data) 27 | self.result = df.rename(columns=fields_map) 28 | -------------------------------------------------------------------------------- /tigeropen/fundamental/response/financial_daily_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import pandas as pd 4 | 5 | from tigeropen.common.response import TigerResponse 6 | 7 | COLUMNS = ['symbol', 'field', 'date', 'value'] 8 | 9 | 10 | class FinancialDailyResponse(TigerResponse): 11 | def __init__(self): 12 | super(FinancialDailyResponse, self).__init__() 13 | self.financial_daily = None 14 | self._is_success = None 15 | 16 | def parse_response_content(self, response_content): 17 | response = super(FinancialDailyResponse, self).parse_response_content(response_content) 18 | if 'is_success' in response: 19 | self._is_success = response['is_success'] 20 | 21 | if self.data and isinstance(self.data, list): 22 | items = list() 23 | for item in self.data: 24 | item_values = dict() 25 | for key, value in item.items(): 26 | item_values[key] = value 27 | items.append(item_values) 28 | self.financial_daily = pd.DataFrame(items, columns=COLUMNS) 29 | -------------------------------------------------------------------------------- /tigeropen/fundamental/response/financial_exchange_rate_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2023/8/11 4 | # @Author : sukai 5 | 6 | import pandas as pd 7 | 8 | from tigeropen.common.response import TigerResponse 9 | 10 | 11 | class FinancialExchangeRateResponse(TigerResponse): 12 | def __init__(self): 13 | super(FinancialExchangeRateResponse, self).__init__() 14 | self.result = None 15 | self._is_success = None 16 | 17 | def parse_response_content(self, response_content): 18 | response = super(FinancialExchangeRateResponse, self).parse_response_content(response_content) 19 | if 'is_success' in response: 20 | self._is_success = response['is_success'] 21 | 22 | 23 | if self.data and isinstance(self.data, list): 24 | data_items = [] 25 | for currency_item in self.data: 26 | df = pd.DataFrame(currency_item.get('dailyValueList')) 27 | df.insert(0, 'currency', currency_item.get('currency')) 28 | data_items.append(df) 29 | self.result = pd.concat(data_items).reset_index(drop=True) 30 | -------------------------------------------------------------------------------- /tigeropen/fundamental/response/financial_report_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import pandas as pd 4 | 5 | from tigeropen.common.response import TigerResponse 6 | 7 | COLUMNS = ['symbol', 'currency', 'field', 'value', 'period_end_date', 'filing_date'] 8 | REPORT_FIELD_MAPPINGS = {'periodEndDate': 'period_end_date', 'filingDate': 'filing_date'} 9 | 10 | 11 | class FinancialReportResponse(TigerResponse): 12 | def __init__(self): 13 | super(FinancialReportResponse, self).__init__() 14 | self.financial_report = None 15 | self._is_success = None 16 | 17 | def parse_response_content(self, response_content): 18 | response = super(FinancialReportResponse, self).parse_response_content(response_content) 19 | if 'is_success' in response: 20 | self._is_success = response['is_success'] 21 | 22 | if self.data and isinstance(self.data, list): 23 | items = list() 24 | for item in self.data: 25 | item_values = dict() 26 | for key, value in item.items(): 27 | item_values[key] = value 28 | items.append(item_values) 29 | self.financial_report = pd.DataFrame(items).rename(columns=REPORT_FIELD_MAPPINGS)[COLUMNS] 30 | -------------------------------------------------------------------------------- /tigeropen/fundamental/response/industry_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from tigeropen.common.response import TigerResponse 4 | 5 | 6 | class IndustryListResponse(TigerResponse): 7 | def __init__(self): 8 | super(IndustryListResponse, self).__init__() 9 | self.industry_list = list() 10 | self._is_success = None 11 | 12 | def parse_response_content(self, response_content): 13 | response = super(IndustryListResponse, self).parse_response_content(response_content) 14 | if 'is_success' in response: 15 | self._is_success = response['is_success'] 16 | if self.data: 17 | for ind in self.data: 18 | industry = dict(industry_level=ind.get('industryLevel'), id=ind.get('id'), 19 | name_cn=ind.get('nameCN'), 20 | name_en=ind.get('nameEN')) 21 | self.industry_list.append(industry) 22 | 23 | 24 | class IndustryStocksResponse(TigerResponse): 25 | def __init__(self): 26 | super(IndustryStocksResponse, self).__init__() 27 | self.industry_stocks = list() 28 | self._is_success = None 29 | 30 | def parse_response_content(self, response_content): 31 | response = super(IndustryStocksResponse, self).parse_response_content(response_content) 32 | if 'is_success' in response: 33 | self._is_success = response['is_success'] 34 | if self.data: 35 | for item in self.data: 36 | industry_list = list() 37 | industries = item.get('industryDetailDTOList', []) 38 | for ind in industries: 39 | industry_list.append(dict(industry_level=ind.get('industryLevel'), id=ind.get('id'), 40 | name_cn=ind.get('nameCN'), 41 | name_en=ind.get('nameEN'))) 42 | company = dict(symbol=item.get('symbol'), company_name=item.get('companyName'), 43 | market=item.get('market'), industry_list=industry_list) 44 | self.industry_stocks.append(company) 45 | 46 | 47 | class StockIndustryResponse(TigerResponse): 48 | def __init__(self): 49 | super(StockIndustryResponse, self).__init__() 50 | self.stock_industry = list() 51 | self._is_success = None 52 | 53 | def parse_response_content(self, response_content): 54 | response = super(StockIndustryResponse, self).parse_response_content(response_content) 55 | if 'is_success' in response: 56 | self._is_success = response['is_success'] 57 | if self.data: 58 | for item in self.data: 59 | industry = dict(industry_level=item.get('industryLevel'), id=item.get('id'), 60 | name_cn=item.get('nameCN'), 61 | name_en=item.get('nameEN')) 62 | self.stock_industry.append(industry) 63 | -------------------------------------------------------------------------------- /tigeropen/push/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/29 4 | 5 | @author: gaoan 6 | """ 7 | import ssl 8 | import time 9 | 10 | 11 | def _patch_ssl(wait=0.01): 12 | def new_wrap_socket(self, sock, server_side=False, 13 | do_handshake_on_connect=True, 14 | suppress_ragged_eofs=True, 15 | server_hostname=None, session=None): 16 | time.sleep(wait) 17 | return self.sslsocket_class._create( 18 | sock=sock, 19 | server_side=server_side, 20 | do_handshake_on_connect=do_handshake_on_connect, 21 | suppress_ragged_eofs=suppress_ragged_eofs, 22 | server_hostname=server_hostname, 23 | context=self, 24 | session=session 25 | ) 26 | ssl.SSLContext.old_wrap_socket = ssl.SSLContext.wrap_socket 27 | ssl.SSLContext.wrap_socket = new_wrap_socket 28 | 29 | -------------------------------------------------------------------------------- /tigeropen/push/network/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tigerfintech/openapi-python-sdk/a111aa5cc31923013da31590e1da891427262997/tigeropen/push/network/__init__.py -------------------------------------------------------------------------------- /tigeropen/push/network/connect.py: -------------------------------------------------------------------------------- 1 | from .protocal import * 2 | from .transport import * 3 | 4 | 5 | class BaseConnection(Publisher): 6 | """ 7 | Base class for all connection classes. 8 | """ 9 | 10 | def __init__(self, transport): 11 | """ 12 | :param Transport transport: 13 | """ 14 | self.transport = transport 15 | 16 | def disconnect(self): pass 17 | 18 | def set_listener(self, name, listener): 19 | self.transport.set_listener(name, listener) 20 | 21 | def remove_listener(self, name): 22 | """ 23 | :param str name: 24 | """ 25 | self.transport.remove_listener(name) 26 | 27 | def get_listener(self, name): 28 | """ 29 | :param str name: 30 | 31 | :rtype: ConnectionListener 32 | """ 33 | return self.transport.get_listener(name) 34 | 35 | def is_connected(self): 36 | """ 37 | :rtype: bool 38 | """ 39 | return self.transport.is_connected() 40 | 41 | def set_ssl(self, *args, **kwargs): 42 | self.transport.set_ssl(*args, **kwargs) 43 | 44 | def get_ssl(self, host_and_port=None): 45 | return self.transport.get_ssl(host_and_port) 46 | 47 | 48 | class PushConnection(BaseConnection, Protocol): 49 | """ 50 | """ 51 | 52 | def __init__(self, 53 | host_and_ports=None, 54 | prefer_localhost=True, 55 | try_loopback_connect=True, 56 | reconnect_sleep_initial=0.1, 57 | reconnect_sleep_increase=0.5, 58 | reconnect_sleep_jitter=0.1, 59 | reconnect_sleep_max=60.0, 60 | reconnect_attempts_max=3, 61 | timeout=None, 62 | heartbeats=(0, 0), 63 | keepalive=None, 64 | vhost=None, 65 | auto_decode=True, 66 | encoding="utf-8", 67 | heart_beat_receive_scale=1.5, 68 | bind_host_port=None): 69 | transport = Transport(host_and_ports, prefer_localhost, try_loopback_connect, 70 | reconnect_sleep_initial, reconnect_sleep_increase, reconnect_sleep_jitter, 71 | reconnect_sleep_max, reconnect_attempts_max, timeout, 72 | keepalive, vhost, auto_decode, encoding, bind_host_port=bind_host_port) 73 | BaseConnection.__init__(self, transport) 74 | Protocol.__init__(self, transport, heartbeats, 75 | heart_beat_receive_scale=heart_beat_receive_scale) 76 | 77 | def connect(self, *args, **kwargs): 78 | self.transport.start() 79 | Protocol.connect(self, *args, **kwargs) 80 | 81 | def disconnect(self): 82 | Protocol.disconnect(self) 83 | self.transport.stop() 84 | -------------------------------------------------------------------------------- /tigeropen/push/network/exception.py: -------------------------------------------------------------------------------- 1 | 2 | class PushException(Exception): 3 | pass 4 | 5 | 6 | class ConnectionClosedException(PushException): 7 | pass 8 | 9 | 10 | class NotConnectedException(PushException): 11 | """ 12 | Raised when there is currently no server connection. 13 | """ 14 | 15 | 16 | class ConnectFailedException(PushException): 17 | """ 18 | Raised by Connection.attempt_connection when reconnection attempts 19 | have exceeded Connection.__reconnect_attempts_max. 20 | """ 21 | 22 | 23 | class InterruptedException(PushException): 24 | """ 25 | Raised by receive when data read is interrupted. 26 | """ 27 | -------------------------------------------------------------------------------- /tigeropen/push/network/protocal.py: -------------------------------------------------------------------------------- 1 | from .exception import ConnectFailedException 2 | from .listener import * 3 | 4 | 5 | class Protocol(HeartbeatListener, ConnectionListener): 6 | """ 7 | :param transport: 8 | :param (int,int) heartbeats: 9 | automatically if it has not been set 10 | :param float heart_beat_receive_scale: how long to wait for a heartbeat before timing out, 11 | as a scale factor of receive time 12 | """ 13 | 14 | def __init__(self, transport, heartbeats=(0, 0), heart_beat_receive_scale=1.5): 15 | HeartbeatListener.__init__(self, transport, heartbeats, heart_beat_receive_scale) 16 | self.transport = transport 17 | transport.set_listener("protocol-listener", self) 18 | 19 | def send_frame(self, request): 20 | """ 21 | Encode and send a frame 22 | through the underlying transport: 23 | """ 24 | self.transport.transmit(request) 25 | 26 | def connect(self, request, wait=False): 27 | """ 28 | Start a connection. 29 | :param bool wait: if True, wait for the connection to be established/acknowledged 30 | """ 31 | self.send_frame(request) 32 | 33 | if wait: 34 | self.transport.wait_for_connection() 35 | if self.transport.connection_error: 36 | raise ConnectFailedException() 37 | 38 | def disconnect(self): 39 | """ 40 | Disconnect from the server. 41 | """ 42 | if not self.transport.is_connected(): 43 | logging.debug("not sending disconnect, already disconnected") 44 | return 45 | self.send_frame(ProtoMessageUtil.build_disconnect_message()) 46 | -------------------------------------------------------------------------------- /tigeropen/push/network/utils.py: -------------------------------------------------------------------------------- 1 | """General utility functions. 2 | """ 3 | 4 | import socket 5 | import threading 6 | 7 | from tigeropen.push.pb.SocketCommon_pb2 import SocketCommon 8 | 9 | CMD_TYPE_NAME_MAP = { 10 | SocketCommon.Command.CONNECT: 'connecting', 11 | SocketCommon.Command.CONNECTED: 'connected', 12 | SocketCommon.Command.DISCONNECT: 'disconnecting', 13 | SocketCommon.Command.ERROR: 'error', 14 | SocketCommon.Command.HEARTBEAT: 'heartbeat', 15 | SocketCommon.Command.MESSAGE: 'message', 16 | SocketCommon.Command.SEND: 'send', 17 | SocketCommon.Command.SUBSCRIBE: 'subscribe', 18 | SocketCommon.Command.UNKNOWN: 'unknown', 19 | SocketCommon.Command.UNSUBSCRIBE: 'unsubscribe', 20 | } 21 | 22 | 23 | def get_command_name(cmd_type): 24 | return CMD_TYPE_NAME_MAP.get(cmd_type, 'unknown') 25 | 26 | 27 | LOCALHOST_NAMES = ["localhost", "127.0.0.1"] 28 | 29 | 30 | try: 31 | LOCALHOST_NAMES.append(socket.gethostbyname(socket.gethostname())) 32 | except Exception: 33 | pass 34 | 35 | try: 36 | LOCALHOST_NAMES.append(socket.gethostname()) 37 | except Exception: 38 | pass 39 | 40 | try: 41 | LOCALHOST_NAMES.append(socket.getfqdn(socket.gethostname())) 42 | except Exception: 43 | pass 44 | 45 | 46 | def is_eol_default(c): 47 | return c == b"\x0a" 48 | 49 | 50 | def default_create_thread(callback): 51 | """ 52 | Default thread creation - used to create threads when the client doesn't want to provide their 53 | own thread creation. 54 | 55 | :param function callback: the callback function provided to threading.Thread 56 | """ 57 | thread = threading.Thread(None, callback) 58 | thread.daemon = True # Don't let thread prevent termination 59 | thread.start() 60 | return thread 61 | 62 | 63 | def is_localhost(host_and_port): 64 | """ 65 | Return 1 if the specified host+port is a member of the 'localhost' list of hosts, 2 if not (predominately used 66 | as a sort key. 67 | 68 | :param (str,int) host_and_port: tuple containing host and port 69 | 70 | :rtype: int 71 | """ 72 | (host, _) = host_and_port 73 | if host in LOCALHOST_NAMES: 74 | return 1 75 | return 2 76 | 77 | 78 | def calculate_heartbeats(shb, chb): 79 | """ 80 | Given a heartbeat string from the server, and a heartbeat tuple from the client, 81 | calculate what the actual heartbeat settings should be. 82 | 83 | :param (str,str) shb: server heartbeat numbers 84 | :param (int,int) chb: client heartbeat numbers 85 | 86 | :rtype: (int,int) 87 | """ 88 | (sx, sy) = shb 89 | (cx, cy) = chb 90 | x = 0 91 | y = 0 92 | if cx != 0 and sy != "0": 93 | x = max(cx, int(sy)) 94 | if cy != 0 and sx != "0": 95 | y = max(cy, int(sx)) 96 | return x, y 97 | 98 | def get_errno(e): 99 | """ 100 | Return the errno of an exception, or the first argument if errno is not available. 101 | 102 | :param Exception e: the exception object 103 | """ 104 | try: 105 | return e.errno 106 | except AttributeError: 107 | return e.args[0] 108 | -------------------------------------------------------------------------------- /tigeropen/push/pb/AssetData.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package tigeropen.push.pb; 4 | 5 | 6 | message AssetData { 7 | string account = 1; // user account 8 | string currency = 2; // currency. USD, HKD, etc. 9 | string segType = 3; // Securities Category C: (Commodities Futures), S: (Securities Stocks) 10 | 11 | double availableFunds = 4; // available funds, overnight liquidity 12 | double excessLiquidity = 5; // excess liquidity, used to represent intraday risk value. 13 | double netLiquidation = 6; // Total Assets (Net Liquidation Value) 14 | double equityWithLoan = 7; // Equity with loan value (asset with loan value) - Securities Segment: Cash Value + Stock Value - Futures Segment: Cash Value - Maintenance Margin 15 | double buyingPower = 8; // buying power. An estimation of how many more dollars you can buy in stock assets. Only apply to stock segment 16 | double cashBalance = 9; // Cash amount. Sum of current cash balances in all currencies 17 | double grossPositionValue = 10; // total value of securities 18 | 19 | double initMarginReq = 11; // initial margin requirement 20 | double maintMarginReq = 12; // maintenance margin requirement 21 | uint64 timestamp = 13; 22 | 23 | } -------------------------------------------------------------------------------- /tigeropen/push/pb/AssetData_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # NO CHECKED-IN PROTOBUF GENCODE 4 | # source: tigeropen/push/pb/AssetData.proto 5 | # Protobuf Python Version: 5.28.3 6 | """Generated protocol buffer code.""" 7 | from google.protobuf import descriptor as _descriptor 8 | from google.protobuf import descriptor_pool as _descriptor_pool 9 | from google.protobuf import runtime_version as _runtime_version 10 | from google.protobuf import symbol_database as _symbol_database 11 | from google.protobuf.internal import builder as _builder 12 | _runtime_version.ValidateProtobufRuntimeVersion( 13 | _runtime_version.Domain.PUBLIC, 14 | 5, 15 | 28, 16 | 3, 17 | '', 18 | 'tigeropen/push/pb/AssetData.proto' 19 | ) 20 | # @@protoc_insertion_point(imports) 21 | 22 | _sym_db = _symbol_database.Default() 23 | 24 | 25 | 26 | 27 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!tigeropen/push/pb/AssetData.proto\x12\x11tigeropen.push.pb\"\xa8\x02\n\tAssetData\x12\x0f\n\x07\x61\x63\x63ount\x18\x01 \x01(\t\x12\x10\n\x08\x63urrency\x18\x02 \x01(\t\x12\x0f\n\x07segType\x18\x03 \x01(\t\x12\x16\n\x0e\x61vailableFunds\x18\x04 \x01(\x01\x12\x17\n\x0f\x65xcessLiquidity\x18\x05 \x01(\x01\x12\x16\n\x0enetLiquidation\x18\x06 \x01(\x01\x12\x16\n\x0e\x65quityWithLoan\x18\x07 \x01(\x01\x12\x13\n\x0b\x62uyingPower\x18\x08 \x01(\x01\x12\x13\n\x0b\x63\x61shBalance\x18\t \x01(\x01\x12\x1a\n\x12grossPositionValue\x18\n \x01(\x01\x12\x15\n\rinitMarginReq\x18\x0b \x01(\x01\x12\x16\n\x0emaintMarginReq\x18\x0c \x01(\x01\x12\x11\n\ttimestamp\x18\r \x01(\x04\x62\x06proto3') 28 | 29 | _globals = globals() 30 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) 31 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tigeropen.push.pb.AssetData_pb2', _globals) 32 | if not _descriptor._USE_C_DESCRIPTORS: 33 | DESCRIPTOR._loaded_options = None 34 | _globals['_ASSETDATA']._serialized_start=57 35 | _globals['_ASSETDATA']._serialized_end=353 36 | # @@protoc_insertion_point(module_scope) 37 | -------------------------------------------------------------------------------- /tigeropen/push/pb/AssetData_pb2.pyi: -------------------------------------------------------------------------------- 1 | from google.protobuf import descriptor as _descriptor 2 | from google.protobuf import message as _message 3 | from typing import ClassVar as _ClassVar, Optional as _Optional 4 | 5 | DESCRIPTOR: _descriptor.FileDescriptor 6 | 7 | class AssetData(_message.Message): 8 | __slots__ = ("account", "currency", "segType", "availableFunds", "excessLiquidity", "netLiquidation", "equityWithLoan", "buyingPower", "cashBalance", "grossPositionValue", "initMarginReq", "maintMarginReq", "timestamp") 9 | ACCOUNT_FIELD_NUMBER: _ClassVar[int] 10 | CURRENCY_FIELD_NUMBER: _ClassVar[int] 11 | SEGTYPE_FIELD_NUMBER: _ClassVar[int] 12 | AVAILABLEFUNDS_FIELD_NUMBER: _ClassVar[int] 13 | EXCESSLIQUIDITY_FIELD_NUMBER: _ClassVar[int] 14 | NETLIQUIDATION_FIELD_NUMBER: _ClassVar[int] 15 | EQUITYWITHLOAN_FIELD_NUMBER: _ClassVar[int] 16 | BUYINGPOWER_FIELD_NUMBER: _ClassVar[int] 17 | CASHBALANCE_FIELD_NUMBER: _ClassVar[int] 18 | GROSSPOSITIONVALUE_FIELD_NUMBER: _ClassVar[int] 19 | INITMARGINREQ_FIELD_NUMBER: _ClassVar[int] 20 | MAINTMARGINREQ_FIELD_NUMBER: _ClassVar[int] 21 | TIMESTAMP_FIELD_NUMBER: _ClassVar[int] 22 | account: str 23 | currency: str 24 | segType: str 25 | availableFunds: float 26 | excessLiquidity: float 27 | netLiquidation: float 28 | equityWithLoan: float 29 | buyingPower: float 30 | cashBalance: float 31 | grossPositionValue: float 32 | initMarginReq: float 33 | maintMarginReq: float 34 | timestamp: int 35 | def __init__(self, account: _Optional[str] = ..., currency: _Optional[str] = ..., segType: _Optional[str] = ..., availableFunds: _Optional[float] = ..., excessLiquidity: _Optional[float] = ..., netLiquidation: _Optional[float] = ..., equityWithLoan: _Optional[float] = ..., buyingPower: _Optional[float] = ..., cashBalance: _Optional[float] = ..., grossPositionValue: _Optional[float] = ..., initMarginReq: _Optional[float] = ..., maintMarginReq: _Optional[float] = ..., timestamp: _Optional[int] = ...) -> None: ... 36 | -------------------------------------------------------------------------------- /tigeropen/push/pb/KlineData.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package tigeropen.push.pb; 3 | 4 | message KlineData { 5 | int64 time = 1; // bar timestamp. 6 | float open = 2; // The first transaction price of current minute. 7 | float high = 3; // The highest price of current minute. 8 | float low = 4; // The lowest price of current minute. 9 | float close = 5; // The last transaction price in the current minute 10 | float avg = 6; // The average price of current minute. 11 | int64 volume = 7; // Cumulative trading volume in current minute. 12 | int32 count = 8; // The number of transaction in current minute. 13 | string symbol = 9; // symbol 14 | double amount = 10; // Cumulative turnover in current minute. 15 | optional uint64 serverTimestamp = 11; 16 | } -------------------------------------------------------------------------------- /tigeropen/push/pb/KlineData_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # NO CHECKED-IN PROTOBUF GENCODE 4 | # source: tigeropen/push/pb/KlineData.proto 5 | # Protobuf Python Version: 5.28.3 6 | """Generated protocol buffer code.""" 7 | from google.protobuf import descriptor as _descriptor 8 | from google.protobuf import descriptor_pool as _descriptor_pool 9 | from google.protobuf import runtime_version as _runtime_version 10 | from google.protobuf import symbol_database as _symbol_database 11 | from google.protobuf.internal import builder as _builder 12 | _runtime_version.ValidateProtobufRuntimeVersion( 13 | _runtime_version.Domain.PUBLIC, 14 | 5, 15 | 28, 16 | 3, 17 | '', 18 | 'tigeropen/push/pb/KlineData.proto' 19 | ) 20 | # @@protoc_insertion_point(imports) 21 | 22 | _sym_db = _symbol_database.Default() 23 | 24 | 25 | 26 | 27 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n!tigeropen/push/pb/KlineData.proto\x12\x11tigeropen.push.pb\"\xcf\x01\n\tKlineData\x12\x0c\n\x04time\x18\x01 \x01(\x03\x12\x0c\n\x04open\x18\x02 \x01(\x02\x12\x0c\n\x04high\x18\x03 \x01(\x02\x12\x0b\n\x03low\x18\x04 \x01(\x02\x12\r\n\x05\x63lose\x18\x05 \x01(\x02\x12\x0b\n\x03\x61vg\x18\x06 \x01(\x02\x12\x0e\n\x06volume\x18\x07 \x01(\x03\x12\r\n\x05\x63ount\x18\x08 \x01(\x05\x12\x0e\n\x06symbol\x18\t \x01(\t\x12\x0e\n\x06\x61mount\x18\n \x01(\x01\x12\x1c\n\x0fserverTimestamp\x18\x0b \x01(\x04H\x00\x88\x01\x01\x42\x12\n\x10_serverTimestampb\x06proto3') 28 | 29 | _globals = globals() 30 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) 31 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tigeropen.push.pb.KlineData_pb2', _globals) 32 | if not _descriptor._USE_C_DESCRIPTORS: 33 | DESCRIPTOR._loaded_options = None 34 | _globals['_KLINEDATA']._serialized_start=57 35 | _globals['_KLINEDATA']._serialized_end=264 36 | # @@protoc_insertion_point(module_scope) 37 | -------------------------------------------------------------------------------- /tigeropen/push/pb/KlineData_pb2.pyi: -------------------------------------------------------------------------------- 1 | from google.protobuf import descriptor as _descriptor 2 | from google.protobuf import message as _message 3 | from typing import ClassVar as _ClassVar, Optional as _Optional 4 | 5 | DESCRIPTOR: _descriptor.FileDescriptor 6 | 7 | class KlineData(_message.Message): 8 | __slots__ = ("time", "open", "high", "low", "close", "avg", "volume", "count", "symbol", "amount", "serverTimestamp") 9 | TIME_FIELD_NUMBER: _ClassVar[int] 10 | OPEN_FIELD_NUMBER: _ClassVar[int] 11 | HIGH_FIELD_NUMBER: _ClassVar[int] 12 | LOW_FIELD_NUMBER: _ClassVar[int] 13 | CLOSE_FIELD_NUMBER: _ClassVar[int] 14 | AVG_FIELD_NUMBER: _ClassVar[int] 15 | VOLUME_FIELD_NUMBER: _ClassVar[int] 16 | COUNT_FIELD_NUMBER: _ClassVar[int] 17 | SYMBOL_FIELD_NUMBER: _ClassVar[int] 18 | AMOUNT_FIELD_NUMBER: _ClassVar[int] 19 | SERVERTIMESTAMP_FIELD_NUMBER: _ClassVar[int] 20 | time: int 21 | open: float 22 | high: float 23 | low: float 24 | close: float 25 | avg: float 26 | volume: int 27 | count: int 28 | symbol: str 29 | amount: float 30 | serverTimestamp: int 31 | def __init__(self, time: _Optional[int] = ..., open: _Optional[float] = ..., high: _Optional[float] = ..., low: _Optional[float] = ..., close: _Optional[float] = ..., avg: _Optional[float] = ..., volume: _Optional[int] = ..., count: _Optional[int] = ..., symbol: _Optional[str] = ..., amount: _Optional[float] = ..., serverTimestamp: _Optional[int] = ...) -> None: ... 32 | -------------------------------------------------------------------------------- /tigeropen/push/pb/OptionTopData.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package tigeropen.push.pb; 4 | 5 | message OptionTopData { 6 | string market = 1; 7 | int64 timestamp = 2; 8 | repeated TopData topData = 3; 9 | 10 | message TopData { 11 | string targetName = 1; // bigOrder, volume, amount, openInt 12 | repeated BigOrder bigOrder = 2; // large order(bigOrder) 13 | repeated OptionItem item = 3; // target value top list(volume, amount, openInt) 14 | } 15 | 16 | message BigOrder { 17 | string symbol = 1; 18 | string expiry = 2; // formate:yyyyMMdd 19 | string strike = 3; // strike price 20 | string right = 4; // CALL/PUT 21 | string dir = 5; // BUY/SELL 22 | double volume = 6; // target value: volume > 1000 23 | double price = 7; // trade price 24 | double amount = 8; // trade amount 25 | int64 tradeTime = 9;// trade timestamp 26 | } 27 | 28 | message OptionItem { 29 | string symbol = 1; 30 | string expiry = 2; // formate:yyyyMMdd 31 | string strike = 3; // strike price 32 | string right = 4; // CALL/PUT 33 | double totalAmount = 5; // total trade amount 34 | double totalVolume = 6; // total trade volume 35 | double totalOpenInt = 7; // open interest 36 | double volumeToOpenInt = 8; // Volume to Open Interest 37 | double latestPrice = 9; // option latest price 38 | int64 updateTime = 10; // uptate timestamp 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /tigeropen/push/pb/OptionTopData_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # NO CHECKED-IN PROTOBUF GENCODE 4 | # source: tigeropen/push/pb/OptionTopData.proto 5 | # Protobuf Python Version: 5.28.3 6 | """Generated protocol buffer code.""" 7 | from google.protobuf import descriptor as _descriptor 8 | from google.protobuf import descriptor_pool as _descriptor_pool 9 | from google.protobuf import runtime_version as _runtime_version 10 | from google.protobuf import symbol_database as _symbol_database 11 | from google.protobuf.internal import builder as _builder 12 | _runtime_version.ValidateProtobufRuntimeVersion( 13 | _runtime_version.Domain.PUBLIC, 14 | 5, 15 | 28, 16 | 3, 17 | '', 18 | 'tigeropen/push/pb/OptionTopData.proto' 19 | ) 20 | # @@protoc_insertion_point(imports) 21 | 22 | _sym_db = _symbol_database.Default() 23 | 24 | 25 | 26 | 27 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%tigeropen/push/pb/OptionTopData.proto\x12\x11tigeropen.push.pb\"\xf0\x04\n\rOptionTopData\x12\x0e\n\x06market\x18\x01 \x01(\t\x12\x11\n\ttimestamp\x18\x02 \x01(\x03\x12\x39\n\x07topData\x18\x03 \x03(\x0b\x32(.tigeropen.push.pb.OptionTopData.TopData\x1a\x95\x01\n\x07TopData\x12\x12\n\ntargetName\x18\x01 \x01(\t\x12;\n\x08\x62igOrder\x18\x02 \x03(\x0b\x32).tigeropen.push.pb.OptionTopData.BigOrder\x12\x39\n\x04item\x18\x03 \x03(\x0b\x32+.tigeropen.push.pb.OptionTopData.OptionItem\x1a\x98\x01\n\x08\x42igOrder\x12\x0e\n\x06symbol\x18\x01 \x01(\t\x12\x0e\n\x06\x65xpiry\x18\x02 \x01(\t\x12\x0e\n\x06strike\x18\x03 \x01(\t\x12\r\n\x05right\x18\x04 \x01(\t\x12\x0b\n\x03\x64ir\x18\x05 \x01(\t\x12\x0e\n\x06volume\x18\x06 \x01(\x01\x12\r\n\x05price\x18\x07 \x01(\x01\x12\x0e\n\x06\x61mount\x18\x08 \x01(\x01\x12\x11\n\ttradeTime\x18\t \x01(\x03\x1a\xcd\x01\n\nOptionItem\x12\x0e\n\x06symbol\x18\x01 \x01(\t\x12\x0e\n\x06\x65xpiry\x18\x02 \x01(\t\x12\x0e\n\x06strike\x18\x03 \x01(\t\x12\r\n\x05right\x18\x04 \x01(\t\x12\x13\n\x0btotalAmount\x18\x05 \x01(\x01\x12\x13\n\x0btotalVolume\x18\x06 \x01(\x01\x12\x14\n\x0ctotalOpenInt\x18\x07 \x01(\x01\x12\x17\n\x0fvolumeToOpenInt\x18\x08 \x01(\x01\x12\x13\n\x0blatestPrice\x18\t \x01(\x01\x12\x12\n\nupdateTime\x18\n \x01(\x03\x62\x06proto3') 28 | 29 | _globals = globals() 30 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) 31 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tigeropen.push.pb.OptionTopData_pb2', _globals) 32 | if not _descriptor._USE_C_DESCRIPTORS: 33 | DESCRIPTOR._loaded_options = None 34 | _globals['_OPTIONTOPDATA']._serialized_start=61 35 | _globals['_OPTIONTOPDATA']._serialized_end=685 36 | _globals['_OPTIONTOPDATA_TOPDATA']._serialized_start=173 37 | _globals['_OPTIONTOPDATA_TOPDATA']._serialized_end=322 38 | _globals['_OPTIONTOPDATA_BIGORDER']._serialized_start=325 39 | _globals['_OPTIONTOPDATA_BIGORDER']._serialized_end=477 40 | _globals['_OPTIONTOPDATA_OPTIONITEM']._serialized_start=480 41 | _globals['_OPTIONTOPDATA_OPTIONITEM']._serialized_end=685 42 | # @@protoc_insertion_point(module_scope) 43 | -------------------------------------------------------------------------------- /tigeropen/push/pb/OrderStatusData.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package tigeropen.push.pb; 4 | 5 | message OrderStatusData { 6 | sint64 id = 1; // unique order id 7 | string account = 2; // user account 8 | string symbol = 3; 9 | string expiry = 4; // for options, formate:yyyyMMdd 10 | string strike = 5; // for options 11 | string right = 6; // for options 12 | string identifier = 7; 13 | uint32 multiplier = 8; // multiplier for futures, options, warrants and CBBC 14 | string action = 9; // BUY or SELL 15 | string market = 10; // market. US, HK, etc. 16 | string currency = 11; // currency. USD, HKD, etc. 17 | string segType = 12; // Securities Category C: (Commodities Futures), S: (Securities Stocks) 18 | string secType = 13; // STK Stocks, OPT Options, WAR Warrants, IOPT CBBC, CASH FOREX, FUT Futures, FOP Future Options 19 | 20 | string orderType = 14; // order type 21 | bool isLong = 15; 22 | sint64 totalQuantity = 16; // total quantity 23 | sint32 totalQuantityScale = 17; // total quantity scale 24 | sint64 filledQuantity = 18; // filled quantity 25 | sint32 filledQuantityScale = 19; // filled quantity scale 26 | double avgFillPrice = 20; // average price at which the orders got filled 27 | double limitPrice = 21; // limit price(required when orderType is 'LMT') 28 | double stopPrice = 22; // stop price(required when orderType is 'STP') 29 | double realizedPnl = 23; // realized profit and loss 30 | string status = 24; // order status 31 | string replaceStatus = 25; // order replace status 32 | string cancelStatus = 26; // order cancel status 33 | 34 | bool outsideRth = 27; // if trade outside regular trading hours (only applicable to U.S. market) 35 | bool canModify = 28; 36 | bool canCancel = 29; 37 | bool liquidation = 30; 38 | string name = 31; // symbol name 39 | string source = 32; // order source(from 'OpenApi', or not) 40 | string errorMsg = 33; // error message 41 | string attrDesc = 34; // order description 42 | float commissionAndFee = 35; // commission and fee 43 | uint64 openTime = 36; // timestamp when the order is placed 44 | uint64 timestamp = 37; 45 | string userMark = 38; 46 | double totalCashAmount = 39; 47 | double filledCashAmount = 40; 48 | double gst = 41; 49 | } -------------------------------------------------------------------------------- /tigeropen/push/pb/OrderStatusData_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # NO CHECKED-IN PROTOBUF GENCODE 4 | # source: tigeropen/push/pb/OrderStatusData.proto 5 | # Protobuf Python Version: 5.28.3 6 | """Generated protocol buffer code.""" 7 | from google.protobuf import descriptor as _descriptor 8 | from google.protobuf import descriptor_pool as _descriptor_pool 9 | from google.protobuf import runtime_version as _runtime_version 10 | from google.protobuf import symbol_database as _symbol_database 11 | from google.protobuf.internal import builder as _builder 12 | _runtime_version.ValidateProtobufRuntimeVersion( 13 | _runtime_version.Domain.PUBLIC, 14 | 5, 15 | 28, 16 | 3, 17 | '', 18 | 'tigeropen/push/pb/OrderStatusData.proto' 19 | ) 20 | # @@protoc_insertion_point(imports) 21 | 22 | _sym_db = _symbol_database.Default() 23 | 24 | 25 | 26 | 27 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\'tigeropen/push/pb/OrderStatusData.proto\x12\x11tigeropen.push.pb\"\xa5\x06\n\x0fOrderStatusData\x12\n\n\x02id\x18\x01 \x01(\x12\x12\x0f\n\x07\x61\x63\x63ount\x18\x02 \x01(\t\x12\x0e\n\x06symbol\x18\x03 \x01(\t\x12\x0e\n\x06\x65xpiry\x18\x04 \x01(\t\x12\x0e\n\x06strike\x18\x05 \x01(\t\x12\r\n\x05right\x18\x06 \x01(\t\x12\x12\n\nidentifier\x18\x07 \x01(\t\x12\x12\n\nmultiplier\x18\x08 \x01(\r\x12\x0e\n\x06\x61\x63tion\x18\t \x01(\t\x12\x0e\n\x06market\x18\n \x01(\t\x12\x10\n\x08\x63urrency\x18\x0b \x01(\t\x12\x0f\n\x07segType\x18\x0c \x01(\t\x12\x0f\n\x07secType\x18\r \x01(\t\x12\x11\n\torderType\x18\x0e \x01(\t\x12\x0e\n\x06isLong\x18\x0f \x01(\x08\x12\x15\n\rtotalQuantity\x18\x10 \x01(\x12\x12\x1a\n\x12totalQuantityScale\x18\x11 \x01(\x11\x12\x16\n\x0e\x66illedQuantity\x18\x12 \x01(\x12\x12\x1b\n\x13\x66illedQuantityScale\x18\x13 \x01(\x11\x12\x14\n\x0c\x61vgFillPrice\x18\x14 \x01(\x01\x12\x12\n\nlimitPrice\x18\x15 \x01(\x01\x12\x11\n\tstopPrice\x18\x16 \x01(\x01\x12\x13\n\x0brealizedPnl\x18\x17 \x01(\x01\x12\x0e\n\x06status\x18\x18 \x01(\t\x12\x15\n\rreplaceStatus\x18\x19 \x01(\t\x12\x14\n\x0c\x63\x61ncelStatus\x18\x1a \x01(\t\x12\x12\n\noutsideRth\x18\x1b \x01(\x08\x12\x11\n\tcanModify\x18\x1c \x01(\x08\x12\x11\n\tcanCancel\x18\x1d \x01(\x08\x12\x13\n\x0bliquidation\x18\x1e \x01(\x08\x12\x0c\n\x04name\x18\x1f \x01(\t\x12\x0e\n\x06source\x18 \x01(\t\x12\x10\n\x08\x65rrorMsg\x18! \x01(\t\x12\x10\n\x08\x61ttrDesc\x18\" \x01(\t\x12\x18\n\x10\x63ommissionAndFee\x18# \x01(\x02\x12\x10\n\x08openTime\x18$ \x01(\x04\x12\x11\n\ttimestamp\x18% \x01(\x04\x12\x10\n\x08userMark\x18& \x01(\t\x12\x17\n\x0ftotalCashAmount\x18\' \x01(\x01\x12\x18\n\x10\x66illedCashAmount\x18( \x01(\x01\x12\x0b\n\x03gst\x18) \x01(\x01\x62\x06proto3') 28 | 29 | _globals = globals() 30 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) 31 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tigeropen.push.pb.OrderStatusData_pb2', _globals) 32 | if not _descriptor._USE_C_DESCRIPTORS: 33 | DESCRIPTOR._loaded_options = None 34 | _globals['_ORDERSTATUSDATA']._serialized_start=63 35 | _globals['_ORDERSTATUSDATA']._serialized_end=868 36 | # @@protoc_insertion_point(module_scope) 37 | -------------------------------------------------------------------------------- /tigeropen/push/pb/OrderTransactionData.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package tigeropen.push.pb; 4 | 5 | message OrderTransactionData { 6 | sint64 id = 1; // transact id 7 | sint64 orderId = 2; // unique order id 8 | string account = 3; // user account 9 | string symbol = 4; 10 | string identifier = 5; 11 | uint32 multiplier = 6; // multiplier for futures, options, warrants and CBBC 12 | string action = 7; // BUY or SELL 13 | string market = 8; // market. US, HK, etc. 14 | string currency = 9; // currency. USD, HKD, etc. 15 | string segType = 10; // Securities Category C: (Commodities Futures), S: (Securities Stocks) 16 | string secType = 11; // STK Stocks, OPT Options, WAR Warrants, IOPT CBBC, CASH FOREX, FUT Futures, FOP Future Options 17 | double filledPrice = 12; // filled price 18 | sint64 filledQuantity = 13; // filled quantity 19 | uint64 createTime = 14; 20 | uint64 updateTime = 15; 21 | uint64 transactTime = 16; // transact time 22 | uint64 timestamp = 17; 23 | 24 | } -------------------------------------------------------------------------------- /tigeropen/push/pb/OrderTransactionData_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # NO CHECKED-IN PROTOBUF GENCODE 4 | # source: tigeropen/push/pb/OrderTransactionData.proto 5 | # Protobuf Python Version: 5.28.3 6 | """Generated protocol buffer code.""" 7 | from google.protobuf import descriptor as _descriptor 8 | from google.protobuf import descriptor_pool as _descriptor_pool 9 | from google.protobuf import runtime_version as _runtime_version 10 | from google.protobuf import symbol_database as _symbol_database 11 | from google.protobuf.internal import builder as _builder 12 | _runtime_version.ValidateProtobufRuntimeVersion( 13 | _runtime_version.Domain.PUBLIC, 14 | 5, 15 | 28, 16 | 3, 17 | '', 18 | 'tigeropen/push/pb/OrderTransactionData.proto' 19 | ) 20 | # @@protoc_insertion_point(imports) 21 | 22 | _sym_db = _symbol_database.Default() 23 | 24 | 25 | 26 | 27 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n,tigeropen/push/pb/OrderTransactionData.proto\x12\x11tigeropen.push.pb\"\xce\x02\n\x14OrderTransactionData\x12\n\n\x02id\x18\x01 \x01(\x12\x12\x0f\n\x07orderId\x18\x02 \x01(\x12\x12\x0f\n\x07\x61\x63\x63ount\x18\x03 \x01(\t\x12\x0e\n\x06symbol\x18\x04 \x01(\t\x12\x12\n\nidentifier\x18\x05 \x01(\t\x12\x12\n\nmultiplier\x18\x06 \x01(\r\x12\x0e\n\x06\x61\x63tion\x18\x07 \x01(\t\x12\x0e\n\x06market\x18\x08 \x01(\t\x12\x10\n\x08\x63urrency\x18\t \x01(\t\x12\x0f\n\x07segType\x18\n \x01(\t\x12\x0f\n\x07secType\x18\x0b \x01(\t\x12\x13\n\x0b\x66illedPrice\x18\x0c \x01(\x01\x12\x16\n\x0e\x66illedQuantity\x18\r \x01(\x12\x12\x12\n\ncreateTime\x18\x0e \x01(\x04\x12\x12\n\nupdateTime\x18\x0f \x01(\x04\x12\x14\n\x0ctransactTime\x18\x10 \x01(\x04\x12\x11\n\ttimestamp\x18\x11 \x01(\x04\x62\x06proto3') 28 | 29 | _globals = globals() 30 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) 31 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tigeropen.push.pb.OrderTransactionData_pb2', _globals) 32 | if not _descriptor._USE_C_DESCRIPTORS: 33 | DESCRIPTOR._loaded_options = None 34 | _globals['_ORDERTRANSACTIONDATA']._serialized_start=68 35 | _globals['_ORDERTRANSACTIONDATA']._serialized_end=402 36 | # @@protoc_insertion_point(module_scope) 37 | -------------------------------------------------------------------------------- /tigeropen/push/pb/OrderTransactionData_pb2.pyi: -------------------------------------------------------------------------------- 1 | from google.protobuf import descriptor as _descriptor 2 | from google.protobuf import message as _message 3 | from typing import ClassVar as _ClassVar, Optional as _Optional 4 | 5 | DESCRIPTOR: _descriptor.FileDescriptor 6 | 7 | class OrderTransactionData(_message.Message): 8 | __slots__ = ("id", "orderId", "account", "symbol", "identifier", "multiplier", "action", "market", "currency", "segType", "secType", "filledPrice", "filledQuantity", "createTime", "updateTime", "transactTime", "timestamp") 9 | ID_FIELD_NUMBER: _ClassVar[int] 10 | ORDERID_FIELD_NUMBER: _ClassVar[int] 11 | ACCOUNT_FIELD_NUMBER: _ClassVar[int] 12 | SYMBOL_FIELD_NUMBER: _ClassVar[int] 13 | IDENTIFIER_FIELD_NUMBER: _ClassVar[int] 14 | MULTIPLIER_FIELD_NUMBER: _ClassVar[int] 15 | ACTION_FIELD_NUMBER: _ClassVar[int] 16 | MARKET_FIELD_NUMBER: _ClassVar[int] 17 | CURRENCY_FIELD_NUMBER: _ClassVar[int] 18 | SEGTYPE_FIELD_NUMBER: _ClassVar[int] 19 | SECTYPE_FIELD_NUMBER: _ClassVar[int] 20 | FILLEDPRICE_FIELD_NUMBER: _ClassVar[int] 21 | FILLEDQUANTITY_FIELD_NUMBER: _ClassVar[int] 22 | CREATETIME_FIELD_NUMBER: _ClassVar[int] 23 | UPDATETIME_FIELD_NUMBER: _ClassVar[int] 24 | TRANSACTTIME_FIELD_NUMBER: _ClassVar[int] 25 | TIMESTAMP_FIELD_NUMBER: _ClassVar[int] 26 | id: int 27 | orderId: int 28 | account: str 29 | symbol: str 30 | identifier: str 31 | multiplier: int 32 | action: str 33 | market: str 34 | currency: str 35 | segType: str 36 | secType: str 37 | filledPrice: float 38 | filledQuantity: int 39 | createTime: int 40 | updateTime: int 41 | transactTime: int 42 | timestamp: int 43 | def __init__(self, id: _Optional[int] = ..., orderId: _Optional[int] = ..., account: _Optional[str] = ..., symbol: _Optional[str] = ..., identifier: _Optional[str] = ..., multiplier: _Optional[int] = ..., action: _Optional[str] = ..., market: _Optional[str] = ..., currency: _Optional[str] = ..., segType: _Optional[str] = ..., secType: _Optional[str] = ..., filledPrice: _Optional[float] = ..., filledQuantity: _Optional[int] = ..., createTime: _Optional[int] = ..., updateTime: _Optional[int] = ..., transactTime: _Optional[int] = ..., timestamp: _Optional[int] = ...) -> None: ... 44 | -------------------------------------------------------------------------------- /tigeropen/push/pb/PositionData.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package tigeropen.push.pb; 4 | 5 | message PositionData { 6 | string account = 1; // user account 7 | string symbol = 2; 8 | string expiry = 3; // for options 9 | string strike = 4; // for options 10 | string right = 5; // for options 11 | string identifier = 6; 12 | uint32 multiplier = 7; // multiplier for futures, options, warrants and CBBC 13 | string market = 8; // market. US, HK, etc. 14 | string currency = 9; // currency. USD, HKD, etc. 15 | string segType = 10; // Securities Category C: (Commodities Futures), S: (Securities Stocks) 16 | string secType = 11; // STK Stocks, OPT Options, WAR Warrants, IOPT CBBC, CASH FOREX, FUT Futures, FOP Future Options 17 | 18 | sint64 position = 12; // total position 19 | sint32 positionScale = 13; // total position scale 20 | double averageCost = 14; // average holding cost 21 | double latestPrice = 15; // last price of the asset 22 | double marketValue = 16; // market value of the asset 23 | double unrealizedPnl = 17; // unrealized profit and loss 24 | string name = 18; // symbol name 25 | uint64 timestamp = 19; 26 | optional sint64 saleable = 20; // saleable quantity for Chinese A-share market stocks 27 | double positionQty = 21; // total position quantity 28 | double salableQty = 22; // saleable quantity 29 | } -------------------------------------------------------------------------------- /tigeropen/push/pb/PositionData_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # NO CHECKED-IN PROTOBUF GENCODE 4 | # source: tigeropen/push/pb/PositionData.proto 5 | # Protobuf Python Version: 5.28.3 6 | """Generated protocol buffer code.""" 7 | from google.protobuf import descriptor as _descriptor 8 | from google.protobuf import descriptor_pool as _descriptor_pool 9 | from google.protobuf import runtime_version as _runtime_version 10 | from google.protobuf import symbol_database as _symbol_database 11 | from google.protobuf.internal import builder as _builder 12 | _runtime_version.ValidateProtobufRuntimeVersion( 13 | _runtime_version.Domain.PUBLIC, 14 | 5, 15 | 28, 16 | 3, 17 | '', 18 | 'tigeropen/push/pb/PositionData.proto' 19 | ) 20 | # @@protoc_insertion_point(imports) 21 | 22 | _sym_db = _symbol_database.Default() 23 | 24 | 25 | 26 | 27 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$tigeropen/push/pb/PositionData.proto\x12\x11tigeropen.push.pb\"\xb7\x03\n\x0cPositionData\x12\x0f\n\x07\x61\x63\x63ount\x18\x01 \x01(\t\x12\x0e\n\x06symbol\x18\x02 \x01(\t\x12\x0e\n\x06\x65xpiry\x18\x03 \x01(\t\x12\x0e\n\x06strike\x18\x04 \x01(\t\x12\r\n\x05right\x18\x05 \x01(\t\x12\x12\n\nidentifier\x18\x06 \x01(\t\x12\x12\n\nmultiplier\x18\x07 \x01(\r\x12\x0e\n\x06market\x18\x08 \x01(\t\x12\x10\n\x08\x63urrency\x18\t \x01(\t\x12\x0f\n\x07segType\x18\n \x01(\t\x12\x0f\n\x07secType\x18\x0b \x01(\t\x12\x10\n\x08position\x18\x0c \x01(\x12\x12\x15\n\rpositionScale\x18\r \x01(\x11\x12\x13\n\x0b\x61verageCost\x18\x0e \x01(\x01\x12\x13\n\x0blatestPrice\x18\x0f \x01(\x01\x12\x13\n\x0bmarketValue\x18\x10 \x01(\x01\x12\x15\n\runrealizedPnl\x18\x11 \x01(\x01\x12\x0c\n\x04name\x18\x12 \x01(\t\x12\x11\n\ttimestamp\x18\x13 \x01(\x04\x12\x15\n\x08saleable\x18\x14 \x01(\x12H\x00\x88\x01\x01\x12\x13\n\x0bpositionQty\x18\x15 \x01(\x01\x12\x12\n\nsalableQty\x18\x16 \x01(\x01\x42\x0b\n\t_saleableb\x06proto3') 28 | 29 | _globals = globals() 30 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) 31 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tigeropen.push.pb.PositionData_pb2', _globals) 32 | if not _descriptor._USE_C_DESCRIPTORS: 33 | DESCRIPTOR._loaded_options = None 34 | _globals['_POSITIONDATA']._serialized_start=60 35 | _globals['_POSITIONDATA']._serialized_end=499 36 | # @@protoc_insertion_point(module_scope) 37 | -------------------------------------------------------------------------------- /tigeropen/push/pb/PositionData_pb2.pyi: -------------------------------------------------------------------------------- 1 | from google.protobuf import descriptor as _descriptor 2 | from google.protobuf import message as _message 3 | from typing import ClassVar as _ClassVar, Optional as _Optional 4 | 5 | DESCRIPTOR: _descriptor.FileDescriptor 6 | 7 | class PositionData(_message.Message): 8 | __slots__ = ("account", "symbol", "expiry", "strike", "right", "identifier", "multiplier", "market", "currency", "segType", "secType", "position", "positionScale", "averageCost", "latestPrice", "marketValue", "unrealizedPnl", "name", "timestamp", "saleable", "positionQty", "salableQty") 9 | ACCOUNT_FIELD_NUMBER: _ClassVar[int] 10 | SYMBOL_FIELD_NUMBER: _ClassVar[int] 11 | EXPIRY_FIELD_NUMBER: _ClassVar[int] 12 | STRIKE_FIELD_NUMBER: _ClassVar[int] 13 | RIGHT_FIELD_NUMBER: _ClassVar[int] 14 | IDENTIFIER_FIELD_NUMBER: _ClassVar[int] 15 | MULTIPLIER_FIELD_NUMBER: _ClassVar[int] 16 | MARKET_FIELD_NUMBER: _ClassVar[int] 17 | CURRENCY_FIELD_NUMBER: _ClassVar[int] 18 | SEGTYPE_FIELD_NUMBER: _ClassVar[int] 19 | SECTYPE_FIELD_NUMBER: _ClassVar[int] 20 | POSITION_FIELD_NUMBER: _ClassVar[int] 21 | POSITIONSCALE_FIELD_NUMBER: _ClassVar[int] 22 | AVERAGECOST_FIELD_NUMBER: _ClassVar[int] 23 | LATESTPRICE_FIELD_NUMBER: _ClassVar[int] 24 | MARKETVALUE_FIELD_NUMBER: _ClassVar[int] 25 | UNREALIZEDPNL_FIELD_NUMBER: _ClassVar[int] 26 | NAME_FIELD_NUMBER: _ClassVar[int] 27 | TIMESTAMP_FIELD_NUMBER: _ClassVar[int] 28 | SALEABLE_FIELD_NUMBER: _ClassVar[int] 29 | POSITIONQTY_FIELD_NUMBER: _ClassVar[int] 30 | SALABLEQTY_FIELD_NUMBER: _ClassVar[int] 31 | account: str 32 | symbol: str 33 | expiry: str 34 | strike: str 35 | right: str 36 | identifier: str 37 | multiplier: int 38 | market: str 39 | currency: str 40 | segType: str 41 | secType: str 42 | position: int 43 | positionScale: int 44 | averageCost: float 45 | latestPrice: float 46 | marketValue: float 47 | unrealizedPnl: float 48 | name: str 49 | timestamp: int 50 | saleable: int 51 | positionQty: float 52 | salableQty: float 53 | def __init__(self, account: _Optional[str] = ..., symbol: _Optional[str] = ..., expiry: _Optional[str] = ..., strike: _Optional[str] = ..., right: _Optional[str] = ..., identifier: _Optional[str] = ..., multiplier: _Optional[int] = ..., market: _Optional[str] = ..., currency: _Optional[str] = ..., segType: _Optional[str] = ..., secType: _Optional[str] = ..., position: _Optional[int] = ..., positionScale: _Optional[int] = ..., averageCost: _Optional[float] = ..., latestPrice: _Optional[float] = ..., marketValue: _Optional[float] = ..., unrealizedPnl: _Optional[float] = ..., name: _Optional[str] = ..., timestamp: _Optional[int] = ..., saleable: _Optional[int] = ..., positionQty: _Optional[float] = ..., salableQty: _Optional[float] = ...) -> None: ... 54 | -------------------------------------------------------------------------------- /tigeropen/push/pb/PushData.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | import public "tigeropen/push/pb/SocketCommon.proto"; 3 | import public "tigeropen/push/pb/OrderStatusData.proto"; 4 | import public "tigeropen/push/pb/PositionData.proto"; 5 | import public "tigeropen/push/pb/AssetData.proto"; 6 | import public "tigeropen/push/pb/QuoteData.proto"; 7 | import public "tigeropen/push/pb/QuoteDepthData.proto"; 8 | import public "tigeropen/push/pb/TradeTickData.proto"; 9 | import public "tigeropen/push/pb/OrderTransactionData.proto"; 10 | import public "tigeropen/push/pb/StockTopData.proto"; 11 | import public "tigeropen/push/pb/OptionTopData.proto"; 12 | import public "tigeropen/push/pb/KlineData.proto"; 13 | import public "tigeropen/push/pb/TickData.proto"; 14 | 15 | package tigeropen.push.pb; 16 | 17 | message PushData { 18 | SocketCommon.DataType dataType = 1; 19 | oneof body { 20 | QuoteData quoteData = 2; 21 | QuoteDepthData quoteDepthData = 3; 22 | TradeTickData tradeTickData = 4; 23 | PositionData positionData = 5; 24 | AssetData assetData = 6; 25 | OrderStatusData orderStatusData = 7; 26 | OrderTransactionData orderTransactionData = 8; 27 | StockTopData stockTopData = 9; 28 | OptionTopData optionTopData = 10; 29 | KlineData klineData = 11; 30 | TickData tickData = 12; 31 | } 32 | } -------------------------------------------------------------------------------- /tigeropen/push/pb/QuoteBBOData.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | import public "tigeropen/push/pb/SocketCommon.proto"; 3 | 4 | package tigeropen.push.pb; 5 | 6 | 7 | message QuoteBBOData { 8 | 9 | string symbol = 1; 10 | SocketCommon.QuoteType type = 2; // BBO 11 | uint64 timestamp = 3; 12 | 13 | double askPrice = 17; 14 | sint64 askSize = 18; 15 | optional uint64 askTimestamp = 19; // Pre/Post-Mkt data not support 16 | double bidPrice = 20; 17 | sint64 bidSize = 21; 18 | optional uint64 bidTimestamp = 22; // Pre/Post-Mkt data not support 19 | 20 | } -------------------------------------------------------------------------------- /tigeropen/push/pb/QuoteBBOData_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # NO CHECKED-IN PROTOBUF GENCODE 4 | # source: tigeropen/push/pb/QuoteBBOData.proto 5 | # Protobuf Python Version: 5.28.3 6 | """Generated protocol buffer code.""" 7 | from google.protobuf import descriptor as _descriptor 8 | from google.protobuf import descriptor_pool as _descriptor_pool 9 | from google.protobuf import runtime_version as _runtime_version 10 | from google.protobuf import symbol_database as _symbol_database 11 | from google.protobuf.internal import builder as _builder 12 | _runtime_version.ValidateProtobufRuntimeVersion( 13 | _runtime_version.Domain.PUBLIC, 14 | 5, 15 | 28, 16 | 3, 17 | '', 18 | 'tigeropen/push/pb/QuoteBBOData.proto' 19 | ) 20 | # @@protoc_insertion_point(imports) 21 | 22 | _sym_db = _symbol_database.Default() 23 | 24 | 25 | from tigeropen.push.pb import SocketCommon_pb2 as tigeropen_dot_push_dot_pb_dot_SocketCommon__pb2 26 | 27 | from tigeropen.push.pb.SocketCommon_pb2 import * 28 | 29 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$tigeropen/push/pb/QuoteBBOData.proto\x12\x11tigeropen.push.pb\x1a$tigeropen/push/pb/SocketCommon.proto\"\x88\x02\n\x0cQuoteBBOData\x12\x0e\n\x06symbol\x18\x01 \x01(\t\x12\x37\n\x04type\x18\x02 \x01(\x0e\x32).tigeropen.push.pb.SocketCommon.QuoteType\x12\x11\n\ttimestamp\x18\x03 \x01(\x04\x12\x10\n\x08\x61skPrice\x18\x11 \x01(\x01\x12\x0f\n\x07\x61skSize\x18\x12 \x01(\x12\x12\x19\n\x0c\x61skTimestamp\x18\x13 \x01(\x04H\x00\x88\x01\x01\x12\x10\n\x08\x62idPrice\x18\x14 \x01(\x01\x12\x0f\n\x07\x62idSize\x18\x15 \x01(\x12\x12\x19\n\x0c\x62idTimestamp\x18\x16 \x01(\x04H\x01\x88\x01\x01\x42\x0f\n\r_askTimestampB\x0f\n\r_bidTimestampP\x00\x62\x06proto3') 30 | 31 | _globals = globals() 32 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) 33 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tigeropen.push.pb.QuoteBBOData_pb2', _globals) 34 | if not _descriptor._USE_C_DESCRIPTORS: 35 | DESCRIPTOR._loaded_options = None 36 | _globals['_QUOTEBBODATA']._serialized_start=98 37 | _globals['_QUOTEBBODATA']._serialized_end=362 38 | # @@protoc_insertion_point(module_scope) 39 | -------------------------------------------------------------------------------- /tigeropen/push/pb/QuoteBBOData_pb2.pyi: -------------------------------------------------------------------------------- 1 | from tigeropen.push.pb import SocketCommon_pb2 as _SocketCommon_pb2 2 | from google.protobuf import descriptor as _descriptor 3 | from google.protobuf import message as _message 4 | from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union 5 | from tigeropen.push.pb.SocketCommon_pb2 import SocketCommon as SocketCommon 6 | 7 | DESCRIPTOR: _descriptor.FileDescriptor 8 | 9 | class QuoteBBOData(_message.Message): 10 | __slots__ = ("symbol", "type", "timestamp", "askPrice", "askSize", "askTimestamp", "bidPrice", "bidSize", "bidTimestamp") 11 | SYMBOL_FIELD_NUMBER: _ClassVar[int] 12 | TYPE_FIELD_NUMBER: _ClassVar[int] 13 | TIMESTAMP_FIELD_NUMBER: _ClassVar[int] 14 | ASKPRICE_FIELD_NUMBER: _ClassVar[int] 15 | ASKSIZE_FIELD_NUMBER: _ClassVar[int] 16 | ASKTIMESTAMP_FIELD_NUMBER: _ClassVar[int] 17 | BIDPRICE_FIELD_NUMBER: _ClassVar[int] 18 | BIDSIZE_FIELD_NUMBER: _ClassVar[int] 19 | BIDTIMESTAMP_FIELD_NUMBER: _ClassVar[int] 20 | symbol: str 21 | type: _SocketCommon_pb2.SocketCommon.QuoteType 22 | timestamp: int 23 | askPrice: float 24 | askSize: int 25 | askTimestamp: int 26 | bidPrice: float 27 | bidSize: int 28 | bidTimestamp: int 29 | def __init__(self, symbol: _Optional[str] = ..., type: _Optional[_Union[_SocketCommon_pb2.SocketCommon.QuoteType, str]] = ..., timestamp: _Optional[int] = ..., askPrice: _Optional[float] = ..., askSize: _Optional[int] = ..., askTimestamp: _Optional[int] = ..., bidPrice: _Optional[float] = ..., bidSize: _Optional[int] = ..., bidTimestamp: _Optional[int] = ...) -> None: ... 30 | -------------------------------------------------------------------------------- /tigeropen/push/pb/QuoteBasicData.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | import public "tigeropen/push/pb/SocketCommon.proto"; 3 | import public "tigeropen/push/pb/QuoteData.proto"; 4 | 5 | package tigeropen.push.pb; 6 | 7 | message QuoteBasicData { 8 | 9 | string symbol = 1; 10 | SocketCommon.QuoteType type = 2; // BASIC/BBO 11 | uint64 timestamp = 3; 12 | optional uint64 serverTimestamp = 4; 13 | optional double avgPrice = 5; // Options data not support 14 | optional double latestPrice = 6; // 15 | optional uint64 latestPriceTimestamp = 7; // Pre/Post-Mkt data not support 16 | optional string latestTime = 8; // 17 | optional double preClose = 9; // 18 | optional sint64 volume = 10; // 19 | optional double amount = 11; // Futures and Options data not support 20 | 21 | optional double open = 12; // Pre/Post-Mkt data not support 22 | optional double high = 13; // Pre/Post-Mkt data not support 23 | optional double low = 14; // Pre/Post-Mkt data not support 24 | 25 | optional string hourTradingTag = 15; // Pre/Post-Mkt 26 | optional string marketStatus = 16; 27 | 28 | optional string identifier = 23; // only Options support 29 | optional sint64 openInt = 24; // open interest, only Options support 30 | 31 | optional uint64 tradeTime = 25; // latest trad time, only Futures support 32 | optional double preSettlement = 26; // previous settlement price, only Futures support 33 | optional float minTick = 27; // min tick, only Futures support 34 | 35 | // minute data: price, average price, time, volume 36 | optional QuoteData.Minute mi = 28; 37 | 38 | } -------------------------------------------------------------------------------- /tigeropen/push/pb/QuoteData.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package tigeropen.push.pb; 3 | 4 | import "tigeropen/push/pb/SocketCommon.proto"; 5 | 6 | 7 | 8 | message QuoteData { 9 | 10 | string symbol = 1; 11 | SocketCommon.QuoteType type = 2; // ALL/BASIC/BBO 12 | uint64 timestamp = 3; 13 | optional uint64 serverTimestamp = 4; 14 | optional double avgPrice = 5; // Options data not support 15 | optional double latestPrice = 6; // required when type is 'BASIC' 16 | optional uint64 latestPriceTimestamp = 7; // required when type is 'BASIC', Pre/Post-Mkt data not support 17 | optional string latestTime = 8; // required when type is 'BASIC' 18 | optional double preClose = 9; // required when type is 'BASIC' 19 | optional sint64 volume = 10; // required when type is 'BASIC' 20 | optional double amount = 11; // required when type is 'BASIC', Futures and Options data not support 21 | 22 | optional double open = 12; // required when symbol in HK market 23 | optional double high = 13; // required when symbol in HK market 24 | optional double low = 14; // required when symbol in HK market 25 | 26 | optional string hourTradingTag = 15; // Pre/Post-Mkt 27 | optional string marketStatus = 16; 28 | 29 | optional double askPrice = 17; // required when type is 'BBO' 30 | optional sint64 askSize = 18; // required when type is 'BBO' 31 | optional uint64 askTimestamp = 19; // Pre/Post-Mkt data not support 32 | optional double bidPrice = 20; // required when type is 'BBO' 33 | optional sint64 bidSize = 21; // required when type is 'BBO' 34 | optional uint64 bidTimestamp = 22; // Pre/Post-Mkt data not support 35 | 36 | optional string identifier = 23; // only Options support 37 | optional sint64 openInt = 24; // open interest, only Options support 38 | 39 | optional uint64 tradeTime = 25; // latest trad time, only Futures support 40 | optional double preSettlement = 26; // previous settlement price, only Futures support 41 | optional float minTick = 27; // min tick, only Futures support 42 | 43 | // minute data: price, average price, time, volume 44 | optional Minute mi = 28; 45 | 46 | message Minute { 47 | double p = 1; // last price of the minute bar 48 | double a = 2; // average price of the minute bar 49 | uint64 t = 3; // timestamp of the minute bar 50 | sint64 v = 4; // trading volume of the minute bar 51 | double o = 5; // open price of the minute bar 52 | double h = 6; // highest price of the minute bar 53 | double l = 7; // lowest price of the minute bar 54 | } 55 | } -------------------------------------------------------------------------------- /tigeropen/push/pb/QuoteDepthData.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package tigeropen.push.pb; 4 | 5 | 6 | message QuoteDepthData { 7 | message OrderBook { 8 | repeated double price = 1; 9 | repeated sint64 volume = 2; 10 | repeated uint32 orderCount = 3; // required when symbol in HK market 11 | repeated string exchange = 4; // option exchange 12 | repeated sint64 time = 5; // option exchange time 13 | } 14 | string symbol = 1; 15 | uint64 timestamp = 2; 16 | 17 | OrderBook ask = 3; 18 | OrderBook bid = 4; 19 | 20 | } -------------------------------------------------------------------------------- /tigeropen/push/pb/QuoteDepthData_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # NO CHECKED-IN PROTOBUF GENCODE 4 | # source: tigeropen/push/pb/QuoteDepthData.proto 5 | # Protobuf Python Version: 5.28.3 6 | """Generated protocol buffer code.""" 7 | from google.protobuf import descriptor as _descriptor 8 | from google.protobuf import descriptor_pool as _descriptor_pool 9 | from google.protobuf import runtime_version as _runtime_version 10 | from google.protobuf import symbol_database as _symbol_database 11 | from google.protobuf.internal import builder as _builder 12 | _runtime_version.ValidateProtobufRuntimeVersion( 13 | _runtime_version.Domain.PUBLIC, 14 | 5, 15 | 28, 16 | 3, 17 | '', 18 | 'tigeropen/push/pb/QuoteDepthData.proto' 19 | ) 20 | # @@protoc_insertion_point(imports) 21 | 22 | _sym_db = _symbol_database.Default() 23 | 24 | 25 | 26 | 27 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n&tigeropen/push/pb/QuoteDepthData.proto\x12\x11tigeropen.push.pb\"\x87\x02\n\x0eQuoteDepthData\x12\x0e\n\x06symbol\x18\x01 \x01(\t\x12\x11\n\ttimestamp\x18\x02 \x01(\x04\x12\x38\n\x03\x61sk\x18\x03 \x01(\x0b\x32+.tigeropen.push.pb.QuoteDepthData.OrderBook\x12\x38\n\x03\x62id\x18\x04 \x01(\x0b\x32+.tigeropen.push.pb.QuoteDepthData.OrderBook\x1a^\n\tOrderBook\x12\r\n\x05price\x18\x01 \x03(\x01\x12\x0e\n\x06volume\x18\x02 \x03(\x12\x12\x12\n\norderCount\x18\x03 \x03(\r\x12\x10\n\x08\x65xchange\x18\x04 \x03(\t\x12\x0c\n\x04time\x18\x05 \x03(\x12\x62\x06proto3') 28 | 29 | _globals = globals() 30 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) 31 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tigeropen.push.pb.QuoteDepthData_pb2', _globals) 32 | if not _descriptor._USE_C_DESCRIPTORS: 33 | DESCRIPTOR._loaded_options = None 34 | _globals['_QUOTEDEPTHDATA']._serialized_start=62 35 | _globals['_QUOTEDEPTHDATA']._serialized_end=325 36 | _globals['_QUOTEDEPTHDATA_ORDERBOOK']._serialized_start=231 37 | _globals['_QUOTEDEPTHDATA_ORDERBOOK']._serialized_end=325 38 | # @@protoc_insertion_point(module_scope) 39 | -------------------------------------------------------------------------------- /tigeropen/push/pb/QuoteDepthData_pb2.pyi: -------------------------------------------------------------------------------- 1 | from google.protobuf.internal import containers as _containers 2 | from google.protobuf import descriptor as _descriptor 3 | from google.protobuf import message as _message 4 | from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union 5 | 6 | DESCRIPTOR: _descriptor.FileDescriptor 7 | 8 | class QuoteDepthData(_message.Message): 9 | __slots__ = ("symbol", "timestamp", "ask", "bid") 10 | class OrderBook(_message.Message): 11 | __slots__ = ("price", "volume", "orderCount", "exchange", "time") 12 | PRICE_FIELD_NUMBER: _ClassVar[int] 13 | VOLUME_FIELD_NUMBER: _ClassVar[int] 14 | ORDERCOUNT_FIELD_NUMBER: _ClassVar[int] 15 | EXCHANGE_FIELD_NUMBER: _ClassVar[int] 16 | TIME_FIELD_NUMBER: _ClassVar[int] 17 | price: _containers.RepeatedScalarFieldContainer[float] 18 | volume: _containers.RepeatedScalarFieldContainer[int] 19 | orderCount: _containers.RepeatedScalarFieldContainer[int] 20 | exchange: _containers.RepeatedScalarFieldContainer[str] 21 | time: _containers.RepeatedScalarFieldContainer[int] 22 | def __init__(self, price: _Optional[_Iterable[float]] = ..., volume: _Optional[_Iterable[int]] = ..., orderCount: _Optional[_Iterable[int]] = ..., exchange: _Optional[_Iterable[str]] = ..., time: _Optional[_Iterable[int]] = ...) -> None: ... 23 | SYMBOL_FIELD_NUMBER: _ClassVar[int] 24 | TIMESTAMP_FIELD_NUMBER: _ClassVar[int] 25 | ASK_FIELD_NUMBER: _ClassVar[int] 26 | BID_FIELD_NUMBER: _ClassVar[int] 27 | symbol: str 28 | timestamp: int 29 | ask: QuoteDepthData.OrderBook 30 | bid: QuoteDepthData.OrderBook 31 | def __init__(self, symbol: _Optional[str] = ..., timestamp: _Optional[int] = ..., ask: _Optional[_Union[QuoteDepthData.OrderBook, _Mapping]] = ..., bid: _Optional[_Union[QuoteDepthData.OrderBook, _Mapping]] = ...) -> None: ... 32 | -------------------------------------------------------------------------------- /tigeropen/push/pb/Request.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | import public "tigeropen/push/pb/SocketCommon.proto"; 3 | 4 | package tigeropen.push.pb; 5 | 6 | message Request { 7 | SocketCommon.Command command = 1; 8 | uint32 id = 2; 9 | optional Subscribe subscribe = 3; 10 | optional Connect connect = 4; 11 | 12 | message Connect { 13 | string tigerId = 1; 14 | string sign = 2; 15 | string sdkVersion = 3; 16 | optional string acceptVersion = 4; 17 | optional uint32 sendInterval = 5; 18 | optional uint32 receiveInterval = 6; 19 | optional bool useFullTick = 7; 20 | } 21 | 22 | message Subscribe { 23 | SocketCommon.DataType dataType = 1; 24 | optional string symbols = 2; 25 | optional string account = 3; 26 | optional string market = 4; 27 | } 28 | } -------------------------------------------------------------------------------- /tigeropen/push/pb/Request_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # NO CHECKED-IN PROTOBUF GENCODE 4 | # source: tigeropen/push/pb/Request.proto 5 | # Protobuf Python Version: 5.28.3 6 | """Generated protocol buffer code.""" 7 | from google.protobuf import descriptor as _descriptor 8 | from google.protobuf import descriptor_pool as _descriptor_pool 9 | from google.protobuf import runtime_version as _runtime_version 10 | from google.protobuf import symbol_database as _symbol_database 11 | from google.protobuf.internal import builder as _builder 12 | _runtime_version.ValidateProtobufRuntimeVersion( 13 | _runtime_version.Domain.PUBLIC, 14 | 5, 15 | 28, 16 | 3, 17 | '', 18 | 'tigeropen/push/pb/Request.proto' 19 | ) 20 | # @@protoc_insertion_point(imports) 21 | 22 | _sym_db = _symbol_database.Default() 23 | 24 | 25 | from tigeropen.push.pb import SocketCommon_pb2 as tigeropen_dot_push_dot_pb_dot_SocketCommon__pb2 26 | 27 | from tigeropen.push.pb.SocketCommon_pb2 import * 28 | 29 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1ftigeropen/push/pb/Request.proto\x12\x11tigeropen.push.pb\x1a$tigeropen/push/pb/SocketCommon.proto\"\x84\x05\n\x07Request\x12\x38\n\x07\x63ommand\x18\x01 \x01(\x0e\x32\'.tigeropen.push.pb.SocketCommon.Command\x12\n\n\x02id\x18\x02 \x01(\r\x12<\n\tsubscribe\x18\x03 \x01(\x0b\x32$.tigeropen.push.pb.Request.SubscribeH\x00\x88\x01\x01\x12\x38\n\x07\x63onnect\x18\x04 \x01(\x0b\x32\".tigeropen.push.pb.Request.ConnectH\x01\x88\x01\x01\x1a\xf2\x01\n\x07\x43onnect\x12\x0f\n\x07tigerId\x18\x01 \x01(\t\x12\x0c\n\x04sign\x18\x02 \x01(\t\x12\x12\n\nsdkVersion\x18\x03 \x01(\t\x12\x1a\n\racceptVersion\x18\x04 \x01(\tH\x00\x88\x01\x01\x12\x19\n\x0csendInterval\x18\x05 \x01(\rH\x01\x88\x01\x01\x12\x1c\n\x0freceiveInterval\x18\x06 \x01(\rH\x02\x88\x01\x01\x12\x18\n\x0buseFullTick\x18\x07 \x01(\x08H\x03\x88\x01\x01\x42\x10\n\x0e_acceptVersionB\x0f\n\r_sendIntervalB\x12\n\x10_receiveIntervalB\x0e\n\x0c_useFullTick\x1a\xab\x01\n\tSubscribe\x12:\n\x08\x64\x61taType\x18\x01 \x01(\x0e\x32(.tigeropen.push.pb.SocketCommon.DataType\x12\x14\n\x07symbols\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x14\n\x07\x61\x63\x63ount\x18\x03 \x01(\tH\x01\x88\x01\x01\x12\x13\n\x06market\x18\x04 \x01(\tH\x02\x88\x01\x01\x42\n\n\x08_symbolsB\n\n\x08_accountB\t\n\x07_marketB\x0c\n\n_subscribeB\n\n\x08_connectP\x00\x62\x06proto3') 30 | 31 | _globals = globals() 32 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) 33 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tigeropen.push.pb.Request_pb2', _globals) 34 | if not _descriptor._USE_C_DESCRIPTORS: 35 | DESCRIPTOR._loaded_options = None 36 | _globals['_REQUEST']._serialized_start=93 37 | _globals['_REQUEST']._serialized_end=737 38 | _globals['_REQUEST_CONNECT']._serialized_start=295 39 | _globals['_REQUEST_CONNECT']._serialized_end=537 40 | _globals['_REQUEST_SUBSCRIBE']._serialized_start=540 41 | _globals['_REQUEST_SUBSCRIBE']._serialized_end=711 42 | # @@protoc_insertion_point(module_scope) 43 | -------------------------------------------------------------------------------- /tigeropen/push/pb/Request_pb2.pyi: -------------------------------------------------------------------------------- 1 | from tigeropen.push.pb import SocketCommon_pb2 as _SocketCommon_pb2 2 | from google.protobuf import descriptor as _descriptor 3 | from google.protobuf import message as _message 4 | from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union 5 | from tigeropen.push.pb.SocketCommon_pb2 import SocketCommon as SocketCommon 6 | 7 | DESCRIPTOR: _descriptor.FileDescriptor 8 | 9 | class Request(_message.Message): 10 | __slots__ = ("command", "id", "subscribe", "connect") 11 | class Connect(_message.Message): 12 | __slots__ = ("tigerId", "sign", "sdkVersion", "acceptVersion", "sendInterval", "receiveInterval", "useFullTick") 13 | TIGERID_FIELD_NUMBER: _ClassVar[int] 14 | SIGN_FIELD_NUMBER: _ClassVar[int] 15 | SDKVERSION_FIELD_NUMBER: _ClassVar[int] 16 | ACCEPTVERSION_FIELD_NUMBER: _ClassVar[int] 17 | SENDINTERVAL_FIELD_NUMBER: _ClassVar[int] 18 | RECEIVEINTERVAL_FIELD_NUMBER: _ClassVar[int] 19 | USEFULLTICK_FIELD_NUMBER: _ClassVar[int] 20 | tigerId: str 21 | sign: str 22 | sdkVersion: str 23 | acceptVersion: str 24 | sendInterval: int 25 | receiveInterval: int 26 | useFullTick: bool 27 | def __init__(self, tigerId: _Optional[str] = ..., sign: _Optional[str] = ..., sdkVersion: _Optional[str] = ..., acceptVersion: _Optional[str] = ..., sendInterval: _Optional[int] = ..., receiveInterval: _Optional[int] = ..., useFullTick: bool = ...) -> None: ... 28 | class Subscribe(_message.Message): 29 | __slots__ = ("dataType", "symbols", "account", "market") 30 | DATATYPE_FIELD_NUMBER: _ClassVar[int] 31 | SYMBOLS_FIELD_NUMBER: _ClassVar[int] 32 | ACCOUNT_FIELD_NUMBER: _ClassVar[int] 33 | MARKET_FIELD_NUMBER: _ClassVar[int] 34 | dataType: _SocketCommon_pb2.SocketCommon.DataType 35 | symbols: str 36 | account: str 37 | market: str 38 | def __init__(self, dataType: _Optional[_Union[_SocketCommon_pb2.SocketCommon.DataType, str]] = ..., symbols: _Optional[str] = ..., account: _Optional[str] = ..., market: _Optional[str] = ...) -> None: ... 39 | COMMAND_FIELD_NUMBER: _ClassVar[int] 40 | ID_FIELD_NUMBER: _ClassVar[int] 41 | SUBSCRIBE_FIELD_NUMBER: _ClassVar[int] 42 | CONNECT_FIELD_NUMBER: _ClassVar[int] 43 | command: _SocketCommon_pb2.SocketCommon.Command 44 | id: int 45 | subscribe: Request.Subscribe 46 | connect: Request.Connect 47 | def __init__(self, command: _Optional[_Union[_SocketCommon_pb2.SocketCommon.Command, str]] = ..., id: _Optional[int] = ..., subscribe: _Optional[_Union[Request.Subscribe, _Mapping]] = ..., connect: _Optional[_Union[Request.Connect, _Mapping]] = ...) -> None: ... 48 | -------------------------------------------------------------------------------- /tigeropen/push/pb/Response.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | import public "tigeropen/push/pb/SocketCommon.proto"; 3 | import public "tigeropen/push/pb/PushData.proto"; 4 | 5 | package tigeropen.push.pb; 6 | 7 | message Response { 8 | 9 | SocketCommon.Command command = 1; 10 | optional uint32 id = 2; // from request's id 11 | optional int32 code = 3;// command为MESSAGE时,code为111,112,113分别表示返回数据为获取所有订阅标的、订阅结果状态,取消订阅结果状态 12 | optional string msg = 4; 13 | optional PushData body = 5; 14 | 15 | } -------------------------------------------------------------------------------- /tigeropen/push/pb/Response_pb2.pyi: -------------------------------------------------------------------------------- 1 | from tigeropen.push.pb import SocketCommon_pb2 as _SocketCommon_pb2 2 | from tigeropen.push.pb import PushData_pb2 as _PushData_pb2 3 | from tigeropen.push.pb import SocketCommon_pb2 as _SocketCommon_pb2_1 4 | from tigeropen.push.pb import OrderStatusData_pb2 as _OrderStatusData_pb2 5 | from tigeropen.push.pb import PositionData_pb2 as _PositionData_pb2 6 | from tigeropen.push.pb import AssetData_pb2 as _AssetData_pb2 7 | from tigeropen.push.pb import QuoteData_pb2 as _QuoteData_pb2 8 | from tigeropen.push.pb import QuoteDepthData_pb2 as _QuoteDepthData_pb2 9 | from tigeropen.push.pb import TradeTickData_pb2 as _TradeTickData_pb2 10 | from tigeropen.push.pb import OrderTransactionData_pb2 as _OrderTransactionData_pb2 11 | from tigeropen.push.pb import StockTopData_pb2 as _StockTopData_pb2 12 | from tigeropen.push.pb import OptionTopData_pb2 as _OptionTopData_pb2 13 | from tigeropen.push.pb import KlineData_pb2 as _KlineData_pb2 14 | from tigeropen.push.pb import TickData_pb2 as _TickData_pb2 15 | from google.protobuf import descriptor as _descriptor 16 | from google.protobuf import message as _message 17 | from typing import ClassVar as _ClassVar, Mapping as _Mapping, Optional as _Optional, Union as _Union 18 | from tigeropen.push.pb.SocketCommon_pb2 import SocketCommon as SocketCommon 19 | from tigeropen.push.pb.PushData_pb2 import PushData as PushData 20 | 21 | DESCRIPTOR: _descriptor.FileDescriptor 22 | 23 | class Response(_message.Message): 24 | __slots__ = ("command", "id", "code", "msg", "body") 25 | COMMAND_FIELD_NUMBER: _ClassVar[int] 26 | ID_FIELD_NUMBER: _ClassVar[int] 27 | CODE_FIELD_NUMBER: _ClassVar[int] 28 | MSG_FIELD_NUMBER: _ClassVar[int] 29 | BODY_FIELD_NUMBER: _ClassVar[int] 30 | command: _SocketCommon_pb2_1.SocketCommon.Command 31 | id: int 32 | code: int 33 | msg: str 34 | body: _PushData_pb2.PushData 35 | def __init__(self, command: _Optional[_Union[_SocketCommon_pb2_1.SocketCommon.Command, str]] = ..., id: _Optional[int] = ..., code: _Optional[int] = ..., msg: _Optional[str] = ..., body: _Optional[_Union[_PushData_pb2.PushData, _Mapping]] = ...) -> None: ... 36 | -------------------------------------------------------------------------------- /tigeropen/push/pb/SocketCommon.proto: -------------------------------------------------------------------------------- 1 | 2 | syntax = "proto3"; 3 | 4 | package tigeropen.push.pb; 5 | 6 | message SocketCommon { 7 | // request and response command 8 | enum Command { 9 | UNKNOWN = 0; 10 | CONNECT = 1; 11 | CONNECTED = 2; 12 | SEND = 3; 13 | SUBSCRIBE = 4; 14 | UNSUBSCRIBE = 5; 15 | DISCONNECT = 6; 16 | MESSAGE = 7; 17 | HEARTBEAT = 8; 18 | ERROR = 9; 19 | } 20 | 21 | // data type 22 | enum DataType { 23 | Unknown = 0; 24 | Quote = 1; 25 | Option = 2; 26 | Future = 3; 27 | QuoteDepth = 4; 28 | TradeTick = 5; 29 | Asset = 6; 30 | Position = 7; 31 | OrderStatus = 8; 32 | OrderTransaction = 9; 33 | StockTop = 10; 34 | OptionTop = 11; 35 | Kline = 12; 36 | } 37 | 38 | enum QuoteType { 39 | None = 0; 40 | BASIC = 1; // basic quote data 41 | BBO = 2; // best bid and offer(include fields: askSize,askPrice,bidSize,bizePrice) 42 | ALL = 3; // include BASIC AND BBO 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /tigeropen/push/pb/SocketCommon_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # NO CHECKED-IN PROTOBUF GENCODE 4 | # source: tigeropen/push/pb/SocketCommon.proto 5 | # Protobuf Python Version: 5.28.3 6 | """Generated protocol buffer code.""" 7 | from google.protobuf import descriptor as _descriptor 8 | from google.protobuf import descriptor_pool as _descriptor_pool 9 | from google.protobuf import runtime_version as _runtime_version 10 | from google.protobuf import symbol_database as _symbol_database 11 | from google.protobuf.internal import builder as _builder 12 | _runtime_version.ValidateProtobufRuntimeVersion( 13 | _runtime_version.Domain.PUBLIC, 14 | 5, 15 | 28, 16 | 3, 17 | '', 18 | 'tigeropen/push/pb/SocketCommon.proto' 19 | ) 20 | # @@protoc_insertion_point(imports) 21 | 22 | _sym_db = _symbol_database.Default() 23 | 24 | 25 | 26 | 27 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$tigeropen/push/pb/SocketCommon.proto\x12\x11tigeropen.push.pb\"\x9c\x03\n\x0cSocketCommon\"\x93\x01\n\x07\x43ommand\x12\x0b\n\x07UNKNOWN\x10\x00\x12\x0b\n\x07\x43ONNECT\x10\x01\x12\r\n\tCONNECTED\x10\x02\x12\x08\n\x04SEND\x10\x03\x12\r\n\tSUBSCRIBE\x10\x04\x12\x0f\n\x0bUNSUBSCRIBE\x10\x05\x12\x0e\n\nDISCONNECT\x10\x06\x12\x0b\n\x07MESSAGE\x10\x07\x12\r\n\tHEARTBEAT\x10\x08\x12\t\n\x05\x45RROR\x10\t\"\xc1\x01\n\x08\x44\x61taType\x12\x0b\n\x07Unknown\x10\x00\x12\t\n\x05Quote\x10\x01\x12\n\n\x06Option\x10\x02\x12\n\n\x06\x46uture\x10\x03\x12\x0e\n\nQuoteDepth\x10\x04\x12\r\n\tTradeTick\x10\x05\x12\t\n\x05\x41sset\x10\x06\x12\x0c\n\x08Position\x10\x07\x12\x0f\n\x0bOrderStatus\x10\x08\x12\x14\n\x10OrderTransaction\x10\t\x12\x0c\n\x08StockTop\x10\n\x12\r\n\tOptionTop\x10\x0b\x12\t\n\x05Kline\x10\x0c\"2\n\tQuoteType\x12\x08\n\x04None\x10\x00\x12\t\n\x05\x42\x41SIC\x10\x01\x12\x07\n\x03\x42\x42O\x10\x02\x12\x07\n\x03\x41LL\x10\x03\x62\x06proto3') 28 | 29 | _globals = globals() 30 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) 31 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tigeropen.push.pb.SocketCommon_pb2', _globals) 32 | if not _descriptor._USE_C_DESCRIPTORS: 33 | DESCRIPTOR._loaded_options = None 34 | _globals['_SOCKETCOMMON']._serialized_start=60 35 | _globals['_SOCKETCOMMON']._serialized_end=472 36 | _globals['_SOCKETCOMMON_COMMAND']._serialized_start=77 37 | _globals['_SOCKETCOMMON_COMMAND']._serialized_end=224 38 | _globals['_SOCKETCOMMON_DATATYPE']._serialized_start=227 39 | _globals['_SOCKETCOMMON_DATATYPE']._serialized_end=420 40 | _globals['_SOCKETCOMMON_QUOTETYPE']._serialized_start=422 41 | _globals['_SOCKETCOMMON_QUOTETYPE']._serialized_end=472 42 | # @@protoc_insertion_point(module_scope) 43 | -------------------------------------------------------------------------------- /tigeropen/push/pb/StockTopData.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package tigeropen.push.pb; 4 | 5 | message StockTopData { 6 | string market = 1; 7 | int64 timestamp = 2; 8 | repeated TopData topData = 3; 9 | 10 | message TopData { 11 | string targetName = 1; // changeRate, changeRate5Min, turnoverRate, amount, volume, amplitude 12 | repeated StockItem item = 2; 13 | } 14 | 15 | message StockItem { 16 | string symbol = 1; 17 | double latestPrice = 2; 18 | double targetValue = 3; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tigeropen/push/pb/StockTopData_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # NO CHECKED-IN PROTOBUF GENCODE 4 | # source: tigeropen/push/pb/StockTopData.proto 5 | # Protobuf Python Version: 5.28.3 6 | """Generated protocol buffer code.""" 7 | from google.protobuf import descriptor as _descriptor 8 | from google.protobuf import descriptor_pool as _descriptor_pool 9 | from google.protobuf import runtime_version as _runtime_version 10 | from google.protobuf import symbol_database as _symbol_database 11 | from google.protobuf.internal import builder as _builder 12 | _runtime_version.ValidateProtobufRuntimeVersion( 13 | _runtime_version.Domain.PUBLIC, 14 | 5, 15 | 28, 16 | 3, 17 | '', 18 | 'tigeropen/push/pb/StockTopData.proto' 19 | ) 20 | # @@protoc_insertion_point(imports) 21 | 22 | _sym_db = _symbol_database.Default() 23 | 24 | 25 | 26 | 27 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n$tigeropen/push/pb/StockTopData.proto\x12\x11tigeropen.push.pb\"\x8a\x02\n\x0cStockTopData\x12\x0e\n\x06market\x18\x01 \x01(\t\x12\x11\n\ttimestamp\x18\x02 \x01(\x03\x12\x38\n\x07topData\x18\x03 \x03(\x0b\x32\'.tigeropen.push.pb.StockTopData.TopData\x1aV\n\x07TopData\x12\x12\n\ntargetName\x18\x01 \x01(\t\x12\x37\n\x04item\x18\x02 \x03(\x0b\x32).tigeropen.push.pb.StockTopData.StockItem\x1a\x45\n\tStockItem\x12\x0e\n\x06symbol\x18\x01 \x01(\t\x12\x13\n\x0blatestPrice\x18\x02 \x01(\x01\x12\x13\n\x0btargetValue\x18\x03 \x01(\x01\x62\x06proto3') 28 | 29 | _globals = globals() 30 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) 31 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tigeropen.push.pb.StockTopData_pb2', _globals) 32 | if not _descriptor._USE_C_DESCRIPTORS: 33 | DESCRIPTOR._loaded_options = None 34 | _globals['_STOCKTOPDATA']._serialized_start=60 35 | _globals['_STOCKTOPDATA']._serialized_end=326 36 | _globals['_STOCKTOPDATA_TOPDATA']._serialized_start=169 37 | _globals['_STOCKTOPDATA_TOPDATA']._serialized_end=255 38 | _globals['_STOCKTOPDATA_STOCKITEM']._serialized_start=257 39 | _globals['_STOCKTOPDATA_STOCKITEM']._serialized_end=326 40 | # @@protoc_insertion_point(module_scope) 41 | -------------------------------------------------------------------------------- /tigeropen/push/pb/StockTopData_pb2.pyi: -------------------------------------------------------------------------------- 1 | from google.protobuf.internal import containers as _containers 2 | from google.protobuf import descriptor as _descriptor 3 | from google.protobuf import message as _message 4 | from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union 5 | 6 | DESCRIPTOR: _descriptor.FileDescriptor 7 | 8 | class StockTopData(_message.Message): 9 | __slots__ = ("market", "timestamp", "topData") 10 | class TopData(_message.Message): 11 | __slots__ = ("targetName", "item") 12 | TARGETNAME_FIELD_NUMBER: _ClassVar[int] 13 | ITEM_FIELD_NUMBER: _ClassVar[int] 14 | targetName: str 15 | item: _containers.RepeatedCompositeFieldContainer[StockTopData.StockItem] 16 | def __init__(self, targetName: _Optional[str] = ..., item: _Optional[_Iterable[_Union[StockTopData.StockItem, _Mapping]]] = ...) -> None: ... 17 | class StockItem(_message.Message): 18 | __slots__ = ("symbol", "latestPrice", "targetValue") 19 | SYMBOL_FIELD_NUMBER: _ClassVar[int] 20 | LATESTPRICE_FIELD_NUMBER: _ClassVar[int] 21 | TARGETVALUE_FIELD_NUMBER: _ClassVar[int] 22 | symbol: str 23 | latestPrice: float 24 | targetValue: float 25 | def __init__(self, symbol: _Optional[str] = ..., latestPrice: _Optional[float] = ..., targetValue: _Optional[float] = ...) -> None: ... 26 | MARKET_FIELD_NUMBER: _ClassVar[int] 27 | TIMESTAMP_FIELD_NUMBER: _ClassVar[int] 28 | TOPDATA_FIELD_NUMBER: _ClassVar[int] 29 | market: str 30 | timestamp: int 31 | topData: _containers.RepeatedCompositeFieldContainer[StockTopData.TopData] 32 | def __init__(self, market: _Optional[str] = ..., timestamp: _Optional[int] = ..., topData: _Optional[_Iterable[_Union[StockTopData.TopData, _Mapping]]] = ...) -> None: ... 33 | -------------------------------------------------------------------------------- /tigeropen/push/pb/TickData.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package tigeropen.push.pb; 3 | 4 | message TickData { 5 | string symbol = 1; 6 | repeated Tick ticks = 2; 7 | int64 timestamp = 3; 8 | string source = 4; // data source (Optional) 9 | 10 | message Tick { 11 | int64 sn = 1; // The order in which upstream data arrives, for reference only. 12 | int64 time = 2; // Execution time of transaction. 13位的时间戳 13 | float price = 3; // Transaction price. 14 | int32 volume = 4; // Transaction volume. 15 | string type = 5; // buy/sell direction. Active buy(+); Active sell(-); Neutral transaction(*) 16 | string cond = 6; // The trade condition for irregular transaction. (Optional) 17 | string partCode = 7; // The market participant reports the transaction. (Optional) 18 | } 19 | } -------------------------------------------------------------------------------- /tigeropen/push/pb/TickData_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # NO CHECKED-IN PROTOBUF GENCODE 4 | # source: tigeropen/push/pb/TickData.proto 5 | # Protobuf Python Version: 5.28.3 6 | """Generated protocol buffer code.""" 7 | from google.protobuf import descriptor as _descriptor 8 | from google.protobuf import descriptor_pool as _descriptor_pool 9 | from google.protobuf import runtime_version as _runtime_version 10 | from google.protobuf import symbol_database as _symbol_database 11 | from google.protobuf.internal import builder as _builder 12 | _runtime_version.ValidateProtobufRuntimeVersion( 13 | _runtime_version.Domain.PUBLIC, 14 | 5, 15 | 28, 16 | 3, 17 | '', 18 | 'tigeropen/push/pb/TickData.proto' 19 | ) 20 | # @@protoc_insertion_point(imports) 21 | 22 | _sym_db = _symbol_database.Default() 23 | 24 | 25 | 26 | 27 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n tigeropen/push/pb/TickData.proto\x12\x11tigeropen.push.pb\"\xdd\x01\n\x08TickData\x12\x0e\n\x06symbol\x18\x01 \x01(\t\x12/\n\x05ticks\x18\x02 \x03(\x0b\x32 .tigeropen.push.pb.TickData.Tick\x12\x11\n\ttimestamp\x18\x03 \x01(\x03\x12\x0e\n\x06source\x18\x04 \x01(\t\x1am\n\x04Tick\x12\n\n\x02sn\x18\x01 \x01(\x03\x12\x0c\n\x04time\x18\x02 \x01(\x03\x12\r\n\x05price\x18\x03 \x01(\x02\x12\x0e\n\x06volume\x18\x04 \x01(\x05\x12\x0c\n\x04type\x18\x05 \x01(\t\x12\x0c\n\x04\x63ond\x18\x06 \x01(\t\x12\x10\n\x08partCode\x18\x07 \x01(\tb\x06proto3') 28 | 29 | _globals = globals() 30 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) 31 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tigeropen.push.pb.TickData_pb2', _globals) 32 | if not _descriptor._USE_C_DESCRIPTORS: 33 | DESCRIPTOR._loaded_options = None 34 | _globals['_TICKDATA']._serialized_start=56 35 | _globals['_TICKDATA']._serialized_end=277 36 | _globals['_TICKDATA_TICK']._serialized_start=168 37 | _globals['_TICKDATA_TICK']._serialized_end=277 38 | # @@protoc_insertion_point(module_scope) 39 | -------------------------------------------------------------------------------- /tigeropen/push/pb/TickData_pb2.pyi: -------------------------------------------------------------------------------- 1 | from google.protobuf.internal import containers as _containers 2 | from google.protobuf import descriptor as _descriptor 3 | from google.protobuf import message as _message 4 | from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union 5 | 6 | DESCRIPTOR: _descriptor.FileDescriptor 7 | 8 | class TickData(_message.Message): 9 | __slots__ = ("symbol", "ticks", "timestamp", "source") 10 | class Tick(_message.Message): 11 | __slots__ = ("sn", "time", "price", "volume", "type", "cond", "partCode") 12 | SN_FIELD_NUMBER: _ClassVar[int] 13 | TIME_FIELD_NUMBER: _ClassVar[int] 14 | PRICE_FIELD_NUMBER: _ClassVar[int] 15 | VOLUME_FIELD_NUMBER: _ClassVar[int] 16 | TYPE_FIELD_NUMBER: _ClassVar[int] 17 | COND_FIELD_NUMBER: _ClassVar[int] 18 | PARTCODE_FIELD_NUMBER: _ClassVar[int] 19 | sn: int 20 | time: int 21 | price: float 22 | volume: int 23 | type: str 24 | cond: str 25 | partCode: str 26 | def __init__(self, sn: _Optional[int] = ..., time: _Optional[int] = ..., price: _Optional[float] = ..., volume: _Optional[int] = ..., type: _Optional[str] = ..., cond: _Optional[str] = ..., partCode: _Optional[str] = ...) -> None: ... 27 | SYMBOL_FIELD_NUMBER: _ClassVar[int] 28 | TICKS_FIELD_NUMBER: _ClassVar[int] 29 | TIMESTAMP_FIELD_NUMBER: _ClassVar[int] 30 | SOURCE_FIELD_NUMBER: _ClassVar[int] 31 | symbol: str 32 | ticks: _containers.RepeatedCompositeFieldContainer[TickData.Tick] 33 | timestamp: int 34 | source: str 35 | def __init__(self, symbol: _Optional[str] = ..., ticks: _Optional[_Iterable[_Union[TickData.Tick, _Mapping]]] = ..., timestamp: _Optional[int] = ..., source: _Optional[str] = ...) -> None: ... 36 | -------------------------------------------------------------------------------- /tigeropen/push/pb/TradeTickData.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package tigeropen.push.pb; 4 | 5 | 6 | message TradeTickData { 7 | string symbol = 1; 8 | string type = 2; // tick type 逐笔方向(+-* 组成的字符串)(Futures are not supported) 9 | string cond = 3; // 成交条件(该值为空时表示所有成交都是正常成交)(Futures are not supported) 10 | int64 sn = 4; // 首个逐笔对应的序号 11 | int64 priceBase = 5; 12 | int32 priceOffset = 6; 13 | repeated int64 time = 7; // 压缩后的成交时间,恢复为原时间信息 time[i] = time[i] + time[i-1] 14 | repeated int64 price = 8; // 压缩后的成交价格,恢复为原始价格信息 price[i] = (priceBase + price[i]) / 10^priceOffset 15 | repeated int64 volume = 9; // 原始的成交量 16 | repeated string partCode = 10; // 交易所代码,一般是 a ~ z 字符(Futures are not supported) 17 | string quoteLevel = 11; // (Futures are not supported) 18 | uint64 timestamp = 12; 19 | 20 | string secType = 13; // STK Stocks, FUT Futures 21 | repeated MergedVol mergedVols = 14; // 原始合并次数(Only futures are supported) 22 | message MergedVol { 23 | int32 mergeTimes = 1; // 原始合并次数 24 | repeated int64 vol = 2; // 原始合并的成交量 25 | } 26 | } -------------------------------------------------------------------------------- /tigeropen/push/pb/TradeTickData_pb2.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by the protocol buffer compiler. DO NOT EDIT! 3 | # NO CHECKED-IN PROTOBUF GENCODE 4 | # source: tigeropen/push/pb/TradeTickData.proto 5 | # Protobuf Python Version: 5.28.3 6 | """Generated protocol buffer code.""" 7 | from google.protobuf import descriptor as _descriptor 8 | from google.protobuf import descriptor_pool as _descriptor_pool 9 | from google.protobuf import runtime_version as _runtime_version 10 | from google.protobuf import symbol_database as _symbol_database 11 | from google.protobuf.internal import builder as _builder 12 | _runtime_version.ValidateProtobufRuntimeVersion( 13 | _runtime_version.Domain.PUBLIC, 14 | 5, 15 | 28, 16 | 3, 17 | '', 18 | 'tigeropen/push/pb/TradeTickData.proto' 19 | ) 20 | # @@protoc_insertion_point(imports) 21 | 22 | _sym_db = _symbol_database.Default() 23 | 24 | 25 | 26 | 27 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n%tigeropen/push/pb/TradeTickData.proto\x12\x11tigeropen.push.pb\"\xd4\x02\n\rTradeTickData\x12\x0e\n\x06symbol\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0c\n\x04\x63ond\x18\x03 \x01(\t\x12\n\n\x02sn\x18\x04 \x01(\x03\x12\x11\n\tpriceBase\x18\x05 \x01(\x03\x12\x13\n\x0bpriceOffset\x18\x06 \x01(\x05\x12\x0c\n\x04time\x18\x07 \x03(\x03\x12\r\n\x05price\x18\x08 \x03(\x03\x12\x0e\n\x06volume\x18\t \x03(\x03\x12\x10\n\x08partCode\x18\n \x03(\t\x12\x12\n\nquoteLevel\x18\x0b \x01(\t\x12\x11\n\ttimestamp\x18\x0c \x01(\x04\x12\x0f\n\x07secType\x18\r \x01(\t\x12>\n\nmergedVols\x18\x0e \x03(\x0b\x32*.tigeropen.push.pb.TradeTickData.MergedVol\x1a,\n\tMergedVol\x12\x12\n\nmergeTimes\x18\x01 \x01(\x05\x12\x0b\n\x03vol\x18\x02 \x03(\x03\x62\x06proto3') 28 | 29 | _globals = globals() 30 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals) 31 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'tigeropen.push.pb.TradeTickData_pb2', _globals) 32 | if not _descriptor._USE_C_DESCRIPTORS: 33 | DESCRIPTOR._loaded_options = None 34 | _globals['_TRADETICKDATA']._serialized_start=61 35 | _globals['_TRADETICKDATA']._serialized_end=401 36 | _globals['_TRADETICKDATA_MERGEDVOL']._serialized_start=357 37 | _globals['_TRADETICKDATA_MERGEDVOL']._serialized_end=401 38 | # @@protoc_insertion_point(module_scope) 39 | -------------------------------------------------------------------------------- /tigeropen/push/pb/TradeTickData_pb2.pyi: -------------------------------------------------------------------------------- 1 | from google.protobuf.internal import containers as _containers 2 | from google.protobuf import descriptor as _descriptor 3 | from google.protobuf import message as _message 4 | from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union 5 | 6 | DESCRIPTOR: _descriptor.FileDescriptor 7 | 8 | class TradeTickData(_message.Message): 9 | __slots__ = ("symbol", "type", "cond", "sn", "priceBase", "priceOffset", "time", "price", "volume", "partCode", "quoteLevel", "timestamp", "secType", "mergedVols") 10 | class MergedVol(_message.Message): 11 | __slots__ = ("mergeTimes", "vol") 12 | MERGETIMES_FIELD_NUMBER: _ClassVar[int] 13 | VOL_FIELD_NUMBER: _ClassVar[int] 14 | mergeTimes: int 15 | vol: _containers.RepeatedScalarFieldContainer[int] 16 | def __init__(self, mergeTimes: _Optional[int] = ..., vol: _Optional[_Iterable[int]] = ...) -> None: ... 17 | SYMBOL_FIELD_NUMBER: _ClassVar[int] 18 | TYPE_FIELD_NUMBER: _ClassVar[int] 19 | COND_FIELD_NUMBER: _ClassVar[int] 20 | SN_FIELD_NUMBER: _ClassVar[int] 21 | PRICEBASE_FIELD_NUMBER: _ClassVar[int] 22 | PRICEOFFSET_FIELD_NUMBER: _ClassVar[int] 23 | TIME_FIELD_NUMBER: _ClassVar[int] 24 | PRICE_FIELD_NUMBER: _ClassVar[int] 25 | VOLUME_FIELD_NUMBER: _ClassVar[int] 26 | PARTCODE_FIELD_NUMBER: _ClassVar[int] 27 | QUOTELEVEL_FIELD_NUMBER: _ClassVar[int] 28 | TIMESTAMP_FIELD_NUMBER: _ClassVar[int] 29 | SECTYPE_FIELD_NUMBER: _ClassVar[int] 30 | MERGEDVOLS_FIELD_NUMBER: _ClassVar[int] 31 | symbol: str 32 | type: str 33 | cond: str 34 | sn: int 35 | priceBase: int 36 | priceOffset: int 37 | time: _containers.RepeatedScalarFieldContainer[int] 38 | price: _containers.RepeatedScalarFieldContainer[int] 39 | volume: _containers.RepeatedScalarFieldContainer[int] 40 | partCode: _containers.RepeatedScalarFieldContainer[str] 41 | quoteLevel: str 42 | timestamp: int 43 | secType: str 44 | mergedVols: _containers.RepeatedCompositeFieldContainer[TradeTickData.MergedVol] 45 | def __init__(self, symbol: _Optional[str] = ..., type: _Optional[str] = ..., cond: _Optional[str] = ..., sn: _Optional[int] = ..., priceBase: _Optional[int] = ..., priceOffset: _Optional[int] = ..., time: _Optional[_Iterable[int]] = ..., price: _Optional[_Iterable[int]] = ..., volume: _Optional[_Iterable[int]] = ..., partCode: _Optional[_Iterable[str]] = ..., quoteLevel: _Optional[str] = ..., timestamp: _Optional[int] = ..., secType: _Optional[str] = ..., mergedVols: _Optional[_Iterable[_Union[TradeTickData.MergedVol, _Mapping]]] = ...) -> None: ... 46 | -------------------------------------------------------------------------------- /tigeropen/push/pb/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | # disable protobuf version check 4 | os.environ.setdefault('TEMORARILY_DISABLE_PROTOBUF_VERSION_CHECK', 'true') 5 | -------------------------------------------------------------------------------- /tigeropen/push/pb/readme.md: -------------------------------------------------------------------------------- 1 | # generate proto 2 | ``` 3 | cd openapi-python-sdk 4 | protoc --proto_path=. --python_out=. --pyi_out=. tigeropen/push/pb/*.proto 5 | ``` 6 | -------------------------------------------------------------------------------- /tigeropen/push/pb/trade_tick.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2023/6/1 4 | # @Author : sukai 5 | class TradeTickItem: 6 | def __int__(self): 7 | self.tick_type = None 8 | self.price = None 9 | self.volume = None 10 | self.part_code = None 11 | self.part_code_name = None 12 | self.cond = None 13 | self.time = None 14 | self.sn = None 15 | 16 | def __repr__(self): 17 | return f'TradeTickItem<{self.__dict__}>' 18 | 19 | class TradeTick: 20 | def __int__(self): 21 | self.symbol = None 22 | self.sec_type = None 23 | self.quote_level = None 24 | self.timestamp = None 25 | self.ticks = None 26 | 27 | def __repr__(self): 28 | return f'TradeTick<{self.__dict__}>' -------------------------------------------------------------------------------- /tigeropen/quote/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ -------------------------------------------------------------------------------- /tigeropen/quote/domain/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ -------------------------------------------------------------------------------- /tigeropen/quote/domain/bar.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | 8 | 9 | class Bar: 10 | def __init__(self): 11 | self.time = None 12 | self.open = None 13 | self.high = None 14 | self.low = None 15 | self.close = None 16 | self.volume = None 17 | 18 | def __repr__(self): 19 | """ 20 | String representation for this object. 21 | """ 22 | return "Bar(%s)" % self.__dict__ 23 | -------------------------------------------------------------------------------- /tigeropen/quote/domain/capital_distribution.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2022/12/9 4 | # @Author : sukai 5 | class CapitalDistribution: 6 | def __init__(self): 7 | self.symbol = None 8 | self.net_inflow = None 9 | self.in_all = None 10 | self.in_big = None 11 | self.in_mid = None 12 | self.in_small = None 13 | self.out_all = None 14 | self.out_big = None 15 | self.out_mid = None 16 | self.out_small = None 17 | 18 | def __repr__(self): 19 | return "CapitalDistribution(%s)" % self.__dict__ 20 | -------------------------------------------------------------------------------- /tigeropen/quote/domain/market_status.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | 8 | 9 | class MarketStatus: 10 | def __init__(self, market, status, open_time, trading_status): 11 | self.market = market 12 | self.status = status 13 | self.open_time = open_time 14 | self.trading_status = trading_status 15 | 16 | def __repr__(self): 17 | """ 18 | String representation for this object. 19 | """ 20 | return "MarketStatus(%s)" % self.__dict__ 21 | -------------------------------------------------------------------------------- /tigeropen/quote/domain/quote_brief.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | 8 | 9 | class HourTrading: 10 | def __init__(self): 11 | self.trading_session = None # 盘前/盘后 12 | self.latest_price = None # 最新价 13 | self.prev_close = None # 昨日收盘价 14 | self.latest_time = None # 最后交易时间 15 | self.volume = None # 成交量 16 | 17 | self.open_price = None # 开盘价 18 | self.high_price = None # 最高价 19 | self.low_price = None # 最低价 20 | self.change = None # 涨跌额 21 | 22 | def __repr__(self): 23 | """ 24 | String representation for this object. 25 | """ 26 | return "HourTrading(%s)" % self.__dict__ 27 | 28 | 29 | class QuoteBrief: 30 | def __init__(self): 31 | # contract info 32 | self.symbol = None # 股票代号 33 | self.market = None # 市场代号 34 | self.name = None # 股票名称 35 | self.sec_type = None # STK 股票, OPT 期权,WAR窝轮,IOPT牛熊证, FUT期货 36 | 37 | self.latest_price = None # 最新价 38 | self.prev_close = None # 昨日收盘价 39 | self.latest_time = None # 最后交易时间 40 | self.volume = None # 成交量 41 | 42 | self.open_price = None # 开盘价 43 | self.high_price = None # 最高价 44 | self.low_price = None # 最低价 45 | self.change = None # 涨跌额 46 | 47 | self.bid_price = None # 卖盘价 48 | self.bid_size = None # 卖盘数量 49 | self.ask_price = None # 买盘价 50 | self.ask_size = None # 买盘数量 51 | 52 | self.halted = None # 是否停牌 0: 正常,3: 停牌,4: 退市 53 | self.delay = None # 延时分钟 54 | self.auction = None # 是否竞价时段(仅港股) 55 | self.expiry = None # 到期时间(仅港股) 56 | 57 | self.hour_trading = None # 盘前盘后数据,可能为空(仅美股 58 | 59 | def __repr__(self): 60 | return "QuoteBrief(%s)" % self.__dict__ 61 | -------------------------------------------------------------------------------- /tigeropen/quote/domain/stock_broker.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2022/12/9 4 | # @Author : sukai 5 | 6 | class Broker: 7 | def __init__(self): 8 | self.id = None 9 | self.name = None 10 | 11 | def __repr__(self): 12 | return "Broker(%s)" % self.__dict__ 13 | 14 | 15 | class LevelBroker: 16 | def __init__(self): 17 | self.level = None 18 | self.price = None 19 | self.broker_count = None 20 | self.broker = None 21 | 22 | def __repr__(self): 23 | return "LevelBroker(%s)" % self.__dict__ 24 | 25 | 26 | class StockBroker: 27 | def __init__(self): 28 | self.symbol = None 29 | self.bid_broker = None 30 | self.ask_broker = None 31 | 32 | def __repr__(self): 33 | return "StockBroker(%s)" % self.__dict__ 34 | -------------------------------------------------------------------------------- /tigeropen/quote/domain/tick.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | 8 | 9 | class TradeTick: 10 | def __init__(self): 11 | self.index = None 12 | self.timestamp = None 13 | self.price = None 14 | self.size = None 15 | self.direction = None 16 | 17 | def __repr__(self): 18 | return "TradeTick(%s)" % self.__dict__ 19 | -------------------------------------------------------------------------------- /tigeropen/quote/domain/timeline.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | 8 | 9 | class Timeline: 10 | def __init__(self): 11 | self.latest_time = None 12 | self.price = None 13 | self.avg_price = None 14 | self.volume = None 15 | 16 | def __repr__(self): 17 | return "Timeline(%s)" % self.__dict__ 18 | -------------------------------------------------------------------------------- /tigeropen/quote/request/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/9/20 4 | 5 | @author: gaoan 6 | """ 7 | 8 | 9 | -------------------------------------------------------------------------------- /tigeropen/quote/response/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ -------------------------------------------------------------------------------- /tigeropen/quote/response/capital_distribution_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2022-12-09 4 | # @Author : sukai 5 | from tigeropen.common.response import TigerResponse 6 | from tigeropen.common.util import string_utils 7 | from tigeropen.quote.domain.capital_distribution import CapitalDistribution 8 | 9 | 10 | class CapitalDistributionResponse(TigerResponse): 11 | def __init__(self): 12 | super().__init__() 13 | self.result = None 14 | self._is_success = None 15 | 16 | def parse_response_content(self, response_content): 17 | response = super().parse_response_content(response_content) 18 | if 'is_success' in response: 19 | self._is_success = response['is_success'] 20 | 21 | if self.data: 22 | capital_distribution = CapitalDistribution() 23 | capital_distribution.__dict__ = string_utils.camel_to_underline_obj(self.data) 24 | self.result = capital_distribution -------------------------------------------------------------------------------- /tigeropen/quote/response/capital_flow_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2022-12-09 4 | # @Author : sukai 5 | import pandas as pd 6 | 7 | from tigeropen.common.response import TigerResponse 8 | from tigeropen.common.util import string_utils 9 | 10 | 11 | class CapitalFlowResponse(TigerResponse): 12 | def __init__(self): 13 | super().__init__() 14 | self.result = None 15 | self._is_success = None 16 | 17 | def parse_response_content(self, response_content): 18 | response = super().parse_response_content(response_content) 19 | if 'is_success' in response: 20 | self._is_success = response['is_success'] 21 | 22 | if self.data: 23 | data = string_utils.camel_to_underline_obj(self.data) 24 | df = pd.DataFrame(data.get('items')) 25 | df['symbol'] = data.get('symbol') 26 | df['period'] = data.get('period') 27 | self.result = df -------------------------------------------------------------------------------- /tigeropen/quote/response/fund_contracts_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2022/4/13 4 | # @Author : sukai 5 | 6 | import pandas as pd 7 | 8 | from tigeropen.common.response import TigerResponse 9 | from tigeropen.common.util.string_utils import camel_to_underline 10 | 11 | 12 | 13 | class FundContractsResponse(TigerResponse): 14 | def __init__(self): 15 | super(FundContractsResponse, self).__init__() 16 | self.result = None 17 | self._is_success = None 18 | 19 | def parse_response_content(self, response_content): 20 | response = super(FundContractsResponse, self).parse_response_content(response_content) 21 | if 'is_success' in response: 22 | self._is_success = response['is_success'] 23 | 24 | if self.data and isinstance(self.data, list): 25 | fields = self.data[0].keys() 26 | fields_map = {origin: camel_to_underline(origin) for origin in fields} 27 | df = pd.DataFrame(self.data) 28 | self.result = df.rename(columns=fields_map) 29 | -------------------------------------------------------------------------------- /tigeropen/quote/response/future_briefs_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | import pandas as pd 8 | 9 | from tigeropen.common.response import TigerResponse 10 | 11 | COLUMNS = ['identifier', 'ask_price', 'ask_size', 'bid_price', 'bid_size', 'pre_close', 'latest_price', 'latest_size', 12 | 'latest_time', 'volume', 'open_interest', 'open', 'high', 'low', 'limit_up', 'limit_down', 'settlement', 13 | 'settle_date'] 14 | BRIEF_FIELD_MAPPINGS = {'askPrice': 'ask_price', 'askSize': 'ask_size', 'bidPrice': 'bid_price', 'bidSize': 'bid_size', 15 | 'latestPrice': 'latest_price', 'openInterest': 'open_interest', 'preClose': 'pre_close', 16 | 'right': 'put_call', 'latestTime': 'latest_time', 'latestSize': 'latest_size', 17 | 'limitUp': 'limit_up', 'limitDown': 'limit_down', 'contractCode': 'identifier', 18 | 'settleDate': 'settle_date'} 19 | 20 | 21 | class FutureBriefsResponse(TigerResponse): 22 | def __init__(self): 23 | super(FutureBriefsResponse, self).__init__() 24 | self.briefs = None 25 | self._is_success = None 26 | 27 | def parse_response_content(self, response_content): 28 | response = super(FutureBriefsResponse, self).parse_response_content(response_content) 29 | if 'is_success' in response: 30 | self._is_success = response['is_success'] 31 | 32 | brief_data = [] 33 | if self.data and isinstance(self.data, list): 34 | for item in self.data: 35 | item_values = {} 36 | for key, value in item.items(): 37 | if value is None: 38 | continue 39 | tag = BRIEF_FIELD_MAPPINGS[key] if key in BRIEF_FIELD_MAPPINGS else key 40 | item_values[tag] = value 41 | brief_data.append([item_values.get(tag) for tag in COLUMNS]) 42 | elif isinstance(self.data, dict): 43 | item_values = {} 44 | for key, value in self.data.items(): 45 | if value is None: 46 | continue 47 | tag = BRIEF_FIELD_MAPPINGS[key] if key in BRIEF_FIELD_MAPPINGS else key 48 | item_values[tag] = value 49 | brief_data.append([item_values.get(tag) for tag in COLUMNS]) 50 | 51 | self.briefs = pd.DataFrame(brief_data, columns=COLUMNS) 52 | -------------------------------------------------------------------------------- /tigeropen/quote/response/future_contract_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | import pandas as pd 8 | 9 | from tigeropen.common.response import TigerResponse 10 | from tigeropen.common.util import string_utils 11 | 12 | CONTRACT_FIELD_MAPPINGS = {'ibCode': 'symbol'} 13 | MAIN_CONTRACT_CODE_SUFFIX = 'main' 14 | CONTRACT_CODE_COLUMN = 'contract_code' 15 | 16 | 17 | class FutureContractResponse(TigerResponse): 18 | def __init__(self): 19 | super(FutureContractResponse, self).__init__() 20 | self.contracts = pd.DataFrame() 21 | self._is_success = None 22 | 23 | def parse_response_content(self, response_content, skip_main=True): 24 | response = super(FutureContractResponse, self).parse_response_content(response_content) 25 | if 'is_success' in response: 26 | self._is_success = response['is_success'] 27 | 28 | if self.data: 29 | if isinstance(self.data, list): 30 | self.contracts = pd.DataFrame(self.data) 31 | elif isinstance(self.data, dict): 32 | self.contracts = pd.DataFrame([self.data]) 33 | 34 | column_map = dict() 35 | for key in self.contracts.columns: 36 | column_map[key] = CONTRACT_FIELD_MAPPINGS.get(key, string_utils.camel_to_underline(key)) 37 | 38 | self.contracts = self.contracts.rename(columns=column_map) 39 | 40 | # 重新排列列,将 contract_code 作为第一列,其余列按字母排序 41 | remaining_columns = sorted([col for col in self.contracts.columns if col != CONTRACT_CODE_COLUMN]) 42 | all_columns = [CONTRACT_CODE_COLUMN] + remaining_columns 43 | self.contracts = self.contracts.reindex(columns=all_columns) 44 | 45 | -------------------------------------------------------------------------------- /tigeropen/quote/response/future_exchange_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | import pandas as pd 8 | 9 | from tigeropen.common.response import TigerResponse 10 | 11 | 12 | class FutureExchangeResponse(TigerResponse): 13 | def __init__(self): 14 | super(FutureExchangeResponse, self).__init__() 15 | self.exchanges = None 16 | self._is_success = None 17 | 18 | def parse_response_content(self, response_content): 19 | response = super(FutureExchangeResponse, self).parse_response_content(response_content) 20 | if 'is_success' in response: 21 | self._is_success = response['is_success'] 22 | 23 | if self.data and isinstance(self.data, list): 24 | items = [] 25 | for item in self.data: 26 | code, name, zone = None, None, None 27 | for key, value in item.items(): 28 | if value is None: 29 | continue 30 | if key == 'code': 31 | code = value 32 | elif key == 'name': 33 | name = value 34 | elif key == 'zoneId': 35 | zone = value 36 | items.append([code, name, zone]) 37 | self.exchanges = pd.DataFrame(items, columns=['code', 'name', 'zone']) 38 | -------------------------------------------------------------------------------- /tigeropen/quote/response/future_quote_bar_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | import pandas as pd 8 | 9 | from tigeropen.common.response import TigerResponse 10 | 11 | COLUMNS = ['identifier', 'time', 'latest_time', 'open', 'high', 'low', 'close', 'settlement', 'volume', 12 | 'open_interest', 'next_page_token'] 13 | BAR_FIELD_MAPPINGS = {'avgPrice': 'avg_price', 'openInterest': 'open_interest', 'lastTime': 'latest_time'} 14 | 15 | 16 | class FutureQuoteBarResponse(TigerResponse): 17 | def __init__(self): 18 | super(FutureQuoteBarResponse, self).__init__() 19 | self.bars = pd.DataFrame(columns=COLUMNS) 20 | self._is_success = None 21 | 22 | def parse_response_content(self, response_content): 23 | response = super(FutureQuoteBarResponse, self).parse_response_content(response_content) 24 | if 'is_success' in response: 25 | self._is_success = response['is_success'] 26 | 27 | if self.data and isinstance(self.data, list): 28 | bar_items = [] 29 | for symbol_item in self.data: 30 | identifier = symbol_item.get('contractCode') 31 | next_page_token = symbol_item.get('nextPageToken') 32 | if 'items' in symbol_item: 33 | for item in symbol_item['items']: 34 | item_values = {'identifier': identifier, 'next_page_token': next_page_token} 35 | for key, value in item.items(): 36 | if value is None: 37 | continue 38 | tag = BAR_FIELD_MAPPINGS[key] if key in BAR_FIELD_MAPPINGS else key 39 | item_values[tag] = value 40 | bar_items.append([item_values.get(tag) for tag in COLUMNS]) 41 | 42 | self.bars = pd.DataFrame(bar_items, columns=COLUMNS) 43 | -------------------------------------------------------------------------------- /tigeropen/quote/response/future_quote_ticks_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | import pandas as pd 8 | 9 | from tigeropen.common.response import TigerResponse 10 | 11 | 12 | class FutureTradeTickResponse(TigerResponse): 13 | def __init__(self): 14 | super(FutureTradeTickResponse, self).__init__() 15 | self.trade_ticks = [] 16 | self._is_success = None 17 | 18 | def parse_response_content(self, response_content): 19 | response = super(FutureTradeTickResponse, self).parse_response_content(response_content) 20 | if 'is_success' in response: 21 | self._is_success = response['is_success'] 22 | 23 | if self.data: 24 | self.trade_ticks = pd.DataFrame(self.data.get('items', [])) 25 | self.trade_ticks.insert(0, column='identifier', value=self.data.get('contractCode')) 26 | -------------------------------------------------------------------------------- /tigeropen/quote/response/future_trading_times_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | import pandas as pd 8 | 9 | from tigeropen.common.response import TigerResponse 10 | 11 | COLUMNS = ['start', 'end', 'trading', 'bidding', 'zone'] 12 | 13 | 14 | class FutureTradingTimesResponse(TigerResponse): 15 | def __init__(self): 16 | super(FutureTradingTimesResponse, self).__init__() 17 | self.trading_times = [] 18 | self._is_success = None 19 | 20 | def parse_response_content(self, response_content): 21 | response = super(FutureTradingTimesResponse, self).parse_response_content(response_content) 22 | if 'is_success' in response: 23 | self._is_success = response['is_success'] 24 | 25 | if self.data: 26 | zone = self.data.get('timeSection') 27 | bidding_times = self.data.get('biddingTimes') 28 | trading_times = self.data.get('tradingTimes') 29 | 30 | time_items = [] 31 | if bidding_times: 32 | for item in bidding_times: 33 | start = item.get('start') 34 | end = item.get('end') 35 | time_items.append([start, end, False, True, zone]) 36 | if trading_times: 37 | for item in trading_times: 38 | start = item.get('start') 39 | end = item.get('end') 40 | time_items.append([start, end, True, False, zone]) 41 | 42 | self.trading_times = pd.DataFrame(time_items, columns=COLUMNS) 43 | -------------------------------------------------------------------------------- /tigeropen/quote/response/kline_quota_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2023/6/8 4 | # @Author : sukai 5 | from tigeropen.common.response import TigerResponse 6 | from tigeropen.common.util import string_utils 7 | 8 | 9 | class KlineQuotaResponse(TigerResponse): 10 | def __init__(self): 11 | super(KlineQuotaResponse, self).__init__() 12 | self.result = None 13 | self._is_success = None 14 | 15 | def parse_response_content(self, response_content): 16 | response = super(KlineQuotaResponse, self).parse_response_content(response_content) 17 | if 'is_success' in response: 18 | self._is_success = response['is_success'] 19 | if self.data: 20 | self.result = string_utils.camel_to_underline_obj(self.data) 21 | return self.result 22 | -------------------------------------------------------------------------------- /tigeropen/quote/response/market_scanner_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2021/11/18 4 | # @Author : sukai 5 | import json 6 | 7 | from tigeropen.common.response import TigerResponse 8 | from tigeropen.common.util.string_utils import camel_to_underline_obj 9 | from tigeropen.quote.domain.filter import ScannerResult 10 | 11 | 12 | class MarketScannerResponse(TigerResponse): 13 | def __init__(self): 14 | super(MarketScannerResponse, self).__init__() 15 | self.result = None 16 | self._is_success = None 17 | 18 | def parse_response_content(self, response_content): 19 | response = super(MarketScannerResponse, self).parse_response_content(response_content) 20 | if 'is_success' in response: 21 | self._is_success = response['is_success'] 22 | if self.data: 23 | data = camel_to_underline_obj(self.data) 24 | self.result = ScannerResult(page=data.get('page'), 25 | page_size=data.get('page_size'), 26 | total_page=data.get('total_page'), 27 | total_count=data.get('total_count'), 28 | items=data.get('items')) 29 | return self.result 30 | 31 | 32 | class MarketScannerTagsResponse(TigerResponse): 33 | def __init__(self): 34 | super(MarketScannerTagsResponse, self).__init__() 35 | self.result = None 36 | self._is_success = None 37 | 38 | def parse_response_content(self, response_content): 39 | response = super(MarketScannerTagsResponse, self).parse_response_content(response_content) 40 | if 'is_success' in response: 41 | self._is_success = response['is_success'] 42 | if self.data: 43 | if isinstance(self.data, str): 44 | self.data = json.loads(self.data) 45 | data = camel_to_underline_obj(self.data) 46 | self.result = data 47 | return self.result -------------------------------------------------------------------------------- /tigeropen/quote/response/market_status_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | 8 | import dateutil.parser as dateparser 9 | 10 | from tigeropen.common.response import TigerResponse 11 | from tigeropen.common.util.common_utils import eastern, china, hongkong 12 | from tigeropen.quote.domain.market_status import MarketStatus 13 | 14 | 15 | class MarketStatusResponse(TigerResponse): 16 | def __init__(self): 17 | super(MarketStatusResponse, self).__init__() 18 | self.markets = [] 19 | self._is_success = None 20 | 21 | def parse_response_content(self, response_content): 22 | response = super(MarketStatusResponse, self).parse_response_content(response_content) 23 | if 'is_success' in response: 24 | self._is_success = response['is_success'] 25 | 26 | if self.data and isinstance(self.data, list): 27 | for item in self.data: 28 | market, status, open_time, trading_status = None, None, None, None 29 | for key, value in item.items(): 30 | if value is None: 31 | continue 32 | if key == 'market': 33 | market = value 34 | elif key == 'marketStatus': 35 | status = value 36 | elif key == 'openTime': 37 | if value.endswith(' EDT') or value.endswith(' EST'): 38 | value = value[0:len(value) - 4] 39 | open_time = dateparser.parse(value) 40 | elif key == 'status': 41 | trading_status = value 42 | 43 | if open_time and market: 44 | if market == 'US': 45 | open_time = eastern.localize(open_time) 46 | elif market == 'HK': 47 | open_time = hongkong.localize(open_time) 48 | elif market == 'CN': 49 | open_time = china.localize(open_time) 50 | market_status = MarketStatus(market, status, open_time, trading_status) 51 | self.markets.append(market_status) 52 | -------------------------------------------------------------------------------- /tigeropen/quote/response/option_briefs_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | import pandas as pd 8 | 9 | from tigeropen.common.response import TigerResponse 10 | from tigeropen.common.util.common_utils import eastern 11 | from tigeropen.common.util.contract_utils import get_option_identifier 12 | 13 | COLUMNS = ['identifier', 'symbol', 'expiry', 'strike', 'put_call', 'multiplier', 'ask_price', 'ask_size', 'bid_price', 14 | 'bid_size', 'pre_close', 'latest_price', 'latest_time', 'volume', 'open_interest', 'open', 'high', 'low', 15 | 'rates_bonds', 'volatility', 'change'] 16 | BRIEF_FIELD_MAPPINGS = {'askPrice': 'ask_price', 'askSize': 'ask_size', 'bidPrice': 'bid_price', 'bidSize': 'bid_size', 17 | 'latestPrice': 'latest_price', 'openInterest': 'open_interest', 'preClose': 'pre_close', 18 | 'right': 'put_call', 'latestTime': 'latest_time', 'openInt': 'open_interest', 19 | 'ratesBonds': 'rates_bonds'} 20 | 21 | 22 | class OptionBriefsResponse(TigerResponse): 23 | def __init__(self): 24 | super(OptionBriefsResponse, self).__init__() 25 | self.briefs = None 26 | self._is_success = None 27 | 28 | def parse_response_content(self, response_content): 29 | response = super(OptionBriefsResponse, self).parse_response_content(response_content) 30 | if 'is_success' in response: 31 | self._is_success = response['is_success'] 32 | 33 | if self.data and isinstance(self.data, list): 34 | brief_data = [] 35 | for item in self.data: 36 | item_values = {} 37 | for key, value in item.items(): 38 | if value is None: 39 | continue 40 | if key == 'right': 41 | value = value.upper() 42 | tag = BRIEF_FIELD_MAPPINGS[key] if key in BRIEF_FIELD_MAPPINGS else key 43 | item_values[tag] = value 44 | if 'identifier' not in item_values: 45 | underlying_symbol = item_values.get('symbol') 46 | expiry = item_values.get('expiry') 47 | strike = float(item_values.get('strike')) 48 | put_call = item_values.get('right') 49 | expiry = pd.Timestamp(expiry, unit='ms', tzinfo=eastern).date().strftime("%Y%m%d") 50 | item_values['identifier'] = get_option_identifier(underlying_symbol, expiry, put_call, strike) 51 | 52 | brief_data.append([item_values.get(tag) for tag in COLUMNS]) 53 | 54 | self.briefs = pd.DataFrame(brief_data, columns=COLUMNS) 55 | -------------------------------------------------------------------------------- /tigeropen/quote/response/option_chains_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | import pandas as pd 8 | 9 | from tigeropen.common.response import TigerResponse 10 | from tigeropen.common.util import string_utils 11 | 12 | CHAIN_FIELD_MAPPINGS = {'right': 'put_call'} 13 | 14 | 15 | class OptionChainsResponse(TigerResponse): 16 | def __init__(self): 17 | super(OptionChainsResponse, self).__init__() 18 | self.chain = None 19 | self._is_success = None 20 | 21 | def parse_response_content(self, response_content): 22 | response = super(OptionChainsResponse, self).parse_response_content(response_content) 23 | if 'is_success' in response: 24 | self._is_success = response['is_success'] 25 | if self.data and isinstance(self.data, list): 26 | chain_data = [] 27 | for item in self.data: 28 | symbol = item.get('symbol') 29 | expiry = item.get('expiry') 30 | items = item.get('items') 31 | if symbol and items: 32 | for chain_item in items: 33 | for call_put_item in chain_item.values(): 34 | item_values = {'symbol': symbol, 'expiry': expiry} 35 | for key, value in call_put_item.items(): 36 | if value is None: 37 | continue 38 | if key == 'right': 39 | value = value.upper() 40 | item_values[CHAIN_FIELD_MAPPINGS.get(key, string_utils.camel_to_underline(key))] = value 41 | chain_data.append(item_values) 42 | self.chain = pd.DataFrame(chain_data) 43 | -------------------------------------------------------------------------------- /tigeropen/quote/response/option_depth_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from tigeropen.common.response import TigerResponse 3 | from tigeropen.common.util.contract_utils import get_option_identifier 4 | 5 | 6 | class OptionDepthQuoteResponse(TigerResponse): 7 | def __init__(self): 8 | super(OptionDepthQuoteResponse, self).__init__() 9 | self.result = dict() 10 | self._is_success = None 11 | 12 | def parse_response_content(self, response_content): 13 | response = super(OptionDepthQuoteResponse, self).parse_response_content(response_content) 14 | if 'is_success' in response: 15 | self._is_success = response['is_success'] 16 | 17 | if self.data and isinstance(self.data, list): 18 | if len(self.data) == 1: 19 | self.result = self.parse_data(self.data[0]) 20 | else: 21 | for item in self.data: 22 | info = self.parse_data(item) 23 | identifier = info.get('identifier') 24 | self.result[identifier] = info 25 | return self.result 26 | 27 | def parse_data(self, item): 28 | symbol = item.get('symbol', '') 29 | expiry = item.get('expiry', '') 30 | strike = item.get('strike', '') 31 | right = item.get('right', '') 32 | identifier = get_option_identifier(symbol, expiry, right, strike) 33 | asks = [(v['price'], v.get('volume', 0), v['timestamp'], v['code']) for v in item.get('ask', [])] 34 | bids = [(v['price'], v.get('volume', 0), v['timestamp'], v['code']) for v in item.get('bid', [])] 35 | return {'identifier': identifier, 'asks': asks, 'bids': bids} 36 | 37 | 38 | -------------------------------------------------------------------------------- /tigeropen/quote/response/option_expirations_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | import pandas as pd 8 | from tigeropen.common.response import TigerResponse 9 | from tigeropen.common.util.string_utils import camel_to_underline 10 | FIELD_MAP = { 11 | 'dates': 'date', 12 | 'timestamps': 'timestamp', 13 | 'periodTags': 'period_tag', 14 | 'optionSymbols': 'option_symbol' 15 | } 16 | 17 | class OptionExpirationsResponse(TigerResponse): 18 | def __init__(self): 19 | super(OptionExpirationsResponse, self).__init__() 20 | self.expirations = pd.DataFrame() 21 | self._is_success = None 22 | 23 | def parse_response_content(self, response_content): 24 | response = super(OptionExpirationsResponse, self).parse_response_content(response_content) 25 | if 'is_success' in response: 26 | self._is_success = response['is_success'] 27 | 28 | if self.data and isinstance(self.data, list): 29 | for item in self.data: 30 | item.pop('count', None) 31 | self.expirations = pd.concat([self.expirations, pd.DataFrame(item)]) 32 | column_map = {col: FIELD_MAP.get(col, camel_to_underline(col)) for col in self.expirations.columns.to_list()} 33 | self.expirations.rename(columns=column_map, inplace=True) 34 | self.expirations.reset_index(inplace=True, drop=True) 35 | -------------------------------------------------------------------------------- /tigeropen/quote/response/option_quote_bar_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | import pandas as pd 8 | 9 | from tigeropen.common.response import TigerResponse 10 | from tigeropen.common.util.common_utils import eastern 11 | from tigeropen.common.util.contract_utils import get_option_identifier 12 | 13 | COLUMNS = ['identifier', 'symbol', 'expiry', 'put_call', 'strike', 'time', 'open', 'high', 'low', 'close', 'volume', 14 | 'open_interest'] 15 | BAR_FIELD_MAPPINGS = {'avgPrice': 'avg_price', 'openInterest': 'open_interest', 'right': 'put_call'} 16 | 17 | 18 | class OptionQuoteBarResponse(TigerResponse): 19 | def __init__(self): 20 | super(OptionQuoteBarResponse, self).__init__() 21 | self.bars = [] 22 | self._is_success = None 23 | 24 | def parse_response_content(self, response_content): 25 | response = super(OptionQuoteBarResponse, self).parse_response_content(response_content) 26 | if 'is_success' in response: 27 | self._is_success = response['is_success'] 28 | 29 | if self.data and isinstance(self.data, list): 30 | bar_items = [] 31 | for symbol_item in self.data: 32 | identifier = symbol_item.get('identifier') 33 | underlying_symbol = symbol_item.get('symbol') 34 | expiry = symbol_item.get('expiry') 35 | strike = float(symbol_item.get('strike')) 36 | put_call = symbol_item.get('right') 37 | if put_call: 38 | put_call = put_call.upper() 39 | 40 | if not identifier: 41 | expiration = pd.Timestamp(expiry, unit='ms', tzinfo=eastern).date().strftime("%Y%m%d") 42 | identifier = get_option_identifier(underlying_symbol, expiration, put_call, strike) 43 | 44 | if 'items' in symbol_item: 45 | for item in symbol_item['items']: 46 | item_values = {'identifier': identifier, 'symbol': underlying_symbol, 'expiry': expiry, 47 | 'put_call': put_call, 'strike': strike} 48 | for key, value in item.items(): 49 | if value is None: 50 | continue 51 | tag = BAR_FIELD_MAPPINGS[key] if key in BAR_FIELD_MAPPINGS else key 52 | item_values[tag] = value 53 | bar_items.append([item_values.get(tag) for tag in COLUMNS]) 54 | 55 | self.bars = pd.DataFrame(bar_items, columns=COLUMNS) 56 | -------------------------------------------------------------------------------- /tigeropen/quote/response/option_quote_ticks_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | import pandas as pd 8 | 9 | from tigeropen.common.response import TigerResponse 10 | from tigeropen.common.util.common_utils import eastern 11 | from tigeropen.common.util.contract_utils import get_option_identifier 12 | 13 | COLUMNS = ['identifier', 'symbol', 'expiry', 'put_call', 'strike', 'time', 'price', 'volume'] 14 | 15 | 16 | class OptionTradeTickResponse(TigerResponse): 17 | def __init__(self): 18 | super(OptionTradeTickResponse, self).__init__() 19 | self.trade_ticks = [] 20 | self._is_success = None 21 | 22 | def parse_response_content(self, response_content): 23 | response = super(OptionTradeTickResponse, self).parse_response_content(response_content) 24 | if 'is_success' in response: 25 | self._is_success = response['is_success'] 26 | 27 | if self.data and isinstance(self.data, list): 28 | tick_items = [] 29 | for symbol_item in self.data: 30 | if 'items' in symbol_item and len(symbol_item['items']) > 0: 31 | underlying_symbol = symbol_item.get('symbol') 32 | put_call = symbol_item.get('right').upper() 33 | expiry = symbol_item.get('expiry') 34 | strike = float(symbol_item.get('strike')) 35 | identifier = symbol_item.get('identifier') 36 | if not identifier: 37 | expiration = pd.Timestamp(expiry, unit='ms', tzinfo=eastern).date().strftime("%Y%m%d") 38 | identifier = get_option_identifier(underlying_symbol, expiration, put_call, strike) 39 | 40 | for item in symbol_item['items']: 41 | item_values = {'identifier': identifier, 'symbol': underlying_symbol, 'expiry': expiry, 42 | 'put_call': put_call, 'strike': strike} 43 | for key, value in item.items(): 44 | if value is None: 45 | continue 46 | item_values[key] = value 47 | tick_items.append([item_values.get(tag) for tag in COLUMNS]) 48 | 49 | self.trade_ticks = pd.DataFrame(tick_items, columns=COLUMNS) 50 | -------------------------------------------------------------------------------- /tigeropen/quote/response/option_symbols_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import pandas as pd 4 | from tigeropen.common.response import TigerResponse 5 | from tigeropen.common.util.string_utils import camel_to_underline 6 | 7 | 8 | class OptionSymbolsResponse(TigerResponse): 9 | def __init__(self): 10 | super(OptionSymbolsResponse, self).__init__() 11 | self.result = dict() 12 | self._is_success = None 13 | 14 | def parse_response_content(self, response_content): 15 | response = super(OptionSymbolsResponse, self).parse_response_content(response_content) 16 | if 'is_success' in response: 17 | self._is_success = response['is_success'] 18 | 19 | if self.data and isinstance(self.data, list): 20 | fields = self.data[0].keys() 21 | fields_map = {origin: camel_to_underline(origin) for origin in fields} 22 | df = pd.DataFrame(self.data) 23 | self.result = df.rename(columns=fields_map) 24 | 25 | 26 | -------------------------------------------------------------------------------- /tigeropen/quote/response/quote_bar_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | import pandas as pd 8 | 9 | from tigeropen.common.response import TigerResponse 10 | 11 | COLUMNS = ['symbol', 'time', 'open', 'high', 'low', 'close', 'volume', 'amount', 'next_page_token'] 12 | BAR_FIELD_MAPPINGS = {'avgPrice': 'avg_price'} 13 | 14 | 15 | class QuoteBarResponse(TigerResponse): 16 | def __init__(self): 17 | super(QuoteBarResponse, self).__init__() 18 | self.bars = pd.DataFrame(columns=COLUMNS) 19 | self._is_success = None 20 | 21 | def parse_response_content(self, response_content): 22 | response = super(QuoteBarResponse, self).parse_response_content(response_content) 23 | if 'is_success' in response: 24 | self._is_success = response['is_success'] 25 | 26 | if self.data and isinstance(self.data, list): 27 | bar_items = [] 28 | for symbol_item in self.data: 29 | symbol = symbol_item.get('symbol') 30 | next_page_token = symbol_item.get('nextPageToken') 31 | if 'items' in symbol_item: 32 | for item in symbol_item['items']: 33 | item_values = {'symbol': symbol, 'next_page_token': next_page_token} 34 | for key, value in item.items(): 35 | if value is None: 36 | continue 37 | tag = BAR_FIELD_MAPPINGS[key] if key in BAR_FIELD_MAPPINGS else key 38 | item_values[tag] = value 39 | bar_items.append([item_values.get(tag) for tag in COLUMNS]) 40 | 41 | self.bars = pd.DataFrame(bar_items, columns=COLUMNS) 42 | -------------------------------------------------------------------------------- /tigeropen/quote/response/quote_brief_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | 8 | from tigeropen.common.consts import TradingSession 9 | from tigeropen.common.response import TigerResponse 10 | from tigeropen.quote.domain.quote_brief import QuoteBrief, HourTrading 11 | 12 | BRIEF_FIELD_MAPPINGS = {'latestPrice': 'latest_price', 'preClose': 'prev_close', 'secType': 'sec_type', 13 | 'timestamp': 'latest_time', 'askPrice': 'ask_price', 'askSize': 'ask_size', 14 | 'bidPrice': 'bid_price', 'bidSize': 'bid_size'} 15 | 16 | 17 | class QuoteBriefResponse(TigerResponse): 18 | def __init__(self): 19 | super(QuoteBriefResponse, self).__init__() 20 | self.briefs = [] 21 | self._is_success = None 22 | 23 | def parse_response_content(self, response_content): 24 | response = super(QuoteBriefResponse, self).parse_response_content(response_content) 25 | if 'is_success' in response: 26 | self._is_success = response['is_success'] 27 | 28 | if self.data: 29 | if 'items' in self.data: 30 | for item in self.data['items']: 31 | brief = QuoteBrief() 32 | for key, value in item.items(): 33 | if value is None: 34 | continue 35 | if key == 'hourTrading': 36 | hour_trading = HourTrading() 37 | for sub_key, sub_value in value.items(): 38 | if sub_key == 'tag': 39 | if sub_value == '盘前': 40 | hour_trading.trading_session = TradingSession.PreMarket 41 | elif sub_value == '盘后': 42 | hour_trading.trading_session = TradingSession.AfterHours 43 | else: 44 | sub_tag = BRIEF_FIELD_MAPPINGS[ 45 | sub_key] if sub_key in BRIEF_FIELD_MAPPINGS else sub_key 46 | if hasattr(hour_trading, sub_tag): 47 | setattr(hour_trading, sub_tag, sub_value) 48 | brief.hour_trading = hour_trading 49 | else: 50 | tag = BRIEF_FIELD_MAPPINGS[key] if key in BRIEF_FIELD_MAPPINGS else key 51 | if hasattr(brief, tag): 52 | setattr(brief, tag, value) 53 | self.briefs.append(brief) 54 | -------------------------------------------------------------------------------- /tigeropen/quote/response/quote_dataframe_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2022/4/13 4 | # @Author : sukai 5 | 6 | import pandas as pd 7 | 8 | from tigeropen.common.response import TigerResponse 9 | from tigeropen.common.util import string_utils 10 | 11 | 12 | class QuoteDataframeResponse(TigerResponse): 13 | def __init__(self): 14 | super(QuoteDataframeResponse, self).__init__() 15 | self.result = None 16 | self._is_success = None 17 | 18 | def parse_response_content(self, response_content): 19 | response = super(QuoteDataframeResponse, self).parse_response_content(response_content) 20 | if 'is_success' in response: 21 | self._is_success = response['is_success'] 22 | 23 | data_items = [] 24 | if self.data and isinstance(self.data, list): 25 | for symbol_item in self.data: 26 | df = pd.DataFrame(symbol_item.get('items')) 27 | df.insert(0, 'symbol', symbol_item.get('symbol')) 28 | data_items.append(df) 29 | final_df = pd.concat(data_items) 30 | elif isinstance(self.data, dict) and 'items' in self.data: 31 | final_df = pd.DataFrame(self.data['items']) 32 | else: 33 | return 34 | field_mapping = {item: string_utils.camel_to_underline(item) for item in final_df.columns} 35 | self.result = final_df.rename(columns=field_mapping) 36 | -------------------------------------------------------------------------------- /tigeropen/quote/response/quote_delay_briefs_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2021/11/11 4 | 5 | @author: sukai 6 | """ 7 | 8 | import pandas as pd 9 | 10 | from tigeropen.common.response import TigerResponse 11 | 12 | from tigeropen.common.util import string_utils 13 | 14 | 15 | class DelayBriefsResponse(TigerResponse): 16 | def __init__(self): 17 | super(DelayBriefsResponse, self).__init__() 18 | self.briefs = None 19 | self._is_success = None 20 | 21 | def parse_response_content(self, response_content): 22 | response = super(DelayBriefsResponse, self).parse_response_content(response_content) 23 | if 'is_success' in response: 24 | self._is_success = response['is_success'] 25 | if self.data and isinstance(self.data, list): 26 | df = pd.DataFrame(self.data) 27 | field_mapping = {item: string_utils.camel_to_underline(item) for item in df.columns} 28 | self.briefs = df.rename(columns=field_mapping) 29 | -------------------------------------------------------------------------------- /tigeropen/quote/response/quote_depth_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from tigeropen.common.response import TigerResponse 3 | 4 | 5 | class DepthQuoteResponse(TigerResponse): 6 | def __init__(self): 7 | super(DepthQuoteResponse, self).__init__() 8 | self.order_book = dict() 9 | self._is_success = None 10 | 11 | def parse_response_content(self, response_content): 12 | response = super(DepthQuoteResponse, self).parse_response_content(response_content) 13 | if 'is_success' in response: 14 | self._is_success = response['is_success'] 15 | 16 | if self.data and isinstance(self.data, list): 17 | if len(self.data) == 1: 18 | item = self.data[0] 19 | symbol = item.get('symbol') 20 | asks = [(v['price'], v['volume'], v['count']) for v in item.get('asks', [])] 21 | bids = [(v['price'], v['volume'], v['count']) for v in item.get('bids', [])] 22 | self.order_book = {'symbol': symbol, 'asks': asks, 'bids': bids} 23 | else: 24 | for item in self.data: 25 | symbol = item.get('symbol') 26 | asks = [(v['price'], v['volume'], v['count']) for v in item.get('asks', [])] 27 | bids = [(v['price'], v['volume'], v['count']) for v in item.get('bids', [])] 28 | self.order_book[symbol] = {'symbol': symbol, 'asks': asks, 'bids': bids} 29 | return self.order_book 30 | 31 | 32 | -------------------------------------------------------------------------------- /tigeropen/quote/response/quote_grab_permission_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2021-04-16 4 | # @Author : sukai 5 | from tigeropen.common.response import TigerResponse 6 | from tigeropen.common.util import string_utils 7 | 8 | 9 | class QuoteGrabPermissionResponse(TigerResponse): 10 | def __init__(self): 11 | super(QuoteGrabPermissionResponse, self).__init__() 12 | self.permissions = None 13 | self._is_success = None 14 | 15 | def parse_response_content(self, response_content): 16 | response = super(QuoteGrabPermissionResponse, self).parse_response_content(response_content) 17 | if 'is_success' in response: 18 | self._is_success = response['is_success'] 19 | 20 | if self.data: 21 | self.permissions = string_utils.camel_to_underline_obj(self.data) 22 | -------------------------------------------------------------------------------- /tigeropen/quote/response/quote_hour_trading_timeline_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | import json 8 | 9 | import pandas as pd 10 | 11 | from tigeropen.common.consts import TradingSession 12 | from tigeropen.common.response import TigerResponse 13 | from tigeropen.quote.domain.quote_brief import HourTrading 14 | 15 | COLUMNS = ['time', 'price', 'avg_price', 'pre_close', 'volume'] 16 | TIMELINE_FIELD_MAPPINGS = {'avgPrice': 'avg_price'} 17 | BRIEF_FIELD_MAPPINGS = {'open': 'open_price', 'high': 'high_price', 'low': 'low_price', 'preClose': 'prev_close', 18 | 'latestPrice': 'latest_price'} 19 | 20 | 21 | class QuoteHourTradingTimelineResponse(TigerResponse): 22 | def __init__(self): 23 | super(QuoteHourTradingTimelineResponse, self).__init__() 24 | self.timelines = [] 25 | self.hour_trading = None 26 | self._is_success = None 27 | 28 | def parse_response_content(self, response_content): 29 | response = super(QuoteHourTradingTimelineResponse, self).parse_response_content(response_content) 30 | if 'is_success' in response: 31 | self._is_success = response['is_success'] 32 | 33 | if self.data: 34 | data_json = self.data 35 | pre_close = data_json.get('preClose') 36 | if 'detail' in data_json: 37 | detail = data_json['detail'] 38 | hour_trading = HourTrading() 39 | if 'timestamp' in response: 40 | hour_trading.latest_time = response['timestamp'] 41 | 42 | for key, value in detail.items(): 43 | if value is None: 44 | continue 45 | if key == 'tag': 46 | if value == '盘前': 47 | hour_trading.trading_session = TradingSession.PreMarket 48 | elif value == '盘后': 49 | hour_trading.trading_session = TradingSession.AfterHours 50 | else: 51 | tag = BRIEF_FIELD_MAPPINGS[key] if key in BRIEF_FIELD_MAPPINGS else key 52 | if hasattr(hour_trading, tag): 53 | setattr(hour_trading, tag, value) 54 | self.hour_trading = hour_trading 55 | if 'items' in data_json: 56 | timeline_items = [] 57 | for item in data_json['items']: 58 | item_values = {'pre_close': pre_close} 59 | for key, value in item.items(): 60 | if value is None: 61 | continue 62 | tag = TIMELINE_FIELD_MAPPINGS[key] if key in TIMELINE_FIELD_MAPPINGS else key 63 | item_values[tag] = value 64 | timeline_items.append([item_values.get(tag) for tag in COLUMNS]) 65 | 66 | self.timelines = pd.DataFrame(timeline_items, columns=COLUMNS) 67 | -------------------------------------------------------------------------------- /tigeropen/quote/response/quote_ticks_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | import pandas as pd 8 | 9 | from tigeropen.common.response import TigerResponse 10 | 11 | COLUMNS = ['symbol', 'index', 'time', 'price', 'volume', 'direction'] 12 | 13 | 14 | class TradeTickResponse(TigerResponse): 15 | def __init__(self): 16 | super(TradeTickResponse, self).__init__() 17 | self.trade_ticks = None 18 | self._is_success = None 19 | 20 | def parse_response_content(self, response_content): 21 | response = super(TradeTickResponse, self).parse_response_content(response_content) 22 | if 'is_success' in response: 23 | self._is_success = response['is_success'] 24 | 25 | # v2: {'data': [{'symbol': 'AAPL', 'beginIndex': 724203, 'endIndex': 724403, 26 | # 'items': [{'time': 1663963199040, 'volume': 200, 'price': 150.66, 'type': '+'}, 27 | # {'time': 1663963199051, 'volume': 100, 'price': 150.65, 'type': '-'}, 28 | # {'time': 1663963199051, 'volume': 300, 'price': 150.65, 'type': '-'}] 29 | 30 | # v1: {'data': '{"beginIndex":722500,"endIndex":724403, 31 | # "items":[{"time":1663963192126,"volume":400,"price":150.5901,"type":"-"}, 32 | # {"time":1663963192142,"volume":100,"price":150.61,"type":"+"} 33 | 34 | if self.data: 35 | # v2 36 | if isinstance(self.data, list): 37 | symbol_items = self.data 38 | else: 39 | symbol_items = [self.data] 40 | 41 | tick_items = [] 42 | for symbol_item in symbol_items: 43 | symbol = symbol_item.get('symbol') 44 | if 'items' in symbol_item: 45 | index = symbol_item.get('beginIndex') 46 | 47 | for item in symbol_item['items']: 48 | item_values = dict() 49 | if symbol is not None: 50 | item_values['symbol'] = symbol 51 | 52 | for key, value in item.items(): 53 | if value is None: 54 | continue 55 | 56 | if key == 'type': 57 | item_values['direction'] = value 58 | else: 59 | item_values[key] = value 60 | 61 | if index is not None: 62 | item_values['index'] = index 63 | index += 1 64 | tick_items.append(item_values) 65 | 66 | self.trade_ticks = pd.DataFrame(tick_items) 67 | -------------------------------------------------------------------------------- /tigeropen/quote/response/quote_timeline_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | 8 | import pandas as pd 9 | 10 | from tigeropen.common.response import TigerResponse 11 | 12 | COLUMNS = ['symbol', 'time', 'price', 'avg_price', 'pre_close', 'volume', 'trading_session'] 13 | TIMELINE_FIELD_MAPPINGS = {'avgPrice': 'avg_price'} 14 | 15 | 16 | class QuoteTimelineResponse(TigerResponse): 17 | def __init__(self): 18 | super(QuoteTimelineResponse, self).__init__() 19 | self.timelines = None 20 | self._is_success = None 21 | 22 | def parse_response_content(self, response_content): 23 | response = super(QuoteTimelineResponse, self).parse_response_content(response_content) 24 | if 'is_success' in response: 25 | self._is_success = response['is_success'] 26 | 27 | if self.data and isinstance(self.data, list): 28 | timeline_items = [] 29 | for symbol_item in self.data: 30 | symbol = symbol_item.get('symbol') 31 | pre_close = symbol_item.get('preClose') 32 | if 'preMarket' in symbol_item: # 盘前 33 | pre_markets = symbol_item['preMarket'].get('items') 34 | if pre_markets: 35 | for item in pre_markets: 36 | item_values = self.parse_timeline(item, symbol, pre_close, 'pre_market') 37 | timeline_items.append([item_values.get(tag) for tag in COLUMNS]) 38 | 39 | if 'intraday' in symbol_item: # 盘中 40 | regulars = symbol_item['intraday'].get('items') 41 | elif 'items' in symbol_item: 42 | regulars = symbol_item['items'][0].get('items') 43 | else: 44 | regulars = None 45 | if regulars: 46 | for item in regulars: 47 | item_values = self.parse_timeline(item, symbol, pre_close, 'regular') 48 | timeline_items.append([item_values.get(tag) for tag in COLUMNS]) 49 | 50 | if 'afterHours' in symbol_item: # 盘后 51 | after_hours = symbol_item['afterHours'].get('items') 52 | if after_hours: 53 | for item in after_hours: 54 | item_values = self.parse_timeline(item, symbol, pre_close, 'after_hours') 55 | timeline_items.append([item_values.get(tag) for tag in COLUMNS]) 56 | 57 | self.timelines = pd.DataFrame(timeline_items, columns=COLUMNS) 58 | 59 | @staticmethod 60 | def parse_timeline(item, symbol, pre_close, trading_session): 61 | item_values = {'symbol': symbol, 'pre_close': pre_close, 'trading_session': trading_session} 62 | for key, value in item.items(): 63 | if value is None: 64 | continue 65 | tag = TIMELINE_FIELD_MAPPINGS[key] if key in TIMELINE_FIELD_MAPPINGS else key 66 | item_values[tag] = value 67 | 68 | return item_values 69 | -------------------------------------------------------------------------------- /tigeropen/quote/response/stock_briefs_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | 8 | import pandas as pd 9 | 10 | from tigeropen.common.response import TigerResponse 11 | from tigeropen.common.util import string_utils 12 | 13 | HOUR_TRADING_KEY = "hour_trading" 14 | 15 | 16 | class StockBriefsResponse(TigerResponse): 17 | def __init__(self): 18 | super(StockBriefsResponse, self).__init__() 19 | self.briefs = None 20 | self._is_success = None 21 | 22 | def parse_response_content(self, response_content): 23 | response = super(StockBriefsResponse, self).parse_response_content(response_content) 24 | if 'is_success' in response: 25 | self._is_success = response['is_success'] 26 | 27 | if self.data and isinstance(self.data, list): 28 | brief_data = [] 29 | for item in self.data: 30 | item_data = string_utils.camel_to_underline_obj(item) 31 | hour_trading = item_data.pop(HOUR_TRADING_KEY, None) 32 | if hour_trading: 33 | for k, v in hour_trading.items(): 34 | item_data[HOUR_TRADING_KEY + '_' + k] = v 35 | brief_data.append(item_data) 36 | self.briefs = pd.DataFrame(brief_data) 37 | -------------------------------------------------------------------------------- /tigeropen/quote/response/stock_broker_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2022-12-09 4 | # @Author : sukai 5 | from tigeropen.common.response import TigerResponse 6 | from tigeropen.common.util import string_utils 7 | from tigeropen.quote.domain.stock_broker import StockBroker, LevelBroker, Broker 8 | 9 | 10 | class StockBrokerResponse(TigerResponse): 11 | def __init__(self): 12 | super().__init__() 13 | self.result = None 14 | self._is_success = None 15 | 16 | def parse_response_content(self, response_content): 17 | response = super().parse_response_content(response_content) 18 | if 'is_success' in response: 19 | self._is_success = response['is_success'] 20 | 21 | if self.data: 22 | data = string_utils.camel_to_underline_obj(self.data) 23 | stock_broker = StockBroker() 24 | stock_broker.symbol = data.get('symbol') 25 | if data.get('bid_broker'): 26 | stock_broker.bid_broker = self._build_level_broker(data.get('bid_broker')) 27 | if data.get('ask_broker'): 28 | stock_broker.ask_broker = self._build_level_broker(data.get('ask_broker')) 29 | self.result = stock_broker 30 | 31 | def _build_level_broker(self, level_data): 32 | level_broker_list = list() 33 | for level_data in level_data: 34 | level_broker = LevelBroker() 35 | level_broker.level = level_data.get('level') 36 | level_broker.price = level_data.get('price') 37 | level_broker.broker_count = level_data.get('broker_count') 38 | if level_data.get('broker'): 39 | broker_list = list() 40 | for broker_data in level_data.get('broker'): 41 | broker = Broker() 42 | broker.__dict__ = broker_data 43 | broker_list.append(broker) 44 | level_broker.broker = broker_list 45 | level_broker_list.append(level_broker) 46 | return level_broker_list 47 | -------------------------------------------------------------------------------- /tigeropen/quote/response/stock_short_interest_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | 8 | import pandas as pd 9 | 10 | from tigeropen.common.response import TigerResponse 11 | 12 | COLUMNS = ['symbol', 'settlement_date', 'short_interest', 'avg_daily_volume', 'days_to_cover', 'percent_of_float'] 13 | SHORT_INTEREST_FIELD_MAPPINGS = {'settlementDate': 'settlement_date', 'shortInterest': 'short_interest', 14 | 'avgDailyVolume': 'avg_daily_volume', 'daysToCover': 'days_to_cover', 15 | 'percentOfFloat': 'percent_of_float'} 16 | 17 | 18 | class ShortInterestResponse(TigerResponse): 19 | def __init__(self): 20 | super(ShortInterestResponse, self).__init__() 21 | self.short_interests = None 22 | self._is_success = None 23 | 24 | def parse_response_content(self, response_content): 25 | response = super(ShortInterestResponse, self).parse_response_content(response_content) 26 | if 'is_success' in response: 27 | self._is_success = response['is_success'] 28 | 29 | if self.data and isinstance(self.data, list): 30 | short_interest_items = [] 31 | for symbol_item in self.data: 32 | symbol = symbol_item.get('symbol') 33 | items = symbol_item.get('items') 34 | for item in items: 35 | item_values = {'symbol': symbol} 36 | for key, value in item.items(): 37 | if value is None: 38 | continue 39 | tag = SHORT_INTEREST_FIELD_MAPPINGS[key] if key in SHORT_INTEREST_FIELD_MAPPINGS else key 40 | item_values[tag] = value 41 | short_interest_items.append([item_values.get(tag) for tag in COLUMNS]) 42 | 43 | self.short_interests = pd.DataFrame(short_interest_items, columns=COLUMNS) 44 | -------------------------------------------------------------------------------- /tigeropen/quote/response/stock_trade_meta_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | 8 | import pandas as pd 9 | 10 | from tigeropen.common.response import TigerResponse 11 | 12 | COLUMNS = ['symbol', 'lot_size', 'min_tick', 'spread_scale'] 13 | BRIEF_FIELD_MAPPINGS = {'lotSize': 'lot_size', 'minTick': 'min_tick', 'spreadScale': 'spread_scale'} 14 | 15 | 16 | class TradeMetaResponse(TigerResponse): 17 | def __init__(self): 18 | super(TradeMetaResponse, self).__init__() 19 | self.metas = None 20 | self._is_success = None 21 | 22 | def parse_response_content(self, response_content): 23 | response = super(TradeMetaResponse, self).parse_response_content(response_content) 24 | if 'is_success' in response: 25 | self._is_success = response['is_success'] 26 | 27 | if self.data and isinstance(self.data, list): 28 | meta_data = [] 29 | for item in self.data: 30 | item_values = {} 31 | for key, value in item.items(): 32 | if value is None: 33 | continue 34 | tag = BRIEF_FIELD_MAPPINGS[key] if key in BRIEF_FIELD_MAPPINGS else key 35 | item_values[tag] = value 36 | 37 | meta_data.append([item_values.get(tag) for tag in COLUMNS]) 38 | 39 | self.metas = pd.DataFrame(meta_data, columns=COLUMNS) 40 | -------------------------------------------------------------------------------- /tigeropen/quote/response/symbol_names_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | 8 | from tigeropen.common.response import TigerResponse 9 | 10 | 11 | class SymbolNamesResponse(TigerResponse): 12 | def __init__(self): 13 | super(SymbolNamesResponse, self).__init__() 14 | self.symbol_names = [] 15 | self._is_success = None 16 | 17 | def parse_response_content(self, response_content): 18 | response = super(SymbolNamesResponse, self).parse_response_content(response_content) 19 | if 'is_success' in response: 20 | self._is_success = response['is_success'] 21 | 22 | if self.data and isinstance(self.data, list): 23 | self.symbol_names = [(item['symbol'], item['name']) for item in self.data if 24 | len(item) == 2] 25 | -------------------------------------------------------------------------------- /tigeropen/quote/response/symbols_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | 8 | from tigeropen.common.response import TigerResponse 9 | 10 | 11 | class SymbolsResponse(TigerResponse): 12 | def __init__(self): 13 | super(SymbolsResponse, self).__init__() 14 | self.result = [] 15 | self._is_success = None 16 | 17 | def parse_response_content(self, response_content): 18 | response = super(SymbolsResponse, self).parse_response_content(response_content) 19 | if 'is_success' in response: 20 | self._is_success = response['is_success'] 21 | 22 | if self.data and isinstance(self.data, list): 23 | self.result = [symbol for symbol in self.data if symbol] 24 | -------------------------------------------------------------------------------- /tigeropen/quote/response/trade_rank_response.py: -------------------------------------------------------------------------------- 1 | from tigeropen.common.response import TigerResponse 2 | import pandas as pd 3 | from tigeropen.common.util.string_utils import camel_to_underline_obj 4 | 5 | class TradeRankResponse(TigerResponse): 6 | def __init__(self): 7 | super(TradeRankResponse, self).__init__() 8 | self.result = pd.DataFrame() 9 | self._is_success = None 10 | 11 | def parse_response_content(self, response_content): 12 | response = super(TradeRankResponse, self).parse_response_content(response_content) 13 | if 'is_success' in response: 14 | self._is_success = response['is_success'] 15 | 16 | if self.data: 17 | df_data = [] 18 | for item in self.data: 19 | formated_item = camel_to_underline_obj(item) 20 | hour_trading = formated_item.pop('hour_trading', None) 21 | if hour_trading: 22 | for key, value in hour_trading.items(): 23 | formated_item['hour_trading_' + key] = value 24 | df_data.append(formated_item) 25 | 26 | self.result = pd.DataFrame(df_data) 27 | 28 | -------------------------------------------------------------------------------- /tigeropen/quote/response/trading_calendar_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2021-04-16 4 | # @Author : sukai 5 | from tigeropen.common.response import TigerResponse 6 | from tigeropen.common.util import string_utils 7 | 8 | 9 | class TradingCalendarResponse(TigerResponse): 10 | def __init__(self): 11 | super(TradingCalendarResponse, self).__init__() 12 | self.calendar = None 13 | self._is_success = None 14 | 15 | def parse_response_content(self, response_content): 16 | response = super(TradingCalendarResponse, self).parse_response_content(response_content) 17 | if 'is_success' in response: 18 | self._is_success = response['is_success'] 19 | 20 | if self.data: 21 | self.calendar = string_utils.camel_to_underline_obj(self.data) 22 | -------------------------------------------------------------------------------- /tigeropen/quote/response/warrant_briefs_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2023/4/6 4 | # @Author : sukai 5 | import pandas as pd 6 | 7 | from tigeropen.common.response import TigerResponse 8 | from tigeropen.common.util import string_utils 9 | 10 | 11 | class WarrantBriefsResponse(TigerResponse): 12 | def __init__(self): 13 | super(WarrantBriefsResponse, self).__init__() 14 | self.result = None 15 | self._is_success = None 16 | 17 | def parse_response_content(self, response_content): 18 | response = super(WarrantBriefsResponse, self).parse_response_content(response_content) 19 | if 'is_success' in response: 20 | self._is_success = response['is_success'] 21 | 22 | if self.data and self.data.get('items'): 23 | self.result = string_utils.camel_to_underline_obj(self.data.get('items')) 24 | self.result = pd.DataFrame(self.result) 25 | -------------------------------------------------------------------------------- /tigeropen/quote/response/warrant_filter_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2023/4/7 4 | # @Author : sukai 5 | import pandas as pd 6 | 7 | from tigeropen.common.response import TigerResponse 8 | from tigeropen.common.util import string_utils 9 | from tigeropen.quote.domain.filter import WarrantFilterItem, WarrantFilterBounds 10 | 11 | 12 | class WarrantFilterResponse(TigerResponse): 13 | def __init__(self): 14 | super(WarrantFilterResponse, self).__init__() 15 | self.result = None 16 | self._is_success = None 17 | 18 | def parse_response_content(self, response_content): 19 | response = super(WarrantFilterResponse, self).parse_response_content(response_content) 20 | if 'is_success' in response: 21 | self._is_success = response['is_success'] 22 | 23 | if self.data: 24 | data = string_utils.camel_to_underline_obj(self.data) 25 | items = pd.DataFrame(data.pop('items')) 26 | bounds = WarrantFilterBounds(**data.pop('bounds')) 27 | self.result = WarrantFilterItem(**data, items=items, bounds=bounds) 28 | -------------------------------------------------------------------------------- /tigeropen/trade/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/9/16 4 | 5 | @author: gaoan 6 | """ -------------------------------------------------------------------------------- /tigeropen/trade/domain/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ -------------------------------------------------------------------------------- /tigeropen/trade/domain/profile.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | 8 | 9 | class AccountProfile: 10 | def __init__(self, account, capability, status, account_type=None): 11 | self.account = account 12 | self.capability = capability 13 | self.status = status 14 | self.account_type = account_type 15 | 16 | def __repr__(self): 17 | """ 18 | String representation for this object. 19 | """ 20 | return "AccountProfile(%s)" % self.__dict__ 21 | -------------------------------------------------------------------------------- /tigeropen/trade/request/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ -------------------------------------------------------------------------------- /tigeropen/trade/response/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | 8 | CONTRACT_FIELDS = set(['symbol', 'market', 'multiplier', 'sec_type', 'currency', 'local_symbol', 'origin_symbol', 9 | 'expiry', 'strike', 'right', 'put_call', 'contract_id', 'exchange', 'name', 'short_margin', 'short_fee_rate', 10 | 'shortable', 'long_initial_margin', 'long_maintenance_margin', 'contract_month', 'identifier', 11 | 'primary_exchange', 'min_tick', 'trading_class', 'continuous', 'trade', 'tradeable', 12 | 'last_trading_date', 'first_notice_date', 'last_bidding_close_time', 'shortable_count', 13 | 'categories', 'is_etf', 'etf_leverage', 'lot_size']) 14 | 15 | -------------------------------------------------------------------------------- /tigeropen/trade/response/account_profile_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | from tigeropen.common.response import TigerResponse 8 | from tigeropen.common.util.string_utils import camel_to_underline_obj 9 | from tigeropen.trade.domain.profile import AccountProfile 10 | 11 | 12 | class ProfilesResponse(TigerResponse): 13 | def __init__(self): 14 | super(ProfilesResponse, self).__init__() 15 | self.profiles = [] 16 | self._is_success = None 17 | 18 | def parse_response_content(self, response_content): 19 | response = super(ProfilesResponse, self).parse_response_content(response_content) 20 | if 'is_success' in response: 21 | self._is_success = response['is_success'] 22 | 23 | if self.data: 24 | if 'items' in self.data: 25 | for item in self.data['items']: 26 | data_dict = camel_to_underline_obj(item) 27 | profile = AccountProfile(account=data_dict.get('account'), capability=data_dict.get('capability'), 28 | status=data_dict.get('status'), account_type=data_dict.get('account_type')) 29 | self.profiles.append(profile) 30 | -------------------------------------------------------------------------------- /tigeropen/trade/response/analytics_asset_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2022/7/8 4 | # @Author : sukai 5 | from datetime import datetime 6 | 7 | from tigeropen.common.response import TigerResponse 8 | from tigeropen.common.util.string_utils import camel_to_underline_obj 9 | 10 | 11 | class AnalyticsAssetResponse(TigerResponse): 12 | def __init__(self): 13 | super().__init__() 14 | self.result = None 15 | self._is_success = None 16 | 17 | def parse_response_content(self, response_content): 18 | response = super().parse_response_content(response_content) 19 | if 'is_success' in response: 20 | self._is_success = response['is_success'] 21 | 22 | if self.data: 23 | result = camel_to_underline_obj(self.data) 24 | history = result.get('history') 25 | if history: 26 | for item in history: 27 | item['dt'] = datetime.fromtimestamp(item['date'] // 1000).strftime('%Y-%m-%d') 28 | result['history'] = history 29 | self.result = result 30 | -------------------------------------------------------------------------------- /tigeropen/trade/response/contracts_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | from tigeropen.common.response import TigerResponse 8 | from tigeropen.common.util.string_utils import camel_to_underline, camel_to_underline_obj 9 | from tigeropen.trade.domain.contract import Contract 10 | 11 | CONTRACT_FIELD_MAPPINGS = {'conid': 'contract_id', 'right': 'put_call', 'tradeable': 'trade'} 12 | 13 | 14 | class ContractsResponse(TigerResponse): 15 | def __init__(self): 16 | super(ContractsResponse, self).__init__() 17 | self.contracts = [] 18 | self._is_success = None 19 | 20 | def parse_response_content(self, response_content): 21 | response = super(ContractsResponse, self).parse_response_content(response_content) 22 | if 'is_success' in response: 23 | self._is_success = response['is_success'] 24 | 25 | if self.data: 26 | if 'items' in self.data: 27 | items = self.data['items'] 28 | elif isinstance(self.data, list): 29 | items = self.data 30 | else: 31 | items = [self.data] 32 | for item in items: 33 | contract_fields = {} 34 | for key, value in item.items(): 35 | tag = CONTRACT_FIELD_MAPPINGS[key] if key in CONTRACT_FIELD_MAPPINGS else camel_to_underline(key) 36 | if isinstance(value, (list, dict)): 37 | value = camel_to_underline_obj(value) 38 | contract_fields[tag] = value 39 | contract = Contract() 40 | for k, v in contract_fields.items(): 41 | setattr(contract, k, v) 42 | self.contracts.append(contract) 43 | -------------------------------------------------------------------------------- /tigeropen/trade/response/forex_order_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2023/3/28 4 | # @Author : sukai 5 | from tigeropen.common.response import TigerResponse 6 | from tigeropen.trade.response.orders_response import OrdersResponse 7 | 8 | 9 | class ForexOrderResponse(TigerResponse): 10 | def __init__(self): 11 | super(ForexOrderResponse, self).__init__() 12 | self._is_success = None 13 | 14 | def parse_response_content(self, response_content): 15 | response = super(ForexOrderResponse, self).parse_response_content(response_content) 16 | if 'is_success' in response: 17 | self._is_success = response['is_success'] 18 | if self.data: 19 | self.data = OrdersResponse.parse_order(self.data) 20 | 21 | -------------------------------------------------------------------------------- /tigeropen/trade/response/funding_history_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2024/03/21 4 | """ 5 | import pandas as pd 6 | 7 | from tigeropen.common.response import TigerResponse 8 | from tigeropen.common.util.string_utils import camel_to_underline 9 | 10 | 11 | class FundingHistoryResponse(TigerResponse): 12 | def __init__(self): 13 | super(FundingHistoryResponse, self).__init__() 14 | self.data = None 15 | self._is_success = None 16 | 17 | def parse_response_content(self, response_content): 18 | response = super(FundingHistoryResponse, self).parse_response_content(response_content) 19 | if 'is_success' in response: 20 | self._is_success = response['is_success'] 21 | 22 | if self.data: 23 | if isinstance(self.data, list): 24 | # 将驼峰命名转换为下划线命名 25 | items = [{camel_to_underline(k): v for k, v in item.items()} for item in self.data] 26 | self.data = pd.DataFrame(items) 27 | else: 28 | # 单个记录的情况 29 | items = {camel_to_underline(k): v for k, v in self.data.items()} 30 | self.data = pd.DataFrame([items]) -------------------------------------------------------------------------------- /tigeropen/trade/response/order_id_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Created on 2018/10/31 4 | 5 | @author: gaoan 6 | """ 7 | from tigeropen.common.response import TigerResponse 8 | 9 | 10 | class OrderIdResponse(TigerResponse): 11 | def __init__(self): 12 | super(OrderIdResponse, self).__init__() 13 | self.order_id = None 14 | self.id = None 15 | self.sub_ids = None 16 | self.orders = None 17 | self._is_success = None 18 | 19 | def parse_response_content(self, response_content): 20 | response = super(OrderIdResponse, self).parse_response_content(response_content) 21 | if 'is_success' in response: 22 | self._is_success = response['is_success'] 23 | 24 | if self.data: 25 | data_json = self.data 26 | if 'code' in data_json and data_json['code'] != '0': 27 | self.code = int(data_json['code']) 28 | if 'message' in data_json: 29 | self.message = data_json['message'] 30 | 31 | if 'orderId' in data_json: 32 | self.order_id = data_json['orderId'] 33 | 34 | if 'id' in data_json: 35 | self.id = data_json['id'] 36 | 37 | if 'subIds' in data_json: 38 | self.sub_ids = data_json['subIds'] 39 | 40 | if 'orders' in data_json: 41 | self.orders = data_json['orders'] 42 | -------------------------------------------------------------------------------- /tigeropen/trade/response/order_preview_response.py: -------------------------------------------------------------------------------- 1 | from tigeropen.common.response import TigerResponse 2 | 3 | PREVIEW_ORDER_FIELD_MAPPING = {"initMarginBefore": "init_margin_before", "commissionCurrency": "commission_currency", 4 | "maintMargin": "maint_margin", "equityWithLoan": "equity_with_loan", 5 | "minCommission": "min_commission", "maintMarginBefore": "maint_margin_before", 6 | "initMargin": "init_margin", "equityWithLoanBefore": "equity_with_loan_before", 7 | "marginCurrency": "margin_currency", "maxCommission": "max_commission", 8 | "warningText": "warning_text"} 9 | 10 | 11 | class PreviewOrderResponse(TigerResponse): 12 | def __init__(self): 13 | super(PreviewOrderResponse, self).__init__() 14 | self.preview_order = dict() 15 | self._is_success = None 16 | 17 | def parse_response_content(self, response_content): 18 | response = super(PreviewOrderResponse, self).parse_response_content(response_content) 19 | if 'is_success' in response: 20 | self._is_success = response['is_success'] 21 | 22 | if self.data: 23 | for key, value in self.data.items(): 24 | field = PREVIEW_ORDER_FIELD_MAPPING.get(key, key) 25 | self.preview_order[field] = value 26 | 27 | -------------------------------------------------------------------------------- /tigeropen/trade/response/prime_assets_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2021/12/2 4 | # @Author : sukai 5 | 6 | from tigeropen.common.response import TigerResponse 7 | from tigeropen.trade.domain.prime_account import PortfolioAccount, Segment, CurrencyAsset 8 | from tigeropen.common.util.string_utils import camel_to_underline, camel_to_underline_obj 9 | 10 | 11 | class PrimeAssetsResponse(TigerResponse): 12 | def __init__(self): 13 | super(PrimeAssetsResponse, self).__init__() 14 | self.assets = None 15 | self._is_success = None 16 | 17 | def parse_response_content(self, response_content): 18 | response = super(PrimeAssetsResponse, self).parse_response_content(response_content) 19 | if 'is_success' in response: 20 | self._is_success = response['is_success'] 21 | 22 | if self.data: 23 | assets = PortfolioAccount(self.data.get('accountId'), self.data.get('updateTimestamp')) 24 | 25 | for segment_data in self.data.get('segments', list()): 26 | segment = Segment() 27 | for key, value in segment_data.items(): 28 | if key == 'currencyAssets': 29 | currency_assets = camel_to_underline_obj(value) 30 | [segment.add_currency_asset(CurrencyAsset.from_dict(i)) for i in currency_assets] 31 | else: 32 | setattr(segment, camel_to_underline(key), value) 33 | assets.add_segment(segment) 34 | self.assets = assets 35 | 36 | 37 | -------------------------------------------------------------------------------- /tigeropen/trade/response/segment_fund_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # @Date : 2023/3/24 4 | # @Author : sukai 5 | from tigeropen.common.response import TigerResponse 6 | from tigeropen.common.util import string_utils 7 | from tigeropen.trade.domain.account import SegmentFundItem, SegmentFundAvailableItem 8 | 9 | 10 | class SegmentFundAvailableResponse(TigerResponse): 11 | def __init__(self): 12 | super(SegmentFundAvailableResponse, self).__init__() 13 | self.data = None 14 | self._is_success = None 15 | 16 | def parse_response_content(self, response_content): 17 | response = super(SegmentFundAvailableResponse, self).parse_response_content(response_content) 18 | if 'is_success' in response: 19 | self._is_success = response['is_success'] 20 | 21 | if self.data: 22 | self.data = [SegmentFundAvailableItem(**item) for item in string_utils.camel_to_underline_obj(self.data)] 23 | 24 | 25 | class SegmentFundHistoryResponse(TigerResponse): 26 | def __init__(self): 27 | super(SegmentFundHistoryResponse, self).__init__() 28 | self.data = None 29 | self._is_success = None 30 | 31 | def parse_response_content(self, response_content): 32 | response = super(SegmentFundHistoryResponse, self).parse_response_content(response_content) 33 | if 'is_success' in response: 34 | self._is_success = response['is_success'] 35 | 36 | if self.data: 37 | self.data = [SegmentFundItem(**item) for item in string_utils.camel_to_underline_obj(self.data)] 38 | 39 | 40 | class SegmentFundTransferResponse(TigerResponse): 41 | def __init__(self): 42 | super(SegmentFundTransferResponse, self).__init__() 43 | self.data = None 44 | self._is_success = None 45 | 46 | def parse_response_content(self, response_content): 47 | response = super(SegmentFundTransferResponse, self).parse_response_content(response_content) 48 | if 'is_success' in response: 49 | self._is_success = response['is_success'] 50 | 51 | if self.data: 52 | self.data = SegmentFundItem(**string_utils.camel_to_underline_obj(self.data)) 53 | 54 | return response 55 | 56 | 57 | class SegmentFundCancelResponse(TigerResponse): 58 | def __init__(self): 59 | super(SegmentFundCancelResponse, self).__init__() 60 | self.data = None 61 | self._is_success = None 62 | 63 | def parse_response_content(self, response_content): 64 | response = super(SegmentFundCancelResponse, self).parse_response_content(response_content) 65 | if 'is_success' in response: 66 | self._is_success = response['is_success'] 67 | 68 | if self.data: 69 | self.data = SegmentFundItem(**string_utils.camel_to_underline_obj(self.data)) 70 | -------------------------------------------------------------------------------- /tigeropen/trade/response/transactions_response.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from tigeropen.common.response import TigerResponse 3 | from tigeropen.common.util import string_utils 4 | from tigeropen.trade.domain.contract import Contract 5 | from tigeropen.trade.domain.order import Transaction 6 | from tigeropen.trade.response import CONTRACT_FIELDS 7 | 8 | FIELD_MAPPINGS = {'account_id': 'account', 'right': 'put_call'} 9 | 10 | 11 | class TransactionsResponse(TigerResponse): 12 | def __init__(self): 13 | super(TransactionsResponse, self).__init__() 14 | self.transactions = [] 15 | self._is_success = None 16 | 17 | def parse_response_content(self, response_content): 18 | response = super(TransactionsResponse, self).parse_response_content(response_content) 19 | if 'is_success' in response: 20 | self._is_success = response['is_success'] 21 | 22 | if self.data: 23 | for item in self.data.get('items', list()): 24 | trans = self._parse_transactions(string_utils.camel_to_underline_obj(item)) 25 | if trans: 26 | self.transactions.append(trans) 27 | 28 | def _parse_transactions(self, item_dict): 29 | trans = Transaction() 30 | contract = Contract() 31 | for k, v in item_dict.items(): 32 | map_k = FIELD_MAPPINGS.get(k, k) 33 | if map_k in CONTRACT_FIELDS: 34 | setattr(contract, map_k, v) 35 | else: 36 | setattr(trans, map_k, v) 37 | trans.contract = contract 38 | return trans 39 | --------------------------------------------------------------------------------