Administrator
2023-03-27 8535f56dbf6e410b4a09f02f95d4d49bcc8753f2
看盘页面数据调整
16个文件已修改
2个文件已添加
1127 ■■■■ 已修改文件
code_nature_analyse.py 82 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
code_volumn_manager.py 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
data_export_util.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
juejin.py 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2/l2_data_manager_new.py 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
l2_trade_test.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
ocr/ocr_server.py 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ocr/ocr_util.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
output/code_info_output.py 306 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server.py 65 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/hot_block.py 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/hot_block_data_process.py 61 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/kpl_util.py 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/bidding_money_manager.py 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/deal_big_money_manager.py 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/first_code_score_manager.py 239 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/l2_trade_factor.py 98 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/trade_gui.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
code_nature_analyse.py
@@ -47,15 +47,17 @@
# 设置历史K线
def set_record_datas(code, limit_up_price, record_datas):
    k_format = get_k_format(limit_up_price, record_datas)
    k_format = get_k_format(float(limit_up_price), record_datas)
    CodeNatureRecordManager.save_k_format(code, k_format)
    natures = get_nature(record_datas)
    CodeNatureRecordManager.save_nature(code, natures)
# 获取K线形态
# 返回 (15个交易日涨幅是否大于24.9%,是否破前高,是否超跌,是否接近前高,是否N,是否V)
def get_k_format(limit_up_price, record_datas):
    p1 = get_lowest_price_rate(record_datas) >= 0.249
    p1_data = get_lowest_price_rate(record_datas)
    p1 = p1_data[0] >= 0.249, p1_data[1]
    p2 = __is_new_top(limit_up_price, record_datas)
    p3 = __is_lowest(record_datas)
    p4 = __is_near_new_top(limit_up_price, record_datas)
@@ -63,13 +65,13 @@
    p6 = __is_v_model(record_datas)
    # N字型包含了N字型
    if p5:
        p6 = False
        p6 = False, ''
    return (p1, p2, p3, p4, p5, p6)
# 是否具有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 = get_k_format(limit_up_price, record_datas)
    is_too_high, is_new_top, is_lowest, is_near_new_top, is_n, is_v = get_k_format(float(limit_up_price), record_datas)
    # if is_too_high:
    #     return False, "15个交易日涨幅大于24.9%"
@@ -91,7 +93,7 @@
def get_nature(record_datas):
    limit_up = is_have_limit_up(record_datas)
    premium_rate = get_limit_up_premium_rate(record_datas)
    result = (limit_up, premium_rate >= 0.6)
    result = (limit_up, premium_rate >= 0.6,premium_rate)
    return result
@@ -101,10 +103,12 @@
    datas.sort(key=lambda x: x["bob"])
    datas = datas[-15:]
    low_price = datas[0]["close"]
    date = None
    for data in datas:
        if low_price > data["close"]:
            low_price = data["close"]
    return (datas[-1]["close"] - low_price) / low_price
            date = data['bob'].strftime("%Y-%m-%d")
    return (datas[-1]["close"] - low_price) / low_price, date
# 是否有涨停
@@ -114,12 +118,8 @@
        item = datas[i]
        limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(item["pre_close"]))
        if abs(limit_up_price - item["close"]) < 0.01:
            return True
    return False
def is_have_limit_up_by_code(code):
    return False
            return True, item['bob'].strftime("%Y-%m-%d")
    return False, ''
# 是否破前高
@@ -131,9 +131,13 @@
    for data in datas:
        if max_price < data["high"]:
            max_price = data["high"]
    if limit_up_price > max_price:
        return True
    return False
    if limit_up_price >= max_price:
        return True, ''
    return False, ''
def is_new_top(limit_up_price, datas):
    return __is_new_top(float(limit_up_price), datas)[0]
# 接近新高
@@ -142,15 +146,33 @@
    datas.sort(key=lambda x: x["bob"])
    datas = datas[-80:]
    max_volume = 0
    price = 0
    for data in datas:
    max_volume_index = 0
    for index in range(0, len(datas)):
        data = datas[index]
        if max_volume < data["volume"]:
            max_volume = data["volume"]
            max_volume_index = index
    price = 0
    price_index = 0
    for index in range(max_volume_index, len(datas)):
        data = datas[index]
        if data["high"] > price:
            price = data["high"]
            price_index = index
    index = price_index
    # 最大量当日最高价比当日之后的最高价涨幅在15%以内
    if (price - datas[max_volume_index]["high"]) / datas[max_volume_index]["high"] < 0.15:
        price = datas[max_volume_index]["high"]
        index = max_volume_index
    print(max_volume)
    if limit_up_price < price and (price - limit_up_price) / limit_up_price < 0.03:
        return True
    return False
    rate = (price - limit_up_price) / limit_up_price
    if 0 < rate < 0.03:
        return True, datas[index]['bob'].strftime("%Y-%m-%d")
    return False, ''
# 是否跌破箱体
@@ -163,13 +185,15 @@
        if min_price > data["low"]:
            min_price = data["low"]
    # 近5天内的最低价
    date = ''
    min_price_5 = 10000
    for data in datas[-5:]:
        if min_price_5 > data["low"]:
            min_price_5 = data["low"]
            date = data['bob']
    if abs(min_price_5 - min_price) / min_price < 0.015:
        return True
    return False
        return True, date.strftime("%Y-%m-%d")
    return False, ''
# N字形
@@ -192,8 +216,8 @@
                if min_price > item["low"]:
                    min_price = item["low"]
        if max_price > min_price:
            return True
    return False
            return True, ''
    return False, ''
# V字形
@@ -215,9 +239,9 @@
            min_price_index = i
    if (max_price - min_price) / max_price > 0.249:
        return True
        return True, ''
    return False
    return False, ''
# 首板涨停溢价率
@@ -234,9 +258,13 @@
            rate = (datas[i + 1]["high"] - datas[i + 1]["pre_close"]) / datas[i + 1]["pre_close"]
            first_rate_list.append(rate)
    if not first_rate_list:
        return 1
        return 0
    count = 0
    for rate in first_rate_list:
        if rate >= 0.01:
            count += 1
    return count / len(first_rate_list)
if __name__ == "__main__":
    print(CodeNatureRecordManager.get_k_format("603717"))
code_volumn_manager.py
@@ -5,6 +5,8 @@
# 设置历史量
# max60 60天最大量
# yesterday 昨天的量
import json
import global_util
import gpcode_manager
from db import redis_manager
@@ -15,11 +17,11 @@
# 设置历史量
def set_histry_volumn(code, max60, yesterday):
def set_histry_volumn(code, max60, yesterday, max60_day=''):
    redis = __redis_manager.getRedis()
    global_util.max60_volumn[code] = max60
    global_util.yesterday_volumn[code] = yesterday
    redis.setex("volumn_max60-{}".format(code), tool.get_expire(), max60)
    redis.setex("volumn_max60-{}".format(code), tool.get_expire(), json.dumps((max60,max60_day)))
    redis.setex("volumn_yes-{}".format(code), tool.get_expire(), yesterday)
@@ -30,6 +32,8 @@
    redis = __redis_manager.getRedis()
    if max60 is None:
        max60 = redis.get("volumn_max60-{}".format(code))
        if max60:
            max60 = json.loads(max60)
    if yesterday is None:
        yesterday = redis.get("volumn_yes-{}".format(code))
    return max60, yesterday
@@ -53,12 +57,15 @@
# 获取量比(今日量/max(60天最大量,昨日量))
def get_volume_rate(code):
def get_volume_rate(code, with_info=False):
    today = get_today_volumn(code)
    max60, yesterday = get_histry_volumn(code)
    if today is None or max60 is None or yesterday is None:
        raise Exception("获取量失败")
    return round(int(today) / max(int(max60), int(yesterday)), 2)
    rate = round(int(today) / max(int(max60[0]), int(yesterday)), 2)
    if not with_info:
        return rate
    return rate, (today, max(int(max60[0]), int(yesterday)))
