| | |
| | | from third_data.third_blocks_manager import CodeThirdBlocksManager, SOURCE_TYPE_KPL, BlockMapManager |
| | | from trade import trade_manager, l2_trade_util, trade_data_manager, trade_constant |
| | | import l2_data_util as l2_data_util_old |
| | | from trade.buy_money_count_setting import BuyMoneyAndCountSetting |
| | | from trade.buy_money_count_setting import BuyMoneyAndCountSetting, RadicalBuyBlockCodeCountManager |
| | | |
| | | from trade.huaxin import huaxin_trade_api, huaxin_trade_data_update, \ |
| | | huaxin_trade_record_manager, huaxin_trade_order_processor, huaxin_sell_util |
| | |
| | | desc_list.append("【红名单】") |
| | | if green: |
| | | desc_list.append("【绿名单】") |
| | | |
| | | |
| | | result = {"code": 0, "data": {"code_info": (code, code_name), "desc": "".join(desc_list)}} |
| | | self.send_response(result, client_id, request_id) |
| | |
| | | data = { |
| | | "normal": BuyMoneyAndCountSetting().get_normal_buy_setting(), |
| | | "radical": BuyMoneyAndCountSetting().get_radical_buy_setting(), |
| | | "moneys":constant.AVAILABLE_BUY_MONEYS |
| | | "moneys": constant.AVAILABLE_BUY_MONEYS |
| | | } |
| | | self.send_response({"code": 0, "data": data, "msg": f""}, |
| | | client_id, |
| | | request_id) |
| | | elif ctype == "set_radical_buy_block_count_setting": |
| | | # 设置买入金额和数量 |
| | | data_str = data["data"] |
| | | setting = json.loads(data_str) |
| | | RadicalBuyBlockCodeCountManager().set_block_code_count(setting) |
| | | self.send_response({"code": 0, "data": setting, "msg": f""}, |
| | | client_id, |
| | | request_id) |
| | | elif ctype == "get_radical_buy_block_count_setting": |
| | | # 设置买入金额和数量 |
| | | data = RadicalBuyBlockCodeCountManager().get_block_code_count_settings() |
| | | self.send_response({"code": 0, "data": data, "msg": f""}, |
| | | client_id, |
| | | request_id) |
| | | |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | logger_debug.exception(e) |
| | |
| | | pass |
| | | |
| | | @classmethod |
| | | def start_buy(cls, code, last_data, last_data_index, is_first_code): |
| | | def __is_pre_can_buy(cls, code): |
| | | """ |
| | | 预判断是否可买 |
| | | @param code: |
| | | @return: |
| | | """ |
| | | if not cls.__TradeStateManager.is_can_buy_cache(): |
| | | return False, True, f"今日已禁止交易", True |
| | | |
| | |
| | | now_time_int = int(tool.get_now_time_str().replace(":", "")) |
| | | if now_time_int >= 145700: |
| | | return False, True, f"14:57后不能交易", True |
| | | cls.__buy(code, 0, last_data, last_data_index, is_first_code) |
| | | return True, False, f"", False |
| | | |
| | | @classmethod |
| | | def start_buy(cls, code, last_data, last_data_index, is_first_code): |
| | | pre_result = cls.__is_pre_can_buy(code) |
| | | if pre_result[0]: |
| | | cls.__buy(code, 0, last_data, last_data_index, is_first_code) |
| | | |
| | | @classmethod |
| | | def get_active_buy_blocks(cls, code): |
| | |
| | | @return:(是否可以下单, 是否清理信号数据, 不能下单消息, 是否算有效执行) |
| | | """ |
| | | |
| | | if not cls.__TradeStateManager.is_can_buy_cache(): |
| | | return False, True, f"今日已禁止交易", True |
| | | pre_result = cls.__is_pre_can_buy(code) |
| | | if not pre_result[0]: |
| | | return pre_result[0],pre_result[1], pre_result[2], pre_result[3] |
| | | |
| | | if l2_trade_util.is_in_forbidden_trade_codes(code): |
| | | return False, True, f"代码禁止交易", True |
| | | |
| | | if cls.__PauseBuyCodesManager.is_in_cache(code): |
| | | return False, True, f"该代码被暂停交易", True |
| | | now_time_int = int(tool.get_now_time_str().replace(":", "")) |
| | | if now_time_int >= 145700: |
| | | return False, True, f"14:57后不能交易", True |
| | | if 130100 >= now_time_int >= 112900 or now_time_int < 93100: |
| | | if now_time_int < 93100: |
| | | # 判断近120天是否有涨停 |
| | |
| | | TargetCodePlateKeyManager |
| | | from third_data.history_k_data_util import JueJinApi |
| | | from trade import trade_manager, l2_trade_util, \ |
| | | trade_data_manager, trade_constant, radical_buy_strategy |
| | | trade_data_manager, trade_constant, radical_buy_strategy, radical_buy_data_manager |
| | | from trade.buy_money_count_setting import BuyMoneyAndCountSetting |
| | | |
| | | from trade.huaxin import huaxin_trade_api as trade_api, huaxin_trade_api, huaxin_trade_data_update, \ |
| | |
| | | async_log_util.info(logger_l2_radical_buy, f"该代码已经成交:{code}") |
| | | return |
| | | |
| | | can_buy_result = RedicalBuyDataManager.can_buy(code, DealAndDelegateWithBuyModeDataManager().get_deal_codes()) |
| | | # 单票是否可买 |
| | | can_buy_result = RedicalBuyDataManager.can_buy(code) |
| | | if can_buy_result[0]: |
| | | # 获取激进买的板块 |
| | | result_cache = self.__radical_buy_by_blocks_result_cache.get(code) |
| | |
| | | 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) |
| | |
| | | # 如果关键词包含已成交的原因就不再下单 |
| | | # 获取已经成交代码的板块 |
| | | try: |
| | | # ---------------获取已经成交代码的板块---------------- |
| | | deal_reasons = set() |
| | | for dc in deal_codes: |
| | | # 获取涨停原因 |
| | | limit_up_reason = kpl_data_manager.LimitUpDataConstant.get_limit_up_reason_with_history(dc) |
| | | if limit_up_reason and limit_up_reason in constant.KPL_INVALID_BLOCKS: |
| | | limit_up_reason = None |
| | | # 如果涨停原因为空就需要获取上次激进买的原因 |
| | | if not limit_up_reason: |
| | | radical_buy_blocks = RadicalBuyDealCodesManager.radical_buy_blocks_dict.get(dc) |
| | | if radical_buy_blocks: |
| | | deal_reasons |= radical_buy_blocks |
| | | else: |
| | | deal_reasons.add(limit_up_reason) |
| | | async_log_util.info(logger_l2_radical_buy, f"已经成交的板块:{deal_reasons}") |
| | | # 成交代码的板块如果和目标代码板块有交集就不扫 |
| | | keys_, k1_, k11_, k2_, k3_, k4_ = TargetCodePlateKeyManager().get_plate_keys(code, |
| | | contains_today=False) |
| | | match_blocks = keys_ & deal_reasons |
| | | if match_blocks: |
| | | async_log_util.info(logger_l2_radical_buy, f"板块有成交:{code}-{match_blocks}") |
| | | # ---------------判断板块是否还可以买入---------------- |
| | | f_buy_blocks = radical_buy_data_manager.is_block_can_radical_buy(code, buy_blocks, deal_codes) |
| | | if not f_buy_blocks: |
| | | return |
| | | buy_blocks = f_buy_blocks |
| | | except Exception as e: |
| | | logger_debug.exception(e) |
| | | |
| | |
| | | from settings.trade_setting import MarketSituationManager |
| | | from third_data.kpl_data_constant import LimitUpDataConstant |
| | | from third_data.third_blocks_manager import BlockMapManager, CodeThirdBlocksManager |
| | | from trade.buy_money_count_setting import RadicalBuyBlockCodeCountManager |
| | | from trade.order_statistic import DealAndDelegateWithBuyModeDataManager |
| | | from trade.radical_buy_data_manager import RedicalBuyDataManager |
| | | from utils import global_util, tool, buy_condition_util |
| | |
| | | kpl_data_constant.open_limit_up_code_dict_for_radical_buy = temp_dict |
| | | |
| | | @classmethod |
| | | def __get_current_index(cls, code, block, yesterday_limit_up_codes, exclude_codes=None): |
| | | def __get_current_index(cls, code, block, yesterday_limit_up_codes, exclude_codes=None, limit_up_time=None): |
| | | """ |
| | | 获取当前涨停身位 |
| | | @param code: |
| | |
| | | current_index = 0 |
| | | block_codes_infos = [] |
| | | timestamp_start, timestamp_end = kpl_block_util.open_limit_up_time_range |
| | | limit_up_time = time.time() |
| | | if limit_up_time is None: |
| | | limit_up_time = time.time() |
| | | for k in LimitUpDataConstant.current_limit_up_datas: |
| | | _code = k[0] |
| | | if _code in exclude_codes: |
| | |
| | | """ |
| | | # 9:45点之前涨停的才能买入 |
| | | # 获取当前代码的涨停时间 |
| | | limit_up_timestamp = LimitUpDataConstant.get_first_limit_up_time(code) |
| | | if not limit_up_timestamp: |
| | | limit_up_timestamp = time.time() |
| | | limit_up_timestamp = cls.__get_limit_up_timestamp(code) |
| | | if int(tool.timestamp_format(limit_up_timestamp, "%H%M%S")) > 94500: |
| | | return False, "超过生效时间" |
| | | # 根据板块聚合数据 |
| | |
| | | # ----获取历史身位---- |
| | | history_index, history_before_codes_info = cls.__get_history_index(code, block, yesterday_limit_up_codes) |
| | | # ----获取实时身位---- |
| | | current_index, current_before_codes_info = cls.__get_current_index(code, block, yesterday_limit_up_codes) |
| | | current_index, current_before_codes_info = cls.__get_current_index(code, block, yesterday_limit_up_codes, |
| | | limit_up_time=limit_up_timestamp) |
| | | exclude_codes = set() |
| | | if count >= 2 or ( |
| | | count == 1 and kpl_data_constant.open_limit_up_code_dict_for_radical_buy[open_limit_up_block_codes[0]][ |
| | |
| | | # ----获取历史身位---- |
| | | history_index, history_before_codes_info = cls.__get_history_index(code, block, set()) |
| | | # ----获取实时身位---- |
| | | current_index, current_before_codes_info = cls.__get_current_index(code, block, set()) |
| | | current_index, current_before_codes_info = cls.__get_current_index(code, block, set(), |
| | | limit_up_time=limit_up_timestamp) |
| | | if history_before_codes_info and current_before_codes_info and history_before_codes_info[0][0] == \ |
| | | current_before_codes_info[0][0]: |
| | | # 前排第一个元素无炸板 |
| | |
| | | return False, f"开1数量:{count},非开1首板身位不匹配:历史-{history_index + 1} 实时-{current_index + 1}" |
| | | if history_index == 1: |
| | | # 当前代码为老2,要判断老大是否可买 |
| | | if RedicalBuyDataManager.can_buy(history_before_codes_info[0][0], DealAndDelegateWithBuyModeDataManager().get_deal_codes())[0]: |
| | | if RedicalBuyDataManager.can_buy(history_before_codes_info[0][0], |
| | | DealAndDelegateWithBuyModeDataManager().get_deal_codes())[0]: |
| | | return False, f"开1数量:{count},前排代码可买:{history_before_codes_info[0]}" |
| | | return True, f"开1数量:{count},前排代码不可买:{history_before_codes_info[0]}" |
| | | return True, f"开1数量:{count},历史-{history_index + 1} 实时-{current_index + 1}" |
| | |
| | | @param yesterday_limit_up_codes: |
| | | @return: |
| | | """ |
| | | |
| | | # 获取当前代码的涨停时间 |
| | | limit_up_timestamp = cls.__get_limit_up_timestamp(code) |
| | | |
| | | # 获取当前的板块 |
| | | current_index, current_before_codes_info = cls.__get_current_index(code, block, set()) |
| | | current_index, current_before_codes_info = cls.__get_current_index(code, block, set(), |
| | | limit_up_time=limit_up_timestamp) |
| | | current_before_codes = [x[0] for x in current_before_codes_info] |
| | | |
| | | if len(current_before_codes_info) < 2: |
| | | return False, f"前排代码小于2个:{current_before_codes_info}" |
| | | |
| | | # 获取当前代码的涨停时间 |
| | | limit_up_timestamp = LimitUpDataConstant.get_first_limit_up_time(code) |
| | | if not limit_up_timestamp: |
| | | limit_up_timestamp = time.time() |
| | | |
| | | # 当前代码开1不能买 |
| | | if limit_up_timestamp < kpl_block_util.open_limit_up_time_range[1]: |
| | |
| | | exclude_codes |= set(open_limit_up_code_dict.keys()) |
| | | history_index, history_before_codes_info = cls.__get_history_index(code, block, yesterday_limit_up_codes, |
| | | exclude_codes) |
| | | if history_index > 1: |
| | | return False, f"排除前2,目标代码位于历史身位-{history_index + 1},前排代码:{history_before_codes_info}" |
| | | elif history_index == 1: |
| | | # 首板老2,判断前面的老大是否是属于不能买的范畴 |
| | | pre_code = history_before_codes_info[0][0] |
| | | # pre_code不能买,才能买 |
| | | if RedicalBuyDataManager.can_buy(pre_code, DealAndDelegateWithBuyModeDataManager().get_deal_codes())[0]: |
| | | return False, f"前排代码可买:{pre_code}" |
| | | # 距离前一个是否在10分钟内 |
| | | if tool.trade_time_sub(tool.timestamp_format(limit_up_timestamp, '%H:%M:%S'), |
| | | tool.timestamp_format(history_before_codes_info[-1][1], '%H:%M:%S')) >= 10 * 60: |
| | | return False, f"距离上个不能买的代码涨停已过去10分钟({history_before_codes_info[0]})" |
| | | # 获取本板块买入代码的最大数量 |
| | | max_count = RadicalBuyBlockCodeCountManager().get_block_code_count(block) |
| | | if history_index > max_count: |
| | | return False, f"排除前2,目标代码位于历史身位-{history_index + 1},前排代码:{history_before_codes_info}, 板块最多可买{max_count}" |
| | | |
| | | if max_count == 1: |
| | | if history_index == 1: |
| | | # 首板老2,判断前面的老大是否是属于不能买的范畴 |
| | | pre_code = history_before_codes_info[0][0] |
| | | # pre_code不能买,才能买 |
| | | if RedicalBuyDataManager.can_buy(pre_code, DealAndDelegateWithBuyModeDataManager().get_deal_codes())[0]: |
| | | return False, f"前排代码可买:{pre_code}" |
| | | # 距离前一个是否在10分钟内 |
| | | if tool.trade_time_sub(tool.timestamp_format(limit_up_timestamp, '%H:%M:%S'), |
| | | tool.timestamp_format(history_before_codes_info[-1][1], '%H:%M:%S')) >= 10 * 60: |
| | | return False, f"距离上个不能买的代码涨停已过去10分钟({history_before_codes_info[0]})" |
| | | else: |
| | | # 距离上个代码涨停5分钟以内 |
| | | if tool.trade_time_sub(tool.timestamp_format(limit_up_timestamp, '%H:%M:%S'), |
| | | tool.timestamp_format(current_before_codes_info[-1][1], '%H:%M:%S')) >= 5 * 60: |
| | | return False, f"距离上个代码涨停已过去5分钟({current_before_codes_info[-1]})" |
| | | else: |
| | | # 距离上个代码涨停5分钟以内 |
| | | if tool.trade_time_sub(tool.timestamp_format(limit_up_timestamp, '%H:%M:%S'), |
| | | tool.timestamp_format(current_before_codes_info[-1][1], '%H:%M:%S')) >= 5 * 60: |
| | | return False, f"距离上个代码涨停已过去5分钟({current_before_codes_info[-1]})" |
| | |
| | | |
| | | @classmethod |
| | | def __is_re_limit_up(cls, code, block): |
| | | """ |
| | | 是否是炸板回封可买 |
| | | @param code: |
| | | @param block: |
| | | @return: |
| | | """ |
| | | # 获取身位 |
| | | current_index, current_before_codes_info = cls.__get_current_index(code, block, set()) |
| | | current_index, current_before_codes_info = cls.__get_current_index(code, block, set(), |
| | | limit_up_time=cls.__get_limit_up_timestamp( |
| | | code)) |
| | | history_index, history_before_codes_info = cls.__get_history_index(code, block, set()) |
| | | if current_index != history_index: |
| | | return False, f"有其他炸板" |
| | |
| | | if diff: |
| | | return False, f"板块炸板不止当前票:{diff}" |
| | | return True, "" |
| | | |
| | | @classmethod |
| | | def __get_limit_up_timestamp(cls, code): |
| | | """ |
| | | 获取代码的涨停时间,默认当前时间 |
| | | @param code: |
| | | @return: |
| | | """ |
| | | limit_up_timestamp = LimitUpDataConstant.get_first_limit_up_time(code) |
| | | if not limit_up_timestamp: |
| | | limit_up_timestamp = time.time() |
| | | return limit_up_timestamp |
| | | |
| | | @classmethod |
| | | def get_code_kpl_blocks(cls, code): |
| | |
| | | result = cls.__is_radical_buy_with_block_up(code, b, yesterday_limit_up_codes) |
| | | if result[0]: |
| | | can_buy_blocks.add(b) |
| | | |
| | | msges.append(f"【{b}】:{result[1]}") |
| | | fmsges.append("板块快速启动判断##" + ",".join(msges)) |
| | | |
| | | if not can_buy_blocks: |
| | | msges.clear() |
| | | for b in keys_: |
| | | result = cls.__is_re_limit_up(code, b) |
| | | if result[0]: |
| | | can_buy_blocks.add(b) |
| | | |
| | | msges.append(f"【{b}】:{result[1]}") |
| | | fmsges.append("板块回封判断##" + ",".join(msges)) |
| | | return can_buy_blocks, " **** ".join(fmsges) |
| | | |
| | | |
| | |
| | | import json |
| | | |
| | | import constant |
| | | from db import redis_manager |
| | | from db.mysql_data_delegate import Mysqldb |
| | | from db.redis_manager_delegate import RedisUtils |
| | | from l2.l2_data_manager import OrderBeginPosInfo |
| | | from utils import tool |
| | | |
| | | |
| | | class BuyMoneyAndCountSetting: |
| | |
| | | return self.__radical_buy |
| | | |
| | | |
| | | class RadicalBuyBlockCodeCountManager: |
| | | """ |
| | | 扫入目标板块的代码个数限制管理 |
| | | """ |
| | | __db = 2 |
| | | __redisManager = redis_manager.RedisManager(2) |
| | | __instance = None |
| | | __block_count_dict = {} |
| | | |
| | | def __new__(cls, *args, **kwargs): |
| | | if not cls.__instance: |
| | | cls.__instance = super(RadicalBuyBlockCodeCountManager, cls).__new__(cls, *args, **kwargs) |
| | | cls.__load_data() |
| | | return cls.__instance |
| | | |
| | | @classmethod |
| | | def __get_redis(cls): |
| | | return cls.__redisManager.getRedis() |
| | | |
| | | @classmethod |
| | | def __load_data(cls): |
| | | val = RedisUtils.get(cls.__get_redis(), "radical_block_code_count_setting") |
| | | if val: |
| | | val = json.loads(val) |
| | | cls.__block_count_dict = val |
| | | |
| | | def set_block_code_count(self, block_count_infos): |
| | | """ |
| | | 设置板板块买入的代码数量 |
| | | @param block_count_infos:[("名称", 数量)] |
| | | @return: |
| | | """ |
| | | if block_count_infos is None: |
| | | block_count_infos = [] |
| | | temp_dict = {x[0]: x[1] for x in block_count_infos} |
| | | self.__block_count_dict = temp_dict |
| | | RedisUtils.setex_async(self.__db, "radical_block_code_count_setting", tool.get_expire(), json.dumps(temp_dict)) |
| | | |
| | | def get_block_code_count(self, block): |
| | | """ |
| | | 获取板块最多买入代码的数量 |
| | | @param block: |
| | | @return: 最大数量,默认1 |
| | | """ |
| | | if block not in self.__block_count_dict: |
| | | return 1 |
| | | return self.__block_count_dict.get(block) |
| | | |
| | | def get_block_code_count_settings(self): |
| | | """ |
| | | 获取所有的板块设置 |
| | | @return: |
| | | """ |
| | | results = [(k, self.__block_count_dict[k]) for k in self.__block_count_dict] |
| | | results.sort(key=lambda x: x[0]) |
| | | return results |
| | | |
| | | |
| | | class BuyMoneyUtil: |
| | | @classmethod |
| | | def get_buy_data(cls, time_str, buy_mode, deals, delegates): |
| | |
| | | # [(委托代码, 委托时间)] |
| | | # delegates = DealAndDelegateWithBuyModeDataManager().get_delegates_codes_info(buy_mode) |
| | | if delegates is None: |
| | | delegates =[] |
| | | delegates = [] |
| | | # 最大委托数量 |
| | | max_count = 0 |
| | | # 配置数据:[(时间,金额,数量)] |
| | |
| | | from code_attribute import code_nature_analyse, code_volumn_manager, gpcode_manager |
| | | from code_attribute.code_l1_data_manager import L1DataManager |
| | | from l2.l2_sell_manager import L2MarketSellManager |
| | | from log_module import async_log_util |
| | | from log_module.log import logger_l2_radical_buy |
| | | from third_data import kpl_data_manager |
| | | from trade.buy_money_count_setting import RadicalBuyBlockCodeCountManager |
| | | from trade.trade_data_manager import RadicalBuyDealCodesManager |
| | | |
| | | |
| | | class RedicalBuyDataManager(): |
| | |
| | | # 拉黑且不是已经买入性质的拉黑 |
| | | return False, "已拉黑" |
| | | return True, "" |
| | | |
| | | |
| | | def is_block_can_radical_buy(code, radical_buy_blocks, deal_codes): |
| | | # 原因下面的代码个数 |
| | | deal_reason_codes = {} |
| | | |
| | | for dc in deal_codes: |
| | | # 获取涨停原因 |
| | | reasons = set() |
| | | limit_up_reason = kpl_data_manager.LimitUpDataConstant.get_limit_up_reason_with_history(dc) |
| | | if limit_up_reason and limit_up_reason in constant.KPL_INVALID_BLOCKS: |
| | | limit_up_reason = None |
| | | # 如果涨停原因为空就需要获取上次激进买的原因 |
| | | if limit_up_reason: |
| | | reasons.add(limit_up_reason) |
| | | if not limit_up_reason: |
| | | radical_buy_blocks = RadicalBuyDealCodesManager.radical_buy_blocks_dict.get(dc) |
| | | if radical_buy_blocks: |
| | | reasons |= radical_buy_blocks |
| | | for r in reasons: |
| | | if r not in deal_reason_codes: |
| | | deal_reason_codes[r] = set() |
| | | deal_reason_codes[r].add(dc) |
| | | async_log_util.info(logger_l2_radical_buy, f"已经成交的板块:{code}-{deal_reason_codes.keys()}") |
| | | |
| | | f_buy_blocks = set() |
| | | for b in radical_buy_blocks: |
| | | # 获取板块的最大买入个数 |
| | | max_count = RadicalBuyBlockCodeCountManager().get_block_code_count(b) |
| | | if b in deal_reason_codes and len(deal_reason_codes[b])>=max_count: |
| | | continue |
| | | f_buy_blocks.add(b) |
| | | async_log_util.info(logger_l2_radical_buy, f"还可以买入的板块:{code}-{f_buy_blocks}") |
| | | return f_buy_blocks |