Administrator
2023-03-30 8ef576b9a1809dd52dacaafe960db456b09e9e0b
看盘界面调整
12个文件已修改
336 ■■■■ 已修改文件
alert_util.py 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
code_nature_analyse.py 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
constant.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
gui.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/code_price_manager.py 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_data_manager_new.py 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2_trade_test.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
log.py 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
output/code_info_output.py 115 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server.py 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/hot_block_data_process.py 61 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/first_code_score_manager.py 70 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
alert_util.py
@@ -9,7 +9,6 @@
def alarm():
    return
    if not tool.is_alert_time() or constant.TEST:
        return
    # TODO 暂时关闭报警
code_nature_analyse.py
@@ -63,6 +63,7 @@
    p4 = __is_near_new_top(limit_up_price, record_datas)
    p5 = __is_n_model(record_datas)
    p6 = __is_v_model(record_datas)
    p8 = __get_big_volumn_info(record_datas)
    # # N字型包含了N字型
    # if p5:
@@ -70,15 +71,18 @@
    p7 = (p1[0] or p2[0] or p3[0] or p4[0] or p5[0] or p6[0], '')
    return p1, p2, p3, p4, p5, p6, p7
    return p1, p2, p3, p4, p5, p6, p7, p8
# 是否具有K线形态
def is_has_k_format(limit_up_price, record_datas):
    is_too_high, is_new_top, is_lowest, is_near_new_top, is_n, is_v, has_format = get_k_format(float(limit_up_price), record_datas)
    is_too_high, is_new_top, is_lowest, is_near_new_top, is_n, is_v, has_format, volume_info = get_k_format(
        float(limit_up_price),
        record_datas)
    if not has_format:
        return False, "不满足K线形态"
    return True, "有形态"
# 获取股性
# 返回(是否涨停,首板溢价率是否大于0.6)
@@ -200,8 +204,8 @@
            item = datas[i]
            print(item)
            limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(item["pre_close"]))
            if abs(limit_up_price - item["close"]) < 0.001 and abs(
                    limit_up_price - datas[i - 1]["close"]) >= 0.001:
            if abs(limit_up_price - item["high"]) < 0.001 and abs(
                    limit_up_price - datas[i - 1]["high"]) >= 0.001:
                # 涨停,前一天非涨停
                max_price = item["close"]
            elif max_price > 0:
@@ -236,6 +240,21 @@
    return False, ''
# 是否天量大阳
def __get_big_volumn_info(datas):
    datas = copy.deepcopy(datas)
    datas.sort(key=lambda x: x["bob"])
    datas = datas[-30:]
    max_volume = 0
    total_volume = 0
    for data in datas:
        if max_volume < data["volume"]:
            max_volume = data["volume"]
        total_volume += data["volume"]
    average_volume = total_volume // len(datas)
    return max_volume, average_volume
# 首板涨停溢价率
def get_limit_up_premium_rate(datas):
    datas = copy.deepcopy(datas)
constant.py
@@ -1,7 +1,7 @@
# 是否为测试
TEST = False
# 是否允许交易
TRADE_ENABLE = False
TRADE_ENABLE = True
# 水下捞累计连续水下时间最小值
UNDER_WATER_PRICE_TIME_AS_SECONDS = 1200
# 大单金额(单位为百)
gui.py
@@ -401,7 +401,7 @@
            # 获取有效的L2客户端数量
            l2_client_count = client_manager.getValidL2Clients()
            if len(l2_client_count) < 2:
            if len(l2_client_count) < 6:
                normal = False
            # 状态有问题,需要报警
l2/code_price_manager.py
@@ -52,6 +52,15 @@
            return True
        return False
    # 获取涨停信息
    # 返回涨停时间与炸板时间
    @classmethod
    def get_limit_up_info(cls,code):
        old_limit_up_time, old_open_limit_up_time = cls.__get_buy1_price_info(code)
        return old_limit_up_time, old_open_limit_up_time
if __name__ == "__main__":
    code = "000333"
