tushare 1.4.5__py3-none-any.whl → 1.4.6__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.
- baks/__init__.py +0 -0
- baks/demo.py +184 -0
- baks/rtqc.py +612 -0
- baks/setup.py +15 -0
- baks/sss.py +56 -0
- test/__init__.py +0 -0
- test/bar_test.py +23 -0
- test/billboard_test.py +35 -0
- test/build_pyd/__init__.py +8 -0
- test/build_pyd/rtqc.py +612 -0
- test/build_pyd/setup.py +15 -0
- test/build_pyd//321/206/320/231/320/243/321/205/320/234/320/225pyd/321/205/320/241/342/225/234/321/204/342/225/227/320/264.txt +1 -0
- test/classifying_test.py +50 -0
- test/dateu_test.py +19 -0
- test/fund_test.py +43 -0
- test/indictor_test.py +23 -0
- test/macro_test.py +50 -0
- test/nav_test.py +104 -0
- test/news_test.py +38 -0
- test/pro_test.py +11 -0
- test/ref_test.py +57 -0
- test/shibor_test.py +33 -0
- test/storing_test.py +61 -0
- test/test_query.py +16 -0
- test/test_realtime.py +24 -0
- test/test_realtime_quote.py +13 -0
- test/test_sdk_event.py +21 -0
- test/test_stk_mins.py +16 -0
- test/test_stock_basic.py +16 -0
- test/test_tgw_subscribe.py +28 -0
- test/test_ts_subscribe.py +22 -0
- test/test_websocket.py +52 -0
- test/trading_test.py +43 -0
- tushare/__init__.py +1 -1
- tushare/stock/rtq.py +6 -4
- tushare/stock/rtqc.pyd +0 -0
- tushare/subs/ht_subs/service/__init__.py +0 -0
- tushare/subs/ht_subs/service/covert.py +189 -0
- tushare/subs/model/tick.py +128 -128
- tushare/subs/tgw_subs/convert.py +20 -20
- tushare/subs/ts_subs.py +192 -0
- {tushare-1.4.5.dist-info → tushare-1.4.6.dist-info}/METADATA +101 -101
- {tushare-1.4.5.dist-info → tushare-1.4.6.dist-info}/RECORD +46 -9
- {tushare-1.4.5.dist-info → tushare-1.4.6.dist-info}/WHEEL +1 -1
- {tushare-1.4.5.dist-info → tushare-1.4.6.dist-info}/top_level.txt +1 -0
- {tushare-1.4.5.dist-info → tushare-1.4.6.dist-info}/LICENSE +0 -0
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'),
|
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'),
|
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}')
|
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}')
|
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"),
|
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"),
|
157
157
|
count=tgw_data.get("num_trades"),
|
158
158
|
**extra
|
159
159
|
)
|
tushare/subs/ts_subs.py
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
# -*- coding:utf-8 -*-
|
2
|
+
'''
|
3
|
+
@group:waditu
|
4
|
+
@author: DY
|
5
|
+
'''
|
6
|
+
import _thread as thread
|
7
|
+
import fnmatch
|
8
|
+
import json
|
9
|
+
|
10
|
+
import logging, sys
|
11
|
+
import re
|
12
|
+
import ssl
|
13
|
+
import threading
|
14
|
+
import time
|
15
|
+
from collections import defaultdict
|
16
|
+
from functools import wraps
|
17
|
+
from multiprocessing.context import Process
|
18
|
+
|
19
|
+
import websocket
|
20
|
+
from websocket import WebSocketConnectionClosedException
|
21
|
+
|
22
|
+
logging.basicConfig(stream=sys.stdout, level=logging.ERROR, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
23
|
+
import logging
|
24
|
+
|
25
|
+
logger = logging.getLogger(__name__)
|
26
|
+
|
27
|
+
|
28
|
+
class Subs(object):
|
29
|
+
|
30
|
+
def __init__(self, token='', callback_mode='multi-thread', debug=False):
|
31
|
+
self.url = 'wss://ws.tushare.pro/listening'
|
32
|
+
self.token = token
|
33
|
+
self.debug = debug
|
34
|
+
|
35
|
+
self.callback_mode = callback_mode
|
36
|
+
self.topics = defaultdict(lambda: list())
|
37
|
+
self.callback_funcs = defaultdict(lambda: list())
|
38
|
+
|
39
|
+
self.websocket = None
|
40
|
+
|
41
|
+
def threading_keepalive_ping(self):
|
42
|
+
def ping():
|
43
|
+
time.sleep(30)
|
44
|
+
req_data = {
|
45
|
+
"action": "ping"
|
46
|
+
}
|
47
|
+
self.websocket.send(json.dumps(req_data))
|
48
|
+
logger.debug('send ping message')
|
49
|
+
threading.Thread(target=ping).start()
|
50
|
+
|
51
|
+
def on_open(self, *args, **kwargs):
|
52
|
+
req_data = {
|
53
|
+
"action": "listening",
|
54
|
+
"token": self.token,
|
55
|
+
"data": self.topics
|
56
|
+
}
|
57
|
+
self.websocket.send(json.dumps(req_data))
|
58
|
+
logger.info('application starting...')
|
59
|
+
self.threading_keepalive_ping()
|
60
|
+
|
61
|
+
def on_message(self, message, *args, **kwargs):
|
62
|
+
logger.debug(message)
|
63
|
+
if isinstance(message, (str, bytes, bytearray)):
|
64
|
+
resp_data = json.loads(message)
|
65
|
+
if not resp_data.get('status'):
|
66
|
+
logger.error(resp_data.get('message'))
|
67
|
+
return
|
68
|
+
else:
|
69
|
+
logger.info(message)
|
70
|
+
return
|
71
|
+
data = resp_data.get('data', {})
|
72
|
+
if not data or not isinstance(data, dict):
|
73
|
+
return
|
74
|
+
|
75
|
+
topic = data.get('topic')
|
76
|
+
code = data.get('code')
|
77
|
+
record = data.get('record')
|
78
|
+
if not topic or not code or not record:
|
79
|
+
logger.warning('get invalid response-data(%s)' % resp_data)
|
80
|
+
return
|
81
|
+
|
82
|
+
self._do_callback_function(topic, code, record)
|
83
|
+
|
84
|
+
def on_error(self, error, *args, **kwargs):
|
85
|
+
if self.debug:
|
86
|
+
logging.error(str(error), exc_info=True)
|
87
|
+
|
88
|
+
def on_close(self, *args, **kwargs):
|
89
|
+
logger.error('close')
|
90
|
+
_type, _value, _traceback = sys.exc_info()
|
91
|
+
if _type in [WebSocketConnectionClosedException, ConnectionRefusedError]:
|
92
|
+
time.sleep(1)
|
93
|
+
self.run()
|
94
|
+
|
95
|
+
def run(self):
|
96
|
+
if not self.topics:
|
97
|
+
logger.error('no data.')
|
98
|
+
return
|
99
|
+
|
100
|
+
self.websocket = websocket.WebSocketApp(
|
101
|
+
self.url,
|
102
|
+
on_message=self.on_message,
|
103
|
+
on_error=self.on_error,
|
104
|
+
on_close=self.on_close,
|
105
|
+
on_open=self.on_open
|
106
|
+
)
|
107
|
+
if self.url.startswith('wss:'):
|
108
|
+
self.websocket.run_forever(sslopt={"cert_reqs": ssl.CERT_NONE})
|
109
|
+
else:
|
110
|
+
self.websocket.run_forever()
|
111
|
+
|
112
|
+
def register(self, topic, codes):
|
113
|
+
codes = set(codes)
|
114
|
+
|
115
|
+
def decorator(func):
|
116
|
+
func.codes = set()
|
117
|
+
func.pcodes = set()
|
118
|
+
for code in codes:
|
119
|
+
if not re.match(r'[\d\w\.\*]+', code):
|
120
|
+
logger.error('error code')
|
121
|
+
exit(1)
|
122
|
+
|
123
|
+
if '*' in code:
|
124
|
+
for code1 in func.pcodes:
|
125
|
+
if fnmatch.fnmatch(code1, code) or fnmatch.fnmatch(code, code1):
|
126
|
+
logger.error('duplicate code')
|
127
|
+
exit(1)
|
128
|
+
for code1 in func.codes:
|
129
|
+
if fnmatch.fnmatch(code1, code):
|
130
|
+
logger.error('duplicate code')
|
131
|
+
exit(1)
|
132
|
+
func.pcodes.add(code)
|
133
|
+
else:
|
134
|
+
for code1 in func.pcodes:
|
135
|
+
if fnmatch.fnmatch(code, code1):
|
136
|
+
logger.error('duplicate code')
|
137
|
+
exit(1)
|
138
|
+
func.codes.add(code)
|
139
|
+
|
140
|
+
self.topics[topic] += codes
|
141
|
+
self.callback_funcs[topic].append(func)
|
142
|
+
|
143
|
+
@wraps(func)
|
144
|
+
def inner(*args, **kwargs):
|
145
|
+
""" should receive a message-value parameter """
|
146
|
+
return func(*args, **kwargs)
|
147
|
+
|
148
|
+
return inner
|
149
|
+
|
150
|
+
return decorator
|
151
|
+
|
152
|
+
def _do_callback_function(self, topic, code, value):
|
153
|
+
for func in self.callback_funcs[topic]:
|
154
|
+
checked = False
|
155
|
+
if code in func.codes:
|
156
|
+
checked = True
|
157
|
+
else:
|
158
|
+
for pcode in func.pcodes:
|
159
|
+
if fnmatch.fnmatch(code, pcode):
|
160
|
+
checked = True
|
161
|
+
break
|
162
|
+
|
163
|
+
if not checked:
|
164
|
+
continue
|
165
|
+
|
166
|
+
if self.callback_mode == 'single-thread':
|
167
|
+
func(value)
|
168
|
+
elif self.callback_mode == 'multi-thread':
|
169
|
+
thread.start_new_thread(func, (value,))
|
170
|
+
elif self.callback_mode == 'multi-process':
|
171
|
+
p = Process(target=func, args=(value,))
|
172
|
+
p.start()
|
173
|
+
|
174
|
+
|
175
|
+
def test():
|
176
|
+
app = Subs(token='')
|
177
|
+
|
178
|
+
# code 可以包含 * (通配符)
|
179
|
+
@app.register(topic='HQ_STK_TICK', codes=["000001.SZ"])
|
180
|
+
def print_message(record):
|
181
|
+
"""
|
182
|
+
订阅主题topic,并指定codes列表,在接收到topic的推送消息时,符合code条件,就会执行回调
|
183
|
+
:param record:
|
184
|
+
:return:
|
185
|
+
"""
|
186
|
+
print('用户定义业务代码输出 print_message(%s)' % str(record))
|
187
|
+
|
188
|
+
app.run()
|
189
|
+
|
190
|
+
|
191
|
+
if __name__ == '__main__':
|
192
|
+
test()
|