gjdatac-api 0.1.4__tar.gz → 0.1.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: gjdatac_api
3
- Version: 0.1.4
4
- Summary: vwap,twap接口数据,接入tick_l2数据,新增实时订阅接口
3
+ Version: 0.1.6
4
+ Summary: 数据接口打包
5
5
  Author: yin
6
6
  Author-email: 2018209921@qq.com
7
7
  Requires-Python: >3.6
8
8
  Description-Content-Type: text/markdown
9
9
 
10
- 将原有接口全部更新,新增后续新需求
10
+ ### 新增主力合约接口
@@ -2,6 +2,7 @@
2
2
 
3
3
  import re
4
4
  import datetime
5
+ import operator
5
6
  import asyncio
6
7
 
7
8
  import holidays
@@ -10,10 +11,11 @@ import pandas as pd
10
11
  import dolphindb as ddb
11
12
 
12
13
  from .dict_data import (get_price_frequency_dict, get_price_data_type_dict, get_instruments_type_dict,
13
- future_delivery_fee_return_fields, future_delivery_fee_return_fields_rename,
14
- future_margin_ratio_return_fields, future_margin_ratio_return_fields_rename,
15
- future_limit_position_return_fields, future_limit_position_return_fields_rename)
14
+ future_delivery_fee_return_fields, future_delivery_fee_return_fields_rename,
15
+ future_margin_ratio_return_fields, future_margin_ratio_return_fields_rename,
16
+ future_limit_position_return_fields, future_limit_position_return_fields_rename)
16
17
  from .dolphindb_info import *
18
+ from .instrument_class import Instrument
17
19
 
18
20
 
19
21
  class GJDataC:
@@ -952,23 +954,37 @@ class GJDataC:
952
954
 
953
955
  """ get_trading_dates(交易日历) """
954
956
 
955
- def get_trading_dates(self, date=datetime.date.today(), n=None, start_date=None, end_date=None):
957
+ def get_trading_dates(self, date=datetime.date.today(), n=None, start_date=None, end_date=None,
958
+ is_include_start=True, is_include_end=True,
959
+ trade_time=None, date_count=None, date_type=None):
956
960
  """
961
+
957
962
  获取交易日历接口
958
963
  :param date: str--选填, 日期
959
964
  :param n: str--必填,根据不同值获取对应的交易日历
960
965
  :param start_date: str(datetime.date, datetime.datetime)--选填, 开始日期
961
966
  :param end_date: str(datetime.date, datetime.datetime)--选填, 结束日期
967
+ :param is_include_start 是否包含开始日期
968
+ :param is_include_end 是否包含结束日期
962
969
  若填写【date、n】为入参,则无法填写【start_date、end_date】,反之依然
963
970
  :return: data:交易日历
971
+
972
+ 当入参为trade_time, date_count, date_type时,功能如下:
973
+ 查询前后 N 个交易日或时间点
974
+ :param trade_time: 当前时间点,格式为 'YYYY.MM.DD hh:mm:ss'
975
+ :param date_count: 查询的交易日或时间数量,负数表示向前查询,正数表示向后查询
976
+ :param date_type: 数据类型,'1d' 表示日频率,'1m' 表示分钟频率
977
+ :return: 查询到的交易日或时间点列表
964
978
  """
965
979
 
966
980
  """ 校验参数 """
967
- data = self.get_trading_dates_validate_date_n_start_end(date, n, start_date, end_date)
981
+ data = self.get_trading_dates_validate_date_n_start_end(date, n, start_date, end_date, is_include_start,
982
+ is_include_end, trade_time, date_count, date_type)
968
983
 
969
984
  return data
970
985
 
