deepquant 0.4.5__cp312-none-win_amd64.whl
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.
- deepquant/__init__.py +1 -0
- deepquant/__main__.py +5 -0
- deepquant/data/__init__.py +0 -0
- deepquant/data/gqclient/__init__.py +8 -0
- deepquant/data/gqclient/commons.py +300 -0
- deepquant/data/gqclient/hclient.py +535 -0
- deepquant/data/gqclient/wsclient.py +602 -0
- deepquant/data/gqclient/wshandler.py +114 -0
- deepquant/data/interface/__init__.py +0 -0
- deepquant/data/interface/dataApi.py +215 -0
- deepquant/data/interface/enum.py +48 -0
- deepquant/data/interface/gid.py +2245 -0
- deepquant/data/proto/__init__.py +8 -0
- deepquant/data/proto/base_pb2.py +200 -0
- deepquant/data/proto/common_pb2.py +390 -0
- deepquant/data/proto/data_type_pb2.py +324 -0
- deepquant/data/proto/financial_fun_pb2.py +314 -0
- deepquant/data/proto/market_data_pb2.py +1209 -0
- deepquant/data/proto/news_pb2.py +13436 -0
- deepquant/data/proto/pb_json_format.py +1049 -0
- deepquant/data/proto/proto_utils.py +178 -0
- deepquant/data/proto/real_time_md_pb2.py +325 -0
- deepquant/data/proto/realtime_factor_data_pb2.py +100 -0
- deepquant/data/proto/realtime_factor_server_pb2.py +232 -0
- deepquant/data/proto/replay_pb2.py +241 -0
- deepquant/data/proto/sdk_message_pb2.py +417 -0
- deepquant/data/utils/__init__.py +8 -0
- deepquant/data/utils/encrypt_util.py +27 -0
- deepquant/data/utils/gqconfig.py +198 -0
- deepquant/data/utils/gqconfig_dev.py +30 -0
- deepquant/data/utils/gqconfig_hub.py +55 -0
- deepquant/data/utils/gqconfig_inner.py +30 -0
- deepquant/data/utils/gqconfig_prod.py +30 -0
- deepquant/data/utils/gqconfig_test.py +30 -0
- deepquant/data/utils/gqconfig_uat.py +30 -0
- deepquant/data/utils/log_writer.py +55 -0
- deepquant/examples/get_factors.py +19 -0
- deepquant/examples/get_kline.py +14 -0
- deepquant/factor/__init__.py +0 -0
- deepquant/factor/analysor.py +302 -0
- deepquant/factor/calc.py +46 -0
- deepquant/factor/factor_analyzer.py +1733 -0
- deepquant/factor/factor_cal.py +235 -0
- deepquant/factor/factor_parser.py +325 -0
- deepquant/factor/financial_data_clean.py +426 -0
- deepquant/factor/globals.py +378 -0
- deepquant/factor/mgr.py +63 -0
- deepquant/factor/op.py +990 -0
- deepquant/factor/op_udf.py +549 -0
- deepquant/factor/oq_data.py +466 -0
- deepquant/factor/perf.py +768 -0
- deepquant/factor/plotting.py +725 -0
- deepquant/factor/summary.py +140 -0
- deepquant/factor/utils.py +68 -0
- deepquant/oplib/__init__.py +42 -0
- deepquant/oplib/_connection.py +20 -0
- deepquant/oplib/_core.py +17 -0
- deepquant/oplib/_enums.py +82 -0
- deepquant/oplib/_helper.py +14 -0
- deepquant/oplib/_runtime.py +56 -0
- deepquant/oplib/_swordfishcpp.cp312-win_amd64.pyd +0 -0
- deepquant/oplib/_translator.py +502 -0
- deepquant/oplib/config.py +92 -0
- deepquant/oplib/connection.py +6 -0
- deepquant/oplib/data.py +354 -0
- deepquant/oplib/dolphindb.cfg +20 -0
- deepquant/oplib/dolphindb.dos +71 -0
- deepquant/oplib/enums.py +30 -0
- deepquant/oplib/exception.py +8 -0
- deepquant/oplib/function.py +4074 -0
- deepquant/oplib/io.py +9 -0
- deepquant/oplib/libSwordfish.dll +0 -0
- deepquant/oplib/libgcc_s_seh-1.dll +0 -0
- deepquant/oplib/libstdc++-6.dll +0 -0
- deepquant/oplib/libwinpthread-1.dll +0 -0
- deepquant/oplib/tools.py +10 -0
- deepquant/oplib/types.py +30 -0
- deepquant/oplib/utils.py +24 -0
- deepquant/samples/__init__.py +8 -0
- deepquant/samples/md_client_demo.py +102 -0
- deepquant/samples/md_handler_demo.py +128 -0
- deepquant/samples/replay_client_demo.py +93 -0
- deepquant-0.4.5.dist-info/METADATA +65 -0
- deepquant-0.4.5.dist-info/RECORD +86 -0
- deepquant-0.4.5.dist-info/WHEEL +5 -0
- deepquant-0.4.5.dist-info/top_level.txt +1 -0
deepquant/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .data.interface import gid
|
deepquant/__main__.py
ADDED
|
File without changes
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
import time
|
|
5
|
+
from enum import Enum
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class DataType(Enum):
|
|
9
|
+
"""
|
|
10
|
+
返回数据类型
|
|
11
|
+
"""
|
|
12
|
+
DATAFRAME = 0 #: 返回dataframe
|
|
13
|
+
JSON = 10 #: 返回json,如[{'symbol':'SH600000','price':10.0},{'symbol':'SZ000001','price':10.0}]
|
|
14
|
+
PROTO_BUF = 11 #: 返回数据为protocol buffer
|
|
15
|
+
|
|
16
|
+
@staticmethod
|
|
17
|
+
def get(name='', code=''):
|
|
18
|
+
for item in DataType:
|
|
19
|
+
if name is not None and item.name == name:
|
|
20
|
+
return item
|
|
21
|
+
elif code is not None and item.value == code:
|
|
22
|
+
return code
|
|
23
|
+
return DataType.JSON
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ApiReqMethod(Enum):
|
|
27
|
+
"""
|
|
28
|
+
API请求类型:POST、GET
|
|
29
|
+
"""
|
|
30
|
+
POST = 0
|
|
31
|
+
GET = 1
|
|
32
|
+
|
|
33
|
+
@staticmethod
|
|
34
|
+
def get(name='', code=''):
|
|
35
|
+
for item in ApiReqMethod:
|
|
36
|
+
if name is not None and item.name == name:
|
|
37
|
+
return item
|
|
38
|
+
elif code is not None and item.value == code:
|
|
39
|
+
return item
|
|
40
|
+
return ApiReqMethod.POST
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class ApiEncrypt(Enum):
|
|
44
|
+
"""
|
|
45
|
+
API是否加密:不加密/请求相应加密/...
|
|
46
|
+
"""
|
|
47
|
+
NO = 0
|
|
48
|
+
# TODO 加解密功能待实现
|
|
49
|
+
ENCRY_REQ_RSP = 10
|
|
50
|
+
|
|
51
|
+
@staticmethod
|
|
52
|
+
def get(name='', code=''):
|
|
53
|
+
for item in ApiEncrypt:
|
|
54
|
+
if name is not None and item.name == name:
|
|
55
|
+
return item
|
|
56
|
+
elif code is not None and item.value == code:
|
|
57
|
+
return item
|
|
58
|
+
return ApiEncrypt.NO
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class ApiRspCode(Enum):
|
|
62
|
+
SUCCESS = '00000'
|
|
63
|
+
HTTP_ERROR = 'H0001'
|
|
64
|
+
HTTP_TIMEOUT = 'H0002'
|
|
65
|
+
# HTTP返回码如果是非200,则错误码为HC404之类
|
|
66
|
+
HTTP_ERRCODE_PRE = 'HC{}'
|
|
67
|
+
|
|
68
|
+
NOT_AUTH = 'U0404'
|
|
69
|
+
|
|
70
|
+
PARAM_ERROR = 'P0001'
|
|
71
|
+
|
|
72
|
+
RSP_ERROR = 'RT999'
|
|
73
|
+
|
|
74
|
+
SDK_ERROR = 'SDK99'
|
|
75
|
+
|
|
76
|
+
@staticmethod
|
|
77
|
+
def is_succ(code):
|
|
78
|
+
if ApiRspCode.SUCCESS == code or ApiRspCode.SUCCESS.value == code or 200 == code or 0 == code or '0' == code:
|
|
79
|
+
return True
|
|
80
|
+
else:
|
|
81
|
+
return False
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class ApiAggregateType(Enum):
|
|
85
|
+
# 不需要聚合
|
|
86
|
+
NO = 0
|
|
87
|
+
# 分批聚合
|
|
88
|
+
BATCH = 1
|
|
89
|
+
|
|
90
|
+
# 分页聚合,TODO,本期暂不实现
|
|
91
|
+
|
|
92
|
+
@staticmethod
|
|
93
|
+
def get(name='', code=''):
|
|
94
|
+
for item in ApiAggregateType:
|
|
95
|
+
if name is not None and item.name == name:
|
|
96
|
+
return item
|
|
97
|
+
elif code is not None and item.value == code:
|
|
98
|
+
return item
|
|
99
|
+
return ApiAggregateType.NO
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class ApiRspMode(Enum):
|
|
103
|
+
# 处理后返回,默认选项
|
|
104
|
+
PROCESSED = 0
|
|
105
|
+
# 透传
|
|
106
|
+
PASSED = 1
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class ApiResponse:
|
|
110
|
+
"""
|
|
111
|
+
Api响应返回对象
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
def __init__(self, code, msg, data, **kwargs):
|
|
115
|
+
"""
|
|
116
|
+
:param code: 返回码,0-成功,其他相关错误码
|
|
117
|
+
:param msg: 返回提示
|
|
118
|
+
:param data: 返回数据
|
|
119
|
+
"""
|
|
120
|
+
self.code = code
|
|
121
|
+
self.msg = msg
|
|
122
|
+
self.data = data
|
|
123
|
+
self.extra = kwargs
|
|
124
|
+
|
|
125
|
+
@staticmethod
|
|
126
|
+
def assemble_succ_resp(data, **kwargs):
|
|
127
|
+
response = ApiResponse(code=ApiRspCode.SUCCESS, msg='success', data=data, **kwargs)
|
|
128
|
+
return response
|
|
129
|
+
|
|
130
|
+
@staticmethod
|
|
131
|
+
def assemble_err_resp(code, msg):
|
|
132
|
+
response = ApiResponse(code=code, msg=msg, data=None)
|
|
133
|
+
return response
|
|
134
|
+
|
|
135
|
+
def is_success(self):
|
|
136
|
+
return ApiRspCode.is_succ(self.code)
|
|
137
|
+
|
|
138
|
+
def __str__(self):
|
|
139
|
+
_str = self.__class__.__name__ + '(' + \
|
|
140
|
+
','.join([key + '=' + str(value) for key, value in self.__dict__.items() if value is not None]) \
|
|
141
|
+
+ ')'
|
|
142
|
+
return _str
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class ApiInfo:
|
|
146
|
+
def __init__(self, mod_type, func_name, api_uri,
|
|
147
|
+
req_method=ApiReqMethod.POST.name,
|
|
148
|
+
req_data_type=DataType.JSON.name,
|
|
149
|
+
rsp_data_type=DataType.JSON.name,
|
|
150
|
+
ret_data_node=None,
|
|
151
|
+
aggregate_type=ApiAggregateType.NO.name,
|
|
152
|
+
encrypt_type=ApiEncrypt.NO.name,
|
|
153
|
+
extras=None, comment=None):
|
|
154
|
+
"""
|
|
155
|
+
HTTP API信息
|
|
156
|
+
:param mod_type: API所属模块类型,比如数据-Data、因子-Factor
|
|
157
|
+
:param func_name: API的唯一名称,模块内唯一,比如getBars
|
|
158
|
+
:param api_uri: API对应网关的URI
|
|
159
|
+
:param req_method: 请求方式
|
|
160
|
+
:param req_data_type: 请求数据格式
|
|
161
|
+
:param rsp_data_type: 响应数据格式
|
|
162
|
+
:param ret_data_node: 返回数据的节点,比如返回json或pb根目录下的datas
|
|
163
|
+
|
|
164
|
+
:param aggregate_type: 是否需要批量聚合,0-不需要,1-分批聚合,2-分页聚合
|
|
165
|
+
:param encrypt_type: 加解密类型
|
|
166
|
+
:param extras: 扩展字段,作为预留
|
|
167
|
+
"""
|
|
168
|
+
# API类型,比如data/factor...
|
|
169
|
+
self.mod_type = mod_type
|
|
170
|
+
self.func_name = func_name
|
|
171
|
+
self.api_uri = api_uri
|
|
172
|
+
self.req_method = ApiReqMethod.get(req_method)
|
|
173
|
+
self.req_data_type = DataType.get(req_data_type)
|
|
174
|
+
self.rsp_data_type = DataType.get(rsp_data_type)
|
|
175
|
+
self.ret_data_node = ret_data_node
|
|
176
|
+
|
|
177
|
+
# 分批聚合功能已支持
|
|
178
|
+
self.aggregate_type = ApiAggregateType.get(aggregate_type)
|
|
179
|
+
self.encrypt_type = ApiEncrypt.get(encrypt_type)
|
|
180
|
+
self.extras = extras
|
|
181
|
+
self.comment = comment
|
|
182
|
+
|
|
183
|
+
@staticmethod
|
|
184
|
+
def gen_from_json_item(_json_config):
|
|
185
|
+
mod_type = _json_config.get('modType')
|
|
186
|
+
if mod_type is None:
|
|
187
|
+
mod_type = _json_config.get('mod_type')
|
|
188
|
+
|
|
189
|
+
func_name = _json_config.get('funcName')
|
|
190
|
+
if func_name is None:
|
|
191
|
+
func_name = _json_config.get('func_name')
|
|
192
|
+
|
|
193
|
+
api_uri = _json_config.get('apiUri')
|
|
194
|
+
if api_uri is None:
|
|
195
|
+
api_uri = _json_config.get('api_uri')
|
|
196
|
+
|
|
197
|
+
req_method = _json_config.get('reqMethod')
|
|
198
|
+
if req_method is None:
|
|
199
|
+
req_method = _json_config.get('req_method')
|
|
200
|
+
|
|
201
|
+
req_data_type = _json_config.get('reqDataType')
|
|
202
|
+
if req_data_type is None:
|
|
203
|
+
req_data_type = _json_config.get('req_data_type')
|
|
204
|
+
|
|
205
|
+
rsp_data_type = _json_config.get('rspDataType')
|
|
206
|
+
if rsp_data_type is None:
|
|
207
|
+
rsp_data_type = _json_config.get('rsp_data_type')
|
|
208
|
+
|
|
209
|
+
ret_data_node = _json_config.get('retDataNode')
|
|
210
|
+
if ret_data_node is None:
|
|
211
|
+
ret_data_node = _json_config.get('ret_data_node')
|
|
212
|
+
|
|
213
|
+
encrypt_type = _json_config.get('encryptType')
|
|
214
|
+
if encrypt_type is None:
|
|
215
|
+
encrypt_type = _json_config.get('encrypt_type')
|
|
216
|
+
|
|
217
|
+
comment = _json_config.get('remark')
|
|
218
|
+
if comment is None:
|
|
219
|
+
comment = _json_config.get('comment')
|
|
220
|
+
|
|
221
|
+
return ApiInfo(mod_type=mod_type, func_name=func_name, api_uri=api_uri, req_method=req_method,
|
|
222
|
+
req_data_type=req_data_type, rsp_data_type=rsp_data_type, ret_data_node=ret_data_node,
|
|
223
|
+
encrypt_type=encrypt_type,
|
|
224
|
+
comment=comment)
|
|
225
|
+
|
|
226
|
+
@staticmethod
|
|
227
|
+
def default(mod_type, func_name, api_uri, method="POST"):
|
|
228
|
+
return ApiInfo(mod_type=mod_type, func_name=func_name, api_uri=api_uri, req_method=method)
|
|
229
|
+
|
|
230
|
+
def set_req_method(self, req_method):
|
|
231
|
+
self.req_method = req_method
|
|
232
|
+
return self
|
|
233
|
+
|
|
234
|
+
def set_data_type(self, data_type):
|
|
235
|
+
self.req_data_type = data_type
|
|
236
|
+
self.rsp_data_type = data_type
|
|
237
|
+
return self
|
|
238
|
+
|
|
239
|
+
def set_ret_data_node(self, ret_data_node):
|
|
240
|
+
self.ret_data_node = ret_data_node
|
|
241
|
+
return self
|
|
242
|
+
|
|
243
|
+
def has_data_node(self):
|
|
244
|
+
if self.ret_data_node is not None and len(self.ret_data_node) > 0:
|
|
245
|
+
return True
|
|
246
|
+
else:
|
|
247
|
+
return False
|
|
248
|
+
|
|
249
|
+
def __str__(self):
|
|
250
|
+
_str = self.__class__.__name__ + '(' + \
|
|
251
|
+
','.join([key + '=' + str(value) for key, value in self.__dict__.items() if value is not None]) \
|
|
252
|
+
+ ')'
|
|
253
|
+
return _str
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
class TTLCache(object):
|
|
257
|
+
"""
|
|
258
|
+
TTL缓存,用于token缓存等
|
|
259
|
+
"""
|
|
260
|
+
NOT_FOUND = None
|
|
261
|
+
|
|
262
|
+
def __init__(self):
|
|
263
|
+
# 记录key-value数据
|
|
264
|
+
self.datas = dict()
|
|
265
|
+
# 记录key-expire失效时间
|
|
266
|
+
self.expires = dict()
|
|
267
|
+
|
|
268
|
+
def check_and_remove_key_expires(self, key):
|
|
269
|
+
if key in self.datas:
|
|
270
|
+
if key in self.expires:
|
|
271
|
+
now = time.time()
|
|
272
|
+
expire_time = self.expires[key]
|
|
273
|
+
if expire_time > now:
|
|
274
|
+
# 超时时间>当前时间,则返回数据
|
|
275
|
+
return self.datas[key]
|
|
276
|
+
else:
|
|
277
|
+
print('[check_key_expires]key-expired:' + key + ', ' + self.datas[key])
|
|
278
|
+
del self.datas[key]
|
|
279
|
+
del self.expires[key]
|
|
280
|
+
return TTLCache.NOT_FOUND
|
|
281
|
+
else:
|
|
282
|
+
del self.datas[key]
|
|
283
|
+
return TTLCache.NOT_FOUND
|
|
284
|
+
else:
|
|
285
|
+
return TTLCache.NOT_FOUND
|
|
286
|
+
|
|
287
|
+
def get(self, key):
|
|
288
|
+
return self.check_and_remove_key_expires(key)
|
|
289
|
+
|
|
290
|
+
def set(self, key, value, ttl=86400):
|
|
291
|
+
now = time.time()
|
|
292
|
+
self.datas[key] = value
|
|
293
|
+
self.expires[key] = now + ttl
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
class FunctionMode(Enum):
|
|
297
|
+
# 无上传参数模式
|
|
298
|
+
SIMPLE = 1
|
|
299
|
+
# 无上传参数模式
|
|
300
|
+
COMPLEX = 2
|