Skip to content

Commit 8acab3d

Browse files
committed
Merge branch 'dev' into 'master'
Dev-master See merge request server/openapi/openapi-python-sdk!127
2 parents 4580136 + 6ef7bd7 commit 8acab3d

File tree

7 files changed

+77
-38
lines changed

7 files changed

+77
-38
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 2.1.6 (2022-08-11)
2+
### Modify
3+
- 支持全局时区配置, 可通过 ClientConfig.timezone 设置时区
4+
5+
16
## 2.1.5 (2022-08-01)
27
### Modify
38
- 交易相关接口支持全局语言配置, 可通过 ClientConfig.language 改变默认语言

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__ = '2.1.5'
7+
__VERSION__ = '2.1.6'

tigeropen/common/util/common_utils.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"""
77
from enum import Enum
88

9+
import delorean
910
import pytz
1011

1112
eastern = pytz.timezone('US/Eastern')
@@ -16,7 +17,7 @@
1617
def has_value(m, key):
1718
if not m:
1819
return False
19-
if not (key in m):
20+
if key not in m:
2021
return False
2122
if not m[key]:
2223
return False
@@ -27,3 +28,18 @@ def get_enum_value(e, enum_type=None):
2728
if enum_type is None:
2829
return e.value if isinstance(e, Enum) else e
2930
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+

tigeropen/examples/client_config.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,5 @@ def get_client_config():
2121
client_config.account = 'your account'
2222
client_config.secret_key = None # 机构交易员专有密钥 (机构用户需要填写, 个人开发者无需填写)
2323
client_config.language = Language.en_US
24+
# client_config.timezone = 'US/Eastern' # 设置全局时区
2425
return client_config

tigeropen/quote/quote_client.py

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@
88
import re
99
import time
1010

11-
import delorean
1211
import pandas as pd
1312

14-
from tigeropen.common.consts import Market, Language, QuoteRight, BarPeriod, OPEN_API_SERVICE_VERSION_V3
13+
from tigeropen.common.consts import Market, QuoteRight, BarPeriod, OPEN_API_SERVICE_VERSION_V3
1514
from tigeropen.common.consts import THREAD_LOCAL, SecurityType, CorporateActionType, IndustryLevel
1615
from tigeropen.common.consts.service_types import GRAB_QUOTE_PERMISSION, QUOTE_DELAY, GET_QUOTE_PERMISSION, \
1716
HISTORY_TIMELINE, FUTURE_CONTRACT_BY_CONTRACT_CODE, TRADING_CALENDAR
@@ -23,7 +22,7 @@
2322
QUOTE_DEPTH, INDUSTRY_LIST, INDUSTRY_STOCKS, STOCK_INDUSTRY, STOCK_DETAIL
2423
from tigeropen.common.exceptions import ApiException
2524
from tigeropen.common.request import OpenApiRequest
26-
from tigeropen.common.util.common_utils import eastern, get_enum_value
25+
from tigeropen.common.util.common_utils import eastern, get_enum_value, date_str_to_timestamp
2726
from tigeropen.common.util.contract_utils import extract_option_info
2827
from tigeropen.fundamental.request.model import FinancialDailyParams, FinancialReportParams, CorporateActionParams, \
2928
IndustryParams
@@ -75,10 +74,12 @@ def __init__(self, client_config, logger=None, is_grab_permission=True):
7574
if not logger:
7675
logger = logging.getLogger('tiger_openapi')
7776
super(QuoteClient, self).__init__(client_config, logger=logger)
77+
self._lang = LANGUAGE
78+
self._timezone = eastern
7879
if client_config:
7980
self._lang = client_config.language
80-
else:
81-
self._lang = LANGUAGE
81+
if client_config.timezone:
82+
self._timezone = client_config.timezone
8283
self.permissions = None
8384
if is_grab_permission and self.permissions is None:
8485
self.permissions = self.grab_quote_permission()
@@ -646,7 +647,7 @@ def get_option_chain(self, symbol, expiry, option_filter=None, **kwargs):
646647
param = SingleContractParams()
647648
param.symbol = symbol
648649
if isinstance(expiry, str) and re.match('[0-9]{4}-[0-9]{2}-[0-9]{2}', expiry):
649-
param.expiry = int(delorean.parse(expiry, timezone=eastern, dayfirst=False).datetime.timestamp() * 1000)
650+
param.expiry = date_str_to_timestamp(expiry, self._timezone)
650651
else:
651652
param.expiry = expiry
652653
params.contracts = [param]
@@ -699,7 +700,7 @@ def get_option_briefs(self, identifiers):
699700
continue
700701
param = SingleContractParams()
701702
param.symbol = symbol
702-
param.expiry = int(delorean.parse(expiry, timezone=eastern, dayfirst=False).datetime.timestamp() * 1000)
703+
param.expiry = date_str_to_timestamp(expiry, self._timezone)
703704
param.put_call = put_call
704705
param.strike = strike
705706
contracts.append(param)
@@ -743,12 +744,12 @@ def get_option_bars(self, identifiers, begin_time=-1, end_time=4070880000000):
743744
continue
744745
param = SingleOptionQuoteParams()
745746
param.symbol = symbol
746-
param.expiry = int(delorean.parse(expiry, timezone=eastern, dayfirst=False).datetime.timestamp() * 1000)
747+
param.expiry = date_str_to_timestamp(expiry, self._timezone)
747748
param.put_call = put_call
748749
param.strike = strike
749750
param.period = BarPeriod.DAY.value
750-
param.begin_time = begin_time
751-
param.end_time = end_time
751+
param.begin_time = date_str_to_timestamp(begin_time, self._timezone)
752+
param.end_time = date_str_to_timestamp(end_time, self._timezone)
752753
contracts.append(param)
753754
params.contracts = contracts
754755
request = OpenApiRequest(OPTION_KLINE, biz_model=params)
@@ -782,7 +783,7 @@ def get_option_trade_ticks(self, identifiers):
782783
continue
783784
param = SingleContractParams()
784785
param.symbol = symbol
785-
param.expiry = int(delorean.parse(expiry, timezone=eastern, dayfirst=False).datetime.timestamp() * 1000)
786+
param.expiry = date_str_to_timestamp(expiry, timezone=self._timezone)
786787
param.put_call = put_call
787788
param.strike = strike
788789
contracts.append(param)
@@ -965,7 +966,7 @@ def get_future_bars(self, identifiers, period=BarPeriod.DAY, begin_time=-1, end_
965966
params = FutureQuoteParams()
966967
params.contract_codes = identifiers if isinstance(identifiers, list) else [identifiers]
967968
params.period = get_enum_value(period)
968-
params.begin_time = begin_time
969+
params.begin_time = date_str_to_timestamp(begin_time, self._timezone)
969970
params.end_time = end_time
970971
params.limit = limit
971972
params.page_token = page_token if len(params.contract_codes) == 1 else None
@@ -1099,8 +1100,8 @@ def get_corporate_split(self, symbols, market, begin_date, end_date):
10991100
params.action_type = CorporateActionType.SPLIT.value
11001101
params.symbols = symbols
11011102
params.market = get_enum_value(market)
1102-
params.begin_date = begin_date
1103-
params.end_date = end_date
1103+
params.begin_date = date_str_to_timestamp(begin_date, self._timezone)
1104+
params.end_date = date_str_to_timestamp(end_date, self._timezone)
11041105
params.lang = get_enum_value(self._lang)
11051106
request = OpenApiRequest(CORPORATE_ACTION, biz_model=params)
11061107
response_content = self.__fetch_data(request)
@@ -1136,8 +1137,8 @@ def get_corporate_dividend(self, symbols, market, begin_date, end_date):
11361137
params.action_type = CorporateActionType.DIVIDEND.value
11371138
params.symbols = symbols
11381139
params.market = get_enum_value(market)
1139-
params.begin_date = begin_date
1140-
params.end_date = end_date
1140+
params.begin_date = date_str_to_timestamp(begin_date, self._timezone)
1141+
params.end_date = date_str_to_timestamp(end_date, self._timezone)
11411142
params.lang = get_enum_value(self._lang)
11421143
request = OpenApiRequest(CORPORATE_ACTION, biz_model=params)
11431144
response_content = self.__fetch_data(request)
@@ -1160,8 +1161,8 @@ def get_corporate_earnings_calendar(self, market, begin_date, end_date):
11601161
params = CorporateActionParams()
11611162
params.action_type = CorporateActionType.EARNINGS_CALENDAR.value
11621163
params.market = get_enum_value(market)
1163-
params.begin_date = begin_date
1164-
params.end_date = end_date
1164+
params.begin_date = date_str_to_timestamp(begin_date, self._timezone)
1165+
params.end_date = date_str_to_timestamp(end_date, self._timezone)
11651166
params.lang = get_enum_value(self._lang)
11661167
request = OpenApiRequest(CORPORATE_ACTION, biz_model=params)
11671168
response_content = self.__fetch_data(request)
@@ -1191,8 +1192,8 @@ def get_financial_daily(self, symbols, market, fields, begin_date, end_date):
11911192
params.symbols = symbols
11921193
params.market = get_enum_value(market)
11931194
params.fields = [get_enum_value(field) for field in fields]
1194-
params.begin_date = begin_date
1195-
params.end_date = end_date
1195+
params.begin_date = date_str_to_timestamp(begin_date, self._timezone)
1196+
params.end_date = date_str_to_timestamp(end_date, self._timezone)
11961197
params.lang = get_enum_value(self._lang)
11971198
request = OpenApiRequest(FINANCIAL_DAILY, biz_model=params)
11981199
response_content = self.__fetch_data(request)

tigeropen/tiger_open_config.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
@author: gaoan
66
"""
77
import json
8-
8+
from pytz import timezone
99
from tigeropen.common.consts import Language
1010
from tigeropen.common.util.signature_utils import read_private_key
1111
from tigeropen.common.util.web_utils import do_get
@@ -59,7 +59,8 @@ def __init__(self, sandbox_debug=False, enable_dynamic_domain=True):
5959
self._charset = CHARSET
6060
# 语言
6161
self._language = LANGUAGE
62-
# 以下为可选参数
62+
# timezone
63+
self._timezone = None
6364
# 请求读取超时,单位秒,默认15s
6465
self._timeout = TIMEOUT
6566
self._sandbox_debug = sandbox_debug
@@ -147,6 +148,16 @@ def language(self):
147148
def language(self, value):
148149
self._language = value
149150