971
- def get_trading_dates_validate_date_n_start_end(self, date, n, start_date, end_date):
986
+ def get_trading_dates_validate_date_n_start_end(self, date, n, start_date, end_date, is_include_start,
987
+ is_include_end, trade_time, date_count, date_type):
972
988
  """
973
989
  校验date、n和start_date、end_date有效性
974
990
 
@@ -976,6 +992,11 @@ class GJDataC:
976
992
  :param n: str--根据不同值获取对应的交易日历
977
993
  :param start_date: str(datetime.date, datetime.datetime)--开始日期
978
994
  :param end_date: str(datetime.date, datetime.datetime)--结束日期
995
+ :param is_include_start 是否包含开始日期
996
+ :param is_include_end 是否包含结束日期
997
+ :param trade_time: 当前时间点,格式为 'YYYY.MM.DD hh:mm:ss'
998
+ :param date_count: 查询的交易日或时间数量,负数表示向前查询,正数表示向后查询
999
+ :param date_type: 数据类型,'1d' 表示日频率,'1m' 表示分钟频率
979
1000
  :return: 如果校验通过,就返回对应的数据,否则抛出异常
980
1001
  """
981
1002
 
@@ -986,7 +1007,9 @@ class GJDataC:
986
1007
  elif date and n: # 根据date和n获取交易日历
987
1008
  return self.get_trading_dates_by_date_n(date, n)
988
1009
  elif start_date and end_date: # 根据start_date和end_date获取交易日历
989
- return self.get_trading_dates_by_start_end(start_date, end_date)
1010
+ return self.get_trading_dates_by_start_end(start_date, end_date, is_include_start, is_include_end)
1011
+ elif trade_time and date_count and date_type: # 查询前/后 N个交易日/时间数据
1012
+ return self.get_trading_date(trade_time, date_count, date_type)
990
1013
  else:
991
1014
  raise ValueError("parameter error: please pass date、n or start_date、end_date")
992
1015
 
@@ -1010,17 +1033,23 @@ class GJDataC:
1010
1033
 
1011
1034
  return self.get_dates_in_n(date, n)
1012
1035
 
1013
- def get_trading_dates_by_start_end(self, start_date, end_date):
1036
+ def get_trading_dates_by_start_end(self, start_date, end_date, is_include_start, is_include_end):
1014
1037
  """
1015
1038
  根据start_date和end_date获取交易日历
1016
1039
  :param start_date: str(datetime.date, datetime.datetime)--选填, 开始日期
1017
1040
  :param end_date: str(datetime.date, datetime.datetime)--选填, 结束日期
1041
+ :param is_include_start 是否包含开始日期
1042
+ :param is_include_end 是否包含结束日期
1018
1043
 
1019
1044
  :return: data:根据start_date和end_date筛选后的数据
1020
1045
  """
1021
1046
 
1022
1047
  trading_params_data = self.get_trading_dates_get_data()
1023
1048
 
1049
+ # 动态生成比较运算符
1050
+ start_operator = operator.ge if is_include_start else operator.gt
1051
+ end_operator = operator.le if is_include_end else operator.lt
1052
+
1024
1053
  # 校验日期类型
1025
1054
  if self.check_date_type(start_date, end_date):
1026
1055
  # 如果类型校验通过,则将start_date和end_date处理成对应的时间数据类型
@@ -1029,14 +1058,22 @@ class GJDataC:
1029
1058
  if isinstance(end_date, str):
1030
1059
  end_date = self._get_trading_dates_by_start_end(end_date)
1031
1060
  # 筛选 trading_day_str 列在 start_date 和 end_date 之间的数据
1061
+ # filtered_df = trading_params_data.loc[
1062
+ # (trading_params_data['trading_day_str'] >= start_date) & (
1063
+ # trading_params_data['trading_day_str'] <= end_date)]
1064
+
1065
+ # 过滤数据
1032
1066
  filtered_df = trading_params_data.loc[
1033
- (trading_params_data['trading_day_str'] >= start_date) & (
1034
- trading_params_data['trading_day_str'] <= end_date)]
1067
+ start_operator(trading_params_data['trading_day_str'], start_date) &
1068
+ end_operator(trading_params_data['trading_day_str'], end_date)
1069
+ ]
1035
1070
 
1036
1071
  # 筛选 trade_flag 列等于 T 的数据(是交易日的数据)