# 获取量比索引
@@ -90,7 +97,10 @@
    if keys is not None:
        for k in keys:
            code = k.split("-")[1]
            global_util.max60_volumn[code] = redis.get(k)
            max60_volumn = redis.get(k)
            if max60_volumn:
                max60_volumn = json.loads(max60_volumn)
            global_util.max60_volumn[code] = max60_volumn
    keys = redis.keys("volumn_yes-*")
    if keys is not None:
        for k in keys:
@@ -98,3 +108,5 @@
            global_util.yesterday_volumn[code] = redis.get(k)
if __name__ == "__main__":
    print(get_histry_volumn("603717"))
data_export_util.py
@@ -196,6 +196,6 @@
if __name__ == "__main__":
    codes = ["000977"]
    codes = ["003021"]
    for code in codes:
        export_l2_excel(code)
juejin.py
@@ -592,23 +592,37 @@
# 解析最大量
def parse_max_volume(datas):
def parse_max_volume(datas, is_new_top=False):
    max_volume = 0
    for i in range(len(datas)):
        # 查询涨停
        item = datas[i]
        volume = item["volume"]
        if max_volume < volume:
            max_volume = volume
        # 是否有涨停
        limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(item["pre_close"]))
        if abs(limit_up_price - item["high"]) < 0.01:
            next_volume = 0
            if i > 0:
                next_volume = datas[i - 1]["volume"]
            volume = max(volume, next_volume)
            return (volume, volume)
    return (max_volume, max_volume)
    max_volume_date = None
    if is_new_top:
        # 如果是突破前高就取最大量
        for item in datas:
            if max_volume < item["volume"]:
                max_volume = item["volume"]
                max_volume_date = item["bob"]
    else:
        date = None
        for i in range(len(datas)):
            # 查询涨停
            item = datas[i]
            volume = item["volume"]
            if max_volume < volume:
                max_volume = volume
                max_volume_date = item['bob']
            # 是否有涨停
            limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(item["pre_close"]))
            if abs(limit_up_price - item["high"]) < 0.01:
                next_volume = 0
                if i > 0:
                    next_volume = datas[i - 1]["volume"]
                date = datas[i]["bob"]
                if volume < next_volume:
                    volume = next_volume
                    date = datas[i - 1]["bob"]
                return volume, volume, date.strftime("%Y-%m-%d")
    return max_volume, max_volume, max_volume_date.strftime("%Y-%m-%d")
# 是否有涨停
@@ -654,6 +668,6 @@
if __name__ == '__main__':
    datas=(get_volumns_by_code("603083", 150))
    datas = (get_volumns_by_code("603083", 150))
    print(datas)
    print(get_limit_up_money_percent(datas))
l2/l2_data_manager_new.py
@@ -16,7 +16,7 @@
import ths_industry_util
import tool
from trade import trade_data_manager, trade_manager, trade_queue_manager, l2_trade_factor, l2_trade_util, \
    trade_result_manager
    trade_result_manager, first_code_score_manager
from l2 import safe_count_manager, l2_data_manager, l2_data_log, l2_log, l2_data_source_util, code_price_manager
from l2.cancel_buy_strategy import SecondCancelBigNumComputer, HourCancelBigNumComputer, L2LimitUpMoneyStatisticUtil, \
    L2LimitUpSellStatisticUtil
@@ -160,7 +160,7 @@
    __ths_l2_trade_queue_manager = trade_queue_manager.thsl2tradequeuemanager()
    __thsBuy1VolumnManager = trade_queue_manager.THSBuy1VolumnManager()
    __buyL2SafeCountManager = safe_count_manager.BuyL2SafeCountManager()
    __l2PlaceOrderParamsManager = l2_trade_factor.L2PlaceOrderParamsManager()
    __l2PlaceOrderParamsManagerDict = {}
    @classmethod
    # 数据处理入口
@@ -226,13 +226,23 @@
                                           "l2数据预处理时间")
        if len(add_datas) > 0:
            # 是否为首板代码
            is_first_code = gpcode_manager.FirstCodeManager.is_in_first_record(code)
            # 计算量
            volume_rate = code_volumn_manager.get_volume_rate(code)
            volume_rate_index = code_volumn_manager.get_volume_rate_index(volume_rate)
            l2_log.debug(code,"量比:{},量索引:{}",volume_rate,volume_rate_index)
            # 计算分值
            limit_up_time = limit_up_time_manager.get_limit_up_time(code)
            if limit_up_time is None:
                limit_up_time = tool.get_now_time_str()
            score = first_code_score_manager.get_score(code, volume_rate, limit_up_time)
            cls.__l2PlaceOrderParamsManagerDict[code] = l2_trade_factor.L2PlaceOrderParamsManager(code, is_first_code,
                                                                                                  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)
            # 是否为首板代码
            is_first_code = gpcode_manager.FirstCodeManager.is_in_first_record(code)
            latest_time = add_datas[len(add_datas) - 1]["val"]["time"]
            # 时间差不能太大才能处理
            if not l2_trade_util.is_in_forbidden_trade_codes(code):
@@ -321,7 +331,8 @@
                b_need_cancel, b_cancel_data = SecondCancelBigNumComputer.need_cancel(code, buy_single_index,
                                                                                      buy_exec_index, start_index,
                                                                                      end_index, total_data,
                                                                                      code_volumn_manager.get_volume_rate_index(buy_volume_rate),
                                                                                      code_volumn_manager.get_volume_rate_index(
                                                                                          buy_volume_rate),
                                                                                      cls.volume_rate_info[code][1],
                                                                                      is_first_code)
                if b_need_cancel:
@@ -438,7 +449,11 @@
    @classmethod
    def __buy(cls, code, capture_timestamp, last_data, last_data_index, is_first_code):
        __start_time = tool.get_now_timestamp()
        can, need_clear_data, reason = cls.__can_buy(code, is_first_code)
        can, need_clear_data, reason = False,False,""
        if not is_first_code:
            can, need_clear_data, reason = cls.__can_buy(code)
        else:
            can, need_clear_data, reason = cls.__can_buy_first(code)
        __start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - __start_time, "最后判断是否能下单", force=True)
        # 删除虚拟下单
        if code in cls.unreal_buy_dict:
@@ -504,18 +519,8 @@
    # 是否可以买
    # 返回是否可以买,是否需要清除之前的买入信息,原因
    @classmethod
    def __can_buy(cls, code, is_first_code):
    def __can_buy(cls, code):
        __start_time = t.time()
        # 判断是否为首板代码
        if is_first_code:
            if not gpcode_manager.WantBuyCodesManager.is_in(code):
                is_limited_up = gpcode_manager.FirstCodeManager.is_limited_up(code)
                gpcode_manager.FirstCodeManager.add_limited_up_record([code])
                if not code_price_manager.Buy1PriceManager.is_can_buy(code):
                    return False, True, "首板代码,没在想要买名单中且未打开涨停板"
                if not is_limited_up:
                    return False, True, "首板代码,没在想要买名单中且未涨停过"
            # 之前的代码
            # 首板代码且尚未涨停过的不能下单
            # is_limited_up = gpcode_manager.FirstCodeManager.is_limited_up(code)