l2/l2_data_manager_new.py
@@ -164,6 +164,16 @@
    __l2PlaceOrderParamsManagerDict = {}
    __last_buy_single_dict = {}
    # 获取代码评分
    @classmethod
    def get_code_scores(cls):
        score_dict = {}
        for code in cls.__l2PlaceOrderParamsManagerDict:
            score = cls.__l2PlaceOrderParamsManagerDict[code].score
            score_dict[code] = score
        return score_dict
    @classmethod
    # 数据处理入口
    # datas: 本次截图数据
@@ -242,7 +252,6 @@
                                                                                                  volume_rate,
                                                                                                  volume_rate_index,
                                                                                                  score)
            l2_log.debug(code, "量比:{},量索引:{}", volume_rate, volume_rate_index)
            cls.volume_rate_info[code] = (volume_rate, volume_rate_index)
            latest_time = add_datas[len(add_datas) - 1]["val"]["time"]
@@ -755,8 +764,8 @@
                new_get_single = True
                num = 0
                count = 0
                l2_log.debug(code, "获取到买入信号起始点:{} ,计算范围:{}-{} ,数据:{}", buy_single_index, compute_start_index,
                             compute_end_index, total_datas[buy_single_index])
                l2_log.debug(code, "获取到买入信号起始点:{} ,计算范围:{}-{} ,量比:{},数据:{}", buy_single_index, compute_start_index,
                             compute_end_index, cls.volume_rate_info[code], total_datas[buy_single_index])
                # 如果是今天第一次有下单开始信号,需要设置大单起始点
                cls.l2BigNumForMProcessor.set_begin_pos(code, buy_single_index)
@@ -804,7 +813,7 @@
        if compute_index is not None:
            l2_log.debug(code, "获取到买入执行位置:{} m值:{} 纯买手数:{} 纯买单数:{} 数据:{} ,量比:{} ", compute_index, threshold_money,
                         buy_nums,
                         buy_count, total_datas[compute_index], cls.volume_rate_info[code][0])
                         buy_count, total_datas[compute_index], cls.volume_rate_info[code])
            f1 = dask.delayed(cls.__save_order_begin_data)(code, buy_single_index, compute_index, compute_index,
                                                           buy_nums, buy_count, max_num_set_new,
l2_trade_test.py
@@ -87,7 +87,7 @@
    @unittest.skip("跳过此单元测试")
    def test_trade(self):
        code = "603801"
        code = "002524"
        clear_trade_data(code)
        l2.l2_data_util.load_l2_data(code)
        total_datas = deepcopy(l2.l2_data_util.local_today_datas[code])
log.py
@@ -378,14 +378,32 @@
        if not os.path.exists(dir_path):
            os.makedirs(dir_path)
        LogUtil.extract_log_from_key(key, f"D:/logs/gp/l2/{log_name}.{date}.log",
                                     target_path )
                                     target_path)
# 加载买入得分记录
def load_buy_score_recod(code):
    path = f"D:/logs/gp/score/buy_score.{tool.get_now_date_str()}.log"
    fdatas = []
    with open(path, 'r', encoding="utf-8") as f:
        lines = f.readlines()
        for line in lines:
            data_index = line.find("{}:".format(code))
            if data_index > 0:
                data_index = line.find(":", data_index)
                time_str = line[10:19]
                line = line[data_index + 1:]
                fdatas.append((time_str, eval(line)))
    return fdatas
if __name__ == '__main__':
    load_buy_score_recod("002213")
    # logger_l2_h_cancel.info("test")
    # logger_l2_process_time.info("test123")
    codes = ["603083"]
    for code in codes:
        export_logs(code)
    # logger_buy_score.info("测试")
    # codes = ["603083"]
    # for code in codes:
    #     export_logs(code)
    # parse_l2_data()
