| | |
| | | # 是否为测试 |
| | | import platform |
| | | |
| | | TEST = False |
| | | TEST = True |
| | | # 是否允许交易 |
| | | TRADE_ENABLE = False |
| | | TRADE_ENABLE = True |
| | | |
| | | # 签名错误 |
| | | RESPONSE_CODE_SIGIN_ERROR = 1001 |
| | |
| | | if code in cls.unreal_buy_dict: |
| | | cls.unreal_buy_dict.pop(code) |
| | | |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos(code) |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos( |
| | | code) |
| | | if not can: |
| | | l2_log.debug(code, "不可以下单,原因:{}", reason) |
| | | if need_clear_data: |
| | |
| | | for i in range(trade_index + 1, total_data[-1]["index"] + 1): |
| | | if L2DataUtil.is_limit_up_price_buy(total_data[i]["val"]): |
| | | left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count(code, |
| | | total_data[i]["index"], |
| | | total_data[ |
| | | i][ |
| | | "index"], |
| | | total_data, |
| | | num_operate_map) |
| | | if left_count > 0: |
| | |
| | | float(open_limit_up_lowest_price) - price_pre_close) / price_pre_close < 0.05: |
| | | return False, True, f"炸板后最低价跌至5%以下" |
| | | |
| | | limit_up_info = cls.__Buy1PriceManager.get_limit_up_info(code) |
| | | if limit_up_info[0] is None and False: |
| | | total_data = local_today_datas.get(code) |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos( |
| | | code) |
| | | # 之前没有涨停过 |
| | | # 统计买入信号位到当前位置没有撤的大单金额 |
| | | min_money_w = l2_data_util.get_big_money_val(float(total_data[buy_single_index]["val"]["price"])) // 10000 |
| | | left_big_num = cls.__SecondCancelBigNumComputer.compute_left_big_num(code, |
| | | buy_single_index, |
| | | buy_exec_index, |
| | | total_data[-1][ |
| | | "index"], |
| | | total_data, |
| | | 0, min_money_w) |
| | | if left_big_num > 0: |
| | | # 重新获取分数与分数索引 |
| | | limit_up_time = cls.__LimitUpTimeManager.get_limit_up_time_cache(code) |
| | | if limit_up_time is None: |
| | | limit_up_time = tool.get_now_time_str() |
| | | score = first_code_score_manager.get_score(code, cls.volume_rate_info[code][0], limit_up_time, True, |
| | | left_big_num) |
| | | cls.__l2PlaceOrderParamsManagerDict[code].set_score(score) |
| | | # limit_up_info = cls.__Buy1PriceManager.get_limit_up_info(code) |
| | | # if limit_up_info[0] is None and False: |
| | | # total_data = local_today_datas.get(code) |
| | | # buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos( |
| | | # code) |
| | | # # 之前没有涨停过 |
| | | # # 统计买入信号位到当前位置没有撤的大单金额 |
| | | # min_money_w = l2_data_util.get_big_money_val(float(total_data[buy_single_index]["val"]["price"])) // 10000 |
| | | # left_big_num = cls.__SecondCancelBigNumComputer.compute_left_big_num(code, |
| | | # buy_single_index, |
| | | # buy_exec_index, |
| | | # total_data[-1][ |
| | | # "index"], |
| | | # total_data, |
| | | # 0, min_money_w) |
| | | # if left_big_num > 0: |
| | | # # 重新获取分数与分数索引 |
| | | # limit_up_time = cls.__LimitUpTimeManager.get_limit_up_time_cache(code) |
| | | # if limit_up_time is None: |
| | | # limit_up_time = tool.get_now_time_str() |
| | | # score = first_code_score_manager.get_score(code, cls.volume_rate_info[code][0], limit_up_time, True, |
| | | # left_big_num) |
| | | # cls.__l2PlaceOrderParamsManagerDict[code].set_score(score) |
| | | |
| | | # logger_place_order_score.info("code={},data='score_index':{},'score_info':{}", code, |
| | | # cls.__l2PlaceOrderParamsManagerDict[code].score_index, |
| | |
| | | # f.write(output.getvalue()) |
| | | # return results |
| | | return cls.can_buy_first(code, limit_up_price) |
| | | |
| | | else: |
| | | return True, False, "在想买名单中" |
| | | |
| | | @classmethod |
| | | def can_buy_first(cls, code, limit_up_price): |
| | | l2_log.debug(code,"can_buy_first start") |
| | | # def is_has_k_format(score_info): |
| | | # # (15个交易日涨幅是否大于24.9%,是否破前高,是否超跌,是否接近前高,是否N,是否V,是否有形态,天量大阳信息,是否具有辨识度) |
| | | # |
| | | # if score_info[1][3][6][0] and not score_info[1][3][3][0]: |
| | | # return True |
| | | # if score_info[1][3][7][0]: |
| | | # return True |
| | | # return False |
| | | |
| | | if float(limit_up_price) >= constant.MAX_CODE_PRICE: |
| | | return False, True, f"股价大于{constant.MAX_CODE_PRICE}块" |
| | | |
| | | # 9:35之前买大市值(>=80亿)票 |
| | | # if int(tool.get_now_date_str("%Y%m%d")) < int("093500"): |
| | | # zyltgb = global_util.zyltgb_map.get(code) |
| | | # if zyltgb is None: |
| | | # global_data_loader.load_zyltgb() |
| | | # zyltgb = global_util.zyltgb_map.get(code) |
| | | # if zyltgb >= 80 * 100000000: |
| | | # return True, False, "{9:30:00-9:35:00}自由市值≥80亿" |
| | | # 判断板块 |
| | | yesterday_codes = kpl_data_manager.get_yesterday_limit_up_codes() |
| | | l2_log.debug(code, "block_can_buy") |
| | | plate_can_buy, msg = CodePlateKeyBuyManager.can_buy(code, |
| | | kpl_data_manager.KPLLimitUpDataRecordManager.latest_origin_datas, |
| | | kpl_data_manager.KPLLimitUpDataRecordManager.total_datas, |
| | | yesterday_codes, |
| | | block_info.get_before_blocks_dict()) |
| | | l2_log.debug(code, "can_buy_first end") |
| | | if not plate_can_buy: |
| | | return False, True, msg |
| | | return True, False, msg |
| | | can_buy_result = CodePlateKeyBuyManager.can_buy(code) |
| | | if can_buy_result is None: |
| | | logger_debug.warning("没有获取到板块缓存,将获取板块") |
| | | yesterday_codes = kpl_data_manager.get_yesterday_limit_up_codes() |
| | | CodePlateKeyBuyManager.update_can_buy_blocks(code, |
| | | kpl_data_manager.KPLLimitUpDataRecordManager.latest_origin_datas, |
| | | kpl_data_manager.KPLLimitUpDataRecordManager.total_datas, |
| | | yesterday_codes, |
| | | block_info.get_before_blocks_dict()) |
| | | can_buy_result = CodePlateKeyBuyManager.can_buy(code) |
| | | |
| | | # if volume_rate_info[0] < 0.4: |
| | | # return False, True, f"量大于40%才下单,量比:{volume_rate_info[0]}" |
| | | |
| | | # 是否有K线形态(有K线形态或者天量大阳),10点后才需要判断是否有K线形态与分值 |
| | | # if int(tool.get_now_time_str().replace(":", "")) > int("100000"): |
| | | # has_k_format = score_info[1][3][6][0] or score_info[1][3][7][0] |
| | | # if not has_k_format: |
| | | # return False, True, f"无K线形态" |
| | | # |
| | | # if score_index < 0: |
| | | # return False, True, f"分值:{score}未达到需要买入的分数线" |
| | | # return True, False, "" |
| | | if can_buy_result is None: |
| | | return False, True, "尚未获取到板块信息" |
| | | if not can_buy_result[0]: |
| | | return False, True, can_buy_result[1] |
| | | return True, False, can_buy_result[1] |
| | | |
| | | @classmethod |
| | | def __cancel_buy(cls, code): |
| | |
| | | _start_time = tool.get_now_timestamp() |
| | | total_datas = local_today_datas[code] |
| | | # 处理安全笔数 |
| | | cls.__buyL2SafeCountManager.compute_left_rate(code, compute_start_index, compute_end_index, total_datas, |
| | | local_today_num_operate_map.get(code)) |
| | | # cls.__buyL2SafeCountManager.compute_left_rate(code, compute_start_index, compute_end_index, total_datas, |
| | | # local_today_num_operate_map.get(code)) |
| | | |
| | | # 获取买入信号计算起始位置 |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos( |
| | |
| | | from l2 import l2_log, l2_data_manager, transaction_progress |
| | | from l2.safe_count_manager import BuyL2SafeCountManager |
| | | from l2.transaction_progress import TradeBuyQueue |
| | | from third_data import kpl_util |
| | | from third_data import kpl_util, kpl_data_manager |
| | | from third_data.code_plate_key_manager import RealTimeKplMarketData, LimitUpCodesPlateKeyManager |
| | | from third_data.kpl_data_manager import KPLDataManager |
| | | from trade import trade_data_manager, current_price_process_manager |
| | |
| | | |
| | | # @unittest.skip("跳过此单元测试") |
| | | def test_trade(self): |
| | | code = "000826" |
| | | code = "600292" |
| | | clear_trade_data(code) |
| | | l2.l2_data_util.load_l2_data(code) |
| | | total_datas = deepcopy(l2.l2_data_util.local_today_datas[code]) |
| | |
| | | LimitUpCodesPlateKeyManager().set_today_limit_up( |
| | | KPLDataManager().get_from_file(kpl_util.KPLDataType.LIMIT_UP, tool.get_now_date_str())) |
| | | |
| | | kpl_data_manager.KPLLimitUpDataRecordManager.load_total_datas() |
| | | |
| | | current_price_process_manager.set_trade_price(code, round(float(gpcode_manager.get_limit_up_price(code)), 2)) |
| | | |
| | | pss_server, pss_strategy = multiprocessing.Pipe() |
| | |
| | | __LimitUpCodesPlateKeyManager = LimitUpCodesPlateKeyManager() |
| | | __CodesHisReasonAndBlocksManager = CodesHisReasonAndBlocksManager() |
| | | __CodesTradeStateManager = trade_manager.CodesTradeStateManager() |
| | | __can_buy_compute_result_dict = {} |
| | | |
| | | # 获取可以买的板块 |
| | | # current_limit_up_datas: 今日实时涨停 |
| | |
| | | for k in k1: |
| | | if k not in constant.KPL_INVALID_BLOCKS: |
| | | keys.add(k) |
| | | if not keys: |
| | | for k in k2: |
| | | if k not in constant.KPL_INVALID_BLOCKS: |
| | | keys.add(k) |
| | | # 始终获取精选板块 |
| | | if True: |
| | | # 获取 |
| | |
| | | can_buy_blocks = [] |
| | | for block in keys: |
| | | log.logger_kpl_debug.info(f"判断板块是否可买:{block}") |
| | | is_top_8_record, top_8_record = kpl_block_util.is_record_top_block(code, block, limit_up_record_datas, |
| | | yesterday_current_limit_up_codes, 50) |
| | | is_top_4_current, top_4_current = kpl_block_util.is_current_top_block(code, block, current_limit_up_datas, |
| | | yesterday_current_limit_up_codes, 50) |
| | | is_top_4 = is_top_8_record and is_top_4_current |
| | | msg_list.append(f"\n实时top10(涨停数量:{len(current_limit_up_datas)})") |
| | | msg_list.append(f"历史top20(涨停数量:{len(top_8_record)})") |
| | | # is_top_8_record, top_8_record = kpl_block_util.is_record_top_block(code, block, limit_up_record_datas, |
| | | # yesterday_current_limit_up_codes, 50) |
| | | # is_top_4_current, top_4_current = kpl_block_util.is_current_top_block(code, block, current_limit_up_datas, |
| | | # yesterday_current_limit_up_codes, 50) |
| | | # is_top_4 = is_top_8_record and is_top_4_current |
| | | # msg_list.append(f"\n实时top10(涨停数量:{len(current_limit_up_datas)})") |
| | | # msg_list.append(f"历史top20(涨停数量:{len(top_8_record)})") |
| | | |
| | | # 获取主板实时身位,剔除高位板 |
| | | current_shsz_rank = kpl_block_util.get_code_current_rank(code, block, current_limit_up_datas, |
| | |
| | | code_limit_up_reason_dict, |
| | | yesterday_current_limit_up_codes, shsz=True) |
| | | # 获取主板历史身位 |
| | | if is_top_4: |
| | | if True: |
| | | pen_limit_up_codes = kpl_block_util.get_shsz_open_limit_up_codes(code, block, limit_up_record_datas, |
| | | code_limit_up_reason_dict) |
| | | if pen_limit_up_codes: |
| | |
| | | # 是否可以下单 |
| | | # 返回:是否可以下单,消息,板块类型 |
| | | @classmethod |
| | | def can_buy(cls, code, current_limit_up_datas, limit_up_record_datas, yesterday_current_limit_up_codes, |
| | | before_blocks_dict): |
| | | if constant.TEST: |
| | | return True, cls.BLOCK_TYPE_NONE |
| | | def can_buy(cls, code): |
| | | # if constant.TEST: |
| | | # return True, cls.BLOCK_TYPE_NONE |
| | | return cls.__can_buy_compute_result_dict.get(code) |
| | | |
| | | @classmethod |
| | | def __compute_can_buy_blocks(cls, code, current_limit_up_datas, limit_up_record_datas, |
| | | yesterday_current_limit_up_codes, before_blocks_dict): |
| | | |
| | | blocks, block_msg = cls.get_can_buy_block(code, current_limit_up_datas, |
| | | limit_up_record_datas, yesterday_current_limit_up_codes, |
| | | before_blocks_dict) |
| | | if not blocks: |
| | | return False, block_msg |
| | | |
| | | # ---------------------------------判断目标代码的板块-------------------start------------ |
| | | # 判断匹配出的涨停原因,判断是否有已经下单的票 |
| | | # reason_need_buy_dict = {} |
| | | # for k in match_limit_up_result: |
| | | # codes = match_limit_up_result[k] |
| | | # final_codes_keys = [keys] |
| | | # for code_ in codes: |
| | | # temp_key_set = set() |
| | | # temp_key_set |= cls.__CodesHisReasonAndBlocksManager.get_total_keys(code_) |
| | | # temp = cls.__LimitUpCodesPlateKeyManager.total_code_keys_dict.get(code_) |
| | | # if temp: |
| | | # temp_key_set |= temp |
| | | # # 二级 |
| | | # industry = global_util.code_industry_map.get(code_) |
| | | # if industry: |
| | | # temp_key_set.add(industry) |
| | | # |
| | | # final_codes_keys.append(temp_key_set) |
| | | # # 求共同的关键词 |
| | | # intersection = set(final_codes_keys[0]) |
| | | # for s in final_codes_keys: |
| | | # intersection &= s |
| | | # log.logger_kpl_debug.info("{}的板块求交集:{}-{}", code, k, intersection) |
| | | # |
| | | # # 求公共的板块是否在流入前5中 |
| | | # is_in, valid_keys = RealTimeKplMarketData.is_in_top(intersection) |
| | | # if is_in: |
| | | # reason_need_buy_dict[k] = (is_in, valid_keys) |
| | | # ---------------------------------判断目标代码的板块-------------------end------------ |
| | | |
| | | # 获取板块可以下单的个数 |
| | | # can_buy_codes_count_dict = {} |
| | | # |
| | | # for key__ in match_limit_up_result: |
| | | # can_buy_count, msg = RealTimeKplMarketData.get_can_buy_codes_count(code, key__) |
| | | # can_buy_codes_count_dict[key__] = can_buy_count |
| | | |
| | | # has_available_key = False |
| | | # for key in can_buy_codes_count_dict: |
| | | # if can_buy_codes_count_dict[key] > 0: |
| | | # has_available_key = True |
| | | # break |
| | | # if not has_available_key: |
| | | # return False, f"匹配到的【{','.join(match_limit_up_result.keys())}】没在精选/行业可以买入的板块中" |
| | | |
| | | # ---------------------------------加载已经下单/成交的代码信息------------start------------- |
| | | # match_reasons = match_limit_up_result.keys() |
| | | # 判断匹配到的原因是否已经有下单/买入成功的代码 |
| | | |
| | | log.logger_kpl_debug.info(f"{code}:获取委托/买入代码") |
| | | codes_delegate = set(cls.__CodesTradeStateManager.get_codes_by_trade_states_cache( |
| | | {trade_manager.TRADE_STATE_BUY_DELEGATED, trade_manager.TRADE_STATE_BUY_PLACE_ORDER})) |
| | |
| | | msg_list.append(f"【{key}】中已经有{success_codes_count}个成交代码") |
| | | log.logger_kpl_debug.debug(f"{code}:板块({key})已经有成交【{trade_success_blocks_count[key]}】") |
| | | continue |
| | | # 10:30以后买1个 |
| | | if int(tool.get_now_time_str().replace(":", "")) > int("103000") and success_codes_count >= 1: |
| | | msg_list.append(f"【{key}】中已经有{success_codes_count}个成交代码") |
| | | log.logger_kpl_debug.debug(f"{code}:板块({key})已经有成交【{trade_success_blocks_count[key]}】") |
| | | continue |
| | | return True, block_msg |
| | | # 板块可以下单数量 |
| | | # if trade_block_codes_dict.get(key) is None or len(trade_block_codes_dict.get(key)) < \ |
| | | # can_buy_codes_count_dict[key]: |
| | | # order_count = len(trade_block_codes_dict.get(key)) if key in trade_block_codes_dict else 0 |
| | | # logger_kpl_block_can_buy.info( |
| | | # f"code={code}:【{key}】可以下单,现有数量:{order_count} 最大数量:{can_buy_codes_count_dict[key]}") |
| | | # return True, f"可以下单,板块:【{key}】,板块中已经下单的数量:{order_count}" |
| | | # else: |
| | | # order_count = len(trade_block_codes_dict.get(key)) |
| | | # msg_list.append(f"【{key}】中下单代码数量{order_count}/允许下单数量{can_buy_codes_count_dict[key]}") |
| | | |
| | | return False, ",".join(msg_list) |
| | | |
| | | @classmethod |
| | | def update_can_buy_blocks(cls, code, current_limit_up_datas, limit_up_record_datas, |
| | | yesterday_current_limit_up_codes, |
| | | before_blocks_dict): |
| | | can_buy, msg = cls.__compute_can_buy_blocks(code, current_limit_up_datas, limit_up_record_datas, |
| | | yesterday_current_limit_up_codes, |
| | | before_blocks_dict) |
| | | # 保存板块计算结果 |
| | | cls.__can_buy_compute_result_dict[code] = (can_buy, msg) |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | pass |
| | |
| | | from l2.l2_data_manager_new import L2TradeDataProcessor |
| | | from log_module.log import hx_logger_l2_upload, hx_logger_contact_debug, hx_logger_trade_callback, \ |
| | | hx_logger_l2_orderdetail, hx_logger_l2_transaction, hx_logger_l2_market_data, logger_l2_trade_buy_queue |
| | | from third_data import block_info, kpl_api |
| | | from third_data.code_plate_key_manager import KPLCodeJXBlockManager |
| | | from third_data import block_info, kpl_api, kpl_data_manager |
| | | from third_data.code_plate_key_manager import KPLCodeJXBlockManager, CodePlateKeyBuyManager |
| | | from third_data.history_k_data_util import JueJinApi, HistoryKDatasUtils |
| | | from third_data.kpl_data_manager import KPLDataManager |
| | | from third_data.kpl_util import KPLDataType |
| | |
| | | limit_up_price, |
| | | sell_1_price, sell_1_volume // 100) |
| | | pre_close_price = round(float(limit_up_price) / 1.1, 2) |
| | | # 如果涨幅大于8%就读取板块 |
| | | # 如果涨幅大于7%就读取板块 |
| | | if (buy_1_price - pre_close_price) / pre_close_price > 0.07: |
| | | if not self.__KPLCodeJXBlockManager.get_jx_blocks(code): |
| | | blocks = kpl_api.getCodeJingXuanBlocks(code) |
| | | self.__KPLCodeJXBlockManager.save_jx_blocks(code, blocks) |
| | | # 更新板块信息 |
| | | yesterday_codes = kpl_data_manager.get_yesterday_limit_up_codes() |
| | | CodePlateKeyBuyManager.update_can_buy_blocks(code, |
| | | kpl_data_manager.KPLLimitUpDataRecordManager.latest_origin_datas, |
| | | kpl_data_manager.KPLLimitUpDataRecordManager.total_datas, |
| | | yesterday_codes, |
| | | block_info.get_before_blocks_dict()) |
| | | |
| | | hx_logger_l2_market_data.info(f"{code}#{data}") |
| | | finally: |
| | |
| | | # return 1 |
| | | # elif self.buy_rank == 3: |
| | | # return 2 |
| | | counts = [2, 1, 1, 1, 0, 0, 0, 0] |
| | | counts = [1, 1, 1, 1, 0, 0, 0, 0] |
| | | volume_rate_index = self.volume_rate_index |
| | | if self.volume_rate_index >= len(counts): |
| | | volume_rate_index = -1 |