Administrator
6 天以前 abd510d66074ac640555c241b6343a53cca8f070
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
"""
激进买策略管理
"""
# 上一个50W的起始时间:{code:"09:30:00.120"}
import time
 
from code_attribute import code_volumn_manager, gpcode_manager
from l2.code_price_manager import Buy1PriceManager
from l2.huaxin import l2_huaxin_util
from l2.l2_limitup_sell_data_manager import L2LimitUpSellDataManager
from l2.l2_sell_manager import L2MarketSellManager
from l2.l2_transaction_data_manager import HuaXinSellOrderStatisticManager, BigOrderDealManager
from log_module import async_log_util
from log_module.log import logger_l2_radical_buy, hx_logger_l2_transaction, logger_l2_not_buy_reasons
from third_data import kpl_data_manager
from third_data.kpl_data_constant import LimitUpDataConstant, LimitUpCodesBlockRecordManager
from trade.buy_radical import radical_buy_data_manager, block_special_codes_manager
from trade.buy_radical.block_special_codes_manager import BlockSpecialCodesManager
from trade.buy_radical.radical_buy_data_manager import RadicalBuyBlockManager, TotalDealBigOrderThresholdMoneyManager
from trade.trade_data_manager import RadicalBuyDealCodesManager
from utils import tool, global_util
 
# 不买入
BUY_MODE_NONE = 0
# 直接买入
BUY_MODE_DIRECT = 1
# 根据L2买入
BUY_MODE_BY_L2 = 2
 
# 开始计时时间
__start_time_dict = {}
# 转换时间缓存
__huaxin_timestamp_convert_temp = {}
# 主动成交的累计金额
__deal_active_buy_total_money = {}
# 最近成交的买单信息{code:[订单号,量,金额]}
__latest_deal_active_buy_order = {}
 
 
def clear_data(code, force=False, market_time_str=None, msg=""):
    """
    清除数据:下单过后/开板后清除数据
    @param market_time_str: L2 market时间
    @param force: 是否强制清除
    @param code:
    @return:
    """
    if code in __latest_deal_active_buy_order:
        __latest_deal_active_buy_order.pop(code)
 
    if not force:
        # 非强制清除数据要看大单成交是否足够
        big_deal_info = radical_buy_data_manager.get_total_deal_big_order_info(code,
                                                                               gpcode_manager.get_limit_up_price_as_num(
                                                                                   code))
        if big_deal_info[0] > 0:
            # 大单不够
            force = True
 
    if force:
        # 如果比最近成交时间<=L2 market时间就视为数据延迟
        if market_time_str and code in RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict:
            if tool.trade_time_sub(market_time_str,
                                   RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict[code][3]) <= 0:
                async_log_util.info(logger_l2_radical_buy, f"L2market时间小于成交时间:{code}-{market_time_str}")
                return
 
        if __deal_active_buy_total_money.get(code):
            async_log_util.info(logger_l2_radical_buy, f"清除涨停卖成交数据:{code}-{market_time_str}")
        # 强制清除数据
        if code in __deal_active_buy_total_money:
            __deal_active_buy_total_money.pop(code)
        # 清除L2下单信号
        if code in RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict:
            async_log_util.info(logger_l2_radical_buy, f"清除下单信号:{code}-{force}-{market_time_str}  msg-{msg}")
            RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict.pop(code)
 
 