output/code_info_output.py
@@ -12,17 +12,21 @@
import gpcode_manager
import juejin
import limit_up_time_manager
import log
import tool
from l2 import l2_data_manager, l2_data_util, transaction_progress
from l2 import l2_data_manager, l2_data_util, transaction_progress, l2_data_manager_new, code_price_manager
from third_data import hot_block_data_process
from trade import first_code_score_manager, l2_trade_factor
from trade.l2_trade_factor import L2TradeFactorUtil
import trade.deal_big_money_manager
def __format_data(code_info, score_info, buy_params_info, xgb_code_info, xgb_infos):
def __format_data(code_info, score_info, buy_params_info, xgb_code_info, xgb_infos, codes_score, trade_info):
    html = ""
    html += f"<h2>{code_info[1]} {code_info[0]}</h2><br>"
    if score_info:
        html += "<b>-----买前评分-------</b><br>"
        score_types = ["换手量能", "竞价强度", "资金力度", "日线形态", "历史股性", "板块热度", "上板时间", "市值大小", "股价大小"]
@@ -30,14 +34,14 @@
        for i in range(0, len(score_info[1])):
            html += f"<tr><td>{score_types[i]}</td><td>{score_info[1][i]}</td><td>{score_info[2][i]}</td></tr>"
        html += f"<tr><td><b>评分求和:</td><td>{score_info[0]}</b></td><td></td></tr>"
        html += f"</table>"
        html += f"</table><br>"
    if buy_params_info:
        html += "<b><br>-----交易参数-------<br></b><table>"
        titles = ["买入意愿", "安全笔数", "动态M值", "买前大单", "成交进度", "买入信号", "买入执行位"]
        for i in range(0, len(titles)):
            html += f"<tr><td>{titles[i]}:</td><td>{buy_params_info[i]}</td></tr>"
        html += "</table>"
        html += "</table><br>"
    if xgb_code_info:
        html += "<b><br>-----选股宝---------<br></b>"
@@ -52,6 +56,57 @@
                        html += f"【{info[0]}】,共【{info[1]}】只票涨停<br>第【{info[2]}】涨停,现价【{info[3]}】元,涨幅【{info[4]}】<br><br>"
            else:
                html += f"无<br>"
    if codes_score[0]:
        html += "<b>-----主动买入-------</b><br>"
        html += "<table>"
        for i in range(0, len(codes_score[0])):
            if i % 4 == 0:
                html += "<tr>"
            html += f"<td><font color='red'>{codes_score[0][i][1]}:{codes_score[0][i][2]}</font></td>"
            if i % 4 == 3 or i == len(codes_score[0]) - 1:
                html += "</tr>"
        html += "</table><br>"
    if codes_score[1]:
        html += "<b>-----被动买入-------</b><br>"
        html += "<table>"
        for i in range(0, len(codes_score[1])):
            if i % 4 == 0:
                html += "<tr>"
            html += f"<td><font color='#000080'>{codes_score[1][i][1]}:{codes_score[1][i][2]}</font></td>"
            if i % 4 == 3 or i == len(codes_score[1]) - 1:
                html += "</tr>"
        html += "</table><br>"
    if codes_score[2]:
        html += "<b>-----不买入-------</b><br>"
        html += "<table>"
        for i in range(0, len(codes_score[2])):
            if i % 4 == 0:
                html += "<tr>"
            html += f"<td>{codes_score[2][i][1]}:{codes_score[2][i][2]}</td>"
            if i % 4 == 3 or i == len(codes_score[1]) - 1:
                html += "</tr>"
        html += "</table><br>"
    if trade_info:
        html += "<b>-----今日挂撤记录-------</b><br>"
        html += "<br>今日是否炸板:"
        if trade_info[0]:
            html += f"炸板-{trade_info[0]}"
        else:
            html += f"未炸板"
        if trade_info[1]:
            html += "<table>"
            for i in range(0, len(trade_info[1])):
                if i % 2 == 0:
                    html += "<tr>"
                html += f"<td>第{i + 1}次下单 评分{trade_info[1][i][1][0][0]} {trade_info[1][i][0]} </td>"
                if i % 2 == 1 or i == len(codes_score[0]) - 1:
                    html += "</tr>"
            html += "</table><br>"
        html += "<br>"
    if xgb_infos:
        html += "<b><br>-----市场热度-------<br></b><table>"
        for info in xgb_infos:
@@ -136,6 +191,9 @@
            elif k == 6:
                if not score_source_list[3][k][0]:
                    k_source.append("【不满足任何形态】")
            elif k == 7:
                if score_source_list[3][k][0]:
                    k_source.append("【天量大阳】")
        score_list_new.append(k_score)
        score_source_list_new.append("/".join(k_source))
