56
56
from tqsdk .calendar import _get_trading_calendar , TqContCalendar , _init_chinese_rest_days
57
57
from tqsdk .data_extension import DataExtension
58
58
from tqsdk .data_series import DataSeries
59
- from tqsdk .datetime import _get_trading_day_start_time , _get_trading_day_end_time , _get_trading_day_from_timestamp , \
60
- _datetime_to_timestamp_nano
59
+ from tqsdk .datetime import _get_trading_day_from_timestamp , _datetime_to_timestamp_nano , _timestamp_nano_to_datetime , \
60
+ _cst_now , _convert_user_input_to_nano
61
61
from tqsdk .diff import _merge_diff , _get_obj , _is_key_exist , _register_update_chan
62
62
from tqsdk .entity import Entity
63
63
from tqsdk .exceptions import TqTimeoutError
@@ -305,7 +305,7 @@ def __init__(self, account: Optional[Union[TqMultiAccount, UnionTradeable]] = No
305
305
def _print (self , msg : str = "" , level : str = "INFO" ):
306
306
if self .disable_print :
307
307
return
308
- dt = "" if self ._backtest else datetime . now ().strftime ('%Y-%m-%d %H:%M:%S' )
308
+ dt = "" if self ._backtest else _cst_now ().strftime ('%Y-%m-%d %H:%M:%S' )
309
309
level = level if isinstance (level , str ) else logging .getLevelName (level )
310
310
print (f"{ (dt + ' - ' ) if dt else '' } { level :>8} - { msg } " )
311
311
@@ -836,9 +836,15 @@ def get_kline_data_series(self, symbol: Union[str, List[str]], duration_seconds:
836
836
duration_seconds (int): K 线数据周期, 以秒为单位。例如: 1 分钟线为 60,1 小时线为 3600,日线为 86400。\
837
837
注意: 周期在日线以内时此参数可以任意填写, 在日线以上时只能是日线(86400)的整数倍
838
838
839
- start_dt (date/datetime): 起始时间, 如果类型为 date 则指的是交易日, 如果为 datetime 则指的是具体时间点
839
+ start_dt (date/datetime): 起始时间
840
+ * date: 指的是交易日
840
841
841
- end_dt (date/datetime): 结束时间, 如果类型为 date 则指的是交易日, 如果为 datetime 则指的是具体时间点
842
+ * datetime: 指的是具体时间点,如果没有指定时区信息,则默认为北京时间
843
+
844
+ end_dt (date/datetime): 结束时间
845
+ * date: 指的是交易日
846
+
847
+ * datetime: 指的是具体时间点,如果没有指定时区信息,则默认为北京时间
842
848
843
849
adj_type (str/None): [可选]指定复权类型,默认为 None。adj_type 参数只对股票和基金类型合约有效。\
844
850
"F" 表示前复权;"B" 表示后复权;None 表示不做处理。
@@ -896,9 +902,15 @@ def get_tick_data_series(self, symbol: Union[str, List[str]], start_dt: Union[da
896
902
Args:
897
903
symbol (str): 指定合约代码。当前只支持单个合约。
898
904
899
- start_dt (date/datetime): 起始时间, 如果类型为 date 则指的是交易日, 如果为 datetime 则指的是具体时间点
905
+ start_dt (date/datetime): 起始时间
906
+ * date: 指的是交易日
907
+
908
+ * datetime: 指的是具体时间点,如果没有指定时区信息,则默认为北京时间
900
909
901
- end_dt (date/datetime): 结束时间, 如果类型为 date 则指的是交易日, 如果为 datetime 则指的是具体时间点
910
+ end_dt (date/datetime): 结束时间
911
+ * date: 指的是交易日
912
+
913
+ * datetime: 指的是具体时间点,如果没有指定时区信息,则默认为北京时间
902
914
903
915
adj_type (str/None): [可选]指定复权类型,默认为 None。adj_type 参数只对股票和基金类型合约有效。\
904
916
"F" 表示前复权;"B" 表示后复权;None 表示不做处理。
@@ -954,20 +966,7 @@ def _get_data_series(self, call_func: str, symbol_list: Union[str, List[str]], d
954
966
if len (symbol_list ) != 1 :
955
967
raise Exception (f"{ call_func } 数据获取方式暂不支持多合约请求" )
956
968
self ._ensure_symbol (symbol_list ) # 检查合约代码是否存在
957
- if isinstance (start_dt , datetime ):
958
- start_dt_nano = _datetime_to_timestamp_nano (start_dt )
959
- elif isinstance (start_dt , date ):
960
- start_dt_nano = _get_trading_day_start_time (
961
- _datetime_to_timestamp_nano (datetime (start_dt .year , start_dt .month , start_dt .day )))
962
- else :
963
- raise Exception (f"start_dt 参数类型 { type (start_dt )} 错误, 只支持 datetime / date 类型,请检查是否正确" )
964
- if isinstance (end_dt , datetime ):
965
- end_dt_nano = _datetime_to_timestamp_nano (end_dt )
966
- elif isinstance (end_dt , date ):
967
- end_dt_nano = _get_trading_day_end_time (
968
- _datetime_to_timestamp_nano (datetime (end_dt .year , end_dt .month , end_dt .day )))
969
- else :
970
- raise Exception (f"end_dt 参数类型 { type (end_dt )} 错误, 只支持 datetime / date 类型,请检查是否正确" )
969
+ start_dt_nano , end_dt_nano = _convert_user_input_to_nano (start_dt , end_dt )
971
970
if adj_type not in [None , "F" , "B" ]:
972
971
raise Exception ("adj_type 参数只支持 None (不复权) | 'F' (前复权) | 'B' (后复权) " )
973
972
ds = DataSeries (self , symbol_list , dur_nano , start_dt_nano , end_dt_nano , adj_type )
@@ -981,17 +980,23 @@ def _get_data_series(self, call_func: str, symbol_list: Union[str, List[str]], d
981
980
# ----------------------------------------------------------------------
982
981
def get_trading_calendar (self , start_dt : Union [date , datetime ], end_dt : Union [date , datetime ]) -> pd .DataFrame :
983
982
"""
984
- 获取一段时间内的交易日历信息,交易日历可以处理的范围为 2003-01-01 ~ 2022 -12-31。
983
+ 获取一段时间内的交易日历信息,交易日历可以处理的范围为 2003-01-01 ~ 2024 -12-31。
985
984
986
985
Args:
987
- start_dt (date/datetime): 起始时间,如果类型为 date 则指的是该日期;如果为 datetime 则指的是该时间点所在日期
986
+ start_dt (date/datetime): 起始时间
987
+ * date: 指的是交易日
988
+
989
+ * datetime: 指的指的是该时间点所在年月日日期
990
+
991
+ end_dt (date/datetime): 结束时间
992
+ * date: 指的是交易日
988
993
989
- end_dt (date/datetime): 结束时间,如果类型为 date 则指的是该日期;如果为 datetime 则指的是该时间点所在日期
994
+ * datetime: 指的指的是该时间点所在年月日日期
990
995
991
996
Returns:
992
997
pandas.DataFrame: 包含以下列:
993
998
994
- * date: (datetime64[ns]) 日期
999
+ * date: (datetime64[ns]) 日期,为北京时间的日期
995
1000
* trading: (bool) 是否是交易日
996
1001
997
1002
Example::
@@ -1016,11 +1021,11 @@ def get_trading_calendar(self, start_dt: Union[date, datetime], end_dt: Union[da
1016
1021
api.close()
1017
1022
"""
1018
1023
if isinstance (start_dt , datetime ):
1019
- start_dt = date ( year = start_dt .year , month = start_dt . month , day = start_dt . day )
1024
+ start_dt = start_dt .date ( )
1020
1025
elif not isinstance (start_dt , date ):
1021
1026
raise Exception (f"start_dt 参数类型 { type (start_dt )} 错误, 只支持 datetime / date 类型,请检查是否正确" )
1022
1027
if isinstance (end_dt , datetime ):
1023
- end_dt = date ( year = end_dt .year , month = end_dt . month , day = end_dt . day )
1028
+ end_dt = end_dt .date ( )
1024
1029
elif not isinstance (end_dt , date ):
1025
1030
raise Exception (f"end_dt 参数类型 { type (end_dt )} 错误, 只支持 datetime / date 类型,请检查是否正确" )
1026
1031
first_date , latest_date = _init_chinese_rest_days ()
@@ -1078,9 +1083,9 @@ def query_his_cont_quotes(self, symbol: Union[str, List[str]], n: int = 200) ->
1078
1083
raise Exception (f"参数错误,n={ n } 应该是大于等于 1 的整数" )
1079
1084
now_dt = self ._get_current_datetime ()
1080
1085
trading_day = _get_trading_day_from_timestamp (_datetime_to_timestamp_nano (now_dt ))
1081
- end_dt = datetime . fromtimestamp (trading_day / 1000000000 )
1082
- cont_calendar = TqContCalendar (start_dt = end_dt - timedelta (days = n * 2 + 30 ), end_dt = end_dt , symbols = symbols ,
1083
- headers = self ._base_headers )
1086
+ end_dt = _timestamp_nano_to_datetime (trading_day )
1087
+ cont_calendar = TqContCalendar (start_dt = ( end_dt - timedelta (days = n * 2 + 30 )). date () , end_dt = end_dt . date () ,
1088
+ symbols = symbols , headers = self ._base_headers )
1084
1089
df = cont_calendar .df .loc [cont_calendar .df .date .le (end_dt ), ['date' ] + symbols ]
1085
1090
df = df .iloc [- n :]
1086
1091
df .reset_index (inplace = True , drop = True )
@@ -2575,10 +2580,8 @@ def filter(query_result):
2575
2580
for edge in quote ["derivatives" ]["edges" ]:
2576
2581
option = edge ["node" ]
2577
2582
if (option_class and option ["call_or_put" ] != option_class ) \
2578
- or (exe_year and datetime .fromtimestamp (
2579
- option ["last_exercise_datetime" ] / 1e9 ).year != exe_year ) \
2580
- or (exe_month and datetime .fromtimestamp (
2581
- option ["last_exercise_datetime" ] / 1e9 ).month != exe_month ) \
2583
+ or (exe_year and _timestamp_nano_to_datetime (option ["last_exercise_datetime" ]).year != exe_year ) \
2584
+ or (exe_month and _timestamp_nano_to_datetime (option ["last_exercise_datetime" ]).month != exe_month ) \
2582
2585
or (strike_price and option ["strike_price" ] != strike_price ) \
2583
2586
or (expired is not None and option ["expired" ] != expired ) \
2584
2587
or (has_A is True and option ["english_name" ].count ('A' ) == 0 ) \
@@ -2740,8 +2743,8 @@ def query_symbol_info(self, symbol: Union[str, List[str]]) -> TqSymbolDataFrame:
2740
2743
* pre_settlement: 昨结算
2741
2744
* pre_open_interest: 昨持仓
2742
2745
* pre_close: 昨收盘
2743
- * trading_time_day: 白盘交易时间段,list 类型
2744
- * trading_time_night: 夜盘交易时间段,list 类型
2746
+ * trading_time_day: 白盘交易时间段,pandas.Series 类型
2747
+ * trading_time_night: 夜盘交易时间段,pandas.Series 类型
2745
2748
2746
2749
注意:
2747
2750
@@ -2999,7 +3002,7 @@ def _convert_query_result_to_list(self, query_result):
2999
3002
for quote in query_result .get ("result" , {}).get ("multi_symbol_info" , []):
3000
3003
if quote .get ("derivatives" ):
3001
3004
for edge in quote ["derivatives" ]["edges" ]:
3002
- last_exercise_datetime = datetime . fromtimestamp (edge ["node" ]["last_exercise_datetime" ] / 1e9 )
3005
+ last_exercise_datetime = _timestamp_nano_to_datetime (edge ["node" ]["last_exercise_datetime" ])
3003
3006
edge ["node" ]["exercise_year" ] = last_exercise_datetime .year
3004
3007
edge ["node" ]["exercise_month" ] = last_exercise_datetime .month
3005
3008
options .append (edge ["node" ])
@@ -3157,7 +3160,7 @@ def _setup_connection(self):
3157
3160
try :
3158
3161
self ._md_url = self ._auth ._get_md_url (self ._stock , backtest = isinstance (self ._backtest , TqBacktest )) # 如果用户未指定行情地址,则使用名称服务获取行情地址
3159
3162
except Exception as e :
3160
- now = datetime . now ()
3163
+ now = _cst_now ()
3161
3164
if now .hour == 19 and 0 <= now .minute <= 30 :
3162
3165
raise Exception (f"{ e } , 每日 19:00-19:30 为日常运维时间,请稍后再试" )
3163
3166
else :
@@ -3178,8 +3181,8 @@ def _setup_connection(self):
3178
3181
# 期权增加了 exercise_year、exercise_month 在旧版合约服务中没有,需要添加,使用下市日期代替最后行权日
3179
3182
for quote in quotes .values ():
3180
3183
if quote ["ins_class" ] == "FUTURE_OPTION" :
3181
- quote ["exercise_year" ] = datetime . fromtimestamp ( quote ["expire_datetime" ]).year
3182
- quote ["exercise_month" ] = datetime . fromtimestamp ( quote ["expire_datetime" ]).month
3184
+ quote ["exercise_year" ] = _timestamp_nano_to_datetime ( int ( quote ["expire_datetime" ] * 1000000 ) * 1000 ).year
3185
+ quote ["exercise_month" ] = _timestamp_nano_to_datetime ( int ( quote ["expire_datetime" ] * 1000000 ) * 1000 ).month
3183
3186
ws_md_recv_chan .send_nowait ({
3184
3187
"aid" : "rtn_data" ,
3185
3188
"data" : [{"quotes" : quotes }]
@@ -3952,9 +3955,9 @@ def _symbols_to_quotes(self, symbols, keys=None):
3952
3955
def _get_current_datetime (self ):
3953
3956
if isinstance (self ._backtest , TqBacktest ):
3954
3957
current_dt = self ._data .get ('_tqsdk_backtest' , {}).get ('current_dt' , 0 )
3955
- return datetime . fromtimestamp (current_dt / 1e9 )
3958
+ return _timestamp_nano_to_datetime (current_dt )
3956
3959
else :
3957
- return datetime . now ()
3960
+ return _cst_now ()
3958
3961
3959
3962
3960
3963
print ("在使用天勤量化之前,默认您已经知晓并同意以下免责条款,如果不同意请立即停止使用:https://www.shinnytech.com/blog/disclaimer/" , file = sys .stderr )
0 commit comments