Administrator
7 天以前 365491c1fcf523994035e4bd28d8b5872dd6ec98
api/outside_api_command_callback.py
@@ -15,7 +15,7 @@
import inited_data
import outside_api_command_manager
from cancel_strategy.s_l_h_cancel_strategy import SCancelBigNumComputer, LCancelRateManager, \
    CancelRateHumanSettingManager
    CancelRateHumanSettingManager, LCancelBigNumComputer, LDownCancelWatchIndexStatisticManager
from code_attribute import gpcode_manager, code_volumn_manager, zyltgb_util, code_nature_analyse
from code_attribute.code_data_util import ZYLTGBUtil
from code_attribute.code_l1_data_manager import L1DataManager
@@ -60,7 +60,8 @@
from trade.sell import sell_manager
from trade.sell.sell_rule_manager import TradeRuleManager, SellRule
from trade.trade_data_manager import RadicalBuyDealCodesManager
from trade.trade_manager import TradeTargetCodeModeManager, AutoCancelSellModeManager
from trade.trade_manager import TradeTargetCodeModeManager, AutoCancelSellModeManager, CodesContinueBuyMoneyManager, \
    CodesTradeStateManager
from settings.trade_setting import MarketSituationManager, TradeBlockBuyModeManager
from utils import socket_util, data_export_util, tool, huaxin_util, output_util, global_util, init_data_util
from servers import server_util
@@ -886,12 +887,16 @@
                    [huaxin_util.TORA_TSTP_OST_Accepted, huaxin_util.TORA_TSTP_OST_PartTraded])
                fdatas = []
                if current_delegates:
                    codes_set = set()
                    for c in current_delegates:
                        try:
                            if int(c["direction"]) != huaxin_util.TORA_TSTP_D_Buy:
                                continue
                            code = c["securityID"]
                            if code in codes_set:
                                continue
                            orderSysID = c.get("orderSysID")
                            codes_set.add(code)
                            code_name = gpcode_manager.get_code_name(code)
                            # 获取下单位置信息
                            order_begin_pos = TradePointManager().get_buy_compute_start_data_cache(code)
@@ -908,22 +913,7 @@
                            place_order_index = SCancelBigNumComputer().get_real_place_order_index_cache(code)
                            if place_order_index is None:
                                place_order_index = 0
                            # 计算信号位置到真实下单位置的总买(不管是否已撤)
                            total_nums = 0
                            for i in range(order_begin_pos.buy_single_index, place_order_index):
                                data = total_datas[i]
                                val = data["val"]
                                if not L2DataUtil.is_limit_up_price_buy(val):
                                    continue
                                total_nums += val["num"]
                            # 计算已成交/已撤单的数量
                            deal_or_cancel_num = 0
                            for i in range(order_begin_pos.buy_single_index, trade_index + 1):
                                data = total_datas[i]
                                val = data["val"]
                                if not L2DataUtil.is_limit_up_price_buy(val):
                                    continue
                                deal_or_cancel_num += val["num"]
                            # 获取剩下的笔数
                            total_left_count = 0
                            total_left_num = 0