@@ -566,16 +571,15 @@
            # 量比超过1.3的不能买
            volumn_rate = cls.volume_rate_info[code][0]
            if not is_first_code and volumn_rate >= 1.3:
            if volumn_rate >= 1.3:
                return False, False, "最大量比超过1.3不能买"
            elif is_first_code and volumn_rate >= 1.1:
                return False, False, "首板最大量比超过1.1不能买"
            limit_up_time = limit_up_time_manager.get_limit_up_time(code)
            if limit_up_time is not None:
                limit_up_time_seconds = l2.l2_data_util.L2DataUtil.get_time_as_second(
                    limit_up_time)
                if not is_first_code and limit_up_time_seconds >= l2.l2_data_util.L2DataUtil.get_time_as_second(
                if  limit_up_time_seconds >= l2.l2_data_util.L2DataUtil.get_time_as_second(
                        "13:00:00"):
                    return False, False, "二板下午涨停的不能买,涨停时间为{}".format(limit_up_time)
                if limit_up_time_seconds >= l2.l2_data_util.L2DataUtil.get_time_as_second("14:55:00"):
@@ -640,6 +644,27 @@
            return True, False, None
        finally:
            l2_data_log.l2_time(code, round((t.time() - __start_time) * 1000), "是否可以下单计算")
    @classmethod
    def __can_buy_first(cls, code):
        if not gpcode_manager.WantBuyCodesManager.is_in(code):
            # 查看分数等级
            score_index = cls.__l2PlaceOrderParamsManagerDict[code].score_index
            score = cls.__l2PlaceOrderParamsManagerDict[code].score
            if score_index < 0:
                return False, True, f"分值:{score}未达到需要买入的分数线"
            if -1 < score_index < 3:
                return True, False, f"分值:{score}达到主动买入的分数线,买入等级:f{score_index}"
            is_limited_up = gpcode_manager.FirstCodeManager.is_limited_up(code)
            gpcode_manager.FirstCodeManager.add_limited_up_record([code])
            if not code_price_manager.Buy1PriceManager.is_can_buy(code):
                return False, True, f"首板代码,没在想要买名单中且未打开涨停板,分数:{score}"
            if not is_limited_up:
                return False, True, f"首板代码,没在想要买名单中且未涨停过,分数:{score}"
            return True, False, ""
        else:
            return True, False, "在想买名单中"
    @classmethod
    def __cancel_buy(cls, code):
@@ -708,7 +733,7 @@
        # 是否为新获取到的位置
        new_get_single = False
        if buy_single_index is None:
            continue_count = cls.__l2PlaceOrderParamsManager.get_begin_continue_buy_count(cls.volume_rate_info[code][1])
            continue_count = cls.__l2PlaceOrderParamsManagerDict[code].get_begin_continue_buy_count()
            # 有买入信号
            has_single, _index = cls.__compute_order_begin_pos(code, max(
                (compute_start_index - continue_count - 1) if new_add else compute_start_index, 0), continue_count,
@@ -765,8 +790,8 @@
            return
        if compute_index is not None:
            l2_log.debug(code, "获取到买入执行位置:{} m值:{} 纯买手数:{} 纯买单数:{} 数据:{}", compute_index, threshold_money, buy_nums,
                         buy_count, total_datas[compute_index])
            l2_log.debug(code, "获取到买入执行位置:{} m值:{} 纯买手数:{} 纯买单数:{} 数据:{} ,量比:{} ", compute_index, threshold_money, buy_nums,
                         buy_count, total_datas[compute_index],cls.volume_rate_info[code][0])
            f1 = dask.delayed(cls.__save_order_begin_data)(code, buy_single_index, compute_index, compute_index,
                                                           buy_nums, buy_count, max_num_set_new,
@@ -902,7 +927,7 @@
    @classmethod
    def __get_threshmoney(cls, code):
        return l2_trade_factor.L2TradeFactorUtil.compute_m_value(code, cls.volume_rate_info[code][1])
        return cls.__l2PlaceOrderParamsManagerDict[code].get_m_val()
    # 计算万手哥笔数
    @classmethod
@@ -937,9 +962,7 @@
        # place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(code)
        # 目标订单数量
        threshold_count = cls.__buyL2SafeCountManager.get_safe_count(code, is_first_code,
                                                                     cls.__l2PlaceOrderParamsManager.get_safe_count_rate(
                                                                         cls.volume_rate_info[code][1]))
        threshold_count = cls.__l2PlaceOrderParamsManagerDict[code].get_safe_count()
        buy_single_time_seconds = L2DataUtil.get_time_as_second(total_datas[buy_single_index]["val"]["time"])
@@ -947,13 +970,13 @@
        trigger_buy = True
        # 间隔最大时间依次为:3,9,27,81
        max_space_time = cls.__l2PlaceOrderParamsManager.get_time_range(cls.volume_rate_info[code][1])
        max_space_time = cls.__l2PlaceOrderParamsManagerDict[code].get_time_range()
        # 最大买量
        max_buy_num = 0
        max_buy_num_set = set(max_num_set)
        # 需要的最小大单笔数
        big_num_count = cls.__l2PlaceOrderParamsManager.get_big_num_count(cls.volume_rate_info[code][1])
        big_num_count = cls.__l2PlaceOrderParamsManagerDict[code].get_big_num_count()
        # 较大单的手数
        bigger_num = round(5900 / limit_up_price)
l2_trade_test.py
@@ -85,7 +85,7 @@
                except Exception as e:
                    pass
    # @unittest.skip("跳过此单元测试")
    @unittest.skip("跳过此单元测试")
    def test_trade(self):
        code = "603801"
        clear_trade_data(code)
ocr/ocr_server.py
@@ -1,3 +1,4 @@
import base64
import json
import logging
import socketserver
@@ -7,6 +8,8 @@
import ths_industry_util
from ocr import ocr_util
from ocr.ocr_util import OcrUtil
from third_data import kpl_util
from trade import bidding_money_manager
class OCRServer(BaseHTTPRequestHandler):
@@ -32,11 +35,14 @@
        try:
            data = ""
            try:
                data = json.loads(_str)
            except:
                if type(_str) == str:
                    data = json.loads(_str)
                else:
                    data = _str
            except Exception as e1:
                raise Exception("json解析失败")
            type = data["type"]
            if type == 100:
            _type = data["type"]
            if _type == 100:
                data = data["data"]
                matId = data["matId"]
                index = data["index"]
@@ -68,7 +74,7 @@
                        return_str = json.dumps({"code": 2, "msg": "数据出错"})
                else:
                    return_str = json.dumps({"code": 1, "msg": "数据尚未上传完"})
            elif type == 101:
            elif _type == 101:
                data = data["data"]
                matId = data["matId"]
                index = data["index"]
@@ -101,6 +107,15 @@
                        return_str = json.dumps({"code": 2, "msg": "数据出错"})
                else:
                    return_str = json.dumps({"code": 1, "msg": "数据尚未上传完"})
            elif _type == 201:
                imgdata = base64.b64decode(data["img"])
                results = ocr_util.OcrUtil.easy_ocr(imgdata)
                print(results)
                kpl_datas = kpl_util.parse_kpl_datas(results)
                if kpl_datas:
                    bidding_money_manager.set_bidding_money(kpl_datas)
                with open("D:/kpl.png", mode="wb") as f:
                    f.write(imgdata)
        except Exception as e:
            logging.exception(e)
            if str(e).__contains__("json解析失败"):
@@ -120,18 +135,21 @@
        datas = self.rfile.read(int(self.headers['content-length']))
        _str = str(datas, encoding="gbk")
        # print(_str)
        start = 0
        while True:
            start = _str.find("Content-Disposition: form-data;", start + 1)
            if start <= 0:
                break
            name_start = start + len("Content-Disposition: form-data;")
            name_end = _str.find("\r\n\r\n", start)
        if _str.find("Content-Disposition: form-data;") > -1:
            start = 0
            while True:
                start = _str.find("Content-Disposition: form-data;", start + 1)
                if start <= 0:
                    break
                name_start = start + len("Content-Disposition: form-data;")
                name_end = _str.find("\r\n\r\n", start)
            val_end = _str.find("------", name_end)
            key = _str[name_start:name_end].strip()[6:-1]
            val = _str[name_end:val_end].strip()
            params[key] = val
                val_end = _str.find("------", name_end)
                key = _str[name_start:name_end].strip()[6:-1]
                val = _str[name_end:val_end].strip()
                params[key] = val
        else:
            params = json.loads(_str)
        return params
@@ -140,3 +158,8 @@
    httpd = socketserver.TCPServer((addr, port), handler)
    print("HTTP server is at: http://%s:%d/" % (addr, port))
    httpd.serve_forever()
if __name__ == "__main__":
    str_={"id":"123"}
    print(type(str_)==str)
ocr/ocr_util.py
@@ -16,6 +16,11 @@
        res = cls.__ocr.ocr(mat)
        return res
    @classmethod
    def easy_ocr(cls, mat):
        res = cls.reader.readtext(mat, detail=1)
        return res
    # 返回(识别内容,位置信息)
    @classmethod
    def ocr_with_key(cls, mat, key):
output/code_info_output.py
New file
@@ -0,0 +1,306 @@
"""
代码信息对外输出
"""
# score_info 得分信息
# 下单参数信息
# 选股宝
# 市场热度
import code_volumn_manager
import global_data_loader
import global_util
import gpcode_manager
import juejin
import limit_up_time_manager
import tool
from l2 import l2_data_manager, l2_data_util, transaction_progress
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
def __format_data(code_info, score_info, buy_params_info, xgb_code_info, xgb_infos):
    html = ""
    html += f"<h2>{code_info[1]} {code_info[0]}</h2><br>"
    if score_info:
        html += "-----买前评分-------<br>"
        score_types = ["换手量能", "竞价强度", "资金力度", "日线形态", "历史股性", "板块热度", "上板时间", "市值大小", "股价大小"]
        html += "<table style='font-size:25px'>"
        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>"
    if buy_params_info:
        html += "<br>-----交易参数-------<br><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>"
    if xgb_code_info:
        html += "<br>-----选股宝---------<br>"
        xgb_code_info_dates = ["今天", "昨天", "前天", "之前"]
        for i in range(0, len(xgb_code_info)):
            html += f"{xgb_code_info_dates[i]}:<br>"
            if xgb_code_info[i]:
                for info in xgb_code_info[i]:
                    if i == 0:
                        html += f"【<font color='red'>{info[0]}</font>】,共【<font color='red'>{info[1]}</font>】只票涨停<br>第【<font color='red'>{info[2]}</font>】涨停,现价【<font color='red'>{info[3]}</font>】元,涨幅【<font color='red'>{info[4]}</font>】<br><br>"
                    else:
                        html += f"【{info[0]}】,共【{info[1]}】只票涨停<br>第【{info[2]}】涨停,现价【{info[3]}】元,涨幅【{info[4]}】<br><br>"
            else:
                html += f"无<br>"
    if xgb_infos:
        html += "<br>-----市场热度-------<br><table>"
        for info in xgb_infos:
            html += f"<tr><td>{info}</td></tr>"
        html += "</tr>"
    return html
def get_output_html(code):
    day = tool.get_now_date_str()
    is_target_code = gpcode_manager.FirstCodeManager.is_in_first_record(code)
    code_info = [code, gpcode_manager.get_code_name(code)]
    score_info = None
    buy_params_info = None
    xgb_infos = None
    if is_target_code:
        limit_up_price = gpcode_manager.get_limit_up_price(code)
        limit_up_time = limit_up_time_manager.get_limit_up_time(code)
        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)
        ################################买前评分################################
        # ["换手量能", "竞价强度", "资金力度", "K线形态", "历史股性", "板块热度", "上板时间", "市值大小","股价大小"]
        score_list_new = []
        score_source_list_new = []
        # 换手量能
        score_list_new.append(score_list[6])
        # 获取当前量信息
        max_60, yest = code_volumn_manager.get_histry_volumn(code)
        today = code_volumn_manager.get_today_volumn(code)
        score_source_list_new.append(f"实时量【{round(int(today)/10000,2)}万手】÷前高量【{round(max_60[0]/10000,2)}万手-{max_60[1]}】=【{round(score_source_list[6]*100,2)}%】")
        # 竞价强度
        score_list_new.append(score_list[2])
        score_source_list_new.append(f"开盘啦今日委停【{score_source_list[2] if score_source_list[2] else 0}万】")
        # 资金力度
        score_list_new.append(score_list[8])
        score_source_list_new.append(f"累计金额【{score_source_list[8][0] / 10000}万】&固定m值【{score_source_list[8][1] / 10000}万】")
        # K线形态
        k_score = 0
        k_source = []
        for k in score_list[3]:
            k_score += k
        # (15个交易日是否涨幅24.9%,是否破前高,是否超跌,是否接近前高,是否N,是否V)
        for k in range(0, len(score_source_list[3])):
            if k == 0:
                if score_source_list[3][k][0]:
                    k_source.append("【涨幅过高】")
            elif k == 1:
                if score_source_list[3][k][0]:
                    k_source.append("【突破前高】")
            elif k == 2:
                if score_source_list[3][k][0]:
                    k_source.append("【超跌补涨】")
            elif k == 3:
                if score_source_list[3][k][0]:
                    k_source.append(f"【逼近前高-{score_source_list[3][k][1]}】")
            elif k == 4:
                if score_source_list[3][k][0]:
                    k_source.append("【N字型】")
            elif k == 5:
                if score_source_list[3][k][0]:
                    k_source.append("【V字型】")
        if not score_source_list[3][1][0] and not score_source_list[3][2][0] and not score_source_list[3][4][0] and not \
                score_source_list[3][5][0]:
            k_source.append("【不满足任何形态】")
        score_list_new.append(k_score)
        score_source_list_new.append("/".join(k_source))
        # 历史股性
        nature_score = 0
        nature_source = []
        for k in score_list[4]:
            nature_score += k
        for n in range(0, len(score_source_list[4])):
            if n == 0:
                if not score_source_list[4][n]:
                    nature_source.append("无涨停")
                else:
                    nature_source.append("有涨停")
            if n == 1:
                nature_source.append(f"首板溢价率【{score_source_list[4][2]}】")
        score_list_new.append(nature_score)
        score_source_list_new.append(",".join(nature_source))
        # 板块热度
        hot_block_score = 0
        hot_block_source = []
        for k in score_list[5]:
            hot_block_score += k
        for n in range(0, len(score_source_list[5])):
            if n == 1:
                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]}个炸板")
        score_list_new.append(hot_block_score)
        score_source_list_new.append(",".join(hot_block_source))
        # 上板时间
        score_list_new.append(score_list[7])
        score_source_list_new.append(f"上板时间【{score_source_list[7]}】")
        # 市值大小
        score_list_new.append(score_list[0])
        score_source_list_new.append(f"自由市值【{round(score_source_list[0] / 100000000, 2)}亿】")
        # 股价大小
        score_list_new.append(score_list[1])
        score_source_list_new.append(f"现价【{score_source_list[1]}】元")
        score_info = (score, score_list_new, score_source_list_new)
        # zyltgb, limit_price, bidding, k_form, code_nature, hot_block, volume_rate, limit_up_time,
        # deal_big_money
        ###############################下单信息###############################
        # 获取买入意愿
        volume_rate = score_source_list[6]
        __L2PlaceOrderParamsManager = l2_trade_factor.L2PlaceOrderParamsManager(code, True, volume_rate,
                                                                                code_volumn_manager.get_volume_rate_index(
                                                                                    volume_rate),
                                                                                (score, score_list))
        __base_L2PlaceOrderParamsManager = l2_trade_factor.L2PlaceOrderParamsManager(code, False, volume_rate,
                                                                                     code_volumn_manager.get_volume_rate_index(
                                                                                         volume_rate),
                                                                                     (score, score_list))
        buy_params_info = []
        if -1 < __L2PlaceOrderParamsManager.score_index < 3:
            buy_params_info.append("<font color='red'>【主动买入】</font>")
        elif __L2PlaceOrderParamsManager.score_index < 0:
            buy_params_info.append("【不执行买入】")
        else:
            buy_params_info.append("【被动买入】")
        # 安全笔数
        safe_count = __L2PlaceOrderParamsManager.get_safe_count()
        base_safe_count, min_count, max_count = L2TradeFactorUtil.get_safe_buy_count(code, True)
        buy_params_info.append(f"固定安全笔数【{base_safe_count}】笔,衰减后安全笔数【{safe_count}】笔")
        # 动态M值
        m = __L2PlaceOrderParamsManager.get_m_val()
        zyltgb = global_util.zyltgb_map.get(code)
        if zyltgb is None:
            global_data_loader.load_zyltgb()
            zyltgb = global_util.zyltgb_map.get(code)
        base_m = L2TradeFactorUtil.get_base_safe_val(zyltgb)
        buy_params_info.append(f"固定M值【{base_m / 10000}万】,动态M值【{m[0] / 10000}万】    ")
        # 买前大单
        big_num = __L2PlaceOrderParamsManager.get_big_num_count()
        base_big_num = __base_L2PlaceOrderParamsManager.get_big_num_count()
        buy_params_info.append(f"固定买前大单【{base_big_num}】笔,衰减后买前大单【{big_num}】笔")
        # 成交进度
        total_datas = l2_data_util.local_today_datas.get(code)
        if total_datas is None:
            l2_data_util.load_l2_data(code)
            total_datas = l2_data_util.local_today_datas.get(code)
        trade_progress, is_default = transaction_progress.TradeBuyQueue().get_traded_index(code)
        if trade_progress is None or trade_progress < 0 or is_default:
            buy_params_info.append("未识别")
        else:
            data = total_datas[trade_progress]
            buy_params_info.append(
                f"【{data['val']['time']}】、【{data['val']['num']}手】、【{round(data['val']['num'] * float(data['val']['price']) * 100 / 10000, 1)}万】")
        # 买入信号
        buy_single_index, buy_exec_index, compute_index, num, count, max_num_set, volume_rate = l2_data_manager.TradePointManager.get_buy_compute_start_data(
            code)
        if buy_single_index is None:
            buy_params_info.append("无信号")
        else:
            data = total_datas[buy_single_index]
            buy_params_info.append(
                f"【{data['val']['time']}】、【{data['val']['num']}手】、【{round(data['val']['num'] * float(data['val']['price']) * 100 / 10000, 1)}万】")
        if buy_exec_index is None or buy_exec_index < 0:
            buy_params_info.append("未下单")
        else:
            data = total_datas[buy_exec_index]
            buy_params_info.append(
                f"【{data['val']['time']}】、【{data['val']['num']}手】、【{round(data['val']['num'] * float(data['val']['price']) * 100 / 10000, 1)}万】")
    ##############################选股宝##################################
    xgb_code_info = []
    for i in range(0, 4):
        xgb_datas = hot_block_data_process.XGBHotBlockDataManager.list_by_code(code, day)
        datas = []
        if xgb_datas:
            for data in xgb_datas:
                block = data[2]
                block_datas = hot_block_data_process.XGBHotBlockDataManager.list_by_block(block, day)
                block_datas = list(block_datas)
                limit_up_count = 0
                limit_up_time = None
                for d in block_datas:
                    if len(d[4]) > 6:
                        limit_up_count += 1
                        if d[3] == code:
                            limit_up_time = d[4]
                # 根据涨停时间排序
                block_datas.sort(key=lambda d: (d[4] if len(d[4]) > 6 else '15:00:00'))
                for i in range(len(block_datas)):
                    if block_datas[i][3] == code:
                        datas.append(
                            (block, limit_up_count, (i + 1) if limit_up_time is not None else (limit_up_count + 1),
                             block_datas[i][5], block_datas[i][6]))
                        break
        xgb_code_info.append(datas)
        day = juejin.JueJinManager.get_previous_trading_date(day)
    ##############################热门风口##################################
    xgb_infos = []
    xgb_latest_datas = hot_block_data_process.XGBHotBlockDataManager.latest_datas
    if not xgb_latest_datas:
        xgb_infos.append('暂未获取到数据')
    else:
        for block in xgb_latest_datas:
            limit_up_count = 0
            for code_data in block[2]:
                if len(code_data[4]) > 6:
                    limit_up_count += 1
            xgb_infos.append(f"【{block[0]}】,涨幅【{block[1]}】,共【{limit_up_count}】个涨停")
    return __format_data(code_info, score_info, buy_params_info, xgb_code_info, xgb_infos)
