tushare 1.4.4__py3-none-any.whl → 1.4.17__py3-none-any.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.
- tushare/__init__.py +2 -2
- tushare/pro/client.py +3 -2
- tushare/pro/data_pro.py +197 -17
- tushare/pro/llm.py +118 -0
- tushare/stock/rtq.py +25 -23
- tushare/subs/model/tick.py +128 -128
- tushare/subs/tgw_subs/convert.py +20 -20
- tushare/subs/ts_subs/subscribe.py +25 -5
- tushare/util/format_stock_code.py +19 -19
- {tushare-1.4.4.dist-info → tushare-1.4.17.dist-info}/METADATA +24 -18
- {tushare-1.4.4.dist-info → tushare-1.4.17.dist-info}/RECORD +14 -13
- {tushare-1.4.4.dist-info → tushare-1.4.17.dist-info}/WHEEL +1 -1
- {tushare-1.4.4.dist-info → tushare-1.4.17.dist-info}/LICENSE +0 -0
- {tushare-1.4.4.dist-info → tushare-1.4.17.dist-info}/top_level.txt +0 -0
tushare/__init__.py
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
import codecs
|
3
3
|
import os
|
4
4
|
|
5
|
-
__version__ = '1.4.
|
5
|
+
__version__ = '1.4.16'
|
6
6
|
__author__ = 'Jimmy Liu'
|
7
7
|
|
8
8
|
"""
|
@@ -78,7 +78,7 @@ from tushare.stock.shibor import (shibor_data, shibor_quote_data,
|
|
78
78
|
"""
|
79
79
|
for tushare pro api
|
80
80
|
"""
|
81
|
-
from tushare.pro.data_pro import (pro_api, pro_bar, subs, ht_subs)
|
81
|
+
from tushare.pro.data_pro import (pro_api, pro_bar, subs, ht_subs, pro_bar_vip)
|
82
82
|
|
83
83
|
"""
|
84
84
|
for LHB
|
tushare/pro/client.py
CHANGED
@@ -17,7 +17,8 @@ import requests
|
|
17
17
|
class DataApi:
|
18
18
|
|
19
19
|
__token = ''
|
20
|
-
__http_url = 'http://api.waditu.com'
|
20
|
+
__http_url = 'http://api.waditu.com/dataapi'
|
21
|
+
# __http_url = 'http://127.0.0.1:8000/dataapi'
|
21
22
|
|
22
23
|
def __init__(self, token, timeout=30):
|
23
24
|
"""
|
@@ -37,7 +38,7 @@ class DataApi:
|
|
37
38
|
'fields': fields
|
38
39
|
}
|
39
40
|
|
40
|
-
res = requests.post(self.__http_url, json=req_params, timeout=self.__timeout)
|
41
|
+
res = requests.post(f"{self.__http_url}/{api_name}", json=req_params, timeout=self.__timeout)
|
41
42
|
if res:
|
42
43
|
result = json.loads(res.text)
|
43
44
|
if result['code'] != 0:
|
tushare/pro/data_pro.py
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
pro init
|
4
4
|
Created on 2018/07/01
|
5
5
|
@author: Jimmy Liu
|
6
|
-
@group : https://
|
6
|
+
@group : https://tushare.pro
|
7
7
|
@contact: jimmysoa@sina.cn
|
8
8
|
"""
|
9
9
|
from __future__ import division
|
@@ -12,8 +12,8 @@ from tushare.pro import client
|
|
12
12
|
from tushare.util import upass
|
13
13
|
from tushare.util.formula import MA
|
14
14
|
|
15
|
-
PRICE_COLS = ['open', 'close', 'high', 'low']
|
16
|
-
FORMAT = lambda x: '%.
|
15
|
+
PRICE_COLS = ['open', 'close', 'high', 'low', 'pre_close']
|
16
|
+
FORMAT = lambda x: '%.2f' % x
|
17
17
|
FREQS = {'D': '1DAY',
|
18
18
|
'W': '1WEEK',
|
19
19
|
'Y': '1YEAR',
|
@@ -26,7 +26,6 @@ FACT_LIST = {
|
|
26
26
|
'pe': 'pe',
|
27
27
|
'pe_ttm': 'pe_ttm',
|
28
28
|
}
|
29
|
-
|
30
29
|
def pro_api(token='', timeout=30):
|
31
30
|
"""
|
32
31
|
初始化pro API,第一次可以通过ts.set_token('your token')来记录自己的token凭证,临时token可以通过本参数传入
|
@@ -37,10 +36,10 @@ def pro_api(token='', timeout=30):
|
|
37
36
|
pro = client.DataApi(token=token, timeout=timeout)
|
38
37
|
return pro
|
39
38
|
else:
|
40
|
-
raise Exception('api init error.')
|
41
|
-
|
39
|
+
raise Exception('api init error.')
|
42
40
|
|
43
|
-
|
41
|
+
|
42
|
+
def pro_bar(ts_code='', api=None, start_date='', end_date='', freq='D', asset='E',
|
44
43
|
exchange='',
|
45
44
|
adj = None,
|
46
45
|
ma = [],
|
@@ -48,6 +47,7 @@ def pro_bar(ts_code='', api=None, start_date='', end_date='', freq='D', asset='E
|
|
48
47
|
adjfactor = False,
|
49
48
|
offset = None,
|
50
49
|
limit = None,
|
50
|
+
fields = '',
|
51
51
|
contract_type = '',
|
52
52
|
retry_count = 3):
|
53
53
|
"""
|
@@ -69,13 +69,13 @@ def pro_bar(ts_code='', api=None, start_date='', end_date='', freq='D', asset='E
|
|
69
69
|
tor:换手率,默认不返回,返回需指定:factor=['tor']
|
70
70
|
以上两种都需要:factor=['vr', 'tor']
|
71
71
|
retry_count:网络重试次数
|
72
|
-
|
72
|
+
|
73
73
|
Return
|
74
74
|
----------
|
75
75
|
DataFrame
|
76
76
|
code:代码
|
77
77
|
open:开盘close/high/low/vol成交量/amount成交额/maN均价/vr量比/tor换手率
|
78
|
-
|
78
|
+
|
79
79
|
期货(asset='FT')
|
80
80
|
code/open/close/high/low/avg_price:均价 position:持仓量 vol:成交总量
|
81
81
|
"""
|
@@ -86,7 +86,7 @@ def pro_bar(ts_code='', api=None, start_date='', end_date='', freq='D', asset='E
|
|
86
86
|
freq = freq.strip().lower()
|
87
87
|
else:
|
88
88
|
freq = freq.strip().upper() if asset != 'C' else freq.strip().lower()
|
89
|
-
|
89
|
+
|
90
90
|
if 'min' not in freq:
|
91
91
|
today= datetime.datetime.today().date()
|
92
92
|
today = str(today)[0:10]
|
@@ -143,6 +143,11 @@ def pro_bar(ts_code='', api=None, start_date='', end_date='', freq='D', asset='E
|
|
143
143
|
data['pct_chg'] = data['pct_chg'].map(lambda x: FORMAT(x)).astype(float)
|
144
144
|
else:
|
145
145
|
data = data.drop(['trade_date', 'pre_close'], axis=1)
|
146
|
+
else:
|
147
|
+
data['pre_close'] = data['close'].shift(-1)
|
148
|
+
data['change'] = data['close'] - data['pre_close']
|
149
|
+
data['pct_chg'] = data['change'] / data['pre_close'] * 100
|
150
|
+
data['pct_chg'] = data['pct_chg'].map(lambda x: FORMAT(x)).astype(float)
|
146
151
|
elif asset == 'I':
|
147
152
|
if freq == 'D':
|
148
153
|
data = api.index_daily(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
@@ -161,7 +166,7 @@ def pro_bar(ts_code='', api=None, start_date='', end_date='', freq='D', asset='E
|
|
161
166
|
if freq == 'D':
|
162
167
|
data = api.opt_daily(ts_code=ts_code, start_date=start_date, end_date=end_date, exchange=exchange, offset=offset, limit=limit)
|
163
168
|
if 'min' in freq:
|
164
|
-
data = api.
|
169
|
+
data = api.opt_mins(ts_code=ts_code, start_date=start_date, end_date=end_date, freq=freq, offset=offset, limit=limit)
|
165
170
|
elif asset == 'CB':
|
166
171
|
if freq == 'D':
|
167
172
|
data = api.cb_daily(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
@@ -175,11 +180,181 @@ def pro_bar(ts_code='', api=None, start_date='', end_date='', freq='D', asset='E
|
|
175
180
|
freq = 'daily'
|
176
181
|
elif freq == 'w':
|
177
182
|
freq = 'week'
|
178
|
-
data = api.coinbar(
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
+
data = api.coinbar(exchange=exchange, symbol=ts_code, freq=freq, start_dae=start_date, end_date=end_date,
|
184
|
+
contract_type=contract_type)
|
185
|
+
if ma is not None and len(ma) > 0:
|
186
|
+
for a in ma:
|
187
|
+
if isinstance(a, int):
|
188
|
+
data['ma%s'%a] = MA(data['close'], a).map(FORMAT).shift(-(a-1))
|
189
|
+
data['ma%s'%a] = data['ma%s'%a].astype(float)
|
190
|
+
data['ma_v_%s'%a] = MA(data['vol'], a).map(FORMAT).shift(-(a-1))
|
191
|
+
data['ma_v_%s'%a] = data['ma_v_%s'%a].astype(float)
|
192
|
+
data = data.reset_index(drop=True)
|
193
|
+
except Exception as e:
|
194
|
+
print(e)
|
195
|
+
else:
|
196
|
+
if fields is not None and fields != '':
|
197
|
+
f_list = [col.strip() for col in fields.split(',')]
|
198
|
+
data = data[f_list]
|
199
|
+
return data
|
200
|
+
raise IOError('ERROR.')
|
201
|
+
|
202
|
+
def pro_api(token='', timeout=30):
|
203
|
+
"""
|
204
|
+
初始化pro API,第一次可以通过ts.set_token('your token')来记录自己的token凭证,临时token可以通过本参数传入
|
205
|
+
"""
|
206
|
+
if token == '' or token is None:
|
207
|
+
token = upass.get_token()
|
208
|
+
if token is not None and token != '':
|
209
|
+
pro = client.DataApi(token=token, timeout=timeout)
|
210
|
+
return pro
|
211
|
+
else:
|
212
|
+
raise Exception('api init error.')
|
213
|
+
|
214
|
+
|
215
|
+
def pro_bar_vip(ts_code='', api=None, start_date='', end_date='', freq='D', asset='E',
|
216
|
+
exchange='',
|
217
|
+
adj = None,
|
218
|
+
ma = [],
|
219
|
+
factors = None,
|
220
|
+
adjfactor = False,
|
221
|
+
offset = None,
|
222
|
+
limit = None,
|
223
|
+
fields = '',
|
224
|
+
contract_type = '',
|
225
|
+
retry_count = 3):
|
226
|
+
"""
|
227
|
+
BAR数据
|
228
|
+
Parameters:
|
229
|
+
------------
|
230
|
+
ts_code:证券代码,支持股票,ETF/LOF,期货/期权,港股,数字货币
|
231
|
+
start_date:开始日期 YYYYMMDD
|
232
|
+
end_date:结束日期 YYYYMMDD
|
233
|
+
freq:支持1/5/15/30/60分钟,周/月/季/年
|
234
|
+
asset:证券类型 E:股票和交易所基金,I:沪深指数,C:数字货币,FT:期货 FD:基金/O期权/H港股/CB可转债
|
235
|
+
exchange:市场代码,用户数字货币行情
|
236
|
+
adj:复权类型,None不复权,qfq:前复权,hfq:后复权
|
237
|
+
ma:均线,支持自定义均线频度,如:ma5/ma10/ma20/ma60/maN
|
238
|
+
offset:开始行数(分页功能,从第几行开始取数据)
|
239
|
+
limit: 本次提取数据行数
|
240
|
+
factors因子数据,目前支持以下两种:
|
241
|
+
vr:量比,默认不返回,返回需指定:factor=['vr']
|
242
|
+
tor:换手率,默认不返回,返回需指定:factor=['tor']
|
243
|
+
以上两种都需要:factor=['vr', 'tor']
|
244
|
+
retry_count:网络重试次数
|
245
|
+
|
246
|
+
Return
|
247
|
+
----------
|
248
|
+
DataFrame
|
249
|
+
code:代码
|
250
|
+
open:开盘close/high/low/vol成交量/amount成交额/maN均价/vr量比/tor换手率
|
251
|
+
|
252
|
+
期货(asset='FT')
|
253
|
+
code/open/close/high/low/avg_price:均价 position:持仓量 vol:成交总量
|
254
|
+
"""
|
255
|
+
if (ts_code=='' or ts_code is None) and (adj is not None):
|
256
|
+
print('提取复权行情必须输入ts_code参数')
|
257
|
+
return
|
258
|
+
if len(freq.strip())>=3:
|
259
|
+
freq = freq.strip().lower()
|
260
|
+
else:
|
261
|
+
freq = freq.strip().upper() if asset != 'C' else freq.strip().lower()
|
262
|
+
|
263
|
+
if 'min' not in freq:
|
264
|
+
today= datetime.datetime.today().date()
|
265
|
+
today = str(today)[0:10]
|
266
|
+
start_date = '' if start_date is None else start_date
|
267
|
+
end_date = today if end_date == '' or end_date is None else end_date
|
268
|
+
start_date = start_date.replace('-', '')
|
269
|
+
end_date = end_date.replace('-', '')
|
270
|
+
ts_code = ts_code.strip().upper() if asset != 'C' else ts_code.strip().lower()
|
271
|
+
asset = asset.strip().upper()
|
272
|
+
api = api if api is not None else pro_api()
|
273
|
+
for _ in range(retry_count):
|
274
|
+
try:
|
275
|
+
if asset == 'E':
|
276
|
+
if freq == 'D':
|
277
|
+
data = api.daily_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
278
|
+
if factors is not None and len(factors) >0 :
|
279
|
+
ds = api.daily_basic_vip(ts_code=ts_code, start_date=start_date, end_date=end_date)[['trade_date', 'turnover_rate', 'volume_ratio']]
|
280
|
+
ds = ds.set_index('trade_date')
|
281
|
+
data = data.set_index('trade_date')
|
282
|
+
data = data.merge(ds, left_index=True, right_index=True)
|
283
|
+
data = data.reset_index()
|
284
|
+
if ('tor' in factors) and ('vr' not in factors):
|
285
|
+
data = data.drop('volume_ratio', axis=1)
|
286
|
+
if ('vr' in factors) and ('tor' not in factors):
|
287
|
+
data = data.drop('turnover_rate', axis=1)
|
288
|
+
if freq == 'W':
|
289
|
+
data = api.weekly_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
290
|
+
if freq == 'M':
|
291
|
+
data = api.monthly_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
292
|
+
if 'min' in freq:
|
293
|
+
data = api.stk_mins_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, freq=freq, offset=offset, limit=limit)
|
294
|
+
data['trade_date'] = data['trade_time'].map(lambda x: x.replace('-', '')[0:8])
|
295
|
+
data['pre_close'] = data['close'].shift(-1)
|
296
|
+
if adj is not None:
|
297
|
+
fcts = api.adj_factor_vip(ts_code=ts_code, start_date=start_date, end_date=end_date)[['trade_date', 'adj_factor']]
|
298
|
+
if fcts.shape[0] == 0:
|
299
|
+
return None
|
300
|
+
data = data.set_index('trade_date', drop=False).merge(fcts.set_index('trade_date'), left_index=True, right_index=True, how='left')
|
301
|
+
if 'min' in freq:
|
302
|
+
data = data.sort_values('trade_time', ascending=False)
|
303
|
+
data['adj_factor'] = data['adj_factor'].fillna(method='bfill')
|
304
|
+
for col in PRICE_COLS:
|
305
|
+
if adj == 'hfq':
|
306
|
+
data[col] = data[col] * data['adj_factor']
|
307
|
+
if adj == 'qfq':
|
308
|
+
data[col] = data[col] * data['adj_factor'] / float(fcts['adj_factor'][0])
|
309
|
+
data[col] = data[col].map(FORMAT)
|
310
|
+
data[col] = data[col].astype(float)
|
311
|
+
if adjfactor is False:
|
312
|
+
data = data.drop('adj_factor', axis=1)
|
313
|
+
if 'min' not in freq:
|
314
|
+
data['change'] = data['close'] - data['pre_close']
|
315
|
+
data['pct_chg'] = data['change'] / data['pre_close'] * 100
|
316
|
+
data['pct_chg'] = data['pct_chg'].map(lambda x: FORMAT(x)).astype(float)
|
317
|
+
else:
|
318
|
+
data = data.drop(['trade_date', 'pre_close'], axis=1)
|
319
|
+
else:
|
320
|
+
data['pre_close'] = data['close'].shift(-1)
|
321
|
+
data['change'] = data['close'] - data['pre_close']
|
322
|
+
data['pct_chg'] = data['change'] / data['pre_close'] * 100
|
323
|
+
data['pct_chg'] = data['pct_chg'].map(lambda x: FORMAT(x)).astype(float)
|
324
|
+
elif asset == 'I':
|
325
|
+
if freq == 'D':
|
326
|
+
data = api.index_daily_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
327
|
+
if freq == 'W':
|
328
|
+
data = api.index_weekly_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
329
|
+
if freq == 'M':
|
330
|
+
data = api.index_monthly_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
331
|
+
if 'min' in freq:
|
332
|
+
data = api.stk_mins_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, freq=freq, offset=offset, limit=limit)
|
333
|
+
elif asset == 'FT':
|
334
|
+
if freq == 'D':
|
335
|
+
data = api.fut_daily_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, exchange=exchange, offset=offset, limit=limit)
|
336
|
+
if 'min' in freq:
|
337
|
+
data = api.ft_mins_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, freq=freq, offset=offset, limit=limit)
|
338
|
+
elif asset == 'O':
|
339
|
+
if freq == 'D':
|
340
|
+
data = api.opt_daily_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, exchange=exchange, offset=offset, limit=limit)
|
341
|
+
if 'min' in freq:
|
342
|
+
data = api.opt_mins_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, freq=freq, offset=offset, limit=limit)
|
343
|
+
elif asset == 'CB':
|
344
|
+
if freq == 'D':
|
345
|
+
data = api.cb_daily_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
346
|
+
elif asset == 'FD':
|
347
|
+
if freq == 'D':
|
348
|
+
data = api.fund_daily_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, offset=offset, limit=limit)
|
349
|
+
if 'min' in freq:
|
350
|
+
data = api.stk_mins_vip(ts_code=ts_code, start_date=start_date, end_date=end_date, freq=freq, offset=offset, limit=limit)
|
351
|
+
if asset == 'C':
|
352
|
+
if freq == 'd':
|
353
|
+
freq = 'daily'
|
354
|
+
elif freq == 'w':
|
355
|
+
freq = 'week'
|
356
|
+
data = api.coinbar(exchange=exchange, symbol=ts_code, freq=freq, start_dae=start_date, end_date=end_date,
|
357
|
+
contract_type=contract_type)
|
183
358
|
if ma is not None and len(ma) > 0:
|
184
359
|
for a in ma:
|
185
360
|
if isinstance(a, int):
|
@@ -191,6 +366,9 @@ def pro_bar(ts_code='', api=None, start_date='', end_date='', freq='D', asset='E
|
|
191
366
|
except Exception as e:
|
192
367
|
print(e)
|
193
368
|
else:
|
369
|
+
if fields is not None and fields != '':
|
370
|
+
f_list = [col.strip() for col in fields.split(',')]
|
371
|
+
data = data[f_list]
|
194
372
|
return data
|
195
373
|
raise IOError('ERROR.')
|
196
374
|
|
@@ -211,5 +389,7 @@ def ht_subs(username, password):
|
|
211
389
|
|
212
390
|
|
213
391
|
if __name__ == '__main__':
|
214
|
-
|
392
|
+
# upass.set_token('')
|
215
393
|
pro = pro_api()
|
394
|
+
df = pro_bar(ts_code='688539.SH', adj='qfq')
|
395
|
+
print(df)
|
tushare/pro/llm.py
ADDED
@@ -0,0 +1,118 @@
|
|
1
|
+
import json
|
2
|
+
|
3
|
+
import requests
|
4
|
+
try:
|
5
|
+
import sseclient
|
6
|
+
except:
|
7
|
+
raise ImportError("sseclient not found, please install it using 'pip install sseclient-py'.")
|
8
|
+
|
9
|
+
|
10
|
+
from tushare import get_token
|
11
|
+
|
12
|
+
BASE_URL = "http://api.waditu.com/dataapi"
|
13
|
+
# BASE_URL = "http://10.255.255.205:8083/dataapi"
|
14
|
+
API_KEY_PREFIX = "tsgpt-"
|
15
|
+
|
16
|
+
|
17
|
+
class GPTClient:
|
18
|
+
def __init__(self, token=None, timetout=120):
|
19
|
+
if not token:
|
20
|
+
token = get_token()
|
21
|
+
self.token = token
|
22
|
+
self.timeout = timetout
|
23
|
+
|
24
|
+
def _request(self, model, messages, temperature=None, max_tokens=None, stream=True, pretty=False) -> requests.Response:
|
25
|
+
"""
|
26
|
+
model string 模型名称, doubao-pro-128k
|
27
|
+
messages list 消息列表
|
28
|
+
[
|
29
|
+
{
|
30
|
+
"role": "user",
|
31
|
+
"content": "Hello World"
|
32
|
+
}
|
33
|
+
]
|
34
|
+
pretty bool 是否只返回回答内容文本
|
35
|
+
"""
|
36
|
+
resp = requests.post(
|
37
|
+
f'{BASE_URL}/llm/{model}',
|
38
|
+
json={"params": {
|
39
|
+
"stream": stream,
|
40
|
+
"messages": messages,
|
41
|
+
"temperature": temperature,
|
42
|
+
"max_tokens": max_tokens
|
43
|
+
}},
|
44
|
+
headers={"Authorization": f"tstoken-{self.token}"},
|
45
|
+
timeout=self.timeout, stream=stream
|
46
|
+
)
|
47
|
+
if resp.status_code != 200:
|
48
|
+
raise Exception(f"请求出现错误,{resp.content}")
|
49
|
+
return resp
|
50
|
+
|
51
|
+
def gpt_query(self, model, messages, temperature=None, max_tokens=None, pretty=False):
|
52
|
+
resp = self._request(model, messages, temperature, max_tokens, False, pretty)
|
53
|
+
resp_data = resp.json()
|
54
|
+
if resp_data.get('code') not in (0, None):
|
55
|
+
raise Exception(resp_data.get('msg') or resp_data)
|
56
|
+
if pretty:
|
57
|
+
return resp_data['choices'][0]["message"]["content"]
|
58
|
+
else:
|
59
|
+
return resp_data
|
60
|
+
|
61
|
+
def gpt_stream(self, model, messages, temperature=None, max_tokens=None, pretty=False):
|
62
|
+
resp = self._request(model, messages, temperature, max_tokens, True, pretty)
|
63
|
+
for e in sseclient.SSEClient(resp).events():
|
64
|
+
if '[DONE]' in e.data.upper():
|
65
|
+
break
|
66
|
+
e_data = json.loads(e.data)
|
67
|
+
if pretty:
|
68
|
+
yield e_data["choices"][0]["delta"]["content"]
|
69
|
+
else:
|
70
|
+
yield e_data
|
71
|
+
|
72
|
+
def gpt(self, model, query) -> str:
|
73
|
+
messages = [{
|
74
|
+
"role": "user",
|
75
|
+
"content": query
|
76
|
+
}]
|
77
|
+
return self.gpt_query(model, messages, pretty=True)
|
78
|
+
|
79
|
+
|
80
|
+
def test_gpt_query():
|
81
|
+
c = GPTClient()
|
82
|
+
dd = c.gpt_query("doubao-pro-128k", [{
|
83
|
+
"role": "user",
|
84
|
+
"content": "你好"
|
85
|
+
}])
|
86
|
+
print(dd)
|
87
|
+
dd = c.gpt_query("doubao-pro-128k", [{
|
88
|
+
"role": "user",
|
89
|
+
"content": "你好"
|
90
|
+
}], pretty=True)
|
91
|
+
print(dd)
|
92
|
+
|
93
|
+
|
94
|
+
def test_gpt_stream():
|
95
|
+
c = GPTClient()
|
96
|
+
dd = c.gpt_stream("doubao-pro-128k", [
|
97
|
+
{
|
98
|
+
"role": "user",
|
99
|
+
"content": "你好"
|
100
|
+
}
|
101
|
+
])
|
102
|
+
for d in dd:
|
103
|
+
print(d)
|
104
|
+
|
105
|
+
dd = c.gpt_stream("doubao-pro-128k", [
|
106
|
+
{
|
107
|
+
"role": "user",
|
108
|
+
"content": "你好"
|
109
|
+
}
|
110
|
+
], pretty=True)
|
111
|
+
for d in dd:
|
112
|
+
print(d)
|
113
|
+
|
114
|
+
|
115
|
+
def test_gpt():
|
116
|
+
c = GPTClient()
|
117
|
+
dd = c.gpt("doubao-pro-128k", "你好")
|
118
|
+
print(dd)
|
tushare/stock/rtq.py
CHANGED
@@ -173,7 +173,7 @@ def realtime_list(src: Optional[str] = None, interval: Optional[int] = 3,
|
|
173
173
|
东方财富:
|
174
174
|
2、代码:TS_CODE
|
175
175
|
3、名称:NAME
|
176
|
-
4、最新价:
|
176
|
+
4、最新价:CLOSE
|
177
177
|
5、涨跌幅:PCT_CHANGE
|
178
178
|
6、涨跌额:CHANGE
|
179
179
|
7、成交量:VOLUME
|
@@ -182,7 +182,7 @@ def realtime_list(src: Optional[str] = None, interval: Optional[int] = 3,
|
|
182
182
|
10、最高:HIGH
|
183
183
|
11、最低:LOW
|
184
184
|
12、今开:OPEN
|
185
|
-
13、昨收:
|
185
|
+
13、昨收:PRE_CLOSE
|
186
186
|
14、量比:VOL_RATIO
|
187
187
|
15、换手率:TURNOVER_RATE
|
188
188
|
16、市盈率-动态:PE
|
@@ -196,12 +196,12 @@ def realtime_list(src: Optional[str] = None, interval: Optional[int] = 3,
|
|
196
196
|
新浪财经:
|
197
197
|
1、代码:TS_CODE
|
198
198
|
2、名称:NAME
|
199
|
-
3、最新价:
|
199
|
+
3、最新价:CLOSE
|
200
200
|
4、涨跌额:CHANGE
|
201
201
|
5、涨跌幅:PCT_CHANGE
|
202
202
|
6、买入:BUY
|
203
203
|
7、卖出:SALE
|
204
|
-
8、昨收:
|
204
|
+
8、昨收:PRE_CLOSE
|
205
205
|
9、今开:OPEN
|
206
206
|
10、最高:HIGH
|
207
207
|
11、最低:LOW
|
@@ -359,7 +359,7 @@ def get_stock_all_a_dc(page_count: Optional[int] = None,
|
|
359
359
|
# "RANK",
|
360
360
|
"TS_CODE",
|
361
361
|
"NAME",
|
362
|
-
"
|
362
|
+
"CLOSE",
|
363
363
|
"PCT_CHANGE",
|
364
364
|
"CHANGE",
|
365
365
|
"VOLUME",
|
@@ -368,7 +368,7 @@ def get_stock_all_a_dc(page_count: Optional[int] = None,
|
|
368
368
|
"HIGH",
|
369
369
|
"LOW",
|
370
370
|
"OPEN",
|
371
|
-
"
|
371
|
+
"PRE_CLOSE",
|
372
372
|
"VOL_RATIO",
|
373
373
|
"TURNOVER_RATE",
|
374
374
|
"PE",
|
@@ -381,8 +381,8 @@ def get_stock_all_a_dc(page_count: Optional[int] = None,
|
|
381
381
|
"1YEAR",
|
382
382
|
]
|
383
383
|
# 指定要转换为 float 类型的列
|
384
|
-
cols_to_convert = ['
|
385
|
-
'HIGH', "LOW", "OPEN", "
|
384
|
+
cols_to_convert = ['CLOSE', 'PCT_CHANGE', 'CHANGE', "VOLUME", "AMOUNT", "SWING",
|
385
|
+
'HIGH', "LOW", "OPEN", "PRE_CLOSE", "VOL_RATIO", "TURNOVER_RATE", "PE", "PB", "TOTAL_MV", "FLOAT_MV",
|
386
386
|
"RISE", "5MIN", "60DAY", "1YEAR"
|
387
387
|
]
|
388
388
|
# 使用 to_numeric() 方法将指定的列转换为 float 类型,并将非数值类型的数据转换为 NaN
|
@@ -420,12 +420,12 @@ def get_stock_all_a_sina(interval: Optional[int] = 3, page_count: Optional[int]
|
|
420
420
|
:rtype: pandas.DataFrame
|
421
421
|
1、代码:TS_CODE
|
422
422
|
2、名称:NAME
|
423
|
-
3、最新价:
|
423
|
+
3、最新价:CLOSE
|
424
424
|
4、涨跌额:CHANGE
|
425
425
|
5、涨跌幅:PCT_CHANGE
|
426
426
|
6、买入:BUY
|
427
427
|
7、卖出:SALE
|
428
|
-
8、昨收:
|
428
|
+
8、昨收:PRE_CLOSE
|
429
429
|
9、今开:OPEN
|
430
430
|
10、最高:HIGH
|
431
431
|
11、最低:LOW
|
@@ -519,12 +519,12 @@ def get_stock_all_a_sina(interval: Optional[int] = 3, page_count: Optional[int]
|
|
519
519
|
big_df.columns = [
|
520
520
|
"TS_CODE",
|
521
521
|
"NAME",
|
522
|
-
"
|
522
|
+
"CLOSE",
|
523
523
|
"CHANGE",
|
524
524
|
"PCT_CHANGE",
|
525
525
|
"BUY",
|
526
526
|
"SALE",
|
527
|
-
"
|
527
|
+
"PRE_CLOSE",
|
528
528
|
"OPEN",
|
529
529
|
"HIGH",
|
530
530
|
"LOW",
|
@@ -563,10 +563,10 @@ def get_realtime_quotes_dc(symbols="688553"):
|
|
563
563
|
if not data_info:
|
564
564
|
return pd.DataFrame()
|
565
565
|
name = data_info["f58"]
|
566
|
-
open = data_info["
|
566
|
+
open = data_info["f46"] # / 100
|
567
567
|
high = data_info["f44"] # / 100
|
568
568
|
pre_close = data_info["f60"] # / 100
|
569
|
-
low =
|
569
|
+
low = data_info["f45"] # / 100
|
570
570
|
price = data_info["f43"] # / 100 if data_info["f43"] != "-" else ""
|
571
571
|
b5_v = format_str_to_float(data_info["f12"])
|
572
572
|
b5_p = data_info["f11"] # / 100 if data_info["f11"] != "-" else ""
|
@@ -636,14 +636,16 @@ def format_str_to_float(x):
|
|
636
636
|
|
637
637
|
if __name__ == '__main__':
|
638
638
|
# df = realtime_quote(ts_code="000688.SH,000010.SH,000012.SH,399005.SZ", src="sina")
|
639
|
-
df = realtime_list(src="sina", page_count=1)
|
640
|
-
print(df)
|
641
|
-
ts_code = '399005.SZ'
|
642
|
-
ts_code = '000001.SZ'
|
643
|
-
# ts_code = '836149.BJ'
|
644
|
-
# ts_code = '600000.SH'
|
645
|
-
# ts_code = '000001.SH'
|
646
|
-
# ts_code = '000010.SH'
|
647
|
-
ts_code = '
|
639
|
+
# df = realtime_list(src="sina", page_count=1)
|
640
|
+
# print(df)
|
641
|
+
# ts_code = '399005.SZ'
|
642
|
+
# ts_code = '000001.SZ'
|
643
|
+
# # ts_code = '836149.BJ'
|
644
|
+
# # ts_code = '600000.SH'
|
645
|
+
# # ts_code = '000001.SH'
|
646
|
+
# # ts_code = '000010.SH'
|
647
|
+
ts_code = '600148.SH'
|
648
648
|
df = realtime_quote(src="dc", ts_code=ts_code)
|
649
649
|
print(df)
|
650
|
+
|
651
|
+
|
tushare/subs/model/tick.py
CHANGED
@@ -1,128 +1,128 @@
|
|
1
|
-
from datetime import datetime
|
2
|
-
from typing import Optional
|
3
|
-
|
4
|
-
from pydantic import BaseModel
|
5
|
-
|
6
|
-
|
7
|
-
class TsTick(BaseModel):
|
8
|
-
ts_code: str
|
9
|
-
name: Optional[str]
|
10
|
-
trade_time: Optional[datetime]
|
11
|
-
pre_close_price: Optional[float]
|
12
|
-
last_price: Optional[float]
|
13
|
-
open_price: Optional[float]
|
14
|
-
high_price: Optional[float]
|
15
|
-
low_price: Optional[float]
|
16
|
-
close_price: Optional[float]
|
17
|
-
volume: Optional[int] # 成交量
|
18
|
-
amount: Optional[int] # 成交金额
|
19
|
-
count: Optional[int] # 交易数量
|
20
|
-
ask_price1: Optional[float] # 申卖价, 委托档位卖1档价格
|
21
|
-
ask_volume1: Optional[int] # 申卖量
|
22
|
-
bid_price1: Optional[float] # 申买价, 委托档位买1档价格
|
23
|
-
bid_volume1: Optional[int] # 申买量
|
24
|
-
ask_price2: Optional[float]
|
25
|
-
ask_volume2: Optional[int]
|
26
|
-
bid_price2: Optional[float]
|
27
|
-
bid_volume2: Optional[int]
|
28
|
-
ask_price3: Optional[float]
|
29
|
-
ask_volume3: Optional[int]
|
30
|
-
bid_price3: Optional[float]
|
31
|
-
bid_volume3: Optional[int]
|
32
|
-
ask_price4: Optional[float]
|
33
|
-
ask_volume4: Optional[int]
|
34
|
-
bid_price4: Optional[float]
|
35
|
-
bid_volume4: Optional[int]
|
36
|
-
ask_price5: Optional[float]
|
37
|
-
ask_volume5: Optional[int]
|
38
|
-
bid_price5: Optional[float]
|
39
|
-
bid_volume5: Optional[int]
|
40
|
-
ask_price6: Optional[float]
|
41
|
-
ask_volume6: Optional[int]
|
42
|
-
bid_price6: Optional[float]
|
43
|
-
bid_volume6: Optional[int]
|
44
|
-
ask_price7: Optional[float]
|
45
|
-
ask_volume7: Optional[int]
|
46
|
-
bid_price7: Optional[float]
|
47
|
-
bid_volume7: Optional[int]
|
48
|
-
ask_price8: Optional[float]
|
49
|
-
ask_volume8: Optional[int]
|
50
|
-
bid_price8: Optional[float]
|
51
|
-
bid_volume8: Optional[int]
|
52
|
-
ask_price9: Optional[float]
|
53
|
-
ask_volume9: Optional[int]
|
54
|
-
bid_price9: Optional[float]
|
55
|
-
bid_volume9: Optional[int]
|
56
|
-
ask_price10: Optional[float]
|
57
|
-
ask_volume10: Optional[int]
|
58
|
-
bid_price10: Optional[float]
|
59
|
-
bid_volume10: Optional[int]
|
60
|
-
|
61
|
-
|
62
|
-
class TsTickIdx(BaseModel):
|
63
|
-
ts_code: str
|
64
|
-
name: Optional[str]
|
65
|
-
trade_time: Optional[datetime]
|
66
|
-
last_price: Optional[float] # last_price
|
67
|
-
pre_close_price: Optional[float] # pre_close_price
|
68
|
-
high_price: Optional[float] # high_price
|
69
|
-
open_price: Optional[float] # open_price
|
70
|
-
low_price: Optional[float] # low_price
|
71
|
-
close_price: Optional[float] # close_price
|
72
|
-
volume: Optional[int] # volume, 成交总量
|
73
|
-
amount: Optional[float] # amount, 成交总金额
|
74
|
-
|
75
|
-
|
76
|
-
class TsTickOpt(BaseModel):
|
77
|
-
ts_code: str
|
78
|
-
instrument_id: str
|
79
|
-
trade_time: Optional[datetime]
|
80
|
-
pre_price: Optional[float]
|
81
|
-
price: Optional[float]
|
82
|
-
open: Optional[float]
|
83
|
-
high: Optional[float]
|
84
|
-
low: Optional[float]
|
85
|
-
close: Optional[float]
|
86
|
-
open_int: Optional[int]
|
87
|
-
vol: Optional[float]
|
88
|
-
amount: Optional[float]
|
89
|
-
num: Optional[int]
|
90
|
-
ask_price1: Optional[float]
|
91
|
-
ask_volume1: Optional[int]
|
92
|
-
bid_price1: Optional[float]
|
93
|
-
bid_volume1: Optional[int]
|
94
|
-
pre_delta: Optional[float] # 昨虚实度,暂未提供
|
95
|
-
dif_price1: Optional[float]
|
96
|
-
dif_price2: Optional[float]
|
97
|
-
high_limit_price: Optional[float]
|
98
|
-
low_limit_price: Optional[float]
|
99
|
-
refer_price: Optional[float] # 参考价,港股使用
|
100
|
-
|
101
|
-
|
102
|
-
class TsTickFuture(BaseModel):
|
103
|
-
ts_code: str
|
104
|
-
instrument_id: Optional[str]
|
105
|
-
trade_time: Optional[datetime]
|
106
|
-
pre_price: Optional[float]
|
107
|
-
price: Optional[float]
|
108
|
-
open: Optional[float]
|
109
|
-
high: Optional[float]
|
110
|
-
low: Optional[float]
|
111
|
-
close: Optional[float]
|
112
|
-
open_int: Optional[int]
|
113
|
-
vol: Optional[int]
|
114
|
-
amount: Optional[int] # 单数量
|
115
|
-
num: Optional[int]
|
116
|
-
ask_price1: Optional[float]
|
117
|
-
ask_volume1: Optional[int]
|
118
|
-
bid_price1: Optional[float]
|
119
|
-
bid_volume1: Optional[int]
|
120
|
-
pre_delta: Optional[float]
|
121
|
-
curr_delta: Optional[float]
|
122
|
-
dif_price1: Optional[float]
|
123
|
-
dif_price2: Optional[float]
|
124
|
-
high_limit_price: Optional[float]
|
125
|
-
low_limit_price: Optional[float]
|
126
|
-
refer_price: Optional[float]
|
127
|
-
pre_settle_price: Optional[float]
|
128
|
-
settle_price: Optional[float]
|
1
|
+
from datetime import datetime
|
2
|
+
from typing import Optional
|
3
|
+
|
4
|
+
from pydantic import BaseModel
|
5
|
+
|
6
|
+
|
7
|
+
class TsTick(BaseModel):
|
8
|
+
ts_code: str
|
9
|
+
name: Optional[str]
|
10
|
+
trade_time: Optional[datetime]
|
11
|
+
pre_close_price: Optional[float]
|
12
|
+
last_price: Optional[float]
|
13
|
+
open_price: Optional[float]
|
14
|
+
high_price: Optional[float]
|
15
|
+
low_price: Optional[float]
|
16
|
+
close_price: Optional[float]
|
17
|
+
volume: Optional[int] # 成交量
|
18
|
+
amount: Optional[int] # 成交金额
|
19
|
+
count: Optional[int] # 交易数量
|
20
|
+
ask_price1: Optional[float] # 申卖价, 委托档位卖1档价格
|
21
|
+
ask_volume1: Optional[int] # 申卖量
|
22
|
+
bid_price1: Optional[float] # 申买价, 委托档位买1档价格
|
23
|
+
bid_volume1: Optional[int] # 申买量
|
24
|
+
ask_price2: Optional[float]
|
25
|
+
ask_volume2: Optional[int]
|
26
|
+
bid_price2: Optional[float]
|
27
|
+
bid_volume2: Optional[int]
|
28
|
+
ask_price3: Optional[float]
|
29
|
+
ask_volume3: Optional[int]
|
30
|
+
bid_price3: Optional[float]
|
31
|
+
bid_volume3: Optional[int]
|
32
|
+
ask_price4: Optional[float]
|
33
|
+
ask_volume4: Optional[int]
|
34
|
+
bid_price4: Optional[float]
|
35
|
+
bid_volume4: Optional[int]
|
36
|
+
ask_price5: Optional[float]
|
37
|
+
ask_volume5: Optional[int]
|
38
|
+
bid_price5: Optional[float]
|
39
|
+
bid_volume5: Optional[int]
|
40
|
+
ask_price6: Optional[float]
|
41
|
+
ask_volume6: Optional[int]
|
42
|
+
bid_price6: Optional[float]
|
43
|
+
bid_volume6: Optional[int]
|
44
|
+
ask_price7: Optional[float]
|
45
|
+
ask_volume7: Optional[int]
|
46
|
+
bid_price7: Optional[float]
|
47
|
+
bid_volume7: Optional[int]
|
48
|
+
ask_price8: Optional[float]
|
49
|
+
ask_volume8: Optional[int]
|
50
|
+
bid_price8: Optional[float]
|
51
|
+
bid_volume8: Optional[int]
|
52
|
+
ask_price9: Optional[float]
|
53
|
+
ask_volume9: Optional[int]
|
54
|
+
bid_price9: Optional[float]
|
55
|
+
bid_volume9: Optional[int]
|
56
|
+
ask_price10: Optional[float]
|
57
|
+
ask_volume10: Optional[int]
|
58
|
+
bid_price10: Optional[float]
|
59
|
+
bid_volume10: Optional[int]
|
60
|
+
|
61
|
+
|
62
|
+
class TsTickIdx(BaseModel):
|
63
|
+
ts_code: str
|
64
|
+
name: Optional[str]
|
65
|
+
trade_time: Optional[datetime]
|
66
|
+
last_price: Optional[float] # last_price 单位元
|
67
|
+
pre_close_price: Optional[float] # pre_close_price
|
68
|
+
high_price: Optional[float] # high_price
|
69
|
+
open_price: Optional[float] # open_price
|
70
|
+
low_price: Optional[float] # low_price
|
71
|
+
close_price: Optional[float] # close_price
|
72
|
+
volume: Optional[int] # volume, 成交总量
|
73
|
+
amount: Optional[float] # amount, 成交总金额
|
74
|
+
|
75
|
+
|
76
|
+
class TsTickOpt(BaseModel):
|
77
|
+
ts_code: str
|
78
|
+
instrument_id: str
|
79
|
+
trade_time: Optional[datetime]
|
80
|
+
pre_price: Optional[float] # 单位元
|
81
|
+
price: Optional[float]
|
82
|
+
open: Optional[float]
|
83
|
+
high: Optional[float]
|
84
|
+
low: Optional[float]
|
85
|
+
close: Optional[float]
|
86
|
+
open_int: Optional[int]
|
87
|
+
vol: Optional[float]
|
88
|
+
amount: Optional[float]
|
89
|
+
num: Optional[int]
|
90
|
+
ask_price1: Optional[float]
|
91
|
+
ask_volume1: Optional[int]
|
92
|
+
bid_price1: Optional[float]
|
93
|
+
bid_volume1: Optional[int]
|
94
|
+
pre_delta: Optional[float] # 昨虚实度,暂未提供
|
95
|
+
dif_price1: Optional[float]
|
96
|
+
dif_price2: Optional[float]
|
97
|
+
high_limit_price: Optional[float]
|
98
|
+
low_limit_price: Optional[float]
|
99
|
+
refer_price: Optional[float] # 参考价,港股使用
|
100
|
+
|
101
|
+
|
102
|
+
class TsTickFuture(BaseModel):
|
103
|
+
ts_code: str
|
104
|
+
instrument_id: Optional[str]
|
105
|
+
trade_time: Optional[datetime]
|
106
|
+
pre_price: Optional[float]
|
107
|
+
price: Optional[float]
|
108
|
+
open: Optional[float]
|
109
|
+
high: Optional[float]
|
110
|
+
low: Optional[float]
|
111
|
+
close: Optional[float]
|
112
|
+
open_int: Optional[int]
|
113
|
+
vol: Optional[int]
|
114
|
+
amount: Optional[int] # 单数量
|
115
|
+
num: Optional[int]
|
116
|
+
ask_price1: Optional[float]
|
117
|
+
ask_volume1: Optional[int]
|
118
|
+
bid_price1: Optional[float]
|
119
|
+
bid_volume1: Optional[int]
|
120
|
+
pre_delta: Optional[float]
|
121
|
+
curr_delta: Optional[float]
|
122
|
+
dif_price1: Optional[float]
|
123
|
+
dif_price2: Optional[float]
|
124
|
+
high_limit_price: Optional[float]
|
125
|
+
low_limit_price: Optional[float]
|
126
|
+
refer_price: Optional[float]
|
127
|
+
pre_settle_price: Optional[float]
|
128
|
+
settle_price: Optional[float]
|
tushare/subs/tgw_subs/convert.py
CHANGED
@@ -62,14 +62,14 @@ def convert_tick_index(tgw_data: dict) -> TsTickIdx:
|
|
62
62
|
ts_code=get_ts_code(tgw_data.get("market_type"), tgw_data.get("security_code")),
|
63
63
|
name=None,
|
64
64
|
trade_time=datetime.strptime(str(tgw_data.get('orig_time'))[:-3], '%Y%m%d%H%M%S'),
|
65
|
-
last_price=tgw_data.get('last_index'),
|
66
|
-
pre_close_price=tgw_data.get('pre_close_index'),
|
67
|
-
open_price=tgw_data.get('open_index'),
|
68
|
-
high_price=tgw_data.get('high_index'),
|
69
|
-
low_price=tgw_data.get('low_index'),
|
70
|
-
close_price=tgw_data.get('close_index'),
|
71
|
-
volume=tgw_data.get('total_volume_trade'),
|
72
|
-
amount=tgw_data.get('total_value_trade'),
|
65
|
+
last_price=tgw_data.get('last_index')/1000000,
|
66
|
+
pre_close_price=tgw_data.get('pre_close_index')/1000000,
|
67
|
+
open_price=tgw_data.get('open_index')/1000000,
|
68
|
+
high_price=tgw_data.get('high_index')/1000000,
|
69
|
+
low_price=tgw_data.get('low_index')/1000000,
|
70
|
+
close_price=tgw_data.get('close_index')/1000000,
|
71
|
+
volume=tgw_data.get('total_volume_trade')/100,
|
72
|
+
amount=tgw_data.get('total_value_trade')/100000,
|
73
73
|
)
|
74
74
|
return item
|
75
75
|
|
@@ -138,22 +138,22 @@ def convert_tick_stock(tgw_data: dict) -> TsTick:
|
|
138
138
|
"""
|
139
139
|
extra = {}
|
140
140
|
for i in range(1, 11):
|
141
|
-
extra[f'ask_price{i}'] = tgw_data.get(f'offer_price{i}')
|
142
|
-
extra[f'ask_volume{i}'] = tgw_data.get(f'offer_volume{i}')
|
143
|
-
extra[f'bid_price{i}'] = tgw_data.get(f'bid_price{i}')
|
144
|
-
extra[f'bid_volume{i}'] = tgw_data.get(f'bid_volume{i}')
|
141
|
+
extra[f'ask_price{i}'] = tgw_data.get(f'offer_price{i}')/1000000
|
142
|
+
extra[f'ask_volume{i}'] = tgw_data.get(f'offer_volume{i}')/100
|
143
|
+
extra[f'bid_price{i}'] = tgw_data.get(f'bid_price{i}')/1000000
|
144
|
+
extra[f'bid_volume{i}'] = tgw_data.get(f'bid_volume{i}')/100
|
145
145
|
item = TsTick(
|
146
146
|
ts_code=get_ts_code(tgw_data.get("market_type"), tgw_data.get("security_code")),
|
147
147
|
name=None,
|
148
148
|
trade_time=datetime.strptime(str(tgw_data.get('orig_time'))[:-3], '%Y%m%d%H%M%S'),
|
149
|
-
pre_close_price=tgw_data.get("pre_close_price"),
|
150
|
-
last_price=tgw_data.get("last_price"),
|
151
|
-
open_price=tgw_data.get("open_price"),
|
152
|
-
high_price=tgw_data.get("high_price"),
|
153
|
-
low_price=tgw_data.get("low_price"),
|
154
|
-
close_price=tgw_data.get("close_price"),
|
155
|
-
volume=tgw_data.get("total_volume_trade"),
|
156
|
-
amount=tgw_data.get("total_value_trade"),
|
149
|
+
pre_close_price=tgw_data.get("pre_close_price")/1000000,
|
150
|
+
last_price=tgw_data.get("last_price")/1000000,
|
151
|
+
open_price=tgw_data.get("open_price")/1000000,
|
152
|
+
high_price=tgw_data.get("high_price")/1000000,
|
153
|
+
low_price=tgw_data.get("low_price")/1000000,
|
154
|
+
close_price=tgw_data.get("close_price")/1000000,
|
155
|
+
volume=tgw_data.get("total_volume_trade")/100,
|
156
|
+
amount=tgw_data.get("total_value_trade")/1000000,
|
157
157
|
count=tgw_data.get("num_trades"),
|
158
158
|
**extra
|
159
159
|
)
|
@@ -58,7 +58,11 @@ class TsSubscribe(object):
|
|
58
58
|
logger.info('application starting...')
|
59
59
|
self.threading_keepalive_ping()
|
60
60
|
|
61
|
-
def on_message(self,
|
61
|
+
def on_message(self, *args, **kwargs):
|
62
|
+
if isinstance(args[0], websocket.WebSocketApp):
|
63
|
+
message = args[1]
|
64
|
+
else:
|
65
|
+
message = args[0]
|
62
66
|
logger.debug(message)
|
63
67
|
if isinstance(message, (str, bytes, bytearray)):
|
64
68
|
resp_data = json.loads(message)
|
@@ -172,11 +176,27 @@ class TsSubscribe(object):
|
|
172
176
|
p.start()
|
173
177
|
|
174
178
|
|
175
|
-
def
|
176
|
-
app = TsSubscribe(
|
179
|
+
def test_min():
|
180
|
+
app = TsSubscribe("xxx")
|
181
|
+
|
182
|
+
# code 可以包含 * (通配符)
|
183
|
+
@app.register(topic='HQ_STK_MIN', codes=["1MIN:*.SH"])
|
184
|
+
def print_message(record):
|
185
|
+
"""
|
186
|
+
订阅主题topic,并指定codes列表,在接收到topic的推送消息时,符合code条件,就会执行回调
|
187
|
+
:param record:
|
188
|
+
:return:
|
189
|
+
"""
|
190
|
+
print('用户定义业务代码输出 print_message(%s)' % str(record))
|
191
|
+
|
192
|
+
app.run()
|
193
|
+
|
194
|
+
|
195
|
+
def test_tick():
|
196
|
+
app = TsSubscribe(token='xxx')
|
177
197
|
|
178
198
|
# code 可以包含 * (通配符)
|
179
|
-
@app.register(topic='HQ_STK_TICK', codes=["
|
199
|
+
@app.register(topic='HQ_STK_TICK', codes=["*.SH"])
|
180
200
|
def print_message(record):
|
181
201
|
"""
|
182
202
|
订阅主题topic,并指定codes列表,在接收到topic的推送消息时,符合code条件,就会执行回调
|
@@ -189,4 +209,4 @@ def test():
|
|
189
209
|
|
190
210
|
|
191
211
|
if __name__ == '__main__':
|
192
|
-
|
212
|
+
test_min()
|
@@ -16,50 +16,47 @@ def format_stock_code(x, special=""):
|
|
16
16
|
@param special:
|
17
17
|
@return:
|
18
18
|
"""
|
19
|
+
x = str(x)
|
20
|
+
stock_len = 6
|
21
|
+
hk_stock_len = 5
|
19
22
|
if special:
|
20
23
|
x = str(x)
|
21
24
|
if "行业" in special or "概念" in special:
|
22
|
-
x = x.zfill(
|
25
|
+
x = x.zfill(stock_len) if len(x) < stock_len else x
|
23
26
|
return '%s.TI' % x
|
24
|
-
elif "港股"
|
27
|
+
elif special == "港股":
|
25
28
|
r = re.search(r"(\d+)", str(x), re.S | re.M)
|
26
29
|
if not r:
|
27
30
|
return x
|
28
31
|
else:
|
29
32
|
x = r.group(1)
|
30
|
-
x = x.zfill(
|
33
|
+
x = x.zfill(hk_stock_len) if len(x) < hk_stock_len else x
|
31
34
|
return '%s.HK' % x
|
32
35
|
elif special == "场外基金" or special == "热基":
|
33
|
-
x = x.zfill(
|
36
|
+
x = x.zfill(stock_len) if len(x) < stock_len else x
|
34
37
|
return '%s.OF' % x
|
35
38
|
elif special == "可转债":
|
36
39
|
if str(x).startswith('11'):
|
37
|
-
x = x.zfill(
|
40
|
+
x = x.zfill(stock_len) if len(x) < stock_len else x
|
38
41
|
return '%s.SH' % x
|
39
42
|
elif str(x).startswith('12'):
|
40
|
-
x = x.zfill(
|
43
|
+
x = x.zfill(stock_len) if len(x) < stock_len else x
|
41
44
|
return '%s.SZ' % x
|
42
|
-
|
43
|
-
if not x[0].isdigit():
|
44
|
-
r = re.search(r"(\d+)", str(x), re.S | re.M)
|
45
|
-
if not r:
|
46
|
-
return x.upper()
|
47
|
-
else:
|
48
|
-
x = r.group(1) # # return f"{r.group(1)}.{str(x).split(r.group(1))[0]}"
|
49
|
-
|
50
45
|
if not x[0].isdigit():
|
51
46
|
return x.upper()
|
47
|
+
if str(x[0:3]) in ['920']:
|
48
|
+
x = x.zfill(stock_len) if len(x) < stock_len else x
|
49
|
+
return '%s.BJ' % x
|
52
50
|
if str(x[0]) in ['5', '6', '9']:
|
53
|
-
x = x.zfill(
|
51
|
+
x = x.zfill(stock_len) if len(x) < stock_len else x
|
54
52
|
return '%s.SH' % x
|
55
53
|
elif str(x[0]) in ['8', '4']:
|
56
|
-
x = x.zfill(
|
54
|
+
x = x.zfill(stock_len) if len(x) < stock_len else x
|
57
55
|
return '%s.BJ' % x
|
58
56
|
else:
|
59
|
-
x = x.zfill(
|
57
|
+
x = x.zfill(stock_len) if len(x) < stock_len else x
|
60
58
|
return '%s.SZ' % x
|
61
59
|
|
62
|
-
|
63
60
|
def a_symbol_verify(x):
|
64
61
|
l = str(x).upper().split(".")
|
65
62
|
if not x[-1].isdigit():
|
@@ -107,6 +104,8 @@ def verify_stock_or_index(x):
|
|
107
104
|
return True
|
108
105
|
elif x.startswith('4') and x.endswith('BJ'):
|
109
106
|
return True
|
107
|
+
elif x.startswith('920') and x.endswith('BJ'):
|
108
|
+
return True
|
110
109
|
elif x.startswith('9') and x.endswith('CSI'):
|
111
110
|
return False
|
112
111
|
else:
|
@@ -119,5 +118,6 @@ if __name__ == '__main__':
|
|
119
118
|
# s = symbol_verify("sz000001")
|
120
119
|
# s = symbol_verify("000001.SZ")
|
121
120
|
# s = symbols_f("000001", special="港股")
|
122
|
-
s = verify_stock_or_index(x="399005.SZ")
|
121
|
+
# s = verify_stock_or_index(x="399005.SZ")
|
122
|
+
s = format_stock_code(x="92052")
|
123
123
|
print(s)
|
@@ -1,13 +1,12 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: tushare
|
3
|
-
Version: 1.4.
|
3
|
+
Version: 1.4.17
|
4
4
|
Summary: A utility for crawling historical and Real-time Quotes data of China stocks
|
5
5
|
Home-page: https://tushare.pro
|
6
6
|
Author: Jimmy Liu
|
7
7
|
Author-email: waditu@163.com
|
8
8
|
License: BSD
|
9
9
|
Keywords: Global Financial Data
|
10
|
-
Platform: UNKNOWN
|
11
10
|
Classifier: Development Status :: 4 - Beta
|
12
11
|
Classifier: Programming Language :: Python :: 3.6
|
13
12
|
Classifier: Programming Language :: Python :: 3.7
|
@@ -16,17 +15,13 @@ Classifier: Programming Language :: Python :: 3.9
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.10
|
17
16
|
Classifier: License :: OSI Approved :: BSD License
|
18
17
|
Description-Content-Type: text/plain
|
18
|
+
License-File: LICENSE
|
19
19
|
Requires-Dist: pandas
|
20
20
|
Requires-Dist: requests
|
21
21
|
Requires-Dist: lxml
|
22
22
|
Requires-Dist: simplejson
|
23
|
-
Requires-Dist: bs4
|
24
|
-
Requires-Dist: websocket-client
|
25
|
-
Requires-Dist: pytdx
|
26
|
-
Requires-Dist: protobuf
|
27
|
-
Requires-Dist: grpcio
|
28
|
-
Requires-Dist: pycryptodome
|
29
|
-
Requires-Dist: pydantic
|
23
|
+
Requires-Dist: bs4
|
24
|
+
Requires-Dist: websocket-client >=0.57.0
|
30
25
|
Requires-Dist: tqdm
|
31
26
|
|
32
27
|
|
@@ -54,21 +49,21 @@ Installation
|
|
54
49
|
--------------
|
55
50
|
|
56
51
|
pip install tushare
|
57
|
-
|
52
|
+
|
58
53
|
Upgrade
|
59
54
|
---------------
|
60
55
|
|
61
56
|
pip install tushare --upgrade
|
62
|
-
|
57
|
+
|
63
58
|
Quick Start
|
64
59
|
--------------
|
65
60
|
|
66
61
|
::
|
67
62
|
|
68
63
|
import tushare as ts
|
69
|
-
|
64
|
+
|
70
65
|
ts.get_hist_data('600848')
|
71
|
-
|
66
|
+
|
72
67
|
return::
|
73
68
|
|
74
69
|
open high close low volume p_change ma5
|
@@ -81,10 +76,23 @@ return::
|
|
81
76
|
2012-01-18 7.000 7.300 6.890 6.880 13075.40 0.44 6.788
|
82
77
|
2012-01-19 6.690 6.950 6.890 6.680 6117.32 0.00 6.770
|
83
78
|
2012-01-20 6.870 7.080 7.010 6.870 6813.09 1.74 6.832
|
84
|
-
|
85
|
-
|
79
|
+
|
80
|
+
|
86
81
|
Log
|
87
82
|
--------------
|
83
|
+
1.4.17
|
84
|
+
-------
|
85
|
+
- 修复 920 开头更改是北交所
|
86
|
+
-------
|
87
|
+
1.4.14
|
88
|
+
-------
|
89
|
+
- 修复 realtime_list (爬虫版)
|
90
|
+
- 修复dc CLOSE和PRE_CLOSE收盘和昨收 字段命名问题
|
91
|
+
-------
|
92
|
+
1.4.6
|
93
|
+
-------
|
94
|
+
- 修复 realtime_quote 实时盘口TICK快照(爬虫版)
|
95
|
+
- 修复dc OPEN和LOW 值相反问题
|
88
96
|
1.4.0
|
89
97
|
-------
|
90
98
|
- 增加 银河证券实时行情数据入口
|
@@ -96,6 +104,4 @@ Log
|
|
96
104
|
1.2.73
|
97
105
|
-------
|
98
106
|
- 支持华泰实时数据15SECOND
|
99
|
-
|
100
|
-
|
101
|
-
|
107
|
+
|
@@ -1,4 +1,4 @@
|
|
1
|
-
tushare/__init__.py,sha256=
|
1
|
+
tushare/__init__.py,sha256=WGp2WFHHZkVf028VsTtx31RvngjcKDEFQCE4Zt3JFcE,4778
|
2
2
|
tushare/bond/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
3
3
|
tushare/bond/bonds.py,sha256=PJM0xDiWZDpOPwDtbEU9PdP0M_Gu0c599YuB1rbZ3r8,232
|
4
4
|
tushare/coins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -17,8 +17,9 @@ tushare/internet/boxoffice.py,sha256=NaAJYg8e6vldIG7vF2fXOcQSqFrNQ_2z9bLx5-TyMYY
|
|
17
17
|
tushare/internet/caixinnews.py,sha256=IwNOB5F1q_CxfuP93-jgUpTW5yY5NANPRJXySm_bj2A,4178
|
18
18
|
tushare/internet/indexes.py,sha256=oteQCv0k2X0pbhXRHwMSviD1AowJWE6xRjKkqr5RNCo,3595
|
19
19
|
tushare/pro/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
20
|
-
tushare/pro/client.py,sha256=
|
21
|
-
tushare/pro/data_pro.py,sha256=
|
20
|
+
tushare/pro/client.py,sha256=w7LfXtlmSd4Aiq7Bz5-tPFfkfjrPS_7jroUiRs7BUWw,1388
|
21
|
+
tushare/pro/data_pro.py,sha256=3ZVaHCsHqJlMouXsqgAeayqD9rThX-EGZ_REOYsAWbs,20568
|
22
|
+
tushare/pro/llm.py,sha256=Zdb81mhr9lQKX6p-JDml7THSbmBm8NmFQT54B8FkgvI,3444
|
22
23
|
tushare/stock/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
23
24
|
tushare/stock/billboard.py,sha256=vCrbN7-NGXSpXMc8jq7NcjjHyu9pTcr4uXp559iA1wA,12833
|
24
25
|
tushare/stock/classifying.py,sha256=3yWqlLhgj2irk-9ksKWFFS5HY-SnjfEr5erwJxBidG8,10539
|
@@ -34,7 +35,7 @@ tushare/stock/news_vars.py,sha256=CQ18hvyoeScelBCqKgF_rgAufoEALAUT8y_LERvZKHk,45
|
|
34
35
|
tushare/stock/newsevent.py,sha256=STR7C8MjtZlaXTCG0QNaojBuK4-oxP_8hT7ZIvRpbiI,6944
|
35
36
|
tushare/stock/ref_vars.py,sha256=MIxor-2rISl65I32vUzC-z7ZC_QFzG4sxOKDyjLWuU4,4449
|
36
37
|
tushare/stock/reference.py,sha256=x_HZlrP58T-5OTZ7SLdf2Dh9THj1h7cT4wcIp42IHFI,38227
|
37
|
-
tushare/stock/rtq.py,sha256=
|
38
|
+
tushare/stock/rtq.py,sha256=uMljEz2030OE-i_JAkeSwM1gghK4g5omTx4mC0EqTVc,23159
|
38
39
|
tushare/stock/rtq_vars.py,sha256=V6LeJkSP76z8veRfP_mGiQ63V5YBHoTMaqUA5hSBWh4,4200
|
39
40
|
tushare/stock/shibor.py,sha256=Fx9OUZ429kz6l7ZdaYSD6p_X79ud69PDM9EZogm8xCY,6422
|
40
41
|
tushare/stock/trading.py,sha256=3bvM4pexEYW-uGGEL7g6Vkte4sqGC1iYO6dC8mGLSdM,55619
|
@@ -44,13 +45,13 @@ tushare/subs/ht_subs/covert.py,sha256=d25f86D_4CHjrX3IGh8JtTSb7VI2Da506FHwlhOhk1
|
|
44
45
|
tushare/subs/ht_subs/subscribe.py,sha256=yYnPeg7c0OHbIJhEf4bXFMLbQ4H1bHhApDPrHeTimuw,8340
|
45
46
|
tushare/subs/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
46
47
|
tushare/subs/model/min.py,sha256=-AYBGOM1U8IB7Q6SPHS0tpoWN3qz1hngCw7k5x2HhUU,375
|
47
|
-
tushare/subs/model/tick.py,sha256=
|
48
|
+
tushare/subs/model/tick.py,sha256=yaYMJY42_IPjViY4v0aMyNahXfpBE_m2dcz3obm8Y94,4339
|
48
49
|
tushare/subs/tgw_subs/__init__.py,sha256=30AFeIgTci0HLNyZTNpr1wRChrVdvpD2dHNKS4Q-fS0,69
|
49
|
-
tushare/subs/tgw_subs/convert.py,sha256=
|
50
|
+
tushare/subs/tgw_subs/convert.py,sha256=VWsDOv_rmz3a9YjQ-ZThXerc1HqcWPlBYAOF6A9SqjQ,5474
|
50
51
|
tushare/subs/tgw_subs/login.py,sha256=z7laiscTx50LzOB0cM2hypv5E78DvWx-2Ip5kDE7uNk,903
|
51
52
|
tushare/subs/tgw_subs/subscribe.py,sha256=OwLKcSTN2xrge33hBkio_S188viMeGuicDj_x0VaR2A,3336
|
52
53
|
tushare/subs/ts_subs/__init__.py,sha256=AyX957j8DDjdpIYcNR7dyRaMfxusa6d2VeunMEB6RAc,107
|
53
|
-
tushare/subs/ts_subs/subscribe.py,sha256=
|
54
|
+
tushare/subs/ts_subs/subscribe.py,sha256=3akQj5IDANatYOBFYSKotigKviAf5N8SNO_ZVx8pBR0,6701
|
54
55
|
tushare/trader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
55
56
|
tushare/trader/trader.py,sha256=O2WJkIKGuUFK_hiQj83N5j971VW-TNAgKaCE0O4oFwg,11360
|
56
57
|
tushare/trader/utils.py,sha256=CG-TCyeu5WqYjnBARxft2lEnLD3xvhHLU40hPSL_CCw,752
|
@@ -60,7 +61,7 @@ tushare/util/common.py,sha256=KG86VdlhfnOf0j6SE2bBeowC_7Z54RqWpVnudS6KvEU,2581
|
|
60
61
|
tushare/util/conns.py,sha256=mkcxGGD7-13GXMlrwmo4LMecmgWdm63I8KDpvcW53cI,1456
|
61
62
|
tushare/util/dateu.py,sha256=YSvPvOlMY0qvT2IDwFNOHxTLBrPQ9ULGO7ljfu9tK3s,2931
|
62
63
|
tushare/util/form_date.py,sha256=4nnjp6xo40FftsRP9YY1FJoPErxaWVCkjIp_3O1Qy7M,1119
|
63
|
-
tushare/util/format_stock_code.py,sha256=
|
64
|
+
tushare/util/format_stock_code.py,sha256=5uQngRIqN6pzEHtI-AX_oBdHxRdOVpAvA_S41mCUY5I,3639
|
64
65
|
tushare/util/formula.py,sha256=XZVK1NTF8BTrCo78EHLzjAM_wLAjxybrN7Q-6HCHmCo,6863
|
65
66
|
tushare/util/mailmerge.py,sha256=y_QkfHvH8nQ7peC8wQs5idB6xW9PYzzrBynzxgo924M,8980
|
66
67
|
tushare/util/netbase.py,sha256=URvOTLJSgO7e6uCmHHD9EeQ2TRvjpxIEF-wQaWx5cKE,942
|
@@ -71,8 +72,8 @@ tushare/util/verify_token.py,sha256=cuV3RErWbOC318NANCYL6K1LKZ3wSAL2yMwZHA7tD3s,
|
|
71
72
|
tushare/util/protobuf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
72
73
|
tushare/util/protobuf/funcs.py,sha256=UCdK8FxTyjPZsNzoEeXqYzqrQXUmRMvW5hua6GPA66A,779
|
73
74
|
tushare/util/protobuf/response_pb2.py,sha256=vJH9ONkDuJlg6y-q1PvuDZoviKrK7hzNtMieQHK45DI,11347
|
74
|
-
tushare-1.4.
|
75
|
-
tushare-1.4.
|
76
|
-
tushare-1.4.
|
77
|
-
tushare-1.4.
|
78
|
-
tushare-1.4.
|
75
|
+
tushare-1.4.17.dist-info/LICENSE,sha256=C2j55UI0Ul-1-wA1-rn7OaY6b3vGl4YukiyvYzHsU9o,1503
|
76
|
+
tushare-1.4.17.dist-info/METADATA,sha256=298UYSq2inzUnYNgOsF6h6O1Gg0rzrT2OVOcwv3wKx0,3030
|
77
|
+
tushare-1.4.17.dist-info/WHEEL,sha256=Wyh-_nZ0DJYolHNn1_hMa4lM7uDedD_RGVwbmTjyItk,91
|
78
|
+
tushare-1.4.17.dist-info/top_level.txt,sha256=HHOxMuqc31KuAIcxpE0t5dAPMKbaiRtjsjTMFd7FlXI,8
|
79
|
+
tushare-1.4.17.dist-info/RECORD,,
|
File without changes
|
File without changes
|