Skip to content

Commit 841dc0e

Browse files
committed
Merge branch 'vip_dev' into 'vip'
股票详情api See merge request server/openapi/openapi-python-sdk!62
2 parents 9dc28e0 + df4c2a9 commit 841dc0e

File tree

5 files changed

+201
-4
lines changed

5 files changed

+201
-4
lines changed

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
setup(
1414
name='tigeropen',
15-
version='1.3.0',
15+
version='1.3.2',
1616
description='TigerBrokers Open API',
1717
packages=find_packages(exclude=[]),
1818
author='TigerBrokers',

tigeropen/common/util/web_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ def do_post(url, query_string=None, headers=None, params=None, timeout=15, chars
6868
response = connection.getresponse()
6969
result = response.read()
7070

71-
if response.status is not 200:
71+
if response.status != 200:
7272
if PYTHON_VERSION_3 and charset:
7373
result = result.decode(charset)
7474
raise ResponseException('[' + THREAD_LOCAL.uuid + ']invalid http status ' + str(response.status) +

tigeropen/examples/quote_client_demo.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ def get_quote():
3939
print(ticks)
4040
short_interest = openapi_client.get_short_interest(['GOOG', 'AAPL', '00700'])
4141
print(short_interest)
42+
# 股票详情
43+
stock_details = openapi_client.get_stock_details(['AAPL', '03690'])
44+
print(stock_details)
4245

4346

4447
def get_option_quote():

tigeropen/quote/quote_client.py

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
from tigeropen.quote.response.quote_timeline_response import QuoteTimelineResponse
3636
from tigeropen.quote.response.quote_brief_response import QuoteBriefResponse
3737
from tigeropen.quote.response.stock_briefs_response import StockBriefsResponse
38+
from tigeropen.quote.response.stock_details_response import StockDetailsResponse
3839
from tigeropen.quote.response.stock_short_interest_response import ShortInterestResponse
3940
from tigeropen.quote.response.stock_trade_meta_response import TradeMetaResponse
4041
from tigeropen.quote.response.symbol_names_response import SymbolNamesResponse
@@ -51,7 +52,7 @@
5152
OPTION_KLINE, OPTION_TRADE_TICK, FUTURE_KLINE, FUTURE_TICK, FUTURE_CONTRACT_BY_EXCHANGE_CODE, \
5253
FUTURE_TRADING_DATE, QUOTE_SHORTABLE_STOCKS, FUTURE_REAL_TIME_QUOTE, \
5354
FUTURE_CURRENT_CONTRACT, QUOTE_REAL_TIME, QUOTE_STOCK_TRADE, FINANCIAL_DAILY, FINANCIAL_REPORT, CORPORATE_ACTION, \
54-
INDUSTRY_LIST, INDUSTRY_STOCKS, STOCK_INDUSTRY
55+
INDUSTRY_LIST, INDUSTRY_STOCKS, STOCK_INDUSTRY, STOCK_DETAIL
5556
from tigeropen.common.consts import Market, Language, QuoteRight, BarPeriod
5657
from tigeropen.common.util.contract_utils import extract_option_info
5758
from tigeropen.common.util.common_utils import eastern
@@ -204,7 +205,7 @@ def get_stock_briefs(self, symbols, lang=None):
204205
"""
205206
获取股票实时行情
206207
:param symbols: 股票代号列表
207-
:param lang: 语言支持: zh_CN,zh_TW,en_US
208+
:param lang: 语言支持: tigeropen.common.consts.Language: zh_CN,zh_TW,en_US
208209
:return: pandas.DataFrame. 各 column 含义如下:
209210
symbol: 证券代码
210211
ask_price: 卖一价
@@ -242,6 +243,58 @@ def get_stock_briefs(self, symbols, lang=None):
242243

243244
return None
244245

246+
def get_stock_details(self, symbols, lang=None):
247+
"""
248+
获取股票详情
249+
:param symbols: 股票代号列表
250+
:param lang: 语言支持: zh_CN,zh_TW,en_US
251+
:return: pandas.DataFrame. 各 column 含义如下:
252+
symbol: 代码
253+
market: 市场
254+
sec_type: 证券类型
255+
exchange: 交易所
256+
name: 名称
257+
shortable: 做空信息
258+
ask_price: 卖一价
259+
ask_size: 卖一量
260+
bid_price: 买一价
261+
bid_size: 买一量
262+
pre_close: 前收价
263+
latest_price: 最新价
264+
adj_pre_close: 复权后前收价
265+
latest_time: 最新成交时间
266+
volume: 成交量
267+
open: 开盘价
268+
high: 最高价
269+
low: 最低价
270+
change: 涨跌额
271+
amount: 成交额
272+
amplitude: 振幅
273+
market_status: 市场状态 (未开盘,交易中,休市等)
274+
trading_status: 0: 非交易状态 1: 盘前交易(盘前竞价) 2: 交易中 3: 盘后交易(收市竞价)
275+
float_shares: 流通股本
276+
shares: 总股本
277+
eps: 每股收益
278+
adr_rate: ADR的比例数据,非ADR的股票为None
279+
etf: 非0表示该股票是ETF,1表示不带杠杆的etf,2表示2倍杠杆etf,3表示3倍etf杠杆
280+
listing_date: 上市日期时间戳(该市场当地时间零点),该key可能不存在
281+
更多字段见 tigeropen.quote.response.stock_details_response.StockDetailsResponse
282+
"""
283+
params = MultipleQuoteParams()
284+
params.symbols = symbols
285+
params.lang = lang.value if lang else self._lang.value
286+
287+
request = OpenApiRequest(STOCK_DETAIL, biz_model=params)
288+
response_content = self.__fetch_data(request)
289+
if response_content:
290+
response = StockDetailsResponse()
291+
response.parse_response_content(response_content)
292+
if response.is_success():
293+
return response.details
294+
else:
295+
raise ApiException(response.code, response.message)
296+
return None
297+
245298
def get_timeline(self, symbols, include_hour_trading=False, begin_time=-1, lang=None):
246299
"""
247300
获取当日分时数据
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Created on 2018/10/31
4+
5+
@author: gaoan
6+
"""
7+
import json
8+
9+
import six
10+
import pandas as pd
11+
from tigeropen.common.util.string_utils import get_string
12+
from tigeropen.common.response import TigerResponse
13+
14+
# 盘前盘后
15+
HOUR_TRADING_COLUMNS = [
16+
'hour_trading_tag',
17+
'hour_trading_latest_price',
18+
'hour_trading_pre_close',
19+
'hour_trading_latest_time',
20+
'hour_trading_volume',
21+
'hour_trading_timestamp',
22+
]
23+
# 下一交易时段信息
24+
NEXT_MARKET_STATUS_COLUMNS = [
25+
# 市场状态(US:开盘、收盘、盘前交易、盘后交易||CN/HK:开盘、收盘、午间休市)
26+
'next_market_status_tag',
27+
# 开始时间
28+
'next_market_status_begin_time',
29+
]
30+
# 拆合股
31+
STOCK_SPLIT_COLUMNS = [
32+
# 执行日期 yyyy-MM-dd格式
33+
'stock_split_execute_date',
34+
# 公司行动后的因子
35+
'stock_split_to_factor',
36+
# 公司行动前的因子
37+
'stock_split_for_factor'
38+
]
39+
# 股权信息
40+
STOCK_RIGHT_COLUMNS = [
41+
# 原股权代码
42+
'stock_right_symbol',
43+
# 股权代码
44+
'stock_right_rights_symbol',
45+
# 开始交易日期, YYYY-MM-dd格式,可能为空字符串
46+
'stock_right_first_dealing_date',
47+
# 最后交易日期, YYYY-MM-dd格式,可能为空字符串
48+
'stock_right_last_dealing_date'
49+
]
50+
# 股票代码变更
51+
SYMBOL_CHANGE_COLUMNS = [
52+
# 新的股票代码
53+
'symbol_change_new_symbol',
54+
# 执行日期,yyyy-MM-dd格式
55+
'symbol_change_execute_date'
56+
]
57+
# 股票公告
58+
STOCK_NOTICE_COLUMNS = [
59+
# 公告标题
60+
'stock_notice_title',
61+
# 公告内容
62+
'stock_notice_content',
63+
# 公告类型
64+
'stock_notice_type'
65+
]
66+
67+
COLUMNS = ['symbol', 'market', 'exchange', 'sec_type', 'name', 'shortable', 'latest_price', 'pre_close',
68+
'adj_pre_close', 'trading_status', 'market_status', 'timestamp', 'latest_time',
69+
'open', 'high', 'low', 'volume', 'amount', 'ask_price', 'ask_size', 'bid_price', 'bid_size', 'change',
70+
'amplitude', 'halted', 'delay', 'float_shares', 'shares', 'eps', 'etf', 'listing_date', 'adr_rate'
71+
] + HOUR_TRADING_COLUMNS + NEXT_MARKET_STATUS_COLUMNS + STOCK_SPLIT_COLUMNS + STOCK_RIGHT_COLUMNS \
72+
+ SYMBOL_CHANGE_COLUMNS + STOCK_NOTICE_COLUMNS
73+
74+
DETAIL_FIELD_MAPPINGS = {'secType': 'sec_type', 'latestPrice': 'latest_price', 'preClose': 'pre_close',
75+
'floatShares': 'float_shares', 'marketStatus': 'market_status', 'latestTime': 'latest_time',
76+
'askPrice': 'ask_price', 'askSize': 'ask_size', 'bidPrice': 'bid_price', 'bidSize': 'bid_size',
77+
'tradingStatus': 'trading_status', 'adjPreClose': 'adj_pre_close', 'adrRate': 'adr_rate',
78+
'listingDate': 'listing_date', 'beginTime': 'begin_time',
79+
'nextMarketStatus': 'next_market_status', 'hourTrading': 'hour_trading',
80+
'stockSplit': 'stock_split', 'stockRight': 'stock_right', 'symbolChange': 'symbol_change',
81+
'executeDate': 'execute_date', 'newSymbol': 'new_symbol', 'forFactor': 'for_factor',
82+
'toFactor': 'to_factor', 'rightsSymbol': 'rights_symbol', 'stockNotice': 'stock_notice',
83+
'firstDealingDate': 'first_dealing_date', 'lastDealingDate': 'last_dealing_date'
84+
}
85+
86+
SUB_FIELDS = {
87+
# 下一交易时段信息
88+
'next_market_status',
89+
# 盘前盘后信息
90+
'hour_trading',
91+
# 拆合股
92+
'stock_split',
93+
# 股权信息
94+
'stock_right'
95+
# 股票代码变更
96+
'symbol_change',
97+
# 公告
98+
'stock_notice'
99+
}
100+
101+
102+
class StockDetailsResponse(TigerResponse):
103+
def __init__(self):
104+
super(StockDetailsResponse, self).__init__()
105+
self.details = None
106+
self._is_success = None
107+
108+
def parse_response_content(self, response_content):
109+
response = super(StockDetailsResponse, self).parse_response_content(response_content)
110+
if 'is_success' in response:
111+
self._is_success = response['is_success']
112+
if not self.data:
113+
return
114+
detail_data = []
115+
data_json = json.loads(self.data)
116+
for item in data_json.get('items', {}):
117+
item_values = dict()
118+
for key, value in item.items():
119+
if value is None:
120+
continue
121+
if isinstance(value, six.string_types):
122+
value = get_string(value)
123+
tag = self._key_to_tag(key)
124+
if tag in SUB_FIELDS:
125+
for sub_k, sub_v in value.items():
126+
sub_tag = self._key_to_tag(sub_k)
127+
item_values[self._join_tag(tag, sub_tag)] = sub_v
128+
else:
129+
item_values[tag] = value
130+
131+
detail_data.append([item_values.get(tag) for tag in COLUMNS])
132+
133+
self.details = pd.DataFrame(detail_data, columns=COLUMNS)
134+
135+
@classmethod
136+
def _key_to_tag(cls, k):
137+
return DETAIL_FIELD_MAPPINGS[k] if k in DETAIL_FIELD_MAPPINGS else k
138+
139+
@classmethod
140+
def _join_tag(cls, tag, sub_tag):
141+
return '_'.join((tag, sub_tag))

0 commit comments

Comments
 (0)