Administrator
2024-08-15 b9404847333a972b55766924ad3aa41aac5fd4f4
utils/buy_strategy_util.py
@@ -1,9 +1,15 @@
"""
买入策略帮助类
"""
import time
from code_attribute import gpcode_manager
from l2 import l2_data_util, l2_data_source_util
from utils import tool
from l2 import l2_data_util, l2_data_source_util, transaction_progress
from l2.l2_data_util import L2DataUtil
from l2.l2_transaction_data_manager import HuaXinSellOrderStatisticManager
from settings.trade_setting import MarketSituationManager, TradeBlockBuyModeManager
from trade import trade_data_manager
from utils import tool, buy_condition_util, global_util
def is_has_small_batch_cancel(code, start_index, end_index):
@@ -49,6 +55,14 @@
def is_cancel_rate_reieved(code, threshhold_rate, start_index, end_index):
    """
    撤单比例是否达到某一个阈值
    @param code:
    @param threshhold_rate:
    @param start_index:
    @param end_index:
    @return:
    """
    # 统计总共的涨停买
    limit_up_price = gpcode_manager.get_limit_up_price_as_num(code)
    min_num = int(round(5000 / limit_up_price))
@@ -80,6 +94,43 @@
        return False
    if round(cancel_count / buy_count, 2) > threshhold_rate:
        return True
    return False
def is_far_away_from_trade_index(code, trade_index, buy1_money):
    """
    是否距离成交进度位太远
    @param code:
    @param trade_index:
    @param buy1_money:
    @return:
    """
    if buy1_money < 1e7:
        # 买1大于1千万才能计算
        return False
    limit_up_price = gpcode_manager.get_limit_up_price_as_num(code)
    min_num = int(round(5000 / limit_up_price))
    threshhold_num = int(round(buy1_money * 0.5 / 100 / limit_up_price))
    total_datas = l2_data_util.local_today_datas.get(code)
    end_index = total_datas[-1]["index"]
    total_num = 0
    canceled_buyno_map = l2_data_util.local_today_canceled_buyno_map.get(
        code)
    for i in range(trade_index, end_index + 1):
        data = total_datas[i]
        val = data["val"]
        if not L2DataUtil.is_limit_up_price_buy(val):
            continue
        if val["num"] < min_num:
            continue
        left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(
            code,
            i,
            total_datas, canceled_buyno_map)
        if left_count > 0:
            total_num += val["num"]
            if total_num > threshhold_num:
                return True
    return False
@@ -117,3 +168,113 @@
    if total_count > 10 or total_big_count < 1:
        return False, f"未成交数量-{total_count},大单数量-{total_big_count}"
    return True, ""
def is_quantization(code, start_index, end_index):
    """
    是否是量化单
    @param code:
    @param satrt_index:
    @param end_index:
    @return:(是否是量化, 下次可以下单时间)
    """
    THRESHOLD_BUY_COUNT = 20
    if end_index - start_index + 1 < THRESHOLD_BUY_COUNT:
        # 总数小于阈值
        return False, None
    total_datas = l2_data_util.local_today_datas.get(code)
    limit_up_price = gpcode_manager.get_limit_up_price_as_num(code)
    buy_count = 0
    min_num = int(5000 / limit_up_price)
    trade_index, is_default = transaction_progress.TradeBuyQueue().get_traded_index(code)
    if trade_index is None:
        trade_index = 0
    # 获取成交进度位
    for i in range(start_index, end_index + 1):
        val = total_datas[i]["val"]
        if not L2DataUtil.is_limit_up_price_buy(val):
            continue
        if val["num"] < min_num:
            continue
        buy_count += 1
        if buy_count > THRESHOLD_BUY_COUNT:
            break
    if buy_count > THRESHOLD_BUY_COUNT:
        # 判断是否为量化
        time_as_ms = tool.trade_time_sub_with_ms(
            L2DataUtil.get_time_with_ms(total_datas[end_index]["val"]),
            L2DataUtil.get_time_with_ms(total_datas[start_index]["val"]))
        if time_as_ms <= 10 if tool.is_sz_code(code) else 100:
            # 深证10ms内,上证100ms内就判定为量化
            HuaXinSellOrderStatisticManager.clear_latest_deal_volume(code)
            next_buy_time = time.time() + buy_condition_util.get_cancel_and_buy_space_time(
                code) / 1000
            # 如果是首次下单,增加一次下单次数
            place_order_count = trade_data_manager.PlaceOrderCountManager().get_place_order_count(code)
            if place_order_count == 0:
                trade_data_manager.PlaceOrderCountManager().place_order(code)
            return True, next_buy_time, f"执行位批次数据量({buy_count})大于{THRESHOLD_BUY_COUNT}  {start_index}-{end_index}"
        return False, None
    else:
        return False, None
def is_block_can_buy(code, can_buy_result):
    """
    板块是否可买
    @param code:
    @param can_buy_result:
    @return:
    """
    now_timestamp = int(tool.get_now_time_str().replace(":", ""))
    # 判断板块
    # (可以买的板块列表, 是否是独苗, 消息简介,可买的强势主线, 板块关键词)
    if can_buy_result is None:
        return False, True, "尚未获取到板块信息"
    # 是否是强势30分钟
    is_in_strong_time_30 = now_timestamp <= int("100000")
    # 获取市场行情
    situation = MarketSituationManager().get_situation_cache()
    zylt_threshold_as_yi = buy_condition_util.get_zyltgb_threshold(situation)
    zyltgb_as_yi = round(global_util.zyltgb_map.get(code) / 100000000, 2)
    if zyltgb_as_yi < zylt_threshold_as_yi[0]:
        return False, True, f"{zylt_threshold_as_yi[0]}亿以下的都不买({zyltgb_as_yi})"
    # 测试时可取消注释
    # if 1 > 0:
    #     return True, False, "买所有"
    if zyltgb_as_yi >= zylt_threshold_as_yi[1]:
        return False, True, f"{zylt_threshold_as_yi[1]}亿以上的都不买({zyltgb_as_yi})"
    msg_list = []
    if is_in_strong_time_30:
        msg_list.append("强势30分钟")
        # 独苗
        if not can_buy_result[0] and can_buy_result[1]:
            msg_list.append("独苗")
            return True, False, "强势30分钟,独苗"
        elif not can_buy_result[0]:
            return False, True, f"强势30分钟,非独苗不满足身位:{can_buy_result[2]}"
        else:
            msg_list.append("非独苗")
            # 后排,满足自由流通市值需要下单
            return True, False, can_buy_result[2]
    else:
        place_order_count = trade_data_manager.PlaceOrderCountManager().get_place_order_count(code)
        if place_order_count > 0:
            return True, False, "之前下过单"
        if not can_buy_result[0]:
            # 没有板块
            if can_buy_result[1]:
                # 是独苗
                if not TradeBlockBuyModeManager().can_buy_unique_block():
                    # 不能买独苗
                    return False, True, f"非强势30分钟,独苗,不满足身位:{can_buy_result[2]}"
            else:
                # 非独苗,没有可以买入的板块
                return False, True, f"非强势30分钟,非独苗,不满足身位:{can_buy_result[2]}"
        return True, False, can_buy_result[2]