@@ -948,69 +938,10 @@
                            if dealing_info:
                                if str(total_datas[trade_index]["val"]["orderNo"]) == str(dealing_info[0]):
                                    total_left_num += (total_datas[trade_index]["val"]["num"] - dealing_info[1] // 100)
                            limit_up_price = gpcode_manager.get_limit_up_price(code)
                            limit_up_price = gpcode_manager.get_limit_up_price_as_num(code)
                            buy1_money = Buy1PriceManager().get_latest_buy1_money(code)
                            if buy1_money is None:
                                buy1_money = 1
                            # 获取已经成交的大单数量
                            total_big_num = 0
                            total_big_count = 0
                            is_ge_code = tool.is_ge_code(code)
                            for i in range(0, trade_index):
                                val = total_datas[i]["val"]
                                if not L2DataUtil.is_limit_up_price_buy(val):
                                    continue
                                # 是不是大单
                                if not l2_data_util_old.is_big_money(val, is_ge_code):
                                    continue
                                canceled_data = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_canceled_data_v2(
                                    code,
                                    i,
                                    total_datas,
                                    l2_data_util.local_today_canceled_buyno_map.get(
                                        code))
                                if not canceled_data:
                                    total_big_count += 1
                                else:
                                    total_big_num -= canceled_data["val"]["num"]
                                total_big_num += val["num"]
                            not_deal_total_big_num_pre = 0
                            not_deal_total_big_count_pre = 0
                            not_deal_total_big_num_after = 0
                            not_deal_total_big_count_after = 0
                            is_ge_code = tool.is_ge_code(code)
                            for i in range(trade_index, total_datas[-1]["index"] + 1):
                                val = total_datas[i]["val"]
                                if not L2DataUtil.is_limit_up_price_buy(val):
                                    continue
                                # 是不是大单
                                if not l2_data_util_old.is_big_money(val, is_ge_code):
                                    continue
                                canceled_data = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_canceled_data_v2(
                                    code,
                                    i,
                                    total_datas,
                                    l2_data_util.local_today_canceled_buyno_map.get(
                                        code))
                                if not canceled_data:
                                    if i < place_order_index:
                                        not_deal_total_big_count_pre += 1
                                    else:
                                        not_deal_total_big_count_after += 1
                                else:
                                    if i < place_order_index:
                                        not_deal_total_big_num_pre -= canceled_data["val"]["num"]
                                    else:
                                        not_deal_total_big_num_after -= canceled_data["val"]["num"]
                                if i < place_order_index:
                                    not_deal_total_big_num_pre += val["num"]
                                else:
                                    not_deal_total_big_num_after += val["num"]
                            real_place_order_after_count = 0
                            real_place_order_after_num = 0
                            is_ge_code = tool.is_ge_code(code)
@@ -1033,89 +964,26 @@
                                    real_place_order_after_count += 1
                                    real_place_order_after_num += val["num"]
                            # 获取当日的量比
                            volume_rate = code_volumn_manager.CodeVolumeManager().get_volume_rate(code)
                            # 是否需要注意
                            need_pay_attention = (total_left_count <= 10 or total_left_num * float(
                                limit_up_price) * 100 < 1500 * 10000) and (
                                                         real_place_order_after_count <= 10 or real_place_order_after_num * float(
                                                     limit_up_price) * 100 < 1500 * 10000)
                            # 统计真实下单位是否距离大单位置过近
                            is_near_big_order = False
                            try:
                                count = 0
                                for i in range(place_order_index - 1, -1, -1):
                                    data = total_datas[i]
                                    val = data["val"]
                                    if not L2DataUtil.is_limit_up_price_buy(val):
                                        continue
                                    money = val["num"] * float(val["price"])
                                    if money < 50 * 100:
                                        continue
                                    left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(
                                        code,
                                        i,
                                        total_datas,
                                        l2_data_util.local_today_canceled_buyno_map.get(
                                            code))
                                    if left_count <= 0:
                                        continue
                                    if money >= 299 * 100:
                                        if count < 1:
                                            is_near_big_order = True
                                    else:
                                        count += 1
                                        if count >= 1:
                                            break
                            except:
                                pass
                                                         real_place_order_after_count <= 10 or real_place_order_after_num * limit_up_price * 100 < 1500 * 10000)
                            # L撤比例
                            l_down_cancel_rate, must_buy, cancel_rate_info = LCancelRateManager.get_cancel_rate(code,
                                                                                                                buy_mode=OrderBeginPosInfo.MODE_RADICAL)
                            # 在挂的距离成交进度位金额/(远近期参考量-单当日实时成交量)*100%
                            expire_rate = "未知"
                            try:
                                referer_volume = code_volumn_manager.CodeVolumeManager().get_radical_buy_refer_volume(
                                    code, limit_up_price)
                                today_volumn = code_volumn_manager.CodeVolumeManager().get_today_volumn_cache(code)
                                if referer_volume == today_volumn:
                                    expire_rate = "100%"
                                else:
                                    expire_rate = f"{100 - round(100 * total_left_num * 100 / (referer_volume - today_volumn), 2)}%"
                            except Exception as e:
                                logger_debug.exception(e)
                            fdata = {"id": orderSysID, "code_info": (code, code_name), "total_num": total_nums,
                                     "finish_num": deal_or_cancel_num,
                            fdata = {"id": orderSysID, "code_info": (code, code_name),
                                     "buy1_money": output_util.money_desc(buy1_money),
                                     "big_num_count": total_big_count,
                                     "big_num_money": output_util.money_desc(
                                         total_big_num * float(limit_up_price) * 100),
                                     "not_deal_big_num_count": (
                                         not_deal_total_big_count_pre, not_deal_total_big_count_after),
                                     "not_deal_big_num_money": (output_util.money_desc(
                                         not_deal_total_big_num_pre * float(limit_up_price) * 100),
                                                                output_util.money_desc(
                                                                    not_deal_total_big_num_after * float(
                                                                        limit_up_price) * 100)),
                                     "left_count": total_left_count,
                                     "volume_rate": volume_rate,
                                     "left_money": output_util.money_desc(total_left_num * float(limit_up_price) * 100),
                                     "pay_attention": need_pay_attention,
                                     "trade_progress_percent": round(
                                         total_left_num * float(limit_up_price) * 100 * 100 / buy1_money, 2),  # 成交进度比例
                                     "limit_up_price": gpcode_manager.get_limit_up_price_as_num(code),
                                     "is_near_big_order": is_near_big_order,
                                     "limit_up_price": limit_up_price,
                                     "block": '',
                                     "trade_queue": [],
                                     "l_down_cancel_rate": l_down_cancel_rate,
                                     "l_down_cancel_rate_info": cancel_rate_info,
                                     "expire_rate": expire_rate
                                     }
                            limit_up_data = kpl_data_manager.KPLLimitUpDataRecordManager.record_code_dict.get(code)
                            # 获取当前板块
@@ -1152,19 +1020,179 @@
                                    fdata['zyltgb'] = output_util.money_desc(zyltgb)
                            except:
                                pass
                            # L后囊括快照
                            try:
                                if order_begin_pos:
                                    fdata['mode'] = order_begin_pos.mode
                                else:
                                    fdata['mode'] = -1
                            except:
                                pass
                                current_info = LCancelBigNumComputer().statistic_l_down_watch_indexes_info(code)
                                fdata['l_down_watch_indexes_info'] = {}
                                if current_info:
                                    fdata['l_down_watch_indexes_info']['current'] = current_info
                            except Exception as e:
                                logger_debug.exception(e)
                            fdatas.append(fdata)
                        except Exception as e:
                            logger_debug.exception(e)
                result = {"code": 0, "data": {"account_available_money": account_available_money, "delegates": fdatas}}
                self.send_response(result, client_id, request_id)
            elif ctype == "get_delegated_buy_code_infos_v2":
                account_available_money = trade_data_manager.AccountMoneyManager().get_available_money_cache()
                # 获取委托中的代码
                current_delegates = huaxin_trade_record_manager.DelegateRecordManager().list_current_delegates()
                fdatas = []
                if current_delegates:
                    codes_set = set()
                    for c in current_delegates:
                        _start_time = time.time()
                        try:
                            if int(c["direction"]) != huaxin_util.TORA_TSTP_D_Buy:
                                continue
                            code = c["securityID"]
                            if code in codes_set:
                                continue
                            orderSysID = c.get("orderSysID")
                            codes_set.add(code)
                            code_name = gpcode_manager.get_code_name(code)
                            # 获取下单位置信息
                            order_begin_pos = TradePointManager().get_buy_compute_start_data_cache(code)
                            if order_begin_pos is None or order_begin_pos.buy_single_index is None:
                                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
                            # 下单位置
                            place_order_index = SCancelBigNumComputer().get_real_place_order_index_cache(code)
                            if place_order_index is None:
                                place_order_index = 0
                            # 获取剩下的笔数
                            total_left_count = 0
                            total_left_num = 0
                            for i in range(trade_index + 1, place_order_index):
                                data = total_datas[i]
                                val = data["val"]
                                if not L2DataUtil.is_limit_up_price_buy(val):
                                    continue
                                if val["num"] * float(val["price"]) < 5000:
                                    continue
                                left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(
                                    code,
                                    i,
                                    total_datas,
                                    l2_data_util.local_today_canceled_buyno_map.get(
                                        code))
                                if left_count > 0:
                                    total_left_count += left_count
                                    total_left_num += val["num"] * left_count
                            # 获取正在成交
                            dealing_info = HuaXinBuyOrderManager.get_dealing_order_info(code)
                            if dealing_info:
                                if str(total_datas[trade_index]["val"]["orderNo"]) == str(dealing_info[0]):
                                    total_left_num += (total_datas[trade_index]["val"]["num"] - dealing_info[1] // 100)
                            limit_up_price = gpcode_manager.get_limit_up_price_as_num(code)
                            buy1_money = Buy1PriceManager().get_latest_buy1_money(code)
                            if buy1_money is None:
                                buy1_money = 1
                            real_place_order_after_count = 0
                            real_place_order_after_num = 0
                            is_ge_code = tool.is_ge_code(code)
                            # 统计真实下单位置后面未撤的金额
                            for i in range(place_order_index, total_datas[-1]["index"]):
                                val = total_datas[i]["val"]
                                if not L2DataUtil.is_limit_up_price_buy(val):
                                    continue
                                # 是不是大单
                                if not l2_data_util_old.is_big_money(val, is_ge_code):
                                    continue
                                canceled_data = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_canceled_data_v2(
                                    code,
                                    i,
                                    total_datas,
                                    l2_data_util.local_today_canceled_buyno_map.get(
                                        code))
                                if not canceled_data:
                                    real_place_order_after_count += 1
                                    real_place_order_after_num += val["num"]
                            # 是否需要注意
                            need_pay_attention = (total_left_count <= 10 or total_left_num * float(
                                limit_up_price) * 100 < 1500 * 10000) and (
                                                         real_place_order_after_count <= 10 or real_place_order_after_num * limit_up_price * 100 < 1500 * 10000)
                            # L撤比例
                            l_down_cancel_rate, must_buy, cancel_rate_info = LCancelRateManager.get_cancel_rate(code,
                                                                                                                buy_mode=OrderBeginPosInfo.MODE_RADICAL)
                            fdata = {"id": orderSysID, "code_info": (code, code_name),
                                     "buy1_money": output_util.money_desc(buy1_money),
                                     "left_count": total_left_count,
                                     "left_money": output_util.money_desc(total_left_num * float(limit_up_price) * 100),
                                     "pay_attention": need_pay_attention,
                                     "trade_progress_percent": round(
                                         total_left_num * float(limit_up_price) * 100 * 100 / buy1_money, 2),  # 成交进度比例
                                     "limit_up_price": limit_up_price,
                                     "block": '',
                                     "trade_queue": [],
                                     "l_down_cancel_rate": l_down_cancel_rate,
                                     "l_down_cancel_rate_info": cancel_rate_info,
                                     }
                            limit_up_data = kpl_data_manager.KPLLimitUpDataRecordManager.record_code_dict.get(code)
                            # 获取当前板块
                            try:
                                limit_up_sequences = CodeLimitUpSequenceManager.get_current_limit_up_sequence(code)
                                if limit_up_sequences:
                                    buy_blocks = RadicalBuyDealCodesManager().get_code_blocks(code)
                                    blocks_info = []
                                    for limit_up_sequence in limit_up_sequences:
                                        # 获取代码下单的板块
                                        if buy_blocks and limit_up_sequence[0] not in buy_blocks:
                                            continue
                                        blocks_info.append(
                                            f"{limit_up_sequence[0]}-{limit_up_sequence[1]}({limit_up_sequence[2]}&{limit_up_sequence[2] - limit_up_sequence[3]})")
                                    if buy_blocks:
                                        fdata['block'] = "/".join(blocks_info)
                            except:
                                pass
                            # 获取涨停时间
                            if limit_up_data:
                                fdata['limit_up_time'] = tool.to_time_str(limit_up_data[2])
                                # 获取委托队列
                            try:
                                real_place_order_index = SCancelBigNumComputer().get_real_place_order_index_cache(code)
                                if real_place_order_index is not None:
                                    trade_queue = l2_output_util.get_trade_queue_at_near_place_order(code,
                                                                                                     real_place_order_index,
                                                                                                     9)
                                    fdata['trade_queue'] = trade_queue
                                # 自由流通股本
                                zyltgb = global_util.zyltgb_map.get(code)
                                if zyltgb is not None:
                                    fdata['zyltgb'] = output_util.money_desc(zyltgb)
                            except:
                                pass
                            # L后囊括快照
                            try:
                                __start_time = time.time()
                                current_info = LCancelBigNumComputer().statistic_l_down_watch_indexes_info(code)
                                fdata['l_down_watch_indexes_info'] = {}
                                if current_info:
                                    fdata['l_down_watch_indexes_info']['current'] = current_info
                                use_time = time.time() - __start_time
                                if use_time > 0.05:
                                    async_log_util.info(logger_debug, f"统计实撤用时:{code} - {use_time}")
                            except Exception as e:
                                logger_debug.exception(e)
                            fdatas.append(fdata)
                        except Exception as e:
                            logger_debug.exception(e)
                        finally:
                            use_time = time.time() - _start_time
                            if use_time > 0.1:
                                async_log_util.info(logger_debug, f"委托信息统计耗时:{c['securityID']}-{use_time}")
                result = {"code": 0, "data": {"account_available_money": account_available_money, "delegates": fdatas}}
                self.send_response(result, client_id, request_id)
            elif ctype == "set_real_place_order_index":
@@ -1503,11 +1531,15 @@
                                       client_id,
                                       request_id)
                    return
                TotalDealBigOrderThresholdMoneyManager().set_money(code, int(money), trade_manager.CodesTradeStateManager().get_trade_state_cache(code))
                TotalDealBigOrderThresholdMoneyManager().set_money(code, int(money),
                                                                   trade_manager.CodesTradeStateManager().get_trade_state_cache(
                                                                       code))
                # 如果是加红状态,且大单不够就需要移红
                if gpcode_manager.MustBuyCodesManager().is_in_cache(code):
                    deal_big_order_info = radical_buy_data_manager.get_total_deal_big_order_info(code, gpcode_manager.get_limit_up_price_as_num(code))
                    deal_big_order_info = radical_buy_data_manager.get_total_deal_big_order_info(code,
                                                                                                 gpcode_manager.get_limit_up_price_as_num(
                                                                                                     code))
                    if deal_big_order_info[0] > 0:
                        gpcode_manager.MustBuyCodesManager().remove_code(code)
                        trade_record_log_util.add_common_msg(code, "移红", f"大单阈值修改({money})")
@@ -1518,17 +1550,73 @@
                # 设置L后撤单比例
                code = data.get("code")
                rate = data.get("rate")
                if rate < 0 or rate > 1:
                if rate < 0 or rate > 2:
                    self.send_response({"code": 1, "msg": "比例范围不在0-1之间"},
                                       client_id,
                                       request_id)
                    return
                rate = round(rate, 2)
                old_rate = LCancelRateManager().get_cancel_rate(code)[0]
                CancelRateHumanSettingManager().set_l_down(code, rate)
                # L后重新囊括
                # if rate < old_rate:
                # 改小才能重新囊括
                trade_record_log_util.add_common_msg(code, "L后重新囊括", msg=f"修改撤单比例: {old_rate}->{rate}")
                LCancelBigNumComputer().re_compute_l_down_watch_indexes(code, is_force=True)
                self.send_response({"code": 0, "data": {}},
                                   client_id,
                                   request_id)
            elif ctype == "get_continue_buy_info":
                # 设置L后撤单比例
                code = data.get("code")
                money = CodesContinueBuyMoneyManager().get_continue_buy_money(code)
                if money is None:
                    money = 0
                self.send_response({"code": 0, "data": {"money": money, "money_list": constant.AVAILABLE_BUY_MONEYS}},
                                   client_id,
                                   request_id)
            elif ctype == "set_continue_buy_money":
                # 设置L后撤单比例
                code = data.get("code")
                money = data.get("money")
                if money <= 0:
                    # 表示移除续买金额
                    CodesContinueBuyMoneyManager().remove_continue_buy_money(code)
                    self.send_response({"code": 0, "data": {}},
                                       client_id,
                                       request_id)
                    return
                if money not in constant.AVAILABLE_BUY_MONEYS:
                    self.send_response({"code": 1, "msg": f"金额({money})没在{constant.AVAILABLE_BUY_MONEYS}中"},
                                       client_id,
                                       request_id)
                    return
                CodesContinueBuyMoneyManager().set_continue_buy_money(code, money)
                l2_trade_util.remove_from_forbidden_trade_codes(code)
                CodesTradeStateManager().set_trade_state(code, trade_constant.TRADE_STATE_NOT_TRADE)
                self.send_response({"code": 0, "data": {}},
                                   client_id,
                                   request_id)
            elif ctype == "set_code_today_ex_rights":
                # 代码今日除权,需要更新K线
                code = data.get("code")
                volumes_data = history_k_data_manager.update_history_k_bars_of_code(code, force=True, juejin=True)
                if not volumes_data:
                    result = {"code": 1, "msg": "拉取K线失败"}
                else:
                    # 更新昨日收盘价数据
                    CodePrePriceManager.set_price_pre(code, volumes_data[0]['close'], force=True)
                    gpcode_manager.clear_limit_up_price_cache(code)
                    limit_up_price = gpcode_manager.get_limit_up_price_as_num(code)
                    # 更新K线特征数据
                    k_format = code_nature_analyse.get_k_format(code, limit_up_price, volumes_data)
                    code_nature_analyse.CodeNatureRecordManager().save_k_format(code, k_format)
                    result = {"code": 0, "msg": "设置成功"}
                self.send_response(result,
                                   client_id,
                                   request_id)
        except Exception as e:
            logging.exception(e)
            logger_debug.exception(e)