Administrator
2024-07-25 9d39b293bde97f31f522010373aad1dd3f654c07
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
"""
目标代码管理
"""
import decimal
 
from code_attribute.history_k_data_util import JueJinHttpApi
from log_module.log import printlog
from utils import tool
 
# 有效代码的缓存
# 数据格式:{"日期":[]}
__valid_codes_cache = {}
# 正股到可转债代码的索引
__valid_underlying_code_map_cache = {}
 
# 可转债代码到正股代码的索引
__valid_cb_to_underlying_code_map_cache = {}
 
# 可转债昨日收盘价
__valid_pre_close_price_map_cache = {}
 
 
def __request_valid_codes_info():
    """
    请求有效的代码信息
    :return:
    """
    results = JueJinHttpApi.get_exchanges_codes("SHSE,SZSE", sec_types=[8], skip_suspended=True, skip_st=True,
                                                fields="symbol, sec_type, sec_id,sec_name, underlying_symbol, delisted_date, sec_level, pre_close")
    fresults = []
    for r in results:
        if r['sec_name'].find('转') == -1 or r['sec_level'] != 1 or int(tool.get_now_date_str('%Y%m%d')) >= int(
                r['delisted_date'].strftime('%Y%m%d')):
            continue
        fresults.append(r)
        # 排除同一股票有2个转债
    cb_count_dict = {}
    exclude_codes = []
    for r in fresults:
        if r['underlying_symbol'] not in cb_count_dict:
            cb_count_dict[r['underlying_symbol']] = []
        cb_count_dict[r['underlying_symbol']].append(r['symbol'])
        if len(cb_count_dict[r['underlying_symbol']]) > 1:
            printlog(r['underlying_symbol'], cb_count_dict[r['underlying_symbol']])
            exclude_codes.extend(cb_count_dict[r['underlying_symbol']])
    ffresults = []
    for x in fresults:
        if x['symbol'] in exclude_codes:
            continue
        ffresults.append(x)
    return ffresults
 
 
def load_valid_codes_info(day=tool.get_now_date_str()):
    """
    加载有效数据
    :param day:
    :return:
    """
    if day in __valid_codes_cache:
        return __valid_codes_cache.get(day)
    results = __request_valid_codes_info()
    if results:
        __valid_codes_cache[day] = results
        __valid_underlying_code_map_cache[day] = {}
        __valid_pre_close_price_map_cache[day] = {}
        __valid_cb_to_underlying_code_map_cache[day] = {}
        for r in results:
            __valid_underlying_code_map_cache[day][r['underlying_symbol'].split('.')[1]] = r['sec_id']
            __valid_cb_to_underlying_code_map_cache[day][r['sec_id']] = r['underlying_symbol'].split('.')[1]
            __valid_pre_close_price_map_cache[day][r['sec_id']] = r['pre_close']
 
 
def get_subscript_underlying_codes():
    """
    获取需要订阅的正股代码
    :return:
    """
    day = tool.get_now_date_str()
    if not __valid_codes_cache.get(day):
        load_valid_codes_info(tool.get_now_date_str())
    ffresults = __valid_codes_cache.get(tool.get_now_date_str())
    return [x['underlying_symbol'].split('.')[1] for x in ffresults]
 
 
def get_subscript_cb_codes():
    """
    获取需要订阅的代码
    :return:
    """
    day = tool.get_now_date_str()
    if not __valid_codes_cache.get(day):
        load_valid_codes_info(tool.get_now_date_str())
    ffresults = __valid_codes_cache.get(tool.get_now_date_str())
    return [x['sec_id'] for x in ffresults]
 
 
def get_underlying_to_cb_code_map():
    """
    获取股票代码-可转债代码的map
    :param code:
    :return:
    """
    day = tool.get_now_date_str()
    if day not in __valid_underlying_code_map_cache:
        load_valid_codes_info(day)
 
    return __valid_underlying_code_map_cache.get(day)
 
 
def get_cb_to_underlying_code_map():
    """
    获取可转债代码-股票代码的map
    :param code:
    :return:
    """
    day = tool.get_now_date_str()
    if day not in __valid_cb_to_underlying_code_map_cache:
        load_valid_codes_info(day)
 
    return __valid_cb_to_underlying_code_map_cache.get(day)
 
 
def get_cb_code(code):
    """
    获取可转债代码
    :param code:
    :return:
    """
    map = get_underlying_to_cb_code_map()
    if map:
        return map.get(code)
    return None
 
 
def get_underlying_code(code):
    map = get_cb_to_underlying_code_map()
    if map:
        return map.get(code)
    return None
 
 
def get_limit_up_price(cb_code):
    """
    获取可转债的涨停价
    :param cb_code:
    :return:
    """
    day = tool.get_now_date_str()
    pre_close_price_map = __valid_pre_close_price_map_cache.get(day)
    if not pre_close_price_map:
        return None
    price_close = pre_close_price_map.get(cb_code)
    price_close = tool.to_price(decimal.Decimal(str(price_close)))
 
    return str(tool.to_price(price_close * decimal.Decimal("1.2"), "0.000"))
 
 
def get_limit_down_price(cb_code):
    """
    获取可转债的跌停价
    :param cb_code:
    :return:
    """
    day = tool.get_now_date_str()
    pre_close_price_map = __valid_pre_close_price_map_cache.get(day)
    if not pre_close_price_map:
        return None
    price_close = pre_close_price_map.get(cb_code)
    price_close = tool.to_price(decimal.Decimal(str(price_close)))
 
    return str(tool.to_price(price_close * decimal.Decimal("0.8"), "0.000"))
 
 
 
if __name__ == '__main__':
    load_valid_codes_info()
    print(get_limit_up_price("110060"), get_limit_down_price("110060"))