| | |
| | | order_begin_pos = OrderBeginPosInfo(buy_single_index=0, buy_exec_index=0) |
| | | l2_data_util.load_l2_data(code) |
| | | total_datas = l2_data_util.local_today_datas.get(code) |
| | | if not total_datas: |
| | | continue |
| | | trade_index, is_default = transaction_progress.TradeBuyQueue().get_traded_index(code) |
| | | if trade_index is None: |
| | | trade_index = 0 |
| | |
| | | elif ctype == "set_per_code_buy_money": |
| | | # 设置单只票的买入金额 |
| | | money = data["money"] |
| | | if money > 30000: |
| | | raise Exception("最多只能设置3w") |
| | | if money > 50000: |
| | | raise Exception("最多只能设置5w") |
| | | constant.BUY_MONEY_PER_CODE = money |
| | | self.send_response({"code": 0, "data": {"money": constant.BUY_MONEY_PER_CODE}}, client_id, request_id) |
| | | elif ctype == "get_per_code_buy_money": |
| | |
| | | # 设置买入金额和数量 |
| | | normal = data["normal"] |
| | | radical = data["radical"] |
| | | default_buy_money = data["default_buy_money"] |
| | | if int(default_buy_money) not in constant.AVAILABLE_BUY_MONEYS: |
| | | raise Exception("默认金额不在预设金额内") |
| | | BuyMoneyAndCountSetting().set_normal_buy_data(normal[0], json.loads(normal[1])) |
| | | BuyMoneyAndCountSetting().set_radical_buy_data(radical[0], json.loads(radical[1])) |
| | | data = { |
| | |
| | | data = { |
| | | "normal": BuyMoneyAndCountSetting().get_normal_buy_setting(), |
| | | "radical": BuyMoneyAndCountSetting().get_radical_buy_setting(), |
| | | "moneys": constant.AVAILABLE_BUY_MONEYS |
| | | "moneys": constant.AVAILABLE_BUY_MONEYS, |
| | | "default_buy_money": constant.BUY_MONEY_PER_CODE |
| | | } |
| | | self.send_response({"code": 0, "data": data, "msg": f""}, |
| | | client_id, |
| | |
| | | MIN_CODE_PRICE = 2 |
| | | MAX_SUBSCRIPT_CODE_PRICE = 100 |
| | | |
| | | # 扫入价格区间 |
| | | MAX_CODE_RADICAL_BUY_PRICE = 40 |
| | | MIN_CODE_RADICAL_BUY_PRICE = 2 |
| | | |
| | | |
| | | # L2数据是否载入完成 |
| | | L2_DATA_IS_LOADED = False |
| | | |
| | |
| | | from trade import current_price_process_manager, trade_constant |
| | | import concurrent.futures |
| | | |
| | | from trade.radical_buy_data_manager import RedicalBuyDataManager |
| | | from trade.radical_buy_data_manager import RedicalBuyDataManager, EveryLimitupBigDealOrderManager |
| | | from utils import tool |
| | | |
| | | |
| | |
| | | buy_datas, bigger_buy_datas = HuaXinBuyOrderManager.statistic_big_buy_data(code, datas, limit_up_price) |
| | | if buy_datas: |
| | | BigOrderDealManager().add_buy_datas(code, buy_datas) |
| | | EveryLimitupBigDealOrderManager.add_big_buy_order_deal(code, [x[0] for x in buy_datas]) |
| | | try: |
| | | is_placed_order = l2_data_manager.TradePointManager.is_placed_order(order_begin_pos) |
| | | if is_placed_order: |
| | |
| | | # 设置成交价 |
| | | try: |
| | | current_price_process_manager.set_trade_price(code, datas[-1][1]) |
| | | if limit_up_price > datas[-1][1]: |
| | | # 没有涨停 |
| | | EveryLimitupBigDealOrderManager.open_limit_up(code) |
| | | except: |
| | | pass |
| | | |
| | | |
| | | total_datas = l2_data_util.local_today_datas.get(code) |
| | | use_time_list = [] |
| | | try: |
| | |
| | | try: |
| | | cancel_result = FCancelBigNumComputer().need_cancel_for_w(code) |
| | | if cancel_result[0]: |
| | | L2TradeDataProcessor.cancel_buy(code, f"W撤:{cancel_result[1]}", cancel_type=trade_constant.CANCEL_TYPE_W) |
| | | L2TradeDataProcessor.cancel_buy(code, f"W撤:{cancel_result[1]}", |
| | | cancel_type=trade_constant.CANCEL_TYPE_W) |
| | | except: |
| | | pass |
| | | |
| | |
| | | fdatas.append((time_str, type, data_json["data"])) |
| | | return fdatas |
| | | |
| | | |
| | | def load_cancel_buy_reasons(code, date=tool.get_now_date_str()): |
| | | """ |
| | | 获取撤单原因 |
| | |
| | | @return: {真实下单位置:撤单原因} |
| | | """ |
| | | fdatas = load_trade_recod(code, date) |
| | | cancel_reason_dict={} |
| | | cancel_reason_dict = {} |
| | | for data in fdatas: |
| | | if data[1] != "cancel": |
| | | continue |
| | |
| | | codes = eval(data) |
| | | fdatas.append((time_str, codes)) |
| | | return fdatas |
| | | |
| | | |
| | | def load_kpl_limit_up_records(current_time_str, date=tool.get_now_date_str()): |
| | | """ |
| | | 获取离给定时间最近的涨停数据 |
| | | @param current_time_str: |
| | | @param date: |
| | | @return: |
| | | """ |
| | | path = f"{constant.get_path_prefix()}/logs/gp/kpl/kpl_limit_up.{date}.log" |
| | | lines = __load_file_content(path) |
| | | lines.reverse() |
| | | current_time_str_int = int(current_time_str.replace(":", "")) |
| | | for line in lines: |
| | | if line: |
| | | time_str = __get_log_time(line) |
| | | if int(time_str.replace(":", "")) < current_time_str_int: |
| | | line = line.split(" - ")[1] |
| | | return eval(line) |
| | | return None |
| | | |
| | | |
| | | # 加载华鑫本地买入订单号 |
| | |
| | | |
| | | |
| | | if __name__ == '__main__': |
| | | fdatas = get_real_place_order_positions("002404") |
| | | print(len(fdatas)) |
| | | fdatas = load_kpl_limit_up_records("10:00:00", "2024-10-21") |
| | | print(fdatas) |
| | | # print(get_h_cancel_compute_info("603912")) |
| | | |
| | | # logger_l2_h_cancel.info("test") |
| | |
| | | |
| | | fresults = fresults[:30] |
| | | response_data = json.dumps({"code": 0, "data": fresults}) |
| | | elif url.path == "/kpl/get_latest_limit_up_queue": |
| | | # 获取最近的涨停队列 |
| | | ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) |
| | | time_str = ps_dict.get("time") |
| | | day = ps_dict.get("day") |
| | | if not day: |
| | | day = tool.get_now_date_str() |
| | | results = log_export.load_kpl_limit_up_records(time_str, date=day) |
| | | if not results: |
| | | results = [] |
| | | response_data = json.dumps({"code": 0, "data": results}) |
| | | elif url.path == "/get_h_cancel_data": |
| | | ps_dict = dict([(k, v[0]) for k, v in parse_qs(url.query).items()]) |
| | | code = ps_dict["code"] |
| | |
| | | return |
| | | |
| | | # -----根据成交比例判断是否可买------ |
| | | result_by_volume = radical_buy_strategy.limit_up_active_buy_deal(code, transaction_datas) |
| | | result_by_volume = radical_buy_strategy.process_limit_up_active_buy_deal(code, transaction_datas) |
| | | async_log_util.info(logger_l2_radical_buy, f"量买入结果判断:{code}, 结果:{result_by_volume} 板块:{buy_blocks}") |
| | | if result_by_volume[0] != radical_buy_strategy.BUY_MODE_NONE: |
| | | if result_by_volume[0] == radical_buy_strategy.BUY_MODE_DIRECT: |
| | |
| | | delegates = [] |
| | | # 最大委托数量 |
| | | max_count = 0 |
| | | # 配置数据:[(时间,金额,数量)] |
| | | # 配置数据:[(时间,金额,数量, 最大数量)] |
| | | money_list = [] |
| | | if buy_mode == OrderBeginPosInfo.MODE_RADICAL: |
| | | max_count, money_list = BuyMoneyAndCountSetting().get_radical_buy_setting() |
| | |
| | | if i > 0: |
| | | start_time = money_list[i - 1][0] |
| | | break |
| | | if end_info is None: |
| | | return False, constant.BUY_MONEY_PER_CODE, f"当前时间段不能扫入" |
| | | # 获取时间段已经成交/已经挂单的代码数量 |
| | | end_time_int = int(end_info[0].replace(":", "")) |
| | | start_time_int = int(start_time.replace(":", "")) |
| | |
| | | if start_time_int < int(d[1].replace(":", "")) <= end_time_int: |
| | | codes.add(d[0]) |
| | | if len(codes) >= end_info[2]: |
| | | return False, constant.BUY_MONEY_PER_CODE, f"时间段:{start_time}-{end_info[0]} 已成交/委托数量({codes})超过{end_info[2]}个,已经不能委托" |
| | | if len(codes) >= end_info[2] + end_info[3]: |
| | | return False, constant.BUY_MONEY_PER_CODE, f"时间段:{start_time}-{end_info[0]} 已成交/委托数量({codes})超过{end_info[2] + end_info[3]}个,已经不能委托" |
| | | else: |
| | | return True, constant.BUY_MONEY_PER_CODE, f"时间段:{start_time}-{end_info[0]} 已成交/委托数量({codes})>={end_info[2]}个,<{end_info[2] + end_info[3]} ,按默认金额扫入" |
| | | else: |
| | | return True, end_info[ |
| | | 1], f"时间段:{start_time}-{end_info[0]} 已成交/委托数量({codes})没有超过{end_info[2]}个,委托金额为:{end_info[1]}" |
| | |
| | | from third_data import kpl_data_manager |
| | | from trade.buy_money_count_setting import RadicalBuyBlockCodeCountManager |
| | | from trade.trade_data_manager import RadicalBuyDealCodesManager |
| | | from utils import tool |
| | | from utils import tool, global_util |
| | | |
| | | |
| | | class RedicalBuyDataManager(): |
| | |
| | | 是否可以买 |
| | | @param code: 代码 |
| | | @param total_sell_volume: 总卖量 |
| | | @return: |
| | | @return: 是否可以买, 原因 |
| | | """ |
| | | k_format = code_nature_analyse.CodeNatureRecordManager().get_k_format_cache(code) |
| | | if k_format: |
| | |
| | | volume_rate = code_volumn_manager.get_volume_rate(code, total_sell_volume=total_sell_volume) |
| | | if volume_rate < 0.6: |
| | | return False, f"昨日炸板,量比({volume_rate})<0.6" |
| | | |
| | | # MAX_CODE_PRICE = 50 |
| | | # MIN_CODE_PRICE = 2 |
| | | # 获取涨停价 |
| | | price = gpcode_manager.get_limit_up_price_as_num(code) |
| | | if not price: |
| | | # 获取现价 |
| | | price = L1DataManager.get_l1_current_price(code) |
| | | if price: |
| | | if price < constant.MIN_CODE_PRICE or price > constant.MAX_CODE_PRICE: |
| | | if price < constant.MIN_CODE_RADICAL_BUY_PRICE or price > constant.MAX_CODE_RADICAL_BUY_PRICE: |
| | | return False, "价格不满足需求" |
| | | # 判断自由流通股本 |
| | | zyltgb = global_util.zyltgb_map.get(code) |
| | | if zyltgb: |
| | | zyltgb_as_yi = round(zyltgb / 100000000, 2) |
| | | if zyltgb_as_yi > 80: |
| | | return False, "自由流通市值过大" |
| | | if gpcode_manager.BlackListCodeManager().is_in_cache(code): |
| | | if deal_codes is not None and code in deal_codes: |
| | | pass |
| | |
| | | gpcode_manager.MustBuyCodesManager().add_code(code) |
| | | |
| | | |
| | | class EveryLimitupBigDealOrderManager: |
| | | """ |
| | | 每次上板的大单管理 |
| | | """ |
| | | # 成交大单的订单号:{"code":{"order_no",...}} |
| | | __deal_big_order_nos_dict = {} |
| | | |
| | | @classmethod |
| | | def open_limit_up(cls, code): |
| | | if code in cls.__deal_big_order_nos_dict: |
| | | cls.__deal_big_order_nos_dict[code].clear() |
| | | |
| | | @classmethod |
| | | def add_big_buy_order_deal(cls, code, order_nos:list): |
| | | if code not in cls.__deal_big_order_nos_dict: |
| | | cls.__deal_big_order_nos_dict[code] = set() |
| | | for order_no in order_nos: |
| | | cls.__deal_big_order_nos_dict[code].add(order_no) |
| | | |
| | | @classmethod |
| | | def get_big_buy_deal_order_count(cls, code): |
| | | if code in cls.__deal_big_order_nos_dict: |
| | | return len(cls.__deal_big_order_nos_dict[code]) |
| | | return 0 |
| | | |
| | | |
| | | def is_block_can_radical_buy(code, radical_buy_blocks, deal_codes): |
| | | # 原因下面的代码个数 |
| | | deal_reason_codes = {} |
| | |
| | | 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 |
| | | 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 |
| | | from trade import radical_buy_data_manager |
| | | from trade.radical_buy_data_manager import EveryLimitupBigDealOrderManager |
| | | from utils import tool |
| | | |
| | | # 不买入 |
| | |
| | | return BUY_MODE_NONE, "尚未获取到总卖额(备用)" |
| | | |
| | | |
| | | def limit_up_active_buy_deal(code, transaction_datas): |
| | | def process_limit_up_active_buy_deal(code, transaction_datas): |
| | | async_log_util.info(hx_logger_l2_transaction, f"板上成交:{code}-{transaction_datas}") |
| | | """ |
| | | 涨停主动买成交 |
| | |
| | | |
| | | price = transaction_datas[-1][1] |
| | | huaxin_timestamp = transaction_datas[-1][3] |
| | | # 判断 |
| | | # 处于涨停卖的委托订单量 |
| | | selling_num = L2LimitUpSellDataManager.get_delegating_sell_num(code) |
| | | if selling_num: |
| | | total_sell = __deal_active_buy_total_money[code] + selling_num * price |
| | |
| | | with_info=False) |
| | | if volume_rate is None: |
| | | volume_rate = 0.5 |
| | | # 根据大单判断是否可以扫 |
| | | big_order_deal_result = __is_big_order_deal_enough(code, volume_rate) |
| | | if not big_order_deal_result[0]: |
| | | return BUY_MODE_NONE, big_order_deal_result[1] |
| | | |
| | | THRESHOLD_RATE = radical_buy_data_manager.get_volume_rate_threshold(code, volume_rate) |
| | | if rate >= THRESHOLD_RATE: |
| | | # 成交的比例 |
| | |
| | | else: |
| | | return BUY_MODE_NONE, f"被动卖成交比例未达到:剩余涨停总卖额-{selling_num * price},原涨停总卖-{total_sell},已成交额-{__deal_active_buy_total_money[code]},成交比例-{rate}/{THRESHOLD_RATE}" |
| | | else: |
| | | # 根据量比与大单成交数量判断是否可扫 |
| | | volume_rate = code_volumn_manager.get_volume_rate(code, with_info=False) |
| | | if volume_rate is None: |
| | | volume_rate = 0.5 |
| | | # 根据大单判断是否可以扫 |
| | | big_order_deal_result = __is_big_order_deal_enough(code, volume_rate) |
| | | if not big_order_deal_result[0]: |
| | | return BUY_MODE_NONE, big_order_deal_result[1] |
| | | return __get_deal_rate_by(code, huaxin_timestamp) |
| | | |
| | | |
| | | def __is_big_order_deal_enough(code, volume_rate): |
| | | """ |
| | | 大单成交是否足够 |
| | | @param code: |
| | | @param volume_rate: |
| | | @return: |
| | | """ |
| | | current_big_order_deal_count = EveryLimitupBigDealOrderManager.get_big_buy_deal_order_count(code) |
| | | if volume_rate >= 0.5: |
| | | # 当换手量>50%时,则,不需要每次扫入时需要≥2笔大单,而是累计需要≥2笔大单即可 |
| | | deal_big_order_count = BigOrderDealManager().get_total_buy_count(code) |
| | | if deal_big_order_count >= 2: |
| | | return True, f"量比-{volume_rate}, 总大单成交数量({deal_big_order_count})>=2" |
| | | else: |
| | | return False, f"量比-{volume_rate}, 总大单成交数量({deal_big_order_count})<2" |
| | | else: |
| | | if current_big_order_deal_count >= 2: |
| | | return True, f"量比-{volume_rate}, 本次大单成交数量({current_big_order_deal_count})>=2" |
| | | else: |
| | | return False, f"量比-{volume_rate}, 本次大单成交数量({current_big_order_deal_count})<2" |