| | |
| | | return rate, (today, max(int(max60[0]), int(yesterday))) |
| | | |
| | | |
| | | # 获取量参考日期 |
| | | def get_volume_refer_date(code): |
| | | max60, yesterday = get_histry_volumn(code) |
| | | if max60 is None or yesterday is None: |
| | | raise Exception("获取失败") |
| | | if max60[0] >= yesterday[0]: |
| | | return max60[1] |
| | | else: |
| | | return yesterday[1] |
| | | |
| | | |
| | | # 获取量比索引 |
| | | def get_volume_rate_index(volume_rate): |
| | | rates = [0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6] |
| | |
| | | |
| | | # -------量的约束-------- |
| | | k_format = code_nature_analyse.CodeNatureRecordManager().get_k_format_cache(code) |
| | | if k_format and (k_format[1][0] or k_format[3][0]): |
| | | # 股价创新高或者逼近前高 |
| | | if cls.volume_rate_info[code][0] < 0.3: |
| | | return False, True, f"股价创新高或者逼近前高,当日量比({cls.volume_rate_info[code][0]})小于0.3" |
| | | |
| | | # 如果是早上的强势后排就不需要判断量 |
| | | now_timestamp = int(tool.get_now_time_str().replace(":", "")) |
| | | if can_buy_result[3] and now_timestamp <= int("094000"): |
| | | # 强势主线与强势10分钟不看量 |
| | | pass |
| | | else: |
| | | if k_format and (k_format[1][0] or k_format[3][0]): |
| | | # 股价创新高或者逼近前高 |
| | | if code in cls.volume_rate_info and cls.volume_rate_info[code][0] < 0.3: |
| | | return False, True, f"股价创新高或者逼近前高,当日量比({cls.volume_rate_info[code][0]})小于0.3" |
| | | # 如果是早上的强势后排就不需要判断量 |
| | | if can_buy_result[0] and not can_buy_result[1] and now_timestamp <= int("094000"): |
| | | return True, False, f"9:40:00之前非独苗:{can_buy_result[0]}" |
| | | else: |
| | |
| | | import sys |
| | | import time |
| | | import code_attribute |
| | | from code_attribute import code_volumn_manager, limit_up_time_manager, global_data_loader, gpcode_manager |
| | | from code_attribute import code_volumn_manager, limit_up_time_manager, global_data_loader, gpcode_manager, \ |
| | | code_nature_analyse |
| | | from l2.l2_data_manager import OrderBeginPosInfo |
| | | from l2.l2_data_util import L2DataUtil |
| | | from utils import global_util, tool |
| | |
| | | if is_target_code: |
| | | limit_up_price = gpcode_manager.get_limit_up_price(code) |
| | | limit_up_time = limit_up_time_manager.LimitUpTimeManager().get_limit_up_time_cache(code) |
| | | volume_rate, volume_info = code_volumn_manager.get_volume_rate(code, with_info = True) |
| | | volume_rate, volume_info = code_volumn_manager.get_volume_rate(code, with_info=True) |
| | | |
| | | ################################买前评分################################ |
| | | |
| | |
| | | except: |
| | | pass |
| | | |
| | | # 获取量参考日期 |
| | | try: |
| | | volume_refer_date = code_volumn_manager.get_volume_refer_date(code) |
| | | params["trade_data"]["volume_refer_date"] = volume_refer_date |
| | | except: |
| | | pass |
| | | |
| | | __base_L2PlaceOrderParamsManager = l2_trade_factor.L2PlaceOrderParamsManager(code, False, volume_rate, |
| | | code_volumn_manager.get_volume_rate_index( |
| | | volume_rate), |
| | |
| | | except Exception as e: |
| | | pass |
| | | |
| | | # @unittest.skip("跳过此单元测试") |
| | | @unittest.skip("跳过此单元测试") |
| | | def test_trade(self): |
| | | trade_manager.TradeStateManager().open_buy() |
| | | threading.Thread(target=async_log_util.run_sync, daemon=True).start() |
| | |
| | | |
| | | # hook |
| | | tool.get_now_time_str = mock.Mock(return_value="09:35:00") |
| | | CodePlateKeyBuyManager.can_buy = mock.Mock(return_value=(["测试"], False, "")) |
| | | CodePlateKeyBuyManager.can_buy = mock.Mock(return_value=(["测试"], False, "",[])) |
| | | |
| | | # 获取交易进度 |
| | | trade_progress_list, buy_queues = log_export.get_trade_progress(code) |
| | |
| | | |
| | | # @unittest.skip("跳过此单元测试") |
| | | def test_block(self): |
| | | code = "002036" |
| | | KPLCodeJXBlockManager().load_jx_blocks(code, 11.83, 11.83, |
| | | code = "002315" |
| | | KPLCodeJXBlockManager().load_jx_blocks(code, 37.24, 38, |
| | | kpl_data_manager.KPLLimitUpDataRecordManager.get_current_reasons()) |
| | | |
| | | block_info.init_code(code) |
| | |
| | | kpl_data_manager.KPLLimitUpDataRecordManager.save_record(tool.get_now_date_str(), |
| | | kpl_data_manager.KPLDataManager.get_data( |
| | | kpl_util.KPLDataType.LIMIT_UP)) |
| | | KPLCodeJXBlockManager().load_jx_blocks(code, 11.83, 11.83, |
| | | kpl_data_manager.KPLLimitUpDataRecordManager.get_current_reasons()) |
| | | |
| | | CodePlateKeyBuyManager.update_can_buy_blocks(code, |
| | | kpl_data_manager.KPLLimitUpDataRecordManager.latest_origin_datas, |
| | |
| | | from log_module import log, async_log_util |
| | | from db import redis_manager_delegate as redis_manager |
| | | |
| | | from log_module.log import logger_kpl_limit_up, logger_kpl_block_can_buy |
| | | from log_module.log import logger_kpl_block_can_buy |
| | | from third_data.kpl_util import KPLPlatManager |
| | | from trade import trade_manager, l2_trade_util |
| | | |
| | |
| | | # 添加备用板块 |
| | | if not self.get_jx_blocks_cache(code, by=True): |
| | | blocks = kpl_api.getCodeJingXuanBlocks(code) |
| | | self.save_jx_blocks(code, blocks,current_limit_up_blocks, by=True) |
| | | self.save_jx_blocks(code, blocks, current_limit_up_blocks, by=True) |
| | | async_log_util.info(logger_kpl_block_can_buy, f"{code}:获取到精选板块(备用)-{blocks}") |
| | | except Exception as e: |
| | | logger_kpl_block_can_buy.error(f"{code} 获取板块出错") |
| | |
| | | self.total_key_codes_dict[k] = set() |
| | | self.total_key_codes_dict[k].add(code) |
| | | |
| | | logger_kpl_limit_up.info("{}板块关键词:{}", code, keys) |
| | | # logger_kpl_limit_up.info("{}板块关键词:{}", code, keys) |
| | | |
| | | # 根据传入的关键词与涨停代码信息匹配身位 |
| | | |
| | |
| | | @classmethod |
| | | def __is_block_can_buy(cls, code, block, current_limit_up_datas, code_limit_up_reason_dict, |
| | | yesterday_current_limit_up_codes, limit_up_record_datas, current_limit_up_block_codes_dict): |
| | | |
| | | # 独苗判断 |
| | | block_codes = current_limit_up_block_codes_dict.get(block) |
| | | if not block_codes: |
| | | return False, True, "" |
| | | return False, True, f"{block}:板块无涨停", False |
| | | elif len(block_codes) == 1 and code in block_codes: |
| | | return False, True, "" |
| | | return False, True, f"{block}:板块只有当前代码涨停", False |
| | | # 可以买的最大排名 |
| | | open_limit_up_codes = kpl_block_util.get_shsz_open_limit_up_codes(code, block, limit_up_record_datas, |
| | | code_limit_up_reason_dict) |
| | | # open_limit_up_codes = kpl_block_util.get_shsz_open_limit_up_codes(code, block, limit_up_record_datas, |
| | | # code_limit_up_reason_dict) |
| | | current_open_limit_up_codes = kpl_block_util.get_shsz_open_limit_up_codes_current(code, block, |
| | | current_limit_up_datas) |
| | | |
| | | max_rank = 2 |
| | | # 如果是强势板块(有1个开1/有非主板涨停/有高位板)可以买到老三 |
| | | msg_list = [] |
| | | for bc in block_codes: |
| | | if bc in current_open_limit_up_codes: |
| | | max_rank = 3 |
| | | msg_list.append(f"{bc}开1") |
| | | break |
| | | elif bc in yesterday_current_limit_up_codes: |
| | | max_rank = 3 |
| | | msg_list.append(f"{bc}高位板") |
| | | break |
| | | elif not tool.is_shsz_code(bc): |
| | | max_rank = 3 |
| | | msg_list.append(f"{bc}创业板/科创板") |
| | | break |
| | | # ---------------------------判断强势主线------------------------- |
| | | is_strong_block = False |
| | | for d in current_limit_up_datas: |
| | | if d[5] != block: |
| | | continue |
| | | if d[4].find("连板") > 0: |
| | | if d[4].replace("连板", "").isdigit(): |
| | | count = int(d[4].replace("连板", "")) |
| | | if count >= 3: |
| | | is_strong_block = True |
| | | break |
| | | |
| | | # 判断身位 |
| | | max_rank = 2 |
| | | # 强势板块买老四 |
| | | if is_strong_block: |
| | | max_rank = 3 |
| | | |
| | | # 需要排除的老大的代码 |
| | | exclude_first_codes = set() # HighIncreaseCodeManager().list_all() |
| | |
| | | # 获取主板开1的代码 |
| | | |
| | | # 剔除高位板 |
| | | if open_limit_up_codes and yesterday_current_limit_up_codes: |
| | | open_limit_up_codes -= yesterday_current_limit_up_codes |
| | | if current_open_limit_up_codes and yesterday_current_limit_up_codes: |
| | | current_open_limit_up_codes -= yesterday_current_limit_up_codes |
| | | |
| | | # 获取主板实时身位,剔除高位板 |
| | | current_shsz_rank, front_current_shsz_rank_codes = kpl_block_util.get_code_current_rank(code, block, |
| | |
| | | yesterday_current_limit_up_codes, |
| | | exclude_first_codes, |
| | | len( |
| | | open_limit_up_codes), |
| | | current_open_limit_up_codes), |
| | | shsz=True) |
| | | # record_shsz_rank, record_shsz_rank_codes = kpl_block_util.get_code_record_rank(code, block, |
| | | # limit_up_record_datas, |
| | | # code_limit_up_reason_dict, |
| | | # yesterday_current_limit_up_codes, |
| | | # shsz=True) |
| | | if int(tool.get_now_time_str().replace(":", "")) <= int("094000") and is_strong_block: |
| | | # 强势主线加强势10分钟 |
| | | return True, False, f"【{block}】:强势主线+强势10分钟", is_strong_block |
| | | |
| | | if current_shsz_rank < len(open_limit_up_codes) + max_rank: |
| | | return True, False, f"【{block}】前排代码:{current_shsz_rank}" |
| | | if current_shsz_rank < len(current_open_limit_up_codes) + max_rank: |
| | | return True, False, f"【{block}】前排代码:{current_shsz_rank}", is_strong_block |
| | | else: |
| | | return False, False, f"【{block}】前排代码:{front_current_shsz_rank_codes} 超过{len(open_limit_up_codes) + max_rank}个" |
| | | return False, False, f"【{block}】前排代码:{front_current_shsz_rank_codes} 超过{len(current_open_limit_up_codes) + max_rank}个", is_strong_block |
| | | |
| | | # 过时的代码 |
| | | # if open_limit_up_codes: |
| | |
| | | |
| | | fresults = [] |
| | | if not keys: |
| | | return fresults |
| | | return fresults, set() |
| | | code_limit_up_reason_dict = {} |
| | | load_code_block() |
| | | for block in keys: |
| | | can_buy, unique, msg = cls.__is_block_can_buy(code, block, current_limit_up_datas, |
| | | code_limit_up_reason_dict, |
| | | yesterday_current_limit_up_codes, limit_up_record_datas, |
| | | current_limit_up_block_codes_dict) |
| | | fresults.append((block, can_buy, unique, msg)) |
| | | return fresults |
| | | can_buy, unique, msg, is_strong = cls.__is_block_can_buy(code, block, current_limit_up_datas, |
| | | code_limit_up_reason_dict, |
| | | yesterday_current_limit_up_codes, |
| | | limit_up_record_datas, |
| | | current_limit_up_block_codes_dict) |
| | | fresults.append((block, can_buy, unique, msg, is_strong)) |
| | | return fresults, keys |
| | | |
| | | # 是否可以下单 |
| | | # 返回:可以买的板块,是否独苗,消息 |
| | | @classmethod |
| | | def can_buy(cls, code): |
| | | if constant.TEST: |
| | | return ["测试"], True, cls.BLOCK_TYPE_NONE |
| | | return ["测试"], True, cls.BLOCK_TYPE_NONE, [], set() |
| | | # if True: |
| | | # # 测试 |
| | | # return True, "不判断板块身位" |
| | | 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, |
| | | current_limit_up_block_codes_dict): |
| | | blocks_compute_results = cls.get_can_buy_block(code, current_limit_up_datas, |
| | | limit_up_record_datas, yesterday_current_limit_up_codes, |
| | | before_blocks_dict, current_limit_up_block_codes_dict) |
| | | blocks_compute_results, keys = cls.get_can_buy_block(code, current_limit_up_datas, |
| | | limit_up_record_datas, yesterday_current_limit_up_codes, |
| | | before_blocks_dict, current_limit_up_block_codes_dict) |
| | | if not blocks_compute_results: |
| | | return False, True, "没有找到板块" |
| | | return False, True, f"没有找到板块", [], keys |
| | | codes_delegate = set(cls.__CodesTradeStateManager.get_codes_by_trade_states_cache( |
| | | {trade_manager.TRADE_STATE_BUY_DELEGATED, trade_manager.TRADE_STATE_BUY_PLACE_ORDER})) |
| | | codes_success = set(cls.__CodesTradeStateManager.get_codes_by_trade_states_cache( |
| | |
| | | |
| | | # |
| | | can_buy_blocks = [] |
| | | can_buy_strong_blocks = [] |
| | | unique_count = 0 |
| | | msg_list = [] |
| | | |
| | | for r in blocks_compute_results: |
| | | # r的数据结构(板块,是否可以买,是否独苗,消息) |
| | | # r的数据结构(板块,是否可以买,是否独苗,消息,是否是强势板块) |
| | | if r[2]: |
| | | # 独苗 |
| | | unique_count += 1 |
| | | if r[1]: |
| | | if r[0] in trade_success_blocks_count and len(trade_success_blocks_count[r[0]]) > 0: |
| | | # 强势主线最多同时挂3只票,最多成交2只票 |
| | | MAX_DELEGATE_COUNT = 3 if r[4] else 2 |
| | | MAX_DEAL_COUNT = 2 if r[4] else 1 |
| | | if r[0] in trade_success_blocks_count and len(trade_success_blocks_count[r[0]]) >= MAX_DEAL_COUNT: |
| | | msg_list.append(f"【{r[0]}】有成交代码:{trade_success_blocks_count[r[0]]}") |
| | | continue |
| | | if r[0] in trade_delegate_blocks_count and len(trade_delegate_blocks_count[r[0]]) >= 2: |
| | | if r[0] in trade_delegate_blocks_count and len(trade_delegate_blocks_count[r[0]]) >= MAX_DELEGATE_COUNT: |
| | | msg_list.append(f"【{r[0]}】已挂单:{trade_delegate_blocks_count[r[0]]}") |
| | | continue |
| | | can_buy_blocks.append(r[0]) |
| | | msg_list.append(r[3]) |
| | | if r[4]: |
| | | can_buy_strong_blocks.append(r[0]) |
| | | if r[3]: |
| | | msg_list.append(r[3]) |
| | | else: |
| | | msg_list.append(r[3]) |
| | | if r[3]: |
| | | msg_list.append(r[3]) |
| | | # 所有板块都是独苗 |
| | | if unique_count == len(blocks_compute_results): |
| | | return can_buy_blocks, True, ",".join(msg_list) |
| | | return can_buy_blocks, False, ",".join(msg_list) |
| | | return can_buy_blocks, True, ",".join(msg_list), can_buy_strong_blocks, keys |
| | | return can_buy_blocks, False, ",".join(msg_list), can_buy_strong_blocks, keys |
| | | |
| | | # 更新代码板块判断是否可以买的结果 |
| | | @classmethod |
| | | def update_can_buy_blocks(cls, code, current_limit_up_datas, limit_up_record_datas, |
| | | yesterday_current_limit_up_codes, |
| | | before_blocks_dict, current_limit_up_block_codes_dict): |
| | | can_buy_blocks, unique, msg = cls.__compute_can_buy_blocks(code, current_limit_up_datas, limit_up_record_datas, |
| | | yesterday_current_limit_up_codes, |
| | | before_blocks_dict, |
| | | current_limit_up_block_codes_dict) |
| | | can_buy_blocks, unique, msg, can_buy_strong_blocks, keys = cls.__compute_can_buy_blocks(code, |
| | | current_limit_up_datas, |
| | | limit_up_record_datas, |
| | | yesterday_current_limit_up_codes, |
| | | before_blocks_dict, |
| | | current_limit_up_block_codes_dict) |
| | | # 保存板块计算结果 |
| | | cls.__can_buy_compute_result_dict[code] = (can_buy_blocks, unique, msg) |
| | | cls.__can_buy_compute_result_dict[code] = (can_buy_blocks, unique, msg, can_buy_strong_blocks, keys) |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | |
| | | |
| | | import constant |
| | | from db.redis_manager_delegate import RedisUtils |
| | | from log_module import async_log_util |
| | | from utils import tool |
| | | |
| | | # 开盘啦历史涨停数据管理 |
| | | from db import mysql_data_delegate as mysql_data, redis_manager_delegate as redis_manager |
| | | from log_module.log import logger_kpl_limit_up_reason_change, logger_debug |
| | | from log_module.log import logger_kpl_limit_up_reason_change, logger_debug, logger_kpl_limit_up |
| | | from third_data import kpl_util, kpl_api |
| | | from third_data.code_plate_key_manager import LimitUpCodesPlateKeyManager, CodesHisReasonAndBlocksManager |
| | | |
| | |
| | | requests.post("http://127.0.0.1:9004/upload_kpl_data", json.dumps(root_data)) |
| | | |
| | | def get_limit_up(): |
| | | last_time = 0 |
| | | while True: |
| | | if tool.is_trade_time(): |
| | | try: |
| | | results = kpl_api.getLimitUpInfo() |
| | | result = json.loads(results) |
| | | start_time = time.time() |
| | | if start_time - last_time >= 60: |
| | | last_time = start_time |
| | | # 记录涨停数据 |
| | | async_log_util.info(logger_kpl_limit_up, result) |
| | | __upload_data("limit_up", result) |
| | | logger_kpl_limit_up_reason_change.info("上传耗时:{}", time.time() - start_time) |
| | | # logger_kpl_limit_up_reason_change.info("上传耗时:{}", time.time() - start_time) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | time.sleep(3) |