if __name__ == '__main__':
    code = "002410"
    day = '2023-03-27'
    xgb_datas = hot_block_data_process.XGBHotBlockDataManager.list_by_code(code, day)
    datas = []
    if xgb_datas:
        for data in xgb_datas:
            block = data[2]
            block_datas = hot_block_data_process.XGBHotBlockDataManager.list_by_block(block, day)
            block_datas = list(block_datas)
            limit_up_count = 0
            limit_up_time = None
            for d in block_datas:
                if len(d[4]) > 6:
                    limit_up_count += 1
                    if d[3] == code:
                        limit_up_time = d[4]
            # 根据涨停时间排序
            block_datas.sort(key=lambda d: (d[4] if len(d[4]) > 6 else '15:00:00'))
            for i in range(len(block_datas)):
                if block_datas[i][3] == code:
                    datas.append((block, limit_up_count, (i + 1) if limit_up_time is not None else (limit_up_count + 1),
                                  block_datas[i][5], block_datas[i][6]))
                    break
server.py
@@ -30,9 +30,11 @@
import ths_industry_util
import ths_util
import tool
from output import code_info_output
from third_data import hot_block_data_process
from ths import l2_listen_pos_health_manager
from trade import trade_gui, trade_data_manager, trade_manager, l2_trade_util, deal_big_money_manager
from trade import trade_gui, trade_data_manager, trade_manager, l2_trade_util, deal_big_money_manager, \
    first_code_score_manager