@@ -152,7 +210,7 @@
                else:
                    nature_source.append("有涨停")
            if n == 1:
                nature_source.append(f"首板溢价率【{score_source_list[4][2]}】")
                nature_source.append(f"首板溢价率【{round(score_source_list[4][2],2)}】")
        score_list_new.append(nature_score)
        score_source_list_new.append(",".join(nature_source))
@@ -167,6 +225,9 @@
                hot_block_source.append(f"【{score_source_list[5][0]}】共{score_source_list[5][n]}个涨停")
            elif n == 2:
                hot_block_source.append(f"共{score_source_list[5][n]}个炸板")
            elif n == 4:
                if score_source_list[5][n]:
                    hot_block_source.append(f"【{score_source_list[5][n][0][0]}】{score_source_list[5][n][1]}")
        score_list_new.append(hot_block_score)
        score_source_list_new.append(",".join(hot_block_source))
@@ -330,8 +391,50 @@
                        codes_data_html += "</tr><tr>"
                codes_data_html += "</tr></table>"
                xgb_infos.append((f"***【{block[0]}】,涨幅【{block[1]}】,共【{limit_up_count}】个涨停", codes_data_html))
    codes_score = __load_codes_scores()
    trade_info = __load_trade_record(code)
    return __format_data(code_info, score_info, buy_params_info, xgb_code_info, xgb_infos, codes_score, trade_info)
    return __format_data(code_info, score_info, buy_params_info, xgb_code_info, xgb_infos)
def __load_codes_scores():
    # 获取所有监听中的代码
    codes = gpcode_manager.get_first_gp_codes()
    scores = l2_data_manager_new.L2TradeDataProcessor.get_code_scores()
    for code in codes:
        if code not in scores:
            # 获取分数
            limit_up_time = limit_up_time_manager.get_limit_up_time(code)
            if limit_up_time is None:
                continue
            volume_rate, volume_info = code_volumn_manager.get_volume_rate(code, True)
            (score, score_list), score_source_list = first_code_score_manager.get_score(code, volume_rate,
                                                                                        limit_up_time,
                                                                                        True)
            scores[code] = score
    # 筛选180分以上的代码
    scores_list = []
    for code in scores:
        code_name = gpcode_manager.get_code_name(code)
        scores_list.append((code, code_name, scores[code]))
    scores_list.sort(key=lambda x: x[2], reverse=True)
    fscores_list = [[], [], []]
    for score in scores_list:
        if score[2] >= 180:
            fscores_list[0].append(score)
        elif score[2] >= 100:
            fscores_list[1].append(score)
        else:
            fscores_list[2].append(score)
    return fscores_list
def __load_trade_record(code):
    # 获取炸板信息
    limit_up_info = code_price_manager.Buy1PriceManager.get_limit_up_info(code)
    break_time = limit_up_info[1]
    records = log.load_buy_score_recod(code)
    return break_time, records
if __name__ == '__main__':
server.py
@@ -916,11 +916,11 @@
    print(cid, pid)
