tushare 1.3.6__py3-none-any.whl → 1.3.7__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.
@@ -0,0 +1,8 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created on 2021-12-31 09:32:16
4
+ ---------
5
+ @summary:
6
+ ---------
7
+ @author: yangyx01
8
+ """
test/build_pyd/rtqc.py ADDED
@@ -0,0 +1,612 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding:utf-8 -*-
3
+ """
4
+ 所有 A 股的实时行情数据
5
+ Created on 2023/12/06
6
+ @author: Monday
7
+ @group : waditu
8
+ @contact:
9
+ """
10
+ import time
11
+ import pandas as pd
12
+ import requests
13
+ from tqdm import tqdm
14
+ from typing import Optional
15
+ import re
16
+ from tushare.util.format_stock_code import symbol_verify
17
+ from tushare.util.format_stock_code import format_stock_code
18
+ from tushare.util.form_date import timestemp_to_time
19
+ from tushare.stock import rtq_vars as rtqv
20
+ from tushare.util.verify_token import require_permission
21
+ from tushare.stock import cons as ct
22
+ from tushare.stock.rtq_vars import (
23
+ zh_sina_a_stock_payload,
24
+ zh_sina_a_stock_url,
25
+ zh_sina_a_stock_count_url,
26
+ zh_sina_a_stock_headers,
27
+ zh_sina_a_stock_cookies,
28
+
29
+ )
30
+
31
+
32
+ def _random(n=13):
33
+ from random import randint
34
+ start = 10 ** (n - 1)
35
+ end = (10 ** n) - 1
36
+ return str(randint(start, end))
37
+
38
+
39
+ def _get_current_timestamp():
40
+ return str(int(time.time() * 1000))
41
+
42
+
43
+ @require_permission(event_name="realtime_quote", event_detail="个股实时交易数据")
44
+ def realtime_quote(ts_code="688553.SH", src="sina", ):
45
+ """
46
+ 获取实时交易数据 getting real time quotes data
47
+ 用于跟踪交易情况(本次执行的结果-上一次执行的数据)
48
+ Parameters
49
+ ------
50
+ ts_code : string
51
+ src : sina ,dc
52
+
53
+ return
54
+ -------
55
+ DataFrame 实时交易数据
56
+ 属性:0:name,股票名字
57
+ 1:open,今日开盘价
58
+ 2:pre_close,昨日收盘价
59
+ 3:price,当前价格
60
+ 4:high,今日最高价
61
+ 5:low,今日最低价
62
+ 6:bid,竞买价,即“买一”报价
63
+ 7:ask,竞卖价,即“卖一”报价
64
+ 8:volumn,成交量 maybe you need do volumn/100
65
+ 9:amount,成交金额(元 CNY)
66
+ 10:b1_v,委买一(笔数 bid volume)
67
+ 11:b1_p,委买一(价格 bid price)
68
+ 12:b2_v,“买二”
69
+ 13:b2_p,“买二”
70
+ 14:b3_v,“买三”
71
+ 15:b3_p,“买三”
72
+ 16:b4_v,“买四”
73
+ 17:b4_p,“买四”
74
+ 18:b5_v,“买五”
75
+ 19:b5_p,“买五”
76
+ 20:a1_v,委卖一(笔数 ask volume)
77
+ 21:a1_p,委卖一(价格 ask price)
78
+ ...
79
+ 30:date,日期;
80
+ 31:time,时间;
81
+ """
82
+ symbols = symbol_verify(ts_code)
83
+ if src == "sina":
84
+ return get_realtime_quotes_sina(symbols)
85
+ else:
86
+ return get_realtime_quotes_dc(symbols)
87
+
88
+
89
+ sina_stock_code = {}
90
+
91
+
92
+ def get_realtime_quotes_sina(symbol="688553"): # "688553"
93
+ global sina_stock_code
94
+ symbols = []
95
+ syms = []
96
+ for i in [j for j in symbol.split(",")]:
97
+ s = i.split(".")
98
+ sina_stock_code[s[0]] = s[1].upper()
99
+ symbols.append(s[1].lower() + s[0])
100
+ syms.append(s[0])
101
+ # symbols = re.search(r"(\d+)", str(symbols), re.S | re.M).group(1)
102
+ symbols_list = ''
103
+ if isinstance(symbols, list) or isinstance(symbols, set) or \
104
+ isinstance(symbols, tuple) or isinstance(symbols, pd.Series):
105
+ for code in symbols:
106
+ symbols_list += code + ','
107
+ else:
108
+ symbols_list = symbols
109
+ symbols_list = symbols_list[:-1] if len(symbols_list) > 8 else symbols_list
110
+ root_url = ct.LIVE_DATA_URL % (ct.P_TYPE['http'], ct.DOMAINS['sinahq'], _get_current_timestamp(), symbols_list)
111
+ response = requests.get(root_url,
112
+ headers={
113
+ "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0",
114
+ 'host': 'hq.sinajs.cn',
115
+ 'referer': 'https://finance.sina.com.cn/'
116
+ })
117
+ text = response.content.decode('GBK')
118
+ reg = re.compile(r'\="(.*?)\";')
119
+ data = reg.findall(text)
120
+ data_list = []
121
+ syms_list = []
122
+ for index, row in enumerate(data):
123
+ if len(row) > 1:
124
+ data_list.append([astr for astr in row.split(',')[:33]])
125
+ syms_list.append(syms[index])
126
+ if len(syms_list) == 0:
127
+ return None
128
+ df = pd.DataFrame(data_list, columns=ct.LIVE_DATA_COLS)
129
+ df = df.drop('s', axis=1)
130
+ df['code'] = syms_list
131
+ ls = [cls for cls in df.columns if '_v' in cls]
132
+ for txt in ls:
133
+ df[txt] = df[txt].map(lambda x: x[:-2])
134
+ df.columns = rtqv.LIVE_DATA_COLS
135
+ df["TS_CODE"] = df["TS_CODE"].apply(format_sina_stock_code)
136
+ df["DATE"] = df["DATE"].apply(format_date_str)
137
+ new_order = rtqv.LIVE_DATA_COLS_REINDEX
138
+ df = df[new_order]
139
+ return df
140
+
141
+
142
+ def format_sina_stock_code(x):
143
+ ts_code = f"{x}.{sina_stock_code[x]}"
144
+ return ts_code
145
+
146
+
147
+ def format_date_str(date_str):
148
+ return date_str.replace("-", "")
149
+
150
+
151
+ @require_permission(event_name="realtime_list", event_detail="A股所有实时交易数据")
152
+ def realtime_list(src: Optional[str] = None, interval: Optional[int] = 3,
153
+ page_count: Optional[int] = None, proxies: Optional[dict] = {}) -> pd.DataFrame:
154
+ """
155
+ 沪深京 A 股 all -实时行情
156
+ @param src: 数据源 新浪sina |东方财富 dc
157
+ @param interval: 分页采集时间间隔(默认3秒翻译一夜)
158
+ @param page_count: 限制抓取的页数(仅对新浪有效)
159
+ @param proxies: 设置代理 防止被封禁
160
+ @return: 按涨跌幅 倒序排序
161
+ -------
162
+ DataFrame 实时交易数据
163
+ 东方财富:
164
+ 2、代码:TS_CODE
165
+ 3、名称:NAME
166
+ 4、最新价:PRICE
167
+ 5、涨跌幅:PCT_CHANGE
168
+ 6、涨跌额:CHANGE
169
+ 7、成交量:VOLUME
170
+ 8、成交额:AMOUNT
171
+ 9、振幅:SWING
172
+ 10、最高:HIGH
173
+ 11、最低:LOW
174
+ 12、今开:OPEN
175
+ 13、昨收:CLOSE
176
+ 14、量比:VOL_RATIO
177
+ 15、换手率:TURNOVER_RATE
178
+ 16、市盈率-动态:PE
179
+ 17、市净率:PB
180
+ 18、总市值:TOTAL_MV
181
+ 19、流通市值:FLOAT_MV
182
+ 20、涨速:RISE
183
+ 21、5分钟涨跌:5MIN
184
+ 22、60日涨跌幅:60DAY
185
+ 23、年初至今涨跌幅:1YEAR
186
+ 新浪财经:
187
+ 1、代码:TS_CODE
188
+ 2、名称:NAME
189
+ 3、最新价:PRICE
190
+ 4、涨跌额:CHANGE
191
+ 5、涨跌幅:PCT_CHANGE
192
+ 6、买入:BUY
193
+ 7、卖出:SALE
194
+ 8、昨收:CLOSE
195
+ 9、今开:OPEN
196
+ 10、最高:HIGH
197
+ 11、最低:LOW
198
+ 12、成交量:VOLUME
199
+ 13、成交额:AMOUNT
200
+ 14、时间戳:TIME
201
+
202
+ """
203
+ if src == "dc":
204
+ return get_stock_all_a_dc(page_count, proxies)
205
+ elif src == "sina":
206
+ return get_stock_all_a_sina(interval, page_count, proxies)
207
+ else:
208
+ return get_stock_all_a_dc(page_count, proxies)
209
+
210
+
211
+ def get_stock_all_a_dc(page_count: Optional[int] = None,
212
+ proxies: Optional[dict] = {}) -> pd.DataFrame:
213
+ """
214
+ 东方财富网-沪深京 A 股-实时行情
215
+ https://quote.eastmoney.com/center/gridlist.html#hs_a_board
216
+ :return: 实时行情
217
+ :rtype: pandas.DataFrame
218
+ 1、序号:RANK
219
+ 2、代码:TS_CODE
220
+ 3、名称:NAME
221
+ 4、最新价:PRICE
222
+ 5、涨跌幅:PCT_CHANGE
223
+ 6、涨跌额:CHANGE
224
+ 7、成交量:VOLUME
225
+ 8、成交额:AMOUNT
226
+ 9、振幅:SWING
227
+ 10、最高:HIGH
228
+ 11、最低:LOW
229
+ 12、今开:OPEN
230
+ 13、昨收:CLOSE
231
+ 14、量比:VOL_RATIO
232
+ 15、换手率:TURNOVER_RATE
233
+ 16、市盈率-动态:PE
234
+ 17、市净率:PB
235
+ 18、总市值:TOTAL_MV
236
+ 19、流通市值:FLOAT_MV
237
+ 20、涨速:RISE
238
+ 21、5分钟涨跌:5MIN
239
+ 22、60日涨跌幅:60DAY
240
+ 23、年初至今涨跌幅:1YEAR
241
+ """
242
+ url = "http://82.push2.eastmoney.com/api/qt/clist/get"
243
+ params = {
244
+ "pn": "1",
245
+ "pz": "50000",
246
+ "po": "1",
247
+ "np": "1",
248
+ "ut": "bd1d9ddb04089700cf9c27f6f7426281",
249
+ "fltt": "2",
250
+ "invt": "2",
251
+ "fid": "f3",
252
+ "fs": "m:0 t:6,m:0 t:80,m:1 t:2,m:1 t:23,m:0 t:81 s:2048",
253
+ "fields": "f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152",
254
+ "_": "1623833739532",
255
+ }
256
+ if page_count:
257
+ params["pz"] = 20
258
+ r = requests.get(url, params=params, proxies=proxies)
259
+ data_json = r.json()
260
+ if not data_json["data"]["diff"]:
261
+ return pd.DataFrame()
262
+ temp_df = pd.DataFrame(data_json["data"]["diff"])
263
+ temp_df.columns = [
264
+ "_",
265
+ "最新价",
266
+ "涨跌幅",
267
+ "涨跌额",
268
+ "成交量",
269
+ "成交额",
270
+ "振幅",
271
+ "换手率",
272
+ "市盈率-动态",
273
+ "量比",
274
+ "5分钟涨跌",
275
+ "代码",
276
+ "_",
277
+ "名称",
278
+ "最高",
279
+ "最低",
280
+ "今开",
281
+ "昨收",
282
+ "总市值",
283
+ "流通市值",
284
+ "涨速",
285
+ "市净率",
286
+ "60日涨跌幅",
287
+ "年初至今涨跌幅",
288
+ "-",
289
+ "-",
290
+ "-",
291
+ "-",
292
+ "-",
293
+ "-",
294
+ "-",
295
+ ]
296
+ temp_df.reset_index(inplace=True)
297
+ # temp_df["index"] = temp_df.index + 1
298
+ # temp_df.rename(columns={"index": "序号"}, inplace=True)
299
+ temp_df = temp_df[
300
+ [
301
+ # "序号",
302
+ "代码",
303
+ "名称",
304
+ "最新价",
305
+ "涨跌幅",
306
+ "涨跌额",
307
+ "成交量",
308
+ "成交额",
309
+ "振幅",
310
+ "最高",
311
+ "最低",
312
+ "今开",
313
+ "昨收",
314
+ "量比",
315
+ "换手率",
316
+ "市盈率-动态",
317
+ "市净率",
318
+ "总市值",
319
+ "流通市值",
320
+ "涨速",
321
+ "5分钟涨跌",
322
+ "60日涨跌幅",
323
+ "年初至今涨跌幅",
324
+ ]
325
+ ]
326
+
327
+ temp_df["代码"] = temp_df["代码"].apply(format_stock_code)
328
+ temp_df["最新价"] = pd.to_numeric(temp_df["最新价"], errors="coerce")
329
+ temp_df["涨跌幅"] = pd.to_numeric(temp_df["涨跌幅"], errors="coerce")
330
+ temp_df["涨跌额"] = pd.to_numeric(temp_df["涨跌额"], errors="coerce")
331
+ temp_df["成交量"] = pd.to_numeric(temp_df["成交量"], errors="coerce")
332
+ temp_df["成交额"] = pd.to_numeric(temp_df["成交额"], errors="coerce")
333
+ temp_df["振幅"] = pd.to_numeric(temp_df["振幅"], errors="coerce")
334
+ temp_df["最高"] = pd.to_numeric(temp_df["最高"], errors="coerce")
335
+ temp_df["最低"] = pd.to_numeric(temp_df["最低"], errors="coerce")
336
+ temp_df["今开"] = pd.to_numeric(temp_df["今开"], errors="coerce")
337
+ temp_df["昨收"] = pd.to_numeric(temp_df["昨收"], errors="coerce")
338
+ temp_df["量比"] = pd.to_numeric(temp_df["量比"], errors="coerce")
339
+ temp_df["换手率"] = pd.to_numeric(temp_df["换手率"], errors="coerce")
340
+ temp_df["市盈率-动态"] = pd.to_numeric(temp_df["市盈率-动态"], errors="coerce")
341
+ temp_df["市净率"] = pd.to_numeric(temp_df["市净率"], errors="coerce")
342
+ temp_df["总市值"] = pd.to_numeric(temp_df["总市值"], errors="coerce")
343
+ temp_df["流通市值"] = pd.to_numeric(temp_df["流通市值"], errors="coerce")
344
+ temp_df["涨速"] = pd.to_numeric(temp_df["涨速"], errors="coerce")
345
+ temp_df["5分钟涨跌"] = pd.to_numeric(temp_df["5分钟涨跌"], errors="coerce")
346
+ temp_df["60日涨跌幅"] = pd.to_numeric(temp_df["60日涨跌幅"], errors="coerce")
347
+ temp_df["年初至今涨跌幅"] = pd.to_numeric(temp_df["年初至今涨跌幅"], errors="coerce")
348
+ temp_df.columns = [
349
+ # "RANK",
350
+ "TS_CODE",
351
+ "NAME",
352
+ "PRICE",
353
+ "PCT_CHANGE",
354
+ "CHANGE",
355
+ "VOLUME",
356
+ "AMOUNT",
357
+ "SWING",
358
+ "HIGH",
359
+ "LOW",
360
+ "OPEN",
361
+ "CLOSE",
362
+ "VOL_RATIO",
363
+ "TURNOVER_RATE",
364
+ "PE",
365
+ "PB",
366
+ "TOTAL_MV",
367
+ "FLOAT_MV",
368
+ "RISE",
369
+ "5MIN",
370
+ "60DAY",
371
+ "1YEAR",
372
+ ]
373
+ df_sorted = temp_df.sort_values(by='PCT_CHANGE', ascending=False).reset_index(drop=True)
374
+ return df_sorted
375
+
376
+
377
+ def _get_zh_a_page_count() -> int:
378
+ """
379
+ 所有股票的总页数
380
+ https://vip.stock.finance.sina.com.cn/mkt/#hs_a
381
+ :return: 需要采集的股票总页数
382
+ :rtype: int
383
+ """
384
+ res = requests.get(zh_sina_a_stock_count_url)
385
+ page_count = int(re.findall(re.compile(r"\d+"), res.text)[0]) / 80
386
+ if isinstance(page_count, int):
387
+ return page_count
388
+ else:
389
+ return int(page_count) + 1
390
+
391
+
392
+ def get_stock_all_a_sina(interval: Optional[int] = 3, page_count: Optional[int] = None,
393
+ proxies: Optional[dict] = {}) -> pd.DataFrame:
394
+ """
395
+ 新浪财经-所有 A 股的实时行情数据; 重复运行本函数会被新浪暂时封 IP
396
+ https://vip.stock.finance.sina.com.cn/mkt/#hs_a
397
+ :param interval:请求间隔时间
398
+ :param page_count:限制抓取页数
399
+ :param proxies: 代理ip {}
400
+ :return: 所有股票的实时行情数据
401
+ :rtype: pandas.DataFrame
402
+ 1、代码:TS_CODE
403
+ 2、名称:NAME
404
+ 3、最新价:PRICE
405
+ 4、涨跌额:CHANGE
406
+ 5、涨跌幅:PCT_CHANGE
407
+ 6、买入:BUY
408
+ 7、卖出:SALE
409
+ 8、昨收:CLOSE
410
+ 9、今开:OPEN
411
+ 10、最高:HIGH
412
+ 11、最低:LOW
413
+ 12、成交量:VOLUME
414
+ 13、成交额:AMOUNT
415
+ 14、时间戳:TIME
416
+
417
+ """
418
+ big_df = pd.DataFrame()
419
+ if not page_count:
420
+ page_count = _get_zh_a_page_count()
421
+ zh_sina_stock_payload_copy = zh_sina_a_stock_payload.copy()
422
+ for page in tqdm(
423
+ range(1, page_count + 1), leave=False, desc="Please wait for a moment"
424
+ ):
425
+ zh_sina_stock_payload_copy.update({"page": page})
426
+ r = requests.get(
427
+ zh_sina_a_stock_url, headers=zh_sina_a_stock_headers,
428
+ cookies=zh_sina_a_stock_cookies,
429
+ params=zh_sina_stock_payload_copy,
430
+ proxies=proxies,
431
+ )
432
+ data_json = r.json()
433
+ big_df = pd.concat(
434
+ [big_df, pd.DataFrame(data_json)], ignore_index=True
435
+ )
436
+
437
+ time.sleep(interval)
438
+
439
+ big_df = big_df.astype(
440
+ {
441
+ "trade": "float",
442
+ "pricechange": "float",
443
+ "changepercent": "float",
444
+ "buy": "float",
445
+ "sell": "float",
446
+ "settlement": "float",
447
+ "open": "float",
448
+ "high": "float",
449
+ "low": "float",
450
+ "volume": "float",
451
+ "amount": "float",
452
+ "per": "float",
453
+ "pb": "float",
454
+ "mktcap": "float",
455
+ "nmc": "float",
456
+ "turnoverratio": "float",
457
+ }
458
+ )
459
+ big_df.columns = [
460
+ "代码",
461
+ "_",
462
+ "名称",
463
+ "最新价",
464
+ "涨跌额",
465
+ "涨跌幅",
466
+ "买入",
467
+ "卖出",
468
+ "昨收",
469
+ "今开",
470
+ "最高",
471
+ "最低",
472
+ "成交量",
473
+ "成交额",
474
+ "时间戳",
475
+ "_",
476
+ "_",
477
+ "_",
478
+ "_",
479
+ "_",
480
+ ]
481
+ big_df = big_df[
482
+ [
483
+ "代码",
484
+ "名称",
485
+ "最新价",
486
+ "涨跌额",
487
+ "涨跌幅",
488
+ "买入",
489
+ "卖出",
490
+ "昨收",
491
+ "今开",
492
+ "最高",
493
+ "最低",
494
+ "成交量",
495
+ "成交额",
496
+ "时间戳",
497
+ ]
498
+ ]
499
+ big_df["代码"] = big_df["代码"].apply(format_stock_code)
500
+ big_df.columns = [
501
+ "TS_CODE",
502
+ "NAME",
503
+ "PRICE",
504
+ "CHANGE",
505
+ "PCT_CHANGE",
506
+ "BUY",
507
+ "SALE",
508
+ "CLOSE",
509
+ "OPEN",
510
+ "HIGH",
511
+ "LOW",
512
+ "VOLUME",
513
+ "AMOUNT",
514
+ "TIME",
515
+
516
+ ]
517
+ df_sorted = big_df.sort_values(by='PCT_CHANGE', ascending=False).reset_index(drop=True)
518
+ return df_sorted
519
+
520
+
521
+ def get_realtime_quotes_dc(symbols="688553"):
522
+ """
523
+ https://quote.eastmoney.com/sh601096.html
524
+ """
525
+ symbols = str(symbols).split(",")[0]
526
+ url = "https://push2.eastmoney.com/api/qt/stock/get"
527
+ symbol = re.search(r"(\d+)", symbols, re.S | re.M).group(1)
528
+ # print(symbol)
529
+ params = {
530
+ "invt": "2",
531
+ "fltt": "1",
532
+ # "cb": "jQuery35108939078769986013_1701853424476",
533
+ "fields": "f58,f734,f107,f57,f43,f59,f169,f301,f60,f170,f152,f177,f111,f46,f44,f45,f47,f260,f48,f261,f279,f277,f278,f288,f19,f17,f531,f15,f13,f11,f20,f18,f16,f14,f12,f39,f37,f35,f33,f31,f40,f38,f36,f34,f32,f211,f212,f213,f214,f215,f210,f209,f208,f207,f206,f161,f49,f171,f50,f86,f84,f85,f168,f108,f116,f167,f164,f162,f163,f92,f71,f117,f292,f51,f52,f191,f192,f262,f294,f295,f748,f747",
534
+ "secid": f"1.{symbol}",
535
+ "ut": "fa5fd1943c7b386f172d6893dbfba10b",
536
+ "wbp2u": "|0|0|0|web",
537
+ "_": _get_current_timestamp()
538
+ }
539
+ response = requests.get(url, headers=rtqv.dc_cookies, cookies=rtqv.dc_headers, params=params)
540
+ data_info = response.json()["data"]
541
+ if not data_info:
542
+ return pd.DataFrame()
543
+ name = data_info["f58"]
544
+ open = data_info["f45"] # / 100
545
+ high = data_info["f44"] # / 100
546
+ pre_close = data_info["f60"] # / 100
547
+ low = data_info["f46"] # / 100
548
+ price = data_info["f43"] # / 100 if data_info["f43"] != "-" else ""
549
+ b5_v = data_info["f12"]
550
+ b5_p = data_info["f11"] # / 100 if data_info["f11"] != "-" else ""
551
+ b4_v = data_info["f14"]
552
+ b4_p = data_info["f13"] # / 100 if data_info["f13"] != "-" else ""
553
+ b3_v = data_info["f16"]
554
+ b3_p = data_info["f15"] # / 100 if data_info["f15"] != "-" else ""
555
+ b2_v = data_info["f18"]
556
+ b2_p = data_info["f17"] # / 100 if data_info["f17"] != "-" else ""
557
+ b1_v = data_info["f20"]
558
+ b1_p = data_info["f19"] # / 100 if data_info["f19"] != "-" else ""
559
+ a5_v = data_info["f32"]
560
+ a5_p = data_info["f31"] # / 100 if data_info["f31"] != "-" else ""
561
+ a4_v = data_info["f34"]
562
+ a4_p = data_info["f33"] # / 100 if data_info["f33"] != "-" else ""
563
+ a3_v = data_info["f36"]
564
+ a3_p = data_info["f35"] # / 100 if data_info["f35"] != "-" else ""
565
+ a2_v = data_info["f38"]
566
+ a2_p = data_info["f37"] # / 100 if data_info["f38"] != "-" else ""
567
+ a1_v = data_info["f40"]
568
+ a1_p = data_info["f39"] # / 100 if data_info["f39"] != "-" else ""
569
+ date_time = timestemp_to_time(data_info["f86"])
570
+ date = date_time[0:10]
571
+ times = date_time[10:]
572
+ volume = data_info["f47"]
573
+ amount = data_info["f48"]
574
+ bid = data_info["f19"] # / 100 if data_info["f19"] != "-" else ""
575
+ ask = data_info["f39"] # / 100 if data_info["f39"] != "-" else ""
576
+ code = symbols
577
+ data_list = [[name, open, pre_close, price, high, low, bid, ask, volume, amount,
578
+ b1_v, b1_p, b2_v, b2_p, b3_v, b3_p, b4_v, b4_p, b5_v, b5_p,
579
+ a1_v, a1_p, a2_v, a2_p, a3_v, a3_p, a4_v, a4_p, a5_v, a5_p, date, times, code]]
580
+ df = pd.DataFrame(data_list, columns=rtqv.LIVE_DATA_COLS)
581
+ df["DATE"] = df["DATE"].apply(format_date_str)
582
+ df["ASK"] = df["ASK"].apply(format_dc_str)
583
+ df["OPEN"] = df["OPEN"].apply(format_dc_str)
584
+ df["HIGH"] = df["HIGH"].apply(format_dc_str)
585
+ df["LOW"] = df["LOW"].apply(format_dc_str)
586
+ df["PRE_CLOSE"] = df["PRE_CLOSE"].apply(format_dc_str)
587
+ df["BID"] = df["BID"].apply(format_dc_str)
588
+ df["A1_P"] = df["A1_P"].apply(format_dc_str)
589
+ df["A2_P"] = df["A2_P"].apply(format_dc_str)
590
+ df["A3_P"] = df["A3_P"].apply(format_dc_str)
591
+ df["A4_P"] = df["A4_P"].apply(format_dc_str)
592
+ df["A5_P"] = df["A5_P"].apply(format_dc_str)
593
+ df["PRICE"] = df["PRICE"].apply(format_dc_str)
594
+ df["B1_P"] = df["B1_P"].apply(format_dc_str)
595
+ df["B2_P"] = df["B2_P"].apply(format_dc_str)
596
+ df["B3_P"] = df["B3_P"].apply(format_dc_str)
597
+ df["B4_P"] = df["B4_P"].apply(format_dc_str)
598
+ df["B5_P"] = df["B5_P"].apply(format_dc_str)
599
+ new_order = rtqv.LIVE_DATA_COLS_REINDEX
600
+ df = df[new_order]
601
+ return df
602
+
603
+
604
+ def format_dc_str(x):
605
+ return x / 100 if x != "-" else ""
606
+
607
+
608
+ if __name__ == '__main__':
609
+ # df = realtime_quote(ts_code="000688.SH,000010.SH,000012.SH,399005.SZ", src="sina")
610
+ df = realtime_list(src="dc", page_count=1)
611
+ # print(help(realtime_quote))
612
+ print(df)
@@ -0,0 +1,15 @@
1
+ # -*- coding: utf-8 -*-
2
+ """
3
+ Created on 2021-12-31 09:32:16
4
+ ---------
5
+ @summary:
6
+ ---------
7
+ @author: yangyx01
8
+ """
9
+ # setup.py
10
+ from setuptools import setup
11
+ from Cython.Build import cythonize
12
+
13
+ setup(
14
+ ext_modules=cythonize("rtqc.py")
15
+ )
test/test_query.py ADDED
@@ -0,0 +1,16 @@
1
+ """
2
+ 作 者:lidy
3
+ 时 间:2023/8/22 22:00
4
+ 项目名:tsdpsdk
5
+ """
6
+
7
+ import tushare
8
+
9
+ def test_query():
10
+ api = tushare.pro_api('75e70c1ef4bd1a14e2301cbf20ec35e1045971c104ab02853e375284')
11
+ df = api.query('stock_basic', fields='ts_code,symbol')
12
+ print(df)
13
+
14
+
15
+ if __name__ == '__main__':
16
+ test_query()
test/test_sdk_event.py ADDED
@@ -0,0 +1,21 @@
1
+ """
2
+ # 作 者:84028
3
+ # 时 间:2024/1/9 13:29
4
+ # tsdpsdk
5
+ """
6
+ import time
7
+
8
+ import requests
9
+
10
+ if __name__ == '__main__':
11
+ for i in range(200):
12
+ start = time.time()
13
+ resp = requests.post(
14
+ 'http://127.0.0.1:8081/dataapi/sdk-event',
15
+ json={
16
+ "user_token": "af4c3a76ff14972b3467d8950dd1587bb3d4b6b2dc9cd94093910795",
17
+ "event_name": "test",
18
+ "event_detail": "测试"
19
+ }
20
+ )
21
+ print(time.time()-start, resp)
@@ -0,0 +1,16 @@
1
+ """
2
+ 作 者:lidy
3
+ 时 间:2023/8/22 22:00
4
+ 项目名:tsdpsdk
5
+ """
6
+
7
+ import tushare
8
+
9
+ def test_stock_basic():
10
+ api = tushare.pro_api('75e70c1ef4bd1a14e2301cbf20ec35e1045971c104ab02853e375284')
11
+ df = api.stock_basic()
12
+ print(df)
13
+
14
+
15
+ if __name__ == '__main__':
16
+ test_stock_basic()
tushare/__init__.py CHANGED
@@ -2,7 +2,7 @@
2
2
  import codecs
3
3
  import os
4
4
 
5
- __version__ = '1.3.6'
5
+ __version__ = '1.3.7'
6
6
  __author__ = 'Jimmy Liu'
7
7
 
8
8
  """