import l2_code_operate
from code_data_util import ZYLTGBUtil
import l2.transaction_progress
@@ -286,11 +288,18 @@
                            logger_first_code_record.info("新增首板:{}", new_add_codes)
                            # 获取60天最大记录
                            for code in codes:
                                need_get_volumn = False
                                if code not in global_util.max60_volumn or global_util.max60_volumn.get(code) is None:
                                    need_get_volumn = True
                                if not need_get_volumn and code_nature_analyse.CodeNatureRecordManager.get_nature(
                                        code) is None:
                                    need_get_volumn = True
                                if need_get_volumn:
                                    volumes_data = juejin.get_volumns_by_code(code, 150)
                                    volumes = juejin.parse_max_volume(volumes_data[:60])
                                    volumes = juejin.parse_max_volume(volumes_data[:60], code_nature_analyse.is_new_top(
                                        gpcode_manager.get_limit_up_price(code), volumes_data[:60]))
                                    logger_first_code_record.info("{} 获取到首板60天最大量:{}", code, volumes)
                                    code_volumn_manager.set_histry_volumn(code, volumes[0], volumes[1])
                                    code_volumn_manager.set_histry_volumn(code, volumes[0], volumes[1], volumes[2])
                                    # 判断K线形态
                                    is_has_k_format, msg = code_nature_analyse.is_has_k_format(
                                        gpcode_manager.get_limit_up_price(code), volumes_data)
@@ -300,11 +309,9 @@
                                        bad_codes.add(code)
                                        # 加入禁止交易代码
                                        l2_trade_util.forbidden_trade(code)
                                        break
                                    else:
                                        code_nature_analyse.set_record_datas(code,
                                                                             gpcode_manager.get_limit_up_price(code),
                                                                             volumes_data)
                                    code_nature_analyse.set_record_datas(code,
                                                                         gpcode_manager.get_limit_up_price(code),
                                                                         volumes_data)
                            # 移除代码
                            listen_codes = gpcode_manager.get_listen_codes()