1037
1072
  final_df = filtered_df.loc[filtered_df['trade_flag'] == 'T']
1038
- data = sorted(final_df["trading_day_str"].tolist())
1039
- return data
1073
+ date_list = sorted(final_df["trading_day_str"].tolist())
1074
+ formatted_date_list = [d.strftime('%Y.%m.%d') for d in date_list]
1075
+
1076
+ return formatted_date_list
1040
1077
  else:
1041
1078
  raise ValueError(
1042
1079
  "start_date or end_date type error, please input str, datetime.date or datetime.datetime type")
@@ -1049,6 +1086,10 @@ class GJDataC:
1049
1086
  :param time_data: 时间数据
1050
1087
  :return: 转换后的时间数据类型
1051
1088
  """
1089
+
1090
+ if isinstance(time_data, str):
1091
+ time_data = time_data.replace('.', '-')
1092
+
1052
1093
  try:
1053
1094
  time_data = datetime.datetime.strptime(time_data, "%Y-%m-%d").date()
1054
1095
  return time_data
@@ -1068,6 +1109,12 @@ class GJDataC:
1068
1109
 
1069
1110
  :return: 如果类型正确,返回 True。否则返回 False,并打印错误信息
1070
1111
  """
1112
+
1113
+ if isinstance(_start_date, str):
1114
+ _start_date = _start_date.replace('.', '-')
1115
+ if isinstance(_start_date, str):
1116
+ _end_date = _end_date.replace('.', '-')
1117
+
1071
1118
  if isinstance(_start_date, (str, datetime.date, datetime.datetime)) and \
1072
1119
  isinstance(_end_date, (str, datetime.date, datetime.datetime)):
1073
1120
  if isinstance(_start_date, str) and not self.general_validate_date(_start_date):
@@ -3152,7 +3199,7 @@ class GJDataC:
3152
3199
  db_session.close()
3153
3200
 
3154
3201
  ''' 处理数据 '''
3155
- return self.get_instrument_handle_data(data)
3202
+ return self.get_instrument_handle_data(data, instrument_id)
3156
3203
 
3157
3204
  def get_instrument_validate_params(self, instrument_id):
3158
3205
  """
@@ -3227,10 +3274,11 @@ class GJDataC:
3227
3274
 
3228
3275
  return query_data
3229
3276
 
3230
- def get_instrument_handle_data(self, data):
3277
+ def get_instrument_handle_data(self, data, instrument_id):
3231
3278
  """
3232
3279
  处理数据
3233
3280
  :param data: 期货/期权数据
3281
+ :param instrument_id: 合约代码
3234
3282
  :return: 处理后的最终数据
