tushare 1.3.6__py3-none-any.whl → 1.3.7__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
@@ -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,,