def process_limit_up_active_buy_deal(code, transaction_datas, is_almost_open_limit_up=False,
                                     no_left_limit_up_sell=False):
    """
    计算抛压消耗之后是否能下单
    @param code:
    @param transaction_datas:   # ((data['SecurityID'], data['TradePrice'], data['TradeVolume'],
        #           data['OrderTime'], data['MainSeq'], data['SubSeq'], data['BuyNo'],
        #           data['SellNo'], data['ExecType']))
    @param is_almost_open_limit_up: 是否即将炸板,如果即将炸板就按照上板无大单处理
    @return: 买入方式, 消息
    """
    if is_almost_open_limit_up:
        return BUY_MODE_BY_L2, f"即将炸板"
 
    # ---------初始化-------------
    if code not in __huaxin_timestamp_convert_temp:
        __huaxin_timestamp_convert_temp[code] = {}
    if code not in __deal_active_buy_total_money:
        __deal_active_buy_total_money[code] = 0
    if code not in __latest_deal_active_buy_order:
        __latest_deal_active_buy_order[code] = ['', 0, 0]
    for transaction_data in transaction_datas:
        # 当遇到大单之后才需要计算累计成交
        # 统计金额
        money = transaction_data[1] * transaction_data[2]
        price = transaction_data[1]
 
        # 统计成交的买单
        if __latest_deal_active_buy_order[code][0] == transaction_data[6]:
            __latest_deal_active_buy_order[code][1] += transaction_data[2]
            __latest_deal_active_buy_order[code][2] += money
        else:
            __latest_deal_active_buy_order[code] = [transaction_data[6], transaction_data[2], money]
 
        if code not in __start_time_dict and False:
            # 判断买单成交的金额,如果金额大于50w就作为计时起始点
            if __latest_deal_active_buy_order[code][2] >= 500000:
                # 设置计时起点,将当前的数据清零
                __start_time_dict[code] = l2_huaxin_util.convert_time(transaction_data[3], with_ms=True)
                __deal_active_buy_total_money[code] = __latest_deal_active_buy_order[code][2]
        else:
            __deal_active_buy_total_money[code] += money
            # 已经开始计数
            # THRESHOLD_TIME = 1000 if tool.is_sh_code(code) else 500
            # huaxin_timestamp = transaction_data[3]
            # time_str_with_ms = __huaxin_timestamp_convert_temp[code].get(huaxin_timestamp)
            # if not time_str_with_ms:
            #     __huaxin_timestamp_convert_temp[code].clear()
            #     time_str_with_ms = l2_huaxin_util.convert_time(huaxin_timestamp, with_ms=True)
            #     __huaxin_timestamp_convert_temp[code][huaxin_timestamp] = time_str_with_ms
 
            # if tool.trade_time_sub_with_ms(time_str_with_ms, __start_time_dict[code]) > THRESHOLD_TIME:
            #     __start_time_dict.pop(code)
            #     __deal_active_buy_total_money[code] = 0
            #     return BUY_MODE_NONE, f"距离上个大单成交超过{THRESHOLD_TIME}ms"
 
    # 初次上板需要计算临时大单
    is_first = radical_buy_data_manager.is_first_limit_up_buy(code)
    if is_first:
        # 首封下单
        money_info_list = BigOrderDealManager().get_total_buy_data_list(code)
        radical_buy_data_manager.BeforeSubDealBigOrderManager().set_temp_deal_big_orders(code, money_info_list)
 
    price = transaction_datas[-1][1]
    huaxin_timestamp = transaction_datas[-1][3]
 
    # 判断是否可以扫入
    can_direct_buy = False
    human_setting_money = TotalDealBigOrderThresholdMoneyManager().get_money_cache(code)
    if human_setting_money:
        can_direct_buy = True
 
    # 获取参考总卖额
    refer_sell_data = L2MarketSellManager().get_refer_sell_data(code, l2_huaxin_util.convert_time(
        huaxin_timestamp))
    async_log_util.info(logger_l2_radical_buy, f"参考总卖额(备用):{code}-{refer_sell_data}")
 
    # 参考总卖额
    refer_sell_money = 0
 
    if refer_sell_data:
        refer_sell_money = refer_sell_data[1]
 
    if refer_sell_money < 500e4:
        # 参考抛压小于500万,直接根据L2下单
        return BUY_MODE_BY_L2, f"总抛压小于500w({refer_sell_money})"
 
    # 处于涨停卖的委托订单总手数
    selling_num = L2LimitUpSellDataManager.get_delegating_sell_num(code)
    if selling_num is None:
        selling_num = 0
    # 剩余涨停卖金额
    left_limit_up_sell_money = selling_num * price
 
    # 每次上板的大单与金额
    big_order_count = radical_buy_data_manager.EveryLimitupBigDealOrderManager.get_big_buy_deal_order_count(code)
    big_order_money = radical_buy_data_manager.EveryLimitupBigDealOrderManager.get_big_buy_deal_order_money(code)
 
    total_lack_money_info = radical_buy_data_manager.get_total_deal_big_order_info(code,
                                                                                   gpcode_manager.get_limit_up_price_as_num(
                                                                                       code),
                                                                                   is_for_buy=True)
    if total_lack_money_info[2] < 1e8:
        # 要求的大单阈值必须>1亿才能直接扫入
        can_direct_buy = False
 
    if total_lack_money_info[0] > 0:
        # 大单够了才能扫入
        can_direct_buy = False
 
 
 
    if total_lack_money_info and total_lack_money_info[2] > 1e8 and total_lack_money_info[0] <= 0:
        # 要求的大单够了 以后,回封买,只要有两个大单成交了,立即下单
        THRESHOLD_MONEY, is_temp_threshold_money = radical_buy_data_manager.BeforeSubDealBigOrderManager().get_big_order_threshold_info(
            code)
        if big_order_money > THRESHOLD_MONEY * 2 and can_direct_buy:
            return BUY_MODE_DIRECT, f"有两个以上大单瞬时成交({big_order_money}/{THRESHOLD_MONEY * 2}), 大单足够"
 
    if big_order_count >= 2:
        # 判断大单是否满足
        average_big_order_money = int(big_order_money / big_order_count)
        # 如果均价涨幅小于7%,均大单等于299w
        average_rate = Buy1PriceManager().get_average_rate(code)
        if average_rate is not None and average_rate < 0.07:
            average_big_order_money = 299 * 10000
        threshold_left_sell_money = average_big_order_money
 
        # 辨识度的票如果是非新题材的首封: 2个大单的折扣
        # if block_special_codes_manager.BlockSpecialCodesManager().get_code_blocks(code) and radical_buy_data_manager.is_first_limit_up_buy(code) and not LimitUpCodesBlockRecordManager().has_new_block(
        #         code):
        #     threshold_left_sell_money = average_big_order_money * 2
        # 判断是否可直接下单,不需要等到封单消耗
        # if refer_sell_money >= 5e7 and is_first:
        #     # 大抛压,是首封
        #     zyltgb = global_util.zyltgb_map.get(code)
        #     if zyltgb and zyltgb > 50e8 and BlockSpecialCodesManager().get_code_blocks(code):
        #         # 自由市值>50亿,具有辨识度
        #         total_lack_money_info = radical_buy_data_manager.get_total_deal_big_order_info(code,
        #                                                                                        gpcode_manager.get_limit_up_price_as_num(
        #                                                                                            code),
        #                                                                                        is_for_buy=True)
        #         if total_lack_money_info[0] <= 0 and total_lack_money_info[1] > 5e7 and total_lack_money_info[1] > \
        #                 total_lack_money_info[2] * 1.5:
        #             # 大单足够,总成交金额是大单的1.2倍以上
        #             return BUY_MODE_DIRECT, f"首封下单抛压大、市值大、成交多、直接扫  卖1-{refer_sell_money} 大单-{total_lack_money_info}"
 
        if threshold_left_sell_money > left_limit_up_sell_money:
            # 剩余总卖小于均大单才能下单
            # 如果是深证且卖一大于5000w可不判断大单是否满足
            if tool.is_sz_code(code) and refer_sell_money >= 5e7 and can_direct_buy:
                return BUY_MODE_DIRECT, f"剩余涨停总卖额-{left_limit_up_sell_money},均大单-{average_big_order_money}, 剩余阈值-{threshold_left_sell_money}, 总抛压大({refer_sell_money})"
            else:
                if total_lack_money_info[0] <= 0 and tool.is_sz_code(code) and can_direct_buy:
                    return BUY_MODE_DIRECT, f"剩余涨停总卖额-{left_limit_up_sell_money},均大单-{average_big_order_money}, 大单足够"
    else:
        average_big_order_money = 0
        # 如果剩余总卖小于100w直接根据L2买入
    if left_limit_up_sell_money < 100e4 or no_left_limit_up_sell:
        return BUY_MODE_BY_L2, f"剩余总卖小于100w({left_limit_up_sell_money}) 是否还有剩余涨停卖-{no_left_limit_up_sell}"
 
    return BUY_MODE_NONE, f"均大单-{average_big_order_money}({big_order_money}/{big_order_count}),剩余涨停卖:{left_limit_up_sell_money}"
    # #总卖 = 涨停主动买成交的累计金额 + 处于委托状态的涨停卖金额
    # total_sell = __deal_active_buy_total_money[code] + left_limit_up_sell_money
    # if total_sell == 0:
    #     total_sell = 1
    # rate = round(__deal_active_buy_total_money[code] / total_sell, 2)
    # # 获取当前的成交量比
    # limit_up_price = gpcode_manager.get_limit_up_price_as_num(code)
    # volume_rate = code_volumn_manager.CodeVolumeManager().get_volume_rate_refer_in_5days(code,
    #                                                                                      total_sell_volume=int(
    #                                                                                          total_sell / limit_up_price))
    # if volume_rate is None:
    #     volume_rate = 0.5
    #
    # THRESHOLD_RATE = radical_buy_data_manager.get_volume_rate_threshold(code, volume_rate)
    # if rate >= THRESHOLD_RATE:
    #     # 根据大单判断是否可以扫
    #     big_order_deal_result = radical_buy_data_manager.is_big_order_deal_enough(code, volume_rate,
    #                                                                               refer_sell_money, for_buy=True)
    #     if big_order_deal_result[0]:
    #         return BUY_MODE_DIRECT, f"剩余涨停总卖额-{selling_num * price},原涨停总卖-{total_sell},已成交额-{__deal_active_buy_total_money[code]},成交比例-{rate}/{THRESHOLD_RATE}, 大单信息-{big_order_deal_result}"
    #     else:
    #         # 无大单成交就只能通过L2下单
    #         return BUY_MODE_BY_L2, f"无大单成交-{big_order_deal_result},原涨停总卖-{total_sell},已成交额-{__deal_active_buy_total_money[code]},成交比例-{rate}/{THRESHOLD_RATE} "
    # else:
    #     return BUY_MODE_NONE, f"被动卖成交比例未达到:剩余涨停总卖额-{selling_num * price},原涨停总卖-{total_sell},已成交额-{__deal_active_buy_total_money[code]},成交比例-{rate}/{THRESHOLD_RATE}"
 
 