3235
3283
  """
3236
3284
 
@@ -3249,7 +3297,7 @@ class GJDataC:
3249
3297
  result_fields = ["instrument_id", "exchange_id", "instrument_name", "product_id", "product_type",
3250
3298
  "create_date", "open_date", "expire_date", "basis_price", "volume_multiple",
3251
3299
  "underlying_instrument_id", "underlying_multiple", "option_type", "strike_price",
3252
- "price_tick", "最小下单数量(暂无此字段)"]
3300
+ "price_tick", "limit_price_min_vol"]
3253
3301
 
3254
3302
  result = pd.DataFrame()
3255
3303
 
@@ -3265,9 +3313,46 @@ class GJDataC:
3265
3313
  # 如果字段在两个数据源中都不存在,填充为空值
3266
3314
  result[field] = None # 或者使用 pd.NA、空字符串等
3267
3315
 
3316
+ # 将所有最小下单量为空的填充为0
3317
+ result['limit_price_min_vol'] = result['limit_price_min_vol'].astype(float).fillna(0)
3318
+
3319
+ # 将dataframe处理成 class 对象
3320
+ result = self.get_instrument_convert_to_instrument(result, instrument_id)
3321
+
3268
3322
  return result
3269
3323
 
3324
+ @staticmethod
3325
+ def get_instrument_convert_to_instrument(df, instrument_id):
3326
+ """
3327
+ 将 DataFrame 转换成 Instrument 对象或对象列表
3328
+ :param 用户传入的合约代码
3329
+ :param 需要转化的结果 dataframe
3330
+ """
3331
+
3332
+ if isinstance(instrument_id, list) and len(instrument_id) > 1:
3333
+ # 如果 instrument_id 是列表且长度大于1
3334
+ matching_records = df[df['instrument_id'].isin(instrument_id)]
3335
+ if matching_records.empty:
3336
+ return None # 没有匹配结果
3337
+ else:
3338
+ # 去重后返回结果
3339
+ unique_records = matching_records.drop_duplicates(subset=['instrument_id'])
3340
+ return [Instrument(**row.to_dict()) for _, row in unique_records.iterrows()]
3341
+ else:
3342
+ # 如果 instrument_id 是单个字符串
3343
+ matching_records = df[df['instrument_id'] == instrument_id] if isinstance(instrument_id, str) else df[
3344
+ df['instrument_id'].isin(instrument_id)]
3345
+ unique_records = matching_records.drop_duplicates(subset=['instrument_id'])
3346
+ if matching_records.empty:
3347
+ return None # 没有匹配结果
3348
+ elif len(unique_records) == 1:
3349
+ return Instrument(**matching_records.iloc[0].to_dict())
3350
+ else:
3351
+ # 返回匹配结果
3352
+ return [Instrument(**row.to_dict()) for _, row in unique_records.iterrows()]
3353
+
3270
3354
  ''' 查询交易日列表 '''
3355
+
3271
3356
  def get_trading__dates(self, start_date, end_date, is_include_start=True, is_include_end=True):
3272
3357
  """
3273
3358
  查询交易日列表
@@ -3324,6 +3409,7 @@ class GJDataC:
3324
3409
  return sorted(result['trading_day'].dt.strftime('%Y.%m.%d').tolist())
3325
3410
 
3326
3411
  """ 查询前/后 N个交易日/时间 """
3412
+
3327
3413
  def get_trading_date(self, trade_time, date_count, date_type):
3328
3414
  """
3329
3415
  查询前后 N 个交易日或时间点
@@ -3391,7 +3477,8 @@ class GJDataC:
3391
3477
  result = filtered_dates['trading_day'].sort_values().head(date_count)
3392
3478
 
3393
3479
  # 将结果转换为指定格式的字符串列表
3394
- return sorted(result.dt.strftime('%Y.%m.%d').tolist())
3480
+ fina_result = sorted(result.dt.strftime('%Y.%m.%d').tolist())
3481
+ return fina_result[0] if len(fina_result) <= 1 else fina_result
3395
3482
 
3396
3483
  @staticmethod
3397
3484
  def get_trading_minutes(trading_dates, trade_time, date_count):
@@ -3431,10 +3518,10 @@ class GJDataC:
3431
3518
  # 向后查询
3432
3519
  result = [p for p in valid_time_points if pd.to_datetime(p) > trade_time][:date_count]
3433
3520
 
3434
- return sorted(result)
3435
-
3521
+ return sorted(result) if len(result) > 1 else result[0]
3436
3522
 
3437
3523
  """ 交易日判断 """
3524
+
3438
3525
  def is_trading_day(self, date):
3439
3526
  """
3440
3527
  判断给定日期是否为交易日
@@ -3452,6 +3539,7 @@ class GJDataC:
3452
3539
  return False if filtered_data.empty else True
3453
3540
 
3454
3541
  """ 节假日判断 """
3542
+
3455
3543
  @staticmethod
3456
3544
  def is_holiday(date):
3457
3545
  """
@@ -3465,8 +3553,8 @@ class GJDataC:
3465
3553
  # 判断是否是节假日
3466
3554
  return calendar.is_holiday(date)
3467
3555
 
3468
-
3469
3556
  """ 周末判断 """
3557
+
3470
3558
  @staticmethod
3471
3559
  def is_weekend(date):
3472
3560
  """
