tushare 1.4.4__py3-none-any.whl → 1.4.17__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- 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
|