@@ -704,9 +711,22 @@
                                        {"block_name": block, "block_size": len(block_datas), "index": i,
                                         "price": block_datas[i][5], "rate": block_datas[i][6]})
                                    break
                    final_data = {'code': code, 'today': today_datas, 'last_day': last_datas}
                    final_data = {'code': code, 'data': code_info_output.get_output_html(code)}
                    return_str = json.dumps({"code": 0, "data": final_data})
                    pass
                # 获取最近2个交易日涨停代码
                elif type == 72:
                    day = tool.get_now_date_str()
                    last_day = juejin.JueJinManager.get_previous_trading_date(day)
                    data_list = list(hot_block_data_process.XGBHotBlockDataManager.list_all(day))
                    data_list_last = list(hot_block_data_process.XGBHotBlockDataManager.list_all(last_day))
                    data_list.extend(data_list_last)
                    codes_set = set()
                    if data_list:
                        for d in data_list:
                            if len(d[4]) > 6:
                                codes_set.add(d[3])
                    return_str = json.dumps({"code": 0, "data": list(codes_set)})
                elif type == 201:
                    # 加入黑名单
                    data = json.loads(_str)
@@ -872,18 +892,29 @@
if __name__ == "__main__":
    codes = ["601698"]
    codes = ["002153", "002253", "002351"]
    for code in codes:
        volumes_data = juejin.get_volumns_by_code(code, 150)
        volumes_data = volumes_data[1:]
        global_data_loader.load_zyltgb()
        limit_up_price = float(gpcode_manager.get_limit_up_price(code))
        # 判断股性
        # is_k_format, msg = code_nature_analyse.is_has_k_format(float(limit_up_price), volumes_data)
        # print(code, is_k_format, msg)
        volumes_data = juejin.get_volumns_by_code(code, 150)
        volumes_data = volumes_data[1:]
        volumes = juejin.parse_max_volume(volumes_data[:60],
                                          code_nature_analyse.is_new_top(gpcode_manager.get_limit_up_price(code),
                                                                         volumes_data[:60]))
        logger_first_code_record.info("{} 获取到首板60天最大量:{}", code, volumes)
        code_volumn_manager.set_histry_volumn(code, volumes[0], volumes[1], volumes[2])
        # 判断K线形态
        is_has_k_format, msg = code_nature_analyse.is_has_k_format(
            gpcode_manager.get_limit_up_price(code), volumes_data)
        if not is_has_k_format:
            logger_first_code_record.info("{}首板K线形态不好,{}", code, msg)
            # 加入禁止交易代码
            l2_trade_util.forbidden_trade(code)
        code_nature_analyse.set_record_datas(code,
                                             limit_up_price,
                                             gpcode_manager.get_limit_up_price(code),
                                             volumes_data)
        print(code_nature_analyse.get_k_format(float(limit_up_price), volumes_data))
        # code_nature_analyse.set_record_datas(code,
        #                                      limit_up_price,
        #                                      volumes_data)
third_data/hot_block.py
@@ -70,10 +70,10 @@
        time.sleep(3)
        # 交易时间才识别
        time_str = datetime.datetime.now().strftime("%H%M%S")
        if int(time_str) < int("092500") or int(time_str) > int("150000"):
            continue
        if int("113000") < int(time_str) < int("130000"):
            continue
        # if int(time_str) < int("092500") or int(time_str) > int("150000"):
        #     continue
        # if int("113000") < int(time_str) < int("130000"):
        #     continue
        try:
            day, result = __parseData(driver)
            callback(day, result)
third_data/hot_block_data_process.py
@@ -16,10 +16,12 @@
class XGBHotBlockDataManager:
    total_datas = []
    __last_datas={}
    __last_datas = {}
    latest_datas = None
    @classmethod
    def save(cls,day, datas):
    def save(cls, day, datas):
        cls.latest_datas = datas
        mysqldb = mysql_data.Mysqldb()
        # 统计代码所属板块
        code_block_dict = {}
@@ -35,15 +37,22 @@
                code = code_info[0].split(".")[0]
                _id = f"{day}_{data[0]}_{code}"
                result = mysqldb.select_one("select count(*) from xgb_hot_block where _id='{}'".format(_id))
                if not result[0]:
                result = mysqldb.select_one("select * from xgb_hot_block where _id='{}'".format(_id))
                limit_up_time = code_info[4]
                if len(limit_up_time) <= 6:
                    limit_up_time = ''
                if not result:
                    mysqldb.execute(
                        f"insert into xgb_hot_block(_id,_day,_block_name,_code,_limit_up_time,_price,_rate,_update_time) values('{_id}','{day}','{data[0]}','{code}','{code_info[4]}','{code_info[2]}','{code_info[3]}',now())")
                        f"insert into xgb_hot_block(_id,_day,_block_name,_code,_limit_up_time,_price,_rate,_update_time,_first_limit_up_time) values('{_id}','{day}','{data[0]}','{code}','{code_info[4]}','{code_info[2]}','{code_info[3]}',now(),'{limit_up_time}')")
                else:
                    # 如果上次的数据和这次一样就不更新,否则需要更新数据
                    if cls.__last_datas.get(_id) != code_info:
                        # 更新
                        mysqldb.execute(f"update xgb_hot_block set _limit_up_time='{code_info[4]}',_price='{code_info[2]}',_rate='{code_info[3]}' where _id='{_id}'")
                        mysqldb.execute(
                            f"update xgb_hot_block set _limit_up_time='{code_info[4]}',_price='{code_info[2]}',_rate='{code_info[3]}',_update_time=now() where _id='{_id}'")
                        if (not result[8] or len(result[8]) <= 6) and len(limit_up_time) >= 6:
                            mysqldb.execute(
                                f"update xgb_hot_block set _first_limit_up_time='{limit_up_time}',_update_time=now() where _id='{_id}'")
                cls.__last_datas[_id] = code_info
                # 获取原来的代码所属板块,删除之前错误的板块
                old_datas = XGBHotBlockDataManager.list_by_code(code, day)
@@ -85,37 +94,37 @@
        return None
    limit_up_codes_set = set()
    for block in latest_datas:
        if block[0] == target_block:
            for code_data in block[2]:
                if len(code_data[4]) > 6:
                    limit_up_codes_set.add(code_data[0].split('.')[0])
    if XGBHotBlockDataManager.latest_datas:
        for block in XGBHotBlockDataManager.latest_datas:
            if block[0] == target_block:
                for code_data in block[2]:
                    if len(code_data[4]) > 6:
                        limit_up_codes_set.add(code_data[0].split('.')[0])
    limit_up_codes_set.discard(code)
    limit_up_count = len(limit_up_codes_set)
    total_datas = XGBHotBlockDataManager.total_datas
    codes = set()
    break_codes = set()
    for data in total_datas:
        block = data[2]
        if block != target_block:
            continue
        code = data[3]
        limit_up_time = data[4]
        if len(limit_up_time) > 6:
            codes.add(code)
    codes.discard(code)
    codes.difference(limit_up_codes_set)
        first_limit_up_time = data[8]
        if len(limit_up_time) <= 6 and first_limit_up_time and len(first_limit_up_time) > 6:
            break_codes.add(code)
    # 排除自己
    break_codes.discard(code)
    # 排除已经涨停的代码
    break_codes = break_codes.difference(limit_up_codes_set)
    # 炸板个数
    break_size = len(codes)
    return (limit_up_count,break_size)
latest_datas = []
    break_size = len(break_codes)
    return target_block, limit_up_count, break_size
# 保存数据
def save_datas(day, datas):
    latest_datas = datas
    XGBHotBlockDataManager.save(day, datas)
    code_block_dict = {}
    block_codes_dict = {}
@@ -167,5 +176,7 @@
if __name__ == "__main__":
    XGBHotBlockDataManager.total_datas=XGBHotBlockDataManager.list_all("2023-03-23")
    get_info('002230')
    # XGBHotBlockDataManager.total_datas=XGBHotBlockDataManager.list_all("2023-03-23")
    # get_info('002230')
    codes = set([1, 2, 3, 4])
    print(codes.difference(set([1, 2])))