@@ -0,0 +1,34 @@
1
+ class Instrument:
2
+ def __init__(self, instrument_id, exchange_id, instrument_name, product_id,
3
+ product_type, create_date, open_date, expire_date,
4
+ basis_price, volume_multiple, underlying_instrument_id,
5
+ underlying_multiple, option_type, strike_price, price_tick,
6
+ limit_price_min_vol):
7
+ self.instrument_id = instrument_id
8
+ self.exchange_id = exchange_id
9
+ self.instrument_name = instrument_name
10
+ self.product_id = product_id
11
+ self.product_type = product_type
12
+ self.create_date = create_date
13
+ self.open_date = open_date
14
+ self.expire_date = expire_date
15
+ self.basis_price = basis_price
16
+ self.volume_multiple = volume_multiple
17
+ self.underlying_instrument_id = underlying_instrument_id
18
+ self.underlying_multiple = underlying_multiple
19
+ self.option_type = option_type
20
+ self.strike_price = strike_price
21
+ self.price_tick = price_tick
22
+ self.limit_price_min_vol = limit_price_min_vol
23
+
24
+ def __repr__(self):
25
+ return (
26
+ f"Instrument(instrument_id={self.instrument_id}, exchange_id={self.exchange_id}, "
27
+ f"instrument_name={self.instrument_name}, product_id={self.product_id}, "
28
+ f"product_type={self.product_type}, create_date={self.create_date}, "
29
+ f"open_date={self.open_date}, expire_date={self.expire_date}, "
30
+ f"basis_price={self.basis_price}, volume_multiple={self.volume_multiple}, "
31
+ f"underlying_instrument_id={self.underlying_instrument_id}, underlying_multiple={self.underlying_multiple}, "
32
+ f"option_type={self.option_type}, strike_price={self.strike_price}, "
33
+ f"price_tick={self.price_tick}, limit_price_min_vol={self.limit_price_min_vol})"
34
+ )
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: gjdatac-api
3
- Version: 0.1.4
4
- Summary: vwap,twap接口数据,接入tick_l2数据,新增实时订阅接口
3
+ Version: 0.1.6
4
+ Summary: 数据接口打包
5
5
  Author: yin
6
6
  Author-email: 2018209921@qq.com
7
7
  Requires-Python: >3.6
8
8
  Description-Content-Type: text/markdown
9
9
 
10
- 将原有接口全部更新,新增后续新需求
10
+ ### 新增主力合约接口
@@ -3,6 +3,7 @@ gjdatac_api/__init__.py
3
3
  gjdatac_api/data_api_class.py
4
4
  gjdatac_api/dict_data.py
5
5
  gjdatac_api/dolphindb_info.py
6
+ gjdatac_api/instrument_class.py
6
7
  gjdatac_api.egg-info/PKG-INFO
7
8
  gjdatac_api.egg-info/SOURCES.txt
8
9
  gjdatac_api.egg-info/dependency_links.txt
@@ -5,12 +5,12 @@ with open('description_info.md', 'r', encoding='utf-8') as f:
5
5
 
6
6
  setup(
7
7
  name='gjdatac_api', # 你的包名
8
- version='0.1.4', # 版本号
9
- description='vwap,twap接口数据,接入tick_l2数据,新增实时订阅接口', # 包的简要描述
8
+ version='0.1.6', # 版本号
9
+ description='数据接口打包', # 包的简要描述
10
10
  long_description=long_description, # 包的详细描述
11
11
  long_description_content_type='text/markdown', # 描述文件的类型
12
12
  include_package_data=True, # 包含包数据
13
- package_data={'gjdatac_api': ['*.py', 'dict_data.py', 'dolphindb_info.py']}, # 指定数据文件
13
+ package_data={'gjdatac_api': ['*.py', 'dict_data.py', 'dolphindb_info.py', 'instrument_class.py']}, # 指定数据文件
14
14
  author='yin', # 作者姓名
15
15
  author_email='2018209921@qq.com', # 作者邮箱
16
16
  packages=find_packages(), # 自动查找包目录
File without changes