151+
@property
152+
def timezone(self):
153+
return self._timezone
154+
155+
@timezone.setter
156+
def timezone(self, value):
157+
if isinstance(value, str):
158+
value = timezone(value)
159+
self._timezone = value
160+
150161
@property
151162
def timeout(self):
152163
return self._timeout
@@ -201,7 +212,7 @@ def refresh_domains(self):
201212

202213
def get_client_config(private_key_path, tiger_id, account, sandbox_debug=False, sign_type=None, timeout=None,
203214
language=None, charset=None, server_url=None, socket_host_port=None, secret_key=None,
204-
enable_dynamic_domain=True):
215+
enable_dynamic_domain=True, timezone=None):
205216
"""
206217
生成客户端配置
207218
:param private_key_path: 私钥文件路径, 如 '/Users/tiger/.ssh/rsa_private_key.pem'
@@ -216,6 +227,7 @@ def get_client_config(private_key_path, tiger_id, account, sandbox_debug=False,
216227
:param socket_host_port: 推送长连接的域名端口, 值为协议, 域名, 端口构成的三元组
217228
:param secret_key: 机构交易员专有密钥 (个人开发者无需指定)
218229
:param enable_dynamic_domain: 是否初始化时拉取服务域名
230+
:param timezone:
219231
:return:
220232
"""
221233
config = TigerOpenClientConfig(sandbox_debug=sandbox_debug, enable_dynamic_domain=enable_dynamic_domain)
@@ -228,6 +240,8 @@ def get_client_config(private_key_path, tiger_id, account, sandbox_debug=False,
228240
config.timeout = timeout
229241
if language:
230242
config.language = language
243+
if timezone:
244+
config.timezone = timezone
231245
if charset:
232246
config.charset = charset
233247
if server_url:

tigeropen/trade/trade_client.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
CANCEL_ORDER, MODIFY_ORDER, PLACE_ORDER, ACTIVE_ORDERS, INACTIVE_ORDERS, FILLED_ORDERS, CONTRACT, PREVIEW_ORDER, \
1212
PRIME_ASSETS, ORDER_TRANSACTIONS, QUOTE_CONTRACT, ANALYTICS_ASSET
1313
from tigeropen.common.exceptions import ApiException
14-
from tigeropen.common.util.common_utils import get_enum_value
14+
from tigeropen.common.util.common_utils import get_enum_value, date_str_to_timestamp
1515
from tigeropen.common.request import OpenApiRequest
1616
from tigeropen.tiger_open_client import TigerOpenClient
1717
from tigeropen.tiger_open_config import LANGUAGE
@@ -39,10 +39,12 @@ def __init__(self, client_config, logger=None):
3939
self._account = client_config.account
4040
self._lang = client_config.language
4141
self._secret_key = client_config.secret_key
42+
self._timezone = client_config.timezone
4243
else:
4344
self._account = None
4445
self._lang = LANGUAGE
4546
self._secret_key = None
47+
self._timezone = None
4648

4749
def get_managed_accounts(self, account=None):
4850
"""
@@ -322,8 +324,8 @@ def get_orders(self, account=None, sec_type=None, market=Market.ALL, symbol=None
322324
params.sec_type = get_enum_value(sec_type)
323325
params.market = get_enum_value(market)
324326
params.symbol = symbol
325-
params.start_date = start_time
326-
params.end_date = end_time
327+
params.start_date = date_str_to_timestamp(start_time, self._timezone)
328+
params.end_date = date_str_to_timestamp(end_time, self._timezone)
327329
params.limit = limit
328330
params.is_brief = is_brief
329331
params.states = [get_enum_value(state) for state in states] if states else None
@@ -352,8 +354,8 @@ def get_open_orders(self, account=None, sec_type=None, market=Market.ALL, symbol
352354
params.sec_type = get_enum_value(sec_type)
353355
params.market = get_enum_value(market)
354356
params.symbol = symbol
355-
params.start_date = start_time
356-
params.end_date = end_time
357+
params.start_date = date_str_to_timestamp(start_time, self._timezone)
358+
params.end_date = date_str_to_timestamp(end_time, self._timezone)
357359
params.parent_id = parent_id
358360
params.sort_by = get_enum_value(sort_by)
359361
params.lang = get_enum_value(self._lang)
@@ -379,8 +381,8 @@ def get_cancelled_orders(self, account=None, sec_type=None, market=Market.ALL, s
379381
params.sec_type = get_enum_value(sec_type)
380382
params.market = get_enum_value(market)
381383
params.symbol = symbol
382-
params.start_date = start_time
383-
params.end_date = end_time
384+
params.start_date = date_str_to_timestamp(start_time, self._timezone)
385+
params.end_date = date_str_to_timestamp(end_time, self._timezone)
384386
params.sort_by = get_enum_value(sort_by)
385387
params.lang = get_enum_value(self._lang)
386388
request = OpenApiRequest(INACTIVE_ORDERS, biz_model=params)
@@ -405,8 +407,8 @@ def get_filled_orders(self, account=None, sec_type=None, market=Market.ALL, symb
405407
params.sec_type = get_enum_value(sec_type)
406408
params.market = get_enum_value(market)
407409
params.symbol = symbol
408-
params.start_date = start_time
409-
params.end_date = end_time
410+
params.start_date = date_str_to_timestamp(start_time, self._timezone)
411+
params.end_date = date_str_to_timestamp(end_time, self._timezone)
410412
params.sort_by = get_enum_value(sort_by)
411413
params.lang = get_enum_value(self._lang)
412414
request = OpenApiRequest(FILLED_ORDERS, biz_model=params)
@@ -665,8 +667,8 @@ def get_transactions(self, account=None, order_id=None, symbol=None, sec_type=No
665667
params.order_id = order_id
666668
params.sec_type = get_enum_value(sec_type)
667669
params.symbol = symbol
668-
params.start_date = start_time
669-
params.end_date = end_time
670+
params.start_date = date_str_to_timestamp(start_time, self._timezone)
671+
params.end_date = date_str_to_timestamp(end_time, self._timezone)
670672
params.limit = limit
671673
params.expiry = expiry
672674
params.strike = strike
@@ -688,8 +690,8 @@ def get_analytics_asset(self, account=None, start_date=None, end_date=None, seg_
688690
"""
689691
get analytics of history asset
690692
:param account:
691-
:param start_date:
692-
:param end_date:
693+
:param start_date: date str. format yyyyMMdd, like '2021-12-01'
694+
:param end_date: date_str.
693695
:param seg_type: tigeropen.common.consts.SegmentType, like SegmentType.SEC
694696
:param currency: tigeropen.common.consts.Currency, like Currency.USD
695697
:param sub_account: sub account of institution account

0 commit comments

Comments
 (0)