@@ -133,5 +133,6 @@ from tushare.util.upass import (get_token, set_token)
133
133
  """
134
134
  for quotes API
135
135
  """
136
+ # from tushare.stock.rtqc import (realtime_quote, realtime_list)
136
137
  from tushare.stock.rtq import (realtime_quote, realtime_list)
137
138
  from tushare.stock.histroy_divide import (realtime_tick)
tushare/pro/data_pro.py CHANGED
@@ -13,7 +13,7 @@ from tushare.util import upass
13
13
  from tushare.util.formula import MA
14
14
  from tushare.subs.ts_subs import Subs
15
15
 
16
- PRICE_COLS = ['open', 'close', 'high', 'low', 'pre_close']
16
+ PRICE_COLS = ['open', 'close', 'high', 'low']
17
17
  FORMAT = lambda x: '%.4f' % x
18
18
  FREQS = {'D': '1DAY',
19
19
  'W': '1WEEK',
tushare/stock/rtq.py CHANGED
@@ -14,7 +14,7 @@ from tqdm import tqdm
14
14
  from typing import Optional
15
15
  import re
16
16
  from tushare.util.format_stock_code import symbol_verify
17
- from tushare.util.format_stock_code import format_stock_code
17
+ from tushare.util.format_stock_code import format_stock_code,verify_stock_or_index
18
18
  from tushare.util.form_date import timestemp_to_time
19
19
  from tushare.stock import rtq_vars as rtqv
20
20
  from tushare.util.verify_token import require_permission
@@ -201,15 +201,15 @@ def realtime_list(src: Optional[str] = None, interval: Optional[int] = 3,
201
201
 
202
202
  """
203
203
  if src == "dc":
204
- return get_stock_all_a_dc( page_count, proxies)
204
+ return get_stock_all_a_dc(page_count, proxies)
205
205
  elif src == "sina":
206
206
  return get_stock_all_a_sina(interval, page_count, proxies)
207
207
  else:
208
- return get_stock_all_a_dc( page_count, proxies)
208
+ return get_stock_all_a_dc(page_count, proxies)
209
209
 
210
210
 
211
211
  def get_stock_all_a_dc(page_count: Optional[int] = None,
212
- proxies: Optional[dict] = {}) -> pd.DataFrame:
212
+ proxies: Optional[dict] = {}) -> pd.DataFrame:
213
213
  """
214
214
  东方财富网-沪深京 A 股-实时行情
215
215
  https://quote.eastmoney.com/center/gridlist.html#hs_a_board
@@ -298,7 +298,7 @@ def get_stock_all_a_dc(page_count: Optional[int] = None,
298
298
  # temp_df.rename(columns={"index": "序号"}, inplace=True)
299
299
  temp_df = temp_df[
300
300
  [
301
- #"序号",
301
+ # "序号",
302
302
  "代码",
303
303
  "名称",
304
304
  "最新价",
@@ -346,7 +346,7 @@ def get_stock_all_a_dc(page_count: Optional[int] = None,
346
346
  temp_df["60日涨跌幅"] = pd.to_numeric(temp_df["60日涨跌幅"], errors="coerce")
347
347
  temp_df["年初至今涨跌幅"] = pd.to_numeric(temp_df["年初至今涨跌幅"], errors="coerce")
348
348
  temp_df.columns = [
349
- #"RANK",
349
+ # "RANK",
350
350
  "TS_CODE",
351
351
  "NAME",
352
352
  "PRICE",
@@ -531,11 +531,13 @@ def get_realtime_quotes_dc(symbols="688553"):
531
531
  "fltt": "1",
532
532
  # "cb": "jQuery35108939078769986013_1701853424476",
533
533
  "fields": "f58,f734,f107,f57,f43,f59,f169,f301,f60,f170,f152,f177,f111,f46,f44,f45,f47,f260,f48,f261,f279,f277,f278,f288,f19,f17,f531,f15,f13,f11,f20,f18,f16,f14,f12,f39,f37,f35,f33,f31,f40,f38,f36,f34,f32,f211,f212,f213,f214,f215,f210,f209,f208,f207,f206,f161,f49,f171,f50,f86,f84,f85,f168,f108,f116,f167,f164,f162,f163,f92,f71,f117,f292,f51,f52,f191,f192,f262,f294,f295,f748,f747",
534
- "secid": f"1.{symbol}",
534
+ "secid": f"0.{symbol}",
535
535
  "ut": "fa5fd1943c7b386f172d6893dbfba10b",
536
536
  "wbp2u": "|0|0|0|web",
537
537
  "_": _get_current_timestamp()
538
538
  }
539
+ if not verify_stock_or_index(symbols):
540
+ params["secid"] = f"1.{symbol}"
539
541
  response = requests.get(url, headers=rtqv.dc_cookies, cookies=rtqv.dc_headers, params=params)
540
542
  data_info = response.json()["data"]
541
543
  if not data_info:
@@ -571,8 +573,8 @@ def get_realtime_quotes_dc(symbols="688553"):
571
573
  times = date_time[10:]
572
574
  volume = data_info["f47"]
573
575
  amount = data_info["f48"]
574
- bid = data_info["f19"] # / 100 if data_info["f19"] != "-" else ""
575
- ask = data_info["f39"] # / 100 if data_info["f39"] != "-" else ""
576
+ bid = data_info["f19"]
577
+ ask = data_info["f39"]
576
578
  code = symbols
577
579
  data_list = [[name, open, pre_close, price, high, low, bid, ask, volume, amount,
578
580
  b1_v, b1_p, b2_v, b2_p, b3_v, b3_p, b4_v, b4_p, b5_v, b5_p,
@@ -607,6 +609,9 @@ def format_dc_str(x):
607
609
 
608
610
  if __name__ == '__main__':
609
611
  # df = realtime_quote(ts_code="000688.SH,000010.SH,000012.SH,399005.SZ", src="sina")
610
- df = realtime_list(src="sina", page_count=1)
611
- # print(help(realtime_quote))
612
- print(df)
612
+ # # df = realtime_list(src="dc", page_count=1)
613
+ # print(df)
614
+ ts_code = '399005.SZ'
615
+ ts_code = '000001.SZ'
616
+ df = realtime_quote(src="dc", ts_code=ts_code)
617
+ print(df)
@@ -10,6 +10,12 @@ import re
10
10
 
11
11
 
12
12
  def format_stock_code(x, special=""):
13
+ """
14
+ 股票代码 code 格式化
15
+ @param x:
16
+ @param special:
17
+ @return:
18
+ """
13
19
  if special:
14
20
  x = str(x)
15
21
  if "行业" in special or "概念" in special:
@@ -78,11 +84,39 @@ def symbol_verify(x):
78
84
  raise '请按照 "000001.SZ" 格式传入symbol'
79
85
 
80
86
 
87
+ def verify_stock_or_index(x):
88
+ """
89
+ 判断代码是否是 股票 True 指数 False
90
+ @param x:
91
+ @return:
92
+ """
93
+ x = str(x).upper()
94
+ if x.startswith('39') and x.endswith('SZ'):
95
+ return True
96
+ elif x.startswith('30') and x.endswith('SZ'):
97
+ return True
98
+ elif x.startswith('0') and x.endswith('SH'):
99
+ return False
100
+ elif x.startswith('0') and x.endswith('SZ'):
101
+ return True
102
+ elif x.startswith('6') and x.endswith('SH'):
103
+ return True
104
+ elif x.startswith('8') and x.endswith('BJ'):
105
+ return True
106
+ elif x.startswith('4') and x.endswith('BJ'):
107
+ return True
108
+ elif x.startswith('9') and x.endswith('CSI'):
109
+ return False
110
+ else:
111
+ return True
112
+
113
+
114
+
81
115
  if __name__ == '__main__':
82
116
  # s = symbol_verify("13.SH")
83
117
  # # s = symbol_verify("sh13")
84
118
  # s = symbol_verify("sz000001")
85
119
  # s = symbol_verify("000001.SZ")
86
120
  # s = symbols_f("000001", special="港股")
87
- s = format_stock_code(x="BJ430017")
121
+ s = verify_stock_or_index(x="399005.SZ")
88
122
  print(s)
@@ -36,6 +36,7 @@ def require_permission(event_name, event_detail):
36
36
  # 如果有足够权限,调用原始函数
37
37
  return func(*args, **kwargs)
38
38
  else:
39
+ print(f"验证token出错,{r.text}")
39
40
  raise PermissionError(f"{r['msg']}")
40
41
  else:
41
42
  raise PermissionError(ct.TOKEN_ERR_MSG)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tushare
3
- Version: 1.3.6
3
+ Version: 1.3.7
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
@@ -12,11 +12,18 @@ test/pro_test.py,sha256=Aj5cmLY12OvxEV2XE1oReHeYBI2paNOhm0CwWSrz1Tg,229
12
12
  test/ref_test.py,sha256=FFOQO1Jnn42TRgmGipGJy_H-qZ9JJyFDb6ShY7YRDNo,1507
13
13
  test/shibor_test.py,sha256=l8EGCh92obzozUcPphOP4V8EQEM2-Xzh1l3CApjNjt8,762
14
14
  test/storing_test.py,sha256=UVyDDZXisjFrKy_5bpWLEN4M5fReOy-q8tvBOGO0XhQ,1789
15
+ test/test_query.py,sha256=X-u8RpJBu77P00DowBLMO1nbbsCxEqIRyHsiEEDVv7s,329
15
16
  test/test_realtime.py,sha256=YpEH3Ic3D-4dgL9BI9RbWNSD-ZM8KfuqtSxyBvexSRg,697
17
+ test/test_sdk_event.py,sha256=NSX0AYuU45BHztn_wcnM0clIf1Xb0s4DzNsm3SgTXRo,529
16
18
  test/test_stk_mins.py,sha256=ctaoAkclIKxNQT6KYuXaB5HESpZSD29dn-KLbUT2rmo,53600
19
+ test/test_stock_basic.py,sha256=XQW6TZGeOjrB0a4OV8WxK0RvOx-iQW_vwARoMLppWVA,309
17
20
  test/test_websocket.py,sha256=DgOEcX9vuYlPVfBi54AJZTh6k0eu9lG4qcOdJhGllNU,1079
18
21
  test/trading_test.py,sha256=otXiHdU0ob441x7o1swadfSEuyPusT7oYU8SQeesSxE,1147
19
- tushare/__init__.py,sha256=0PICFtLOZb4NfnG1Gszv7ltTC1emX2tyuLIQKDvcdX0,4698
22
+ test/build_pyd/__init__.py,sha256=pel_N6SRBWzJKf55rnF6eZa0zDNpO41JU1_3IRwi3uU,121
23
+ test/build_pyd/rtqc.py,sha256=0TJHzK41zWR7ka34bT5UIIcXMW6WOs__WB1HVwrcfjA,21085
24
+ test/build_pyd/setup.py,sha256=rNK-9qDmwnb6mSnwMoHsQbyTSEKJf8c7gPPbmaPMHHY,250
25
+ test/build_pyd/打包pyd命令.txt,sha256=EO6iGOJXxFWOCJlIhhvRylaZpoa1R8PznZM9jDek55w,35
26
+ tushare/__init__.py,sha256=Tj0xKQgYHDU2EXDAZlX9AmelF3Lcel8tJpDL2QEkLJ4,4764
20
27
  tushare/bond/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
28
  tushare/bond/bonds.py,sha256=PJM0xDiWZDpOPwDtbEU9PdP0M_Gu0c599YuB1rbZ3r8,232
22
29
  tushare/coins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -36,7 +43,7 @@ tushare/internet/caixinnews.py,sha256=IwNOB5F1q_CxfuP93-jgUpTW5yY5NANPRJXySm_bj2
36
43
  tushare/internet/indexes.py,sha256=oteQCv0k2X0pbhXRHwMSviD1AowJWE6xRjKkqr5RNCo,3595
37
44
  tushare/pro/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
45
  tushare/pro/client.py,sha256=91jKHO9OPrNWPp3193edresGg6UoX0NlmOqAdf0mX4A,1312
39
- tushare/pro/data_pro.py,sha256=ZcgGg2Fialu-M6FPPqyARlUnZvXxOfuoSOAnkRHftIU,10287
46
+ tushare/pro/data_pro.py,sha256=GA1U8dlWGan23-B8oU76teY-c8XYC3q_4rWJKcHZCDk,10274
40
47
  tushare/stock/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
41
48
  tushare/stock/billboard.py,sha256=vCrbN7-NGXSpXMc8jq7NcjjHyu9pTcr4uXp559iA1wA,12833
42
49
  tushare/stock/classifying.py,sha256=3yWqlLhgj2irk-9ksKWFFS5HY-SnjfEr5erwJxBidG8,10539
@@ -52,7 +59,7 @@ tushare/stock/news_vars.py,sha256=CQ18hvyoeScelBCqKgF_rgAufoEALAUT8y_LERvZKHk,45
52
59
  tushare/stock/newsevent.py,sha256=STR7C8MjtZlaXTCG0QNaojBuK4-oxP_8hT7ZIvRpbiI,6944
53
60
  tushare/stock/ref_vars.py,sha256=MIxor-2rISl65I32vUzC-z7ZC_QFzG4sxOKDyjLWuU4,4449
54
61
  tushare/stock/reference.py,sha256=x_HZlrP58T-5OTZ7SLdf2Dh9THj1h7cT4wcIp42IHFI,38227
55
- tushare/stock/rtq.py,sha256=_78O-u5ZoRcj8ldEb9bLugIFlTSvZsMi5v6c0a-mUH8,21089
62
+ tushare/stock/rtq.py,sha256=kjbfyP6M3pNnA7k92aovnSgarRd8l0WdtE6vKneXVUc,21194
56
63
  tushare/stock/rtq_vars.py,sha256=V6LeJkSP76z8veRfP_mGiQ63V5YBHoTMaqUA5hSBWh4,4200
57
64
  tushare/stock/shibor.py,sha256=Fx9OUZ429kz6l7ZdaYSD6p_X79ud69PDM9EZogm8xCY,6422
58
65
  tushare/stock/trading.py,sha256=3bvM4pexEYW-uGGEL7g6Vkte4sqGC1iYO6dC8mGLSdM,55619
@@ -73,19 +80,19 @@ tushare/util/common.py,sha256=KG86VdlhfnOf0j6SE2bBeowC_7Z54RqWpVnudS6KvEU,2581
73
80
  tushare/util/conns.py,sha256=mkcxGGD7-13GXMlrwmo4LMecmgWdm63I8KDpvcW53cI,1456
74
81
  tushare/util/dateu.py,sha256=YSvPvOlMY0qvT2IDwFNOHxTLBrPQ9ULGO7ljfu9tK3s,2931
75
82
  tushare/util/form_date.py,sha256=4nnjp6xo40FftsRP9YY1FJoPErxaWVCkjIp_3O1Qy7M,1119
76
- tushare/util/format_stock_code.py,sha256=TeybxxI2k-agCs8HbifO0qwEvc7wCQX3gadfMv5ouek,2530
83
+ tushare/util/format_stock_code.py,sha256=I3nG-tbJKj9Fp6HQ51sG830JpUQT9vs6MARvmOj5X7Y,3400
77
84
  tushare/util/formula.py,sha256=XZVK1NTF8BTrCo78EHLzjAM_wLAjxybrN7Q-6HCHmCo,6863
78
85
  tushare/util/mailmerge.py,sha256=y_QkfHvH8nQ7peC8wQs5idB6xW9PYzzrBynzxgo924M,8980
79
86
  tushare/util/netbase.py,sha256=URvOTLJSgO7e6uCmHHD9EeQ2TRvjpxIEF-wQaWx5cKE,942
80
87
  tushare/util/store.py,sha256=CSsPo0hUj1agOLVhayM4Gw3wqA7w0Gd0Dnv5sh_HlBo,1167
81
88
  tushare/util/upass.py,sha256=PCizfpPhiae0qQWGe5fuXYdIjnh8hXcvvsCVr_GBb-Q,1515
82
89
  tushare/util/vars.py,sha256=0jIgiA4Pc0cx9tt-8NC037qC_ghm9lEF66vWpfTJ4DY,69946
83
- tushare/util/verify_token.py,sha256=ygUGhxoY82uT54fQ0x9rNjIrqnTh8RvS9ZpOmLrlpYo,2411
90
+ tushare/util/verify_token.py,sha256=cuV3RErWbOC318NANCYL6K1LKZ3wSAL2yMwZHA7tD3s,2471
84
91
  tushare/util/protobuf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
92
  tushare/util/protobuf/funcs.py,sha256=UCdK8FxTyjPZsNzoEeXqYzqrQXUmRMvW5hua6GPA66A,779
86
93
  tushare/util/protobuf/response_pb2.py,sha256=vJH9ONkDuJlg6y-q1PvuDZoviKrK7hzNtMieQHK45DI,11347
87
- tushare-1.3.6.dist-info/LICENSE,sha256=C2j55UI0Ul-1-wA1-rn7OaY6b3vGl4YukiyvYzHsU9o,1503
88
- tushare-1.3.6.dist-info/METADATA,sha256=E1D8ryiDLmmNsv9akwBLAWeaO0zmVuXvrJAmNBk3kD0,2425
89
- tushare-1.3.6.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
90
- tushare-1.3.6.dist-info/top_level.txt,sha256=0mgc2vMZJnuC65-OMhhOjT_zydkyE9Okxd1V3p2LeeA,13
91
- tushare-1.3.6.dist-info/RECORD,,
94
+ tushare-1.3.7.dist-info/LICENSE,sha256=C2j55UI0Ul-1-wA1-rn7OaY6b3vGl4YukiyvYzHsU9o,1503
95
+ tushare-1.3.7.dist-info/METADATA,sha256=SlM1vdIlIfj7iEX6LX1tSS9TosCL1sIStSA0csQQoRc,2425
96
+ tushare-1.3.7.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
97
+ tushare-1.3.7.dist-info/top_level.txt,sha256=0mgc2vMZJnuC65-OMhhOjT_zydkyE9Okxd1V3p2LeeA,13
98
+ tushare-1.3.7.dist-info/RECORD,,