if __name__ == "__main__":
    codes = ["000719"]
    codes = gpcode_manager.get_first_gp_codes()
    for code in codes:
        try:
            global_data_loader.load_zyltgb()
            limit_up_price = float("11.13")  # float(gpcode_manager.get_limit_up_price(code))
            limit_up_price =  float(gpcode_manager.get_limit_up_price(code))
            volumes_data = juejin.get_volumns_by_code(code, 150)
            volumes_data = volumes_data[1:]
            volumes = juejin.parse_max_volume(volumes_data[:60],
third_data/hot_block_data_process.py
@@ -97,6 +97,24 @@
        return fresult
class XGBDataUtil:
    # 板块中是否有高位票
    @classmethod
    def is_has_high_code(cls, block_name, latest_datas):
        if not latest_datas:
            return False
        for block in latest_datas:
            if block[0] != block_name:
                continue
            for code_data in block[2]:
                if code_data[1] and code_data[1].find("板") >= 0:
                    day = code_data[1][-2:-1]
                    if int(day) >= 2:
                        return True, code_data
        return False, None
__blocks_dict = {}
@@ -122,21 +140,24 @@
    # 新概念
    new_block = None
    latest_blocks = get_latest_block(15)
    for block in blocks:
        if block not in latest_blocks:
            new_block = block
            # 如果板块中的涨停票数》=2才算新题材
            count = 0
            if XGBHotBlockDataManager.latest_datas:
                for b in XGBHotBlockDataManager.latest_datas:
                    if b[0] == new_block:
                        for code_data in b[2]:
                            if len(code_data[4]) > 6:
                                count += 0
            if count < 2:
                new_block = None
            if not new_block:
    if blocks:
        for block in blocks:
            if block not in latest_blocks:
                new_block = block
                break
                # # 如果板块中的涨停票数》=2才算新题材,暂时取消
                # count = 0
                # if XGBHotBlockDataManager.latest_datas:
                #     for b in XGBHotBlockDataManager.latest_datas:
                #         if b[0] == new_block:
                #             for code_data in b[2]:
                #                 if len(code_data[4]) > 6:
                #                     count += 0
                # if count < 1:
                #     # 板块中最低有
                #     new_block = None
                # if not new_block:
                # break
    target_block = None
    if blocks:
@@ -147,6 +168,16 @@
            break
    if not target_block:
        return None
    # 是否出现过高位板
    high_block_info = None
    for block in blocks:
        if block == '公告' or block == '其他':
            continue
        if XGBHotBlockDataManager.latest_datas:
            has_high, high_code_info = XGBDataUtil.is_has_high_code(block, XGBHotBlockDataManager.latest_datas)
            if has_high:
                high_block_info = (high_code_info[0], high_code_info[1])
    limit_up_codes_set = set()
    if XGBHotBlockDataManager.latest_datas:
@@ -175,7 +206,7 @@
    break_codes = break_codes.difference(limit_up_codes_set)
    # 炸板个数
    break_size = len(break_codes)
    return target_block, limit_up_count, break_size, new_block
    return target_block, limit_up_count, break_size, new_block, high_block_info
# 保存数据
trade/first_code_score_manager.py
@@ -5,12 +5,13 @@
# bidding 是否满足竞价
# deal_big_money 成交大金额是否满足
# code_nature = (是否有涨停,是否有溢价)
# hot_block(板块中涨停票个数(包含自己),板块炸板票个数, 新板块名称)
# hot_block(板块中涨停票个数(包含自己),板块炸板票个数, 新板块名称 , 高位板信息)
# zyltgb自由流通市值是否大于250亿
# limit_price 涨停价是否大于100块
# limit_up_time 是否10点之前涨停
# k_form(15个交易日是否涨幅24.9%,是否破前高,是否超跌,是否接近前高,是否N,是否V,是否有形态)
import code_nature_analyse
import code_volumn_manager
import global_data_loader
import global_util
import gpcode_manager
@@ -20,11 +21,11 @@
def __get_score(zyltgb, limit_price, bidding, k_form, code_nature, hot_block, volume_rate, limit_up_time,
                deal_big_money):
                deal_big_money_rate):
    score_list = []
    if zyltgb:
        zyltgbs = [0, 10, 31, 51, 101, 150, 250, 1000000]
        zyltgb_score = [20, 30, 20, 10, -1000, -1000, -1000]
        zyltgb_score = [15, 25, 15, 5, -5, -55, -1000]
        for i in range(1, len(zyltgbs)):
            if zyltgbs[i - 1] <= zyltgb / 100000000 < zyltgbs[i]:
                score_list.append(zyltgb_score[i - 1])
@@ -62,7 +63,7 @@
    # 是否接近前高
    if k_form[3]:
        k_score.append(-35)
        k_score.append(-10)
    else:
        k_score.append(0)
    # 是否N
@@ -80,7 +81,14 @@
    if k_form[6]:
        k_score.append(0)
    else:
        k_score.append(-35)
        k_score.append(0)
    # 是否天量大阳
    if k_form[7] and not k_form[1]:
        # 天量大阳且不是突破前高
        k_score.append(30)
    else:
        k_score.append(0)
    score_list.append(k_score)