third_data/kpl_util.py
New file
@@ -0,0 +1,25 @@
def parse_kpl_datas(results):
    start_y = -1
    end_x = -1
    index = 0
    datas = []
    for result in results:
        text = result[1]
        if text.find("股票名称") > -1:
            start_y = result[0][0][1]
        if text.find("竞价涨幅") > -1:
            end_x = result[0][0][0]
        if start_y > 0 and end_x > 0:
            if result[0][0][0] < end_x and result[0][0][1] > start_y and (result[0][1][0] - result[0][0][0]) > 30:
                datas.append(text)
                index += 1
    datas = datas[:3 * 5]
    fdatas = []
    temp = []
    for data in datas:
        temp.append(data)
        if len(temp) == 3:
            fdatas.append((temp[2][:6], temp[1]))
            temp = []
    return fdatas
trade/bidding_money_manager.py
@@ -28,7 +28,7 @@
# 获取竞价金额
def get_bidding_money(code):
def get_bidding_money(code) -> object:
    val = __get_redis().get("bidding_money")
    if not val:
        return None
@@ -37,3 +37,9 @@
        if v[0] == code:
            return v[1]
    return None
if __name__ == "__main__":
    # datas = [('002229', '10.92亿'), ('000977', '2592万'), ('000829', '2294万'), ('002467', '1869万'), ('002217', '1546万')]
    # set_bidding_money(datas)
    print(get_bidding_money("000977"))
trade/deal_big_money_manager.py
@@ -28,6 +28,19 @@
    return None
def __save_traded_index(code, index):
    __get_redis().sadd(f"deal_indexes-{code}", index)
    __get_redis().expire(f"deal_indexes-{code}", tool.get_expire())
def __get_traded_indexes(code):
    return __get_redis().smembers(f"deal_indexes-{code}")
# 获取成交的索引
def get_traded_indexes(code):
    return __get_traded_indexes(code)
# 获取成交计算进度
def __get_deal_compute_progress(code):
    val = __get_redis().get(f"deal_compute_info-{code}")
@@ -60,6 +73,7 @@
            cancel_data = __get_cancel_data(code, data, local_today_num_operate_map)
            if cancel_data is None:
                deal_num += val["num"]
                __save_traded_index(code, data["index"])
    __set_deal_compute_progress(code, progress, deal_num)
trade/first_code_score_manager.py
@@ -21,151 +21,192 @@
def __get_score(zyltgb, limit_price, bidding, k_form, code_nature, hot_block, volume_rate, limit_up_time,
                deal_big_money):
    score = 0
    score_list = []
    # 开盘前竞价
    if bidding:
        score += 25
        score_list.append(25)
    else:
        score_list.append(0)
    # 大单成交
    if deal_big_money:
        score += 30
        score_list.append(30)
    else:
        score_list.append(0)
    # 量
    volume_score = [0, 40, 50, 40, 30, 10, -150, -1000]
    volume_rates = [0, 0.499, 0.649, 0.799, 0.949, 1.099, 1.249, 1.399]
    for i in range(1, len(volume_rates)):
        if volume_rates[i - 1] <= volume_rate < volume_rates[i]:
            score += volume_score[i - 1]
            score_list.append(volume_score[i - 1])
            break
    # 15个交易日是否涨幅24.9%
    if k_form[0]:
        score += -100
        score_list.append(-100)
    else:
        score_list.append(0)
    # 是否破前高
    if k_form[1]:
        score += 50
        score_list.append(50)
    else:
        score_list.append(0)
    # 是否超跌
    if k_form[2]:
        score += 40
        score_list.append(40)
    else:
        score_list.append(0)
    # 是否接近前高
    if k_form[3]:
        score += -50
        score_list.append(-50)
    else:
        score_list.append(0)
    # 是否N
    if k_form[4]:
        score += 35
        score_list.append(35)
    else:
        score_list.append(0)
    # 是否V
    if k_form[5]:
        score += 30
        score_list.append(30)
    else:
        score_list.append(0)
    if not code_nature[0]:
        score += 5
        score_list.append(5)
    else:
        score_list.append(0)
    if code_nature[1]:
        score += 20
        score_list.append(20)
    else:
        score_list.append(0)
    if hot_block[0] >= 2:
        score += 40
        score_list.append(40)
    else:
        score += 30
        score_list.append(30)
    if hot_block[1] > 0:
        score += 10
        score_list.append(10)
    else:
        score_list.append(0)
    if zyltgb:
        score += -80
        score_list.append(-80)
        zyltgbs = [0, 10, 31, 51, 101, 150, 250, 1000000]
        zyltgb_score = [5, 25, 20, 15, 10, 5, -80]
        for i in range(1, len(zyltgbs)):
            if zyltgbs[i - 1] <= zyltgb / 100000000 < zyltgbs[i]:
                score_list.append(zyltgb_score[i - 1])
    else:
        score_list.append(0)
    if limit_price:
        score += -1000
        score_list.append(-1000)
    else:
        score_list.append(0)
    # 开盘前竞价
    if bidding:
        score_list.append(25)
    else:
        score_list.append(0)
    k_score = []
    # 15个交易日是否涨幅24.9%
    if k_form[0]:
        k_score.append(-25)
    else:
        k_score.append(0)
    # 是否破前高
    if k_form[1]:
        k_score.append(50)
    else:
        k_score.append(0)
    # 是否超跌
    if k_form[2]:
        k_score.append(40)
    else:
        k_score.append(0)
    # 是否接近前高
    if k_form[3]:
        k_score.append(-25)
    else:
        k_score.append(0)
    # 是否N
    if k_form[4]:
        k_score.append(35)
    else:
        k_score.append(0)
    # 是否V
    if k_form[5]:
        k_score.append(30)
    else:
        k_score.append(0)
    score_list.append(k_score)
    nature_score = []
    if code_nature is None:
        code_nature = [True, False]
    if not code_nature[0]:
        nature_score.append(5)
    else:
        nature_score.append(0)
    if code_nature[1]:
        nature_score.append(20)
    else:
        nature_score.append(0)
    score_list.append(nature_score)
    hot_block_score = []
    if hot_block[1] >= 2:
        hot_block_score.append(40)
    else:
        hot_block_score.append(30)
    if hot_block[2] > 0:
        hot_block_score.append(10)
    else:
        hot_block_score.append(0)
    score_list.append(hot_block_score)
    # 量
    volume_score = [0, 40, 50, 40, 30, 10, -15, -35]
    volume_rates = [0, 0.499, 0.649, 0.799, 0.949, 1.099, 1.249, 1.399]
    volume_add = False
    for i in range(1, len(volume_rates)):
        if volume_rates[i - 1] <= volume_rate < volume_rates[i]:
            score_list.append(volume_score[i - 1])
            volume_add = True
            break
    if not volume_add:
        score_list.append(volume_score[-1])
    if limit_up_time:
        score += 20
        score_list.append(20)
    else:
        score_list.append(0)
        # 大单成交
    if deal_big_money:
        score_list.append(30)
    else:
        score_list.append(0)
    score = 0
    for s in score_list:
        if type(s) == list:
            for ss in s:
                score += ss
        else:
            score += s
    return score, score_list
def get_score(code, volume_rate, limit_up_time):
    bidding_money = bidding_money_manager.get_bidding_money(code)
    bidding = False
    if bidding_money and bidding_money >= 5000:
        bidding = True