def is_can_buy_with_open_price(code, open_price):
    """
    根据开盘价判断是否可买
    @param code:
    @param open_price: 开盘价没获取到就不判断
    @return:
    """
    if tool.get_now_time_as_int() < int("093500") and open_price:
        async_log_util.info(logger_l2_radical_buy, f"开盘价:{code}-{open_price}")
        pre_price = gpcode_manager.CodePrePriceManager.get_price_pre_cache(code)
        if pre_price:
            rate = round((open_price - pre_price) / pre_price, 4)
            async_log_util.info(logger_l2_radical_buy, f"开盘价涨幅:{code}-{rate}")
            if tool.get_limit_up_rate(code) > 1.1:
                return rate < 0.149
            else:
                return rate < 0.049
    return True
 
 
# 板块缓存
__radical_buy_by_blocks_result_cache = {}
 
 
def compute_can_radical_buy_blocks(code, deal_codes):
    """
    计算可以扫入的板块
    @param code:
    @return: 可买板块集合, 过滤后的集合
    """
    result_cache = __radical_buy_by_blocks_result_cache.get(code)
    if not result_cache or result_cache[0] < time.time():
        # 不存在/过期
        yesterday_codes = kpl_data_manager.get_yesterday_limit_up_codes()
        if yesterday_codes is None:
            yesterday_codes = set()
        # 计算是否可以扫入
        radical_result = RadicalBuyBlockManager.is_radical_buy(code, yesterday_codes)
        async_log_util.info(logger_l2_radical_buy, f"计算板块结果:{code}-{radical_result}")
        result_cache = (time.time() + 3, radical_result)
        __radical_buy_by_blocks_result_cache[code] = result_cache
        RadicalBuyDealCodesManager().set_code_blocks(code, radical_result[0])
        if not radical_result[0]:
            async_log_util.info(logger_l2_not_buy_reasons, f"{code}#{radical_result[1]}")
    # 取缓存
    result = result_cache[1]
    if result[0]:
        # 买入的板块
        buy_blocks = result[0]
        # 如果关键词包含已成交的原因就不再下单
        # 获取已经成交代码的板块
        # ---------------判断板块是否还可以买入----------------
        f_buy_blocks = radical_buy_data_manager.is_block_can_radical_buy(code, buy_blocks, deal_codes)
        return f_buy_blocks, result[0]
    return set(), result[0]