@@ -102,13 +110,16 @@
    hot_block_score = []
    # 板块中只有自己涨停,且无炸板
    if hot_block[1] == 1 and hot_block[2] == 0:
        hot_block_score.append(20)
    elif hot_block[1] >= 2 and hot_block[2] == 0:
    if hot_block[1] >= 2 and hot_block[2] == 0:
        hot_block_score.append(30)
    elif hot_block[3] and not k_form[6]:
        # 有新题材,且没有K线形态
        hot_block_score.append(30)
    elif hot_block[1] == 1 and hot_block[2] == 0:
        hot_block_score.append(20)
    elif hot_block[4] is not None and not k_form[6]:
        # 有高位板且无K线形态
        hot_block_score.append(20)
    else:
        hot_block_score.append(0)
    score_list.append(hot_block_score)
@@ -135,11 +146,12 @@
    else:
        score_list.append(0)
        # 大单成交
    if deal_big_money:
        score_list.append(35)
    else:
        score_list.append(0)
    # 大单成交
    deal_big_money_rates = [0, 0.00001, 0.5, 1, 1.2, 1.5, 10000]
    deal_big_money_scores = [0, -20, -10, 20, 30, 40]
    for i in range(1, len(deal_big_money_rates)):
        if deal_big_money_rate < deal_big_money_rates[i]:
            score_list.append(deal_big_money_scores[i - 1])
    score = 0
    for s in score_list:
@@ -175,7 +187,20 @@
    k_form = code_nature_analyse.CodeNatureRecordManager.get_k_format(code)
    if k_form is None:
        k_form = [(True, ''), (False, ''), (False, ''), (False, ''), (False, ''), (False, ''), (True, '')]
        k_form = [(True, ''), (False, ''), (False, ''), (False, ''), (False, ''), (False, ''), (True, ''), (1, 1)]
    today_volume = code_volumn_manager.get_today_volumn(code)
    if today_volume:
        today_volume = int(today_volume)
    if k_form[7][0] < today_volume * 0.7 and k_form[7][1] < today_volume * 0.3:
        #  最大量小于今日量的70%,平均量小于今日量的30%
        k_form[7] = (True, f"最大量:{k_form[7][0]} 均量:{k_form[7][1]}")
    else:
        k_form[7] = (False, f"最大量:{k_form[7][0]} 均量:{k_form[7][1]}")
    if not k_form[6][0] and k_form[7][0]:
        # 将天量大阳融合进去
        k_form[6] = (True, '')
    source_datas.append(k_form)
    code_nature = code_nature_analyse.CodeNatureRecordManager.get_nature(code)
@@ -183,10 +208,10 @@
    hot_block = hot_block_data_process.get_info(code)
    if hot_block is None:
        hot_block = ('无板块', 1, 0, None)
        hot_block = ('无板块', 1, 0, None, None)
    else:
        # 加上自己
        hot_block = (hot_block[0], hot_block[1] + 1, hot_block[2], hot_block[3])
        hot_block = (hot_block[0], hot_block[1] + 1, hot_block[2], hot_block[3], hot_block[4])
    source_datas.append(hot_block)
@@ -198,18 +223,13 @@
    deal_big_num = deal_big_money_manager.get_deal_big_money_num(code)
    m = l2_trade_factor.L2TradeFactorUtil.get_base_safe_val(zyltgb)
    source_datas.append((deal_big_num * limit_price * 100, m))
    if deal_big_num * limit_price * 100 > m:
        deal_big_num = True
    else:
        deal_big_num = False
    deal_big_num_rate = (deal_big_num * limit_price * 100) / m
    k_form_1 = []
    for d in k_form:
        k_form_1.append(d[0])
    for i in range(0, len(k_form)):
        k_form_1.append(k_form[i][0])
    result = __get_score(zyltgb, limit_price > 100, bidding, k_form_1, code_nature, hot_block,
                         volume_rate, limit_up_time, deal_big_num)
                         volume_rate, limit_up_time, deal_big_num_rate)
    if with_source_data:
        return result, source_datas
    return result