def get_score(code, volume_rate, limit_up_time, with_source_data=False):
    source_datas = []
    # 获取自由流通股本
    zyltgb = global_util.zyltgb_map.get(code)
    if zyltgb is None:
        global_data_loader.load_zyltgb()
        zyltgb = global_util.zyltgb_map.get(code)
    if zyltgb is None:
        zyltgb = 100 * 100000000
    source_datas.append(zyltgb)
    limit_price = float(gpcode_manager.get_limit_up_price(code))
    source_datas.append(limit_price)
    # 竞价金额
    bidding_money = bidding_money_manager.get_bidding_money(code)
    source_datas.append(bidding_money)
    bidding = False
    if bidding_money and bidding_money >= 5000:
        bidding = True
    k_form = code_nature_analyse.CodeNatureRecordManager.get_k_format(code)
    if k_form is None:
        k_form = [True, False, False, False, False, False]
        k_form = [(True, ''), (False, ''), (False, ''), (False, ''), (False, ''), (False, '')]
    source_datas.append(k_form)
    code_nature = code_nature_analyse.CodeNatureRecordManager.get_nature(code)
    source_datas.append(code_nature)
    hot_block = hot_block_data_process.get_info(code)
    if hot_block is None:
        hot_block = (1, 0)
        hot_block = ('无板块', 1, 0)
    else:
        # 加上自己
        hot_block = (hot_block[0] + 1, hot_block[1])
        hot_block = (hot_block[0], hot_block[1] + 1, hot_block[2])
    source_datas.append(hot_block)
    source_datas.append(volume_rate)
    source_datas.append(limit_up_time)
    if limit_up_time and tool.trade_time_sub(limit_up_time, "10:00:00") < 0:
        limit_up_time = True
    else:
        limit_up_time = False
    # 获取成交大单
    deal_big_num = deal_big_money_manager.get_deal_big_money_num(code)
    m = l2_trade_factor.L2TradeFactorUtil.get_base_safe_val(zyltgb)
    limit_price = float(gpcode_manager.get_limit_up_price(code))
    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
    return __get_score(zyltgb >= 250 * 100000000, limit_price > 100, bidding, k_form, code_nature, hot_block,
                       volume_rate, limit_up_time, deal_big_num)
    k_form_1 = []
    for d in k_form:
        k_form_1.append(d[0])
    result = __get_score(zyltgb, limit_price > 100, bidding, k_form_1, code_nature, hot_block,
                         volume_rate, limit_up_time, deal_big_num)
    if with_source_data:
        return result, source_datas
    return result
if __name__ == "__main__":
    global_data_loader.load_zyltgb()
    score = get_score("601698", 1.2, "15:00:01")
    score = get_score("000779", 1.2, "15:00:01", True)
    print(score)
trade/l2_trade_factor.py
@@ -13,45 +13,105 @@
# 下单参数
class L2PlaceOrderParamsManager:
    # 得分
    def __init__(self, code, is_first_code, volume_rate, volume_rate_index, score):
        self.code = code
        self.is_first_code = is_first_code
        score_ranks = [200, 190, 180, 100]
        self.score = score[0]
        # 为分数设置等级
        score_index = -1
        for i in range(0, len(score_ranks)):
            if self.score >= score_ranks[i]:
                score_index = i
                break
        self.score_index = score_index
        self.volume_rate = volume_rate
        self.volume_rate_index = volume_rate_index
    # 获取信号连续买笔数
    @staticmethod
    def get_begin_continue_buy_count(volume_rate_index):
    def get_begin_continue_buy_count(self):
        counts = [3, 3, 3, 2, 2, 2, 2]
        if volume_rate_index >= len(counts):
        volume_rate_index = self.volume_rate_index
        if self.volume_rate_index >= len(counts):
            volume_rate_index = -1
        return counts[volume_rate_index]
    # 获取时间计算范围,返回s
    @staticmethod
    def get_time_range(volume_rate_index):
    def get_time_range(self):
        ts = [pow(3, 1), pow(3, 1), pow(3, 1), pow(3, 2), pow(3, 2), pow(3, 3), pow(3, 3), pow(3, 3)]
        if volume_rate_index >= len(ts):
        volume_rate_index = self.volume_rate_index
        if self.volume_rate_index >= len(ts):
            volume_rate_index = -1
        return ts[volume_rate_index]
    # 获取需要的大单个数
    @staticmethod
    def get_big_num_count(volume_rate_index):
    def get_big_num_count(self):
        if self.is_first_code:
            if self.score_index == 0:
                return 0
            elif self.score_index == 1:
                return 0
            elif self.score_index == 2:
                return 1
            elif self.score_index < 0:
                return 65535
        counts = [3, 1, 1, 1, 0, 0, 0, 0]
        if volume_rate_index >= len(counts):
        volume_rate_index = self.volume_rate_index
        if self.volume_rate_index >= len(counts):
            volume_rate_index = -1
        return counts[volume_rate_index]
    # 获取安全笔数影响比例
    @staticmethod
    def get_safe_count_rate(volume_rate_index):
    def get_safe_count_rate(self):
        rates = [0, -0.1, -0.2, -0.4, -0.6, -0.8, -0.8, -0.8]
        if volume_rate_index >= len(rates):
        volume_rate_index = self.volume_rate_index
        if self.volume_rate_index >= len(rates):
            volume_rate_index = -1
        return rates[volume_rate_index]
    def get_safe_count(self):
        if self.is_first_code:
            if 3 > self.score_index > -1:
                return 0
            elif self.score_index < 0:
                return 65535
        base_count, min_count, max_count = L2TradeFactorUtil.get_safe_buy_count(self.code, True)
        rate = self.get_safe_count_rate()
        count = int(round(base_count * (1 + rate)))
        return count
    # 获取m值影响比例
    @staticmethod
    def get_m_val_rate(volume_rate_index):
    @classmethod
    def get_m_val_rate(cls, volume_rate_index):
        rates = [0.0, 0.0, 0.0, -0.3, -0.4, -0.5, -0.6, -0.7]
        if volume_rate_index >= len(rates):
            volume_rate_index = -1
        return rates[volume_rate_index]
    # 获取m值
    def get_m_val(self):
        if self.is_first_code:
            if self.score_index == 0:
                return 0, ""
            elif self.score_index == 1:
                return 1000 * 10000, ""
            elif self.score_index == 2:
                return 1000 * 10000, ""
            elif self.score_index < 0:
                return 65535 * 10000, ""
        # 获取固定m值
        zyltgb = global_util.zyltgb_map.get(self.code)
        if zyltgb is None:
            global_data_loader.load_zyltgb()
            zyltgb = global_util.zyltgb_map.get(self.code)
        base_m = L2TradeFactorUtil.get_base_safe_val(zyltgb)
        rate = self.get_m_val_rate(self.volume_rate_index)
        m = round(base_m * (1 + rate))
        return m, ""
# S撤参数
@@ -105,11 +165,13 @@
    # 获取基础m值,返回单位为元
    @classmethod
    def get_base_safe_val(cls, zyltgb):
        if zyltgb is None:
            return 10000000
        yi = round(zyltgb / 100000000)
        if yi < 1:
            yi = 1
        m = 5000000 + (yi - 1) * 500000
        return round(m*(1-0.3))
        return round(m * (1 - 0.3))
    # 获取行业影响比例
    # total_limit_percent为统计的比例之和乘以100
@@ -144,8 +206,8 @@
        if today is None:
            return 0
        old_volumn = int(yest)
        if int(day60_max) > int(yest):
            old_volumn = int(day60_max)
        if int(day60_max[0]) > int(yest):
            old_volumn = int(day60_max[0])
        r = round(int(today) / old_volumn, 2)
        if r < 0.01:
            r = 0.01
@@ -325,7 +387,7 @@
            MAX_VAL = 13
        if not gb:
            # 默认8笔
            return MIN_VAL
            return MIN_VAL,MIN_VAL, MAX_VAL
        count = gb // 100000000
        if True:
            if count < 8:
trade/trade_gui.py
@@ -568,7 +568,7 @@
        main_hwnds = []
        win32gui.EnumWindows(lambda hWnd, param: param.append(hWnd), hWndList)
        for hwnd in hWndList:
            if THSGuiUtil.getText(hwnd) == "专业版下单":
            if win32gui.IsWindowVisible(hwnd) and THSGuiUtil.getText(hwnd) == "专业版下单":
                main_hwnds.append(hwnd)
        if not main_hwnds:
            raise Exception("专业版下单未打开")