Skip to content

Commit 9fbe615

Browse files
committed
Merge branch 'feat_stock_fundamental' into 'master'
【FEAT】 stock fundamental See merge request server/openapi/openapi-python-sdk!228
2 parents 8af1c5b + 664b1e9 commit 9fbe615

8 files changed

Lines changed: 49 additions & 12 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 3.3.0 (2024-12-17)
2+
### New
3+
- `QuoteClient.get_stock_fundamental` 获取股票基础数据, 如 ROE, PB
4+
### Fix
5+
- 长连接 `error_callback` 未调用的问题
6+
17
## 3.2.9 (2024-11-25)
28
### Fix
39
- 修复批量获取合约 `TradeClient.get_contracts` 传参错误

tigeropen/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@
44
55
@author: gaoan
66
"""
7-
__VERSION__ = '3.2.9'
7+
__VERSION__ = '3.3.0'

tigeropen/common/consts/service_types.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@
7070
WARRANT_FILTER = "warrant_filter"
7171
WARRANT_REAL_TIME_QUOTE = "warrant_real_time_quote"
7272
KLINE_QUOTA = "kline_quota" # 历史k线额度
73-
73+
STOCK_FUNDAMENTAL = "stock_fundamental"
7474

7575
# 期权行情
7676
OPTION_EXPIRATION = "option_expiration"

tigeropen/examples/quote_client_demo.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ def get_quote():
7070
calendar = openapi_client.get_trading_calendar(Market.US, begin_date='2022-07-01', end_date='2022-09-02')
7171
print(calendar)
7272

73+
fundamental = openapi_client.get_stock_fundamental(['AAPL', 'GOOG'], market=Market.US)
74+
print(fundamental)
7375

7476
def test_gat_bars_by_page():
7577
bars = openapi_client.get_bars_by_page(['AAPL'], period=BarPeriod.DAY,

tigeropen/push/protobuf_push_client.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,10 @@ def on_heartbeat(self, frame):
122122
self.heartbeat_callback(frame)
123123

124124
def on_error(self, frame):
125-
self.logger.error(frame)
125+
if self.error_callback:
126+
self.error_callback(frame)
127+
else:
128+
self.logger.error(frame)
126129

127130
def on_message(self, frame):
128131
try:

tigeropen/quote/quote_client.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from tigeropen.common.consts import THREAD_LOCAL, SecurityType, CorporateActionType, IndustryLevel
1616
from tigeropen.common.consts.filter_fields import FieldBelongType
1717
from tigeropen.common.consts.service_types import GRAB_QUOTE_PERMISSION, QUOTE_DELAY, GET_QUOTE_PERMISSION, \
18-
HISTORY_TIMELINE, FUTURE_CONTRACT_BY_CONTRACT_CODE, TRADING_CALENDAR, FUTURE_CONTRACTS, MARKET_SCANNER, \
18+
HISTORY_TIMELINE, FUTURE_CONTRACT_BY_CONTRACT_CODE, STOCK_FUNDAMENTAL, TRADING_CALENDAR, FUTURE_CONTRACTS, MARKET_SCANNER, \
1919
STOCK_BROKER, CAPITAL_FLOW, CAPITAL_DISTRIBUTION, WARRANT_REAL_TIME_QUOTE, WARRANT_FILTER, MARKET_SCANNER_TAGS, \
2020
KLINE_QUOTA, FUND_ALL_SYMBOLS, FUND_CONTRACTS, FUND_QUOTE, FUND_HISTORY_QUOTE, FINANCIAL_CURRENCY, \
2121
FINANCIAL_EXCHANGE_RATE, ALL_HK_OPTION_SYMBOLS, OPTION_DEPTH
@@ -1838,6 +1838,21 @@ def get_fund_history_quote(self, symbols, begin_time, end_time, limit=None):
18381838
params.lang = get_enum_value(self._lang)
18391839
request = OpenApiRequest(FUND_HISTORY_QUOTE, biz_model=params)
18401840
response_content = self.__fetch_data(request)
1841+
if response_content:
1842+
response = QuoteDataframeResponse()
1843+
response.parse_response_content(response_content)
1844+
if response.is_success():
1845+
return response.result
1846+
else:
1847+
raise ApiException(response.code, response.message)
1848+
1849+
def get_stock_fundamental(self, symbols, market):
1850+
params = MultipleQuoteParams()
1851+
params.symbols = symbols if isinstance(symbols, list) else [symbols]
1852+
params.market = get_enum_value(market)
1853+
params.lang = get_enum_value(self._lang)
1854+
request = OpenApiRequest(STOCK_FUNDAMENTAL, biz_model=params)
1855+
response_content = self.__fetch_data(request)
18411856
if response_content:
18421857
response = QuoteDataframeResponse()
18431858
response.parse_response_content(response_content)

tigeropen/quote/response/quote_dataframe_response.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@
66
import pandas as pd
77

88
from tigeropen.common.response import TigerResponse
9-
10-
FIELD_MAPPINGS = {'avgPrice': 'avg_price'}
9+
from tigeropen.common.util import string_utils
1110

1211

1312
class QuoteDataframeResponse(TigerResponse):
@@ -21,10 +20,16 @@ def parse_response_content(self, response_content):
2120
if 'is_success' in response:
2221
self._is_success = response['is_success']
2322

23+
data_items = []
2424
if self.data and isinstance(self.data, list):
25-
data_items = []
2625
for symbol_item in self.data:
2726
df = pd.DataFrame(symbol_item.get('items'))
2827
df.insert(0, 'symbol', symbol_item.get('symbol'))
2928
data_items.append(df)
30-
self.result = pd.concat(data_items).rename(columns=FIELD_MAPPINGS)
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)

tigeropen/tiger_open_config.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,13 @@
5858
TOKEN_REFRESH_DURATION = 24 * 60 * 60 # seconds
5959
TOKEN_CHECK_INTERVAL = 5 * 60 # seconds
6060

61+
def fallback_get_mac_address():
62+
return ':'.join(("%012x" % uuid.getnode())[i:i + 2] for i in range(0, 12, 2))
63+
6164
try:
6265
from getmac import get_mac_address
6366
except ImportError:
64-
def get_mac_address():
65-
return ':'.join(("%012x" % uuid.getnode())[i:i + 2] for i in range(0, 12, 2))
67+
get_mac_address = fallback_get_mac_address
6668

6769

6870
class TigerOpenClientConfig:
@@ -274,10 +276,14 @@ def __get_device_id():
274276
获取mac地址作为device_id
275277
:return:
276278
"""
279+
device_id = None
277280
try:
278-
return get_mac_address()
281+
device_id = get_mac_address()
279282
except:
280-
return None
283+
pass
284+
if not device_id:
285+
device_id = fallback_get_mac_address()
286+
return device_id
281287

282288
def _get_props_path(self, filename):
283289
if self.props_path is not None:

0 commit comments

Comments
 (0)