Administrator
2023-04-28 c8b740733f0f9fcf438fc4606eea317011ebd8bd
看盘页面及相关接口修改
10个文件已修改
1个文件已添加
892 ■■■■■ 已修改文件
alert_util.py 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
constant.py 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
output/code_info_output.py 178 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
output/css/index.css 212 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
output/index.html 348 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
server.py 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/block_info.py 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/data_server.py 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/kpl_api.py 28 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
third_data/kpl_data_manager.py 24 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
trade/trade_manager.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
alert_util.py
@@ -11,7 +11,8 @@
def alarm():
    if not tool.is_alert_time() or constant.TEST:
        return
    # TODO 暂时关闭报警
    if not constant.NEED_ALERT:
        return
    AlertUtil().stop_audio()
    AlertUtil().play_audio()
constant.py
@@ -1,7 +1,11 @@
# 是否为测试
TEST = True
TEST = False
# 是否允许交易
TRADE_ENABLE = False
# 是否需要报警
NEED_ALERT =True
# 水下捞累计连续水下时间最小值
UNDER_WATER_PRICE_TIME_AS_SECONDS = 1200
# 大单金额(单位为百)
output/code_info_output.py
@@ -8,6 +8,7 @@
# 市场热度
import os
import sys
import time
import code_volumn_manager
import constant
@@ -19,7 +20,8 @@
import log
import tool
from l2 import l2_data_manager, l2_data_util, transaction_progress, l2_data_manager_new, code_price_manager
from third_data import kpl_data_manager, kpl_util
from third_data import kpl_data_manager, kpl_util, kpl_api, block_info
from third_data.kpl_data_manager import KPLLimitUpDataRecordManager, KPLDataManager
from trade import first_code_score_manager, l2_trade_factor, trade_manager, l2_trade_util
from trade.l2_trade_factor import L2TradeFactorUtil
import trade.deal_big_money_manager
@@ -73,6 +75,7 @@
    # 获取白名单,黑名单
    if trade_manager.gpcode_manager.WantBuyCodesManager.is_in(code):
        code_extra_infos.append("想买单")
    params["code"] = code
    params["code_name"] = f"{gpcode_manager.get_code_name(code)} {code}  ({','.join(code_extra_infos)})"
    score_info = None
@@ -201,7 +204,8 @@
                # 高位版信息
                "high_block_infos": [],
            }
        params["score_data"]["hot_block"] = {"score": hot_block_score,"limit_up_index":hot_block_source_data['limit_up_index']+1,
        params["score_data"]["hot_block"] = {"score": hot_block_score,
                                             "limit_up_index": hot_block_source_data['limit_up_index'] + 1,
                                             "block_name": hot_block_source_data['target_block_info'][0],
                                             "limit_up_count": hot_block_source_data['limit_up_codes_count'],
                                             "open_limit_up_count": hot_block_source_data['break_size']}
@@ -219,7 +223,7 @@
        # deal_big_money
        ###############################下单信息###############################
        params["score_data"]["trade_data"] = {}
        params["trade_data"] = {}
        # 获取买入意愿
        volume_rate = score_source_list[6]
@@ -235,22 +239,22 @@
                                                                                     ((score, score_list),
                                                                                      score_source_list))
        if -1 < __L2PlaceOrderParamsManager.score_index < 3:
            params["score_data"]["trade_data"]["start"] = {"desc": "主动买入"}
            params["trade_data"]["star"] = {"desc": "主动买入"}
            if __L2PlaceOrderParamsManager.score_index == 0:
                params["score_data"]["trade_data"]["start"]["count"] = 3
                params["trade_data"]["star"]["count"] = 3
            elif __L2PlaceOrderParamsManager.score_index == 1:
                params["score_data"]["trade_data"]["start"]["count"] = 2
                params["trade_data"]["star"]["count"] = 2
            else:
                params["score_data"]["trade_data"]["start"]["count"] = 1
                params["trade_data"]["star"]["count"] = 1
        elif __L2PlaceOrderParamsManager.score_index < 0:
            params["score_data"]["trade_data"]["start"] = {"desc": "不执行买入", "count": 0}
            params["trade_data"]["star"] = {"desc": "不执行买入", "count": 0}
        else:
            params["score_data"]["trade_data"]["start"] = {"desc": "被动买入", "count": 0}
            params["trade_data"]["star"] = {"desc": "被动买入", "count": 0}
        # 安全笔数
        safe_count = __L2PlaceOrderParamsManager.get_safe_count()
        base_safe_count, min_count, max_count = L2TradeFactorUtil.get_safe_buy_count(code, True)
        params["score_data"]["trade_data"]["safe_count"] = {"base": base_safe_count, "now": safe_count}
        params["trade_data"]["safe_count"] = {"base": base_safe_count, "now": safe_count}
        # 动态M值
        m = __L2PlaceOrderParamsManager.get_m_val()
        zyltgb = global_util.zyltgb_map.get(code)
@@ -258,11 +262,11 @@
            global_data_loader.load_zyltgb()
            zyltgb = global_util.zyltgb_map.get(code)
        base_m = L2TradeFactorUtil.get_base_safe_val(zyltgb)
        params["score_data"]["trade_data"]["m"] = {"base": base_m // 10000, "now": m[0] // 10000},
        params["trade_data"]["m_val"] = {"base": base_m // 10000, "now": m[0] // 10000},
        # 买前大单
        big_num = __L2PlaceOrderParamsManager.get_big_num_count()
        base_big_num = __base_L2PlaceOrderParamsManager.get_big_num_count()
        params["score_data"]["trade_data"]["big_num"] = {"base": base_big_num, "now": big_num}
        params["trade_data"]["big_num"] = {"base": base_big_num, "now": big_num}
        # 成交进度
        trade_progress, is_default = transaction_progress.TradeBuyQueue().get_traded_index(code)
        if trade_progress is None or trade_progress < 0 or is_default:
@@ -270,8 +274,8 @@
            pass
        else:
            data = total_datas[trade_progress]
            params["score_data"]["trade_data"]["trade_progress"] = {"time": data['val']['time'],
                                                                    "num": data['val']['num'], "money": round(
            params["trade_data"]["trade_progress"] = {"time": data['val']['time'],
                                                      "num": data['val']['num'], "money": round(
                    data['val']['num'] * float(data['val']['price']) * 100 / 10000, 1)}
        # 买入信号
@@ -283,18 +287,33 @@
            pass
        else:
            data = total_datas[buy_single_index]
            params["score_data"]["trade_data"]["buy_single"] = {"time": data['val']['time'], "num": data['val']['num'],
                                                                "money": round(data['val']['num'] * float(
                                                                    data['val']['price']) * 100 / 10000, 1)}
            params["trade_data"]["buy_single"] = {"time": data['val']['time'], "num": data['val']['num'],
                                                  "money": 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("未下单")
            pass
        else:
            data = total_datas[buy_exec_index]
            params["score_data"]["trade_data"]["buy_exec"] = {"time": data['val']['time'], "num": data['val']['num'],
                                                              "money": round(data['val']['num'] * float(
                                                                  data['val']['price']) * 100 / 10000, 1)}
            params["trade_data"]["buy_exec"] = {"time": data['val']['time'], "num": data['val']['num'],
                                                "money": round(data['val']['num'] * float(
                                                    data['val']['price']) * 100 / 10000, 1)}
        params["trade_data"]["trade_state"] = {}
        trade_state = trade_manager.get_trade_state(code)
        if trade_state == trade_manager.TRADE_STATE_BUY_PLACE_ORDER or trade_state == trade_manager.TRADE_STATE_BUY_DELEGATED:
            params["trade_data"]["trade_state"]["order"] = True
            params["trade_data"]["trade_state"]["desc"] = "已下单"
        else:
            params["trade_data"]["trade_state"]["order"] = False
            if trade_state == trade_manager.TRADE_STATE_NOT_TRADE:
                params["trade_data"]["trade_state"]["desc"] = "未交易"
            elif trade_state == trade_manager.TRADE_STATE_BUY_CANCEL_ING:
                params["trade_data"]["trade_state"]["desc"] = "撤单中"
            elif trade_state == trade_manager.TRADE_STATE_BUY_CANCEL_SUCCESS:
                params["trade_data"]["trade_state"]["desc"] = "撤单成功"
            elif trade_state == trade_manager.TRADE_STATE_BUY_SUCCESS:
                params["trade_data"]["trade_state"]["desc"] = "已成交"
    ##############################选股宝##################################
@@ -320,39 +339,91 @@
    params["trade_record"] = {"open_limit_up": trade_info[0], "records": trade_info[2]}
    ##############################开盘啦相关信息##################################
    params["kpl_industry_rank"] = []
    params["kpl_best_feng_kou"] = []
    params["kpl_feng_kou"] = []
    params["kpl_feng_xiang"] = []
    best_fengkou = __kplDataManager.get_data(kpl_util.KPLDataType.BEST_FENG_KOU)
    fengkou = __kplDataManager.get_data(kpl_util.KPLDataType.FENG_KOU)
    fengxiang = __kplDataManager.get_data(kpl_util.KPLDataType.FENG_XIANG)
    rank_infos = __kplDataManager.get_data(kpl_util.KPLDataType.INDUSTRY_RANK)
    # (代码,名称,强度,涨幅,热门板块,所有板块)
    if best_fengkou:
        for r in best_fengkou:
            hot_block = "、".join(r[4].split("、")[:2])
            params["kpl_best_feng_kou"].append(
                {"name": r[1], "weight": r[2], "money": money_desc(r[2]), "rate": r[3], "hot_block": hot_block,
                 "hot_block_all": r[5]})
    if fengkou:
        fengkou = fengkou[:30]
        for r in fengkou:
            # 市场风口
            # (代码,名称,涨幅,主力净额,风口概念)
            params["kpl_feng_kou"].append(
                {"name": r[1], "money": money_desc(r[3]), "rate": r[2], "block": r[4]})
    if fengxiang:
        for r in fengxiang:
            # 风向标
            # (代码, 名称, 现价, 涨幅, 板块, 300万大单净额, 主力净额, 自由市值)
            params["kpl_feng_xiang"].append(
                {"name": r[1], "money_300w": money_desc(r[5]), "money_main": money_desc(r[6]), "rate": r[3],
                 "block": r[4]})
    params["kpl_code_info"] = {}
    # 获取开盘啦板块
    plate_info = kpl_api.getStockIDPlate(code)
    if plate_info:
        plate_info.sort(key=lambda x: x[2])
        plate_info.reverse()
        params["kpl_code_info"]["plate"] = plate_info
    if rank_infos:
        for r in rank_infos:
            params["kpl_industry_rank"].append({"name": r[1], "money": money_desc(r[2]), "rate": r[3]})
    # 获取代码的历史涨停数据
    params["kpl_code_info"]["code_records"] = KPLLimitUpDataRecordManager.get_latest_infos(code, 4)
    # 获取今日板块
    block = block_info.get_target_block(code, False)
    if block is None:
        block = "无板块"
    # 获取最近的4个交易日
    today = tool.get_now_date_str()
    days = []
    day = today
    for i in range(3):
        day = juejin.JueJinManager.get_previous_trading_date(day)
        days.append(day)
    days.insert(0, today)
    # 获取这几天的涨停代码
    kpl_record_datas = {}
    for d in days:
        tem_datas = KPLLimitUpDataRecordManager.list_by_block(block, d)
        tem_datas = list(tem_datas)
        # 根据涨停时间排序
        tem_datas.sort(key=lambda x: int(x[5]))
        kpl_record_datas[d] = {"codes": [], "hot_block": block, "index": -1, "limit_up_count": 0}
        for i in range(len(tem_datas)):
            temp = tem_datas[i]
            __code = temp[3]
            kpl_record_datas[d]["codes"].append(
                {"name": temp[4], "code": __code, "limit_up": False, "open_limit_up": False,"ss":(__code.find("00")==0 or __code.find("60")==0) })
            if __code == code:
                kpl_record_datas[d]["blocks"] = temp[6].split("、")
                kpl_record_datas[d]["index"] = i + 1
                kpl_record_datas[d]["limit_up_time"] = time.strftime("%H:%M:%S", time.localtime(int(temp[5])))
    # 获取今日代码的得分
    __score_dict = {}
    for fs in codes_score:
        for s in fs:
            # (得分,是否涨停)
            __score_dict[s[0]] = (s[2], s[3])
    # 获取分值
    for d in kpl_record_datas[today]["codes"]:
        __code = d["code"]
        if __code in __score_dict:
            d["score"] = __score_dict[__code][0]
    # 获取是否涨停,统计涨停数量
    for d in kpl_record_datas:
        # 获取涨停代码信息
        limit_up_datas = __kplDataManager.get_from_file(kpl_util.KPLDataType.LIMIT_UP, d)
        if limit_up_datas is None:
            limit_up_datas = []
        limit_up_codes = set([x[0] for x in limit_up_datas])
        limit_up_count = 0
        for code_info in kpl_record_datas[d]["codes"]:
            __code = code_info["code"]
            if __code in limit_up_codes:
                code_info["limit_up"] = True
                code_info["open_limit_up"] = False
                limit_up_count += 1
            else:
                code_info["limit_up"] = False
                code_info["open_limit_up"] = True
        kpl_record_datas[d]["limit_up_count"] = limit_up_count
    block_records = [[key, kpl_record_datas[key]] for key in kpl_record_datas]
    block_records.sort(key=lambda x: x[0])
    block_records.reverse()
    for i in range(len(block_records)):
        if i == 0:
            block_records[i][0] = "今天"
        elif i == 1:
            block_records[i][0] = "昨天"
        elif i == 2:
            block_records[i][0] = "前天"
        elif i == 3:
            block_records[i][0] = "之前"
    params["kpl_code_info"]["block_records"] = block_records
    return render(params)
@@ -476,7 +547,8 @@
                       "big_num": {"base": 10, "now": 2},
                       "trade_progress": {"time": "09:12:12", "num": 1111, "money": "12.56"},
                       "buy_single": {"time": "09:12:12", "num": 1111, "money": "12.56"},
                       "buy_exec": {"time": "09:12:12", "num": 1111, "money": "12.56"}
                       "buy_exec": {"time": "09:12:12", "num": 1111, "money": "12.56"},
                       },
        "xgb_code_infos": [{"date": "今天", "blocks": [
            {"name": "影视", "limit_up_count": 2, "index": 1, "price": "12.00", "rate": "+10.00%"},
output/css/index.css
@@ -34,10 +34,12 @@
a {
    text-decoration: none;
    color: inherit;
}
a:hover {
    text-decoration: underline;
    text-decoration: none;
    color: inherit;
}
button,
@@ -45,6 +47,10 @@
select,
textarea {
    font-size: 100%;
    margin: 0;
    padding: 0;
    border: 1px solid transparent; //自定义边框
    outline: none; //消除默认点击蓝色边框效果
}
table {
@@ -54,65 +60,94 @@
body {
    max-width: 540px;
    font-size: 13px;
    max-width: 1080px;
    font-size: 14px;
    color: #FFFFFF;
    background: #191921;
    font-family: Microsfot YaHei;
    background: #000000;
    font-family: "Microsfot YaHei","微软雅黑";
}
.top {
    width: 540px;
    height: 50px;
    width: 1080px;
    height: 40px;
    /* padding-left: 15px; */
    line-height: 50px;
    line-height: 40px;
    font-size: 20px;
    background: #3E3E57;
    background: #35353b;
}
.table-name {
    height: 40px;
    line-height: 40px;
    height: 30px;
    width: 520px;
    line-height: 30px;
    padding-left: 10px;
    margin-top: 12px;
    font-size: 16px;
    font-weight: 600;
    background: #2F2F3E;
    background: #200404;
    /* border: 1px solid #191921; */
}
.table-name-right {
    float: left;
    height: 30px;
    width: 50%;
    line-height: 30px;
    /* margin-left: 10px; */
    /* padding-left: 10px; */
    margin-top: 12px;
    font-size: 16px;
    font-weight: 600;
    background: #200404;
    /* border: 1px solid #191921; */
}
.half-width {
    float: left;
    width: 50%;
}
.table-title {
    height: 40px;
    width: 540px;
    font-size: 16px;
    font-weight: 600;
}
table tr td {
    font-size: 13px;
    font-size: 12px;
    padding: 0px 8px;
}
table {
    width: 100%;
    width: 530px;
    border-collapse: collapse;
    border-color: brown;
    /* margin: 0 auto; */
    /* text-align: center; */
}
table td {
    height: 20px;
    height: 26px;
    /* border: 1px solid #191921; */
}
tr {
    border: 1px solid #870000;
}
table tr:nth-child(odd) {
    background: #343444;
    background: #000;
}
table tr:nth-child(even) {
    background: #2F2F3E;
    background: #000;
}
table tr:hover {
    background: #3e3e57;
    background: #222222;
}
.td-max {
@@ -125,11 +160,15 @@
    padding: 0px 3px;
    height: 22px;
    line-height: 22px;
    font-size: 13px;
    font-size: 12px;
    font-weight: 400;
    background: #21212B;
    /*background: #2b2b2b;*/
    border-radius: 5px;
    text-align: center;
}
.color-not-buy{
    color: #00E600;
}
.bold {
@@ -149,6 +188,14 @@
    color: #FFEC17;
}
.bule {
    color: #00d5ff;
}
.purple {
    color: #ff80ff;
}
.num-card-color1 {
    background: #843960;
}
@@ -162,16 +209,15 @@
}
.score-card-color {
    min-width: 40px;
    max-width: 0px;
    padding: 0px 2px;
    height: 22px;
    line-height: 22px;
    font-size: 13px;
    font-weight: 400;
    background: #9B7A15;
    border-radius: 5px;
    text-align: center;
    /*min-width: 40px;*/
    /*max-width: 0px;*/
    /*padding: 0px 2px;*/
    /*height: 22px;*/
    /*line-height: 22px;*/
    /*font-weight: 400;*/
    /*background: #9B7A15;*/
    /*border-radius: 5px;*/
    /*text-align: center;*/
}
.icon-null {
@@ -186,12 +232,14 @@
    display: block;
    /* float: left; */
    width: 106px;
    height: 30px;
    margin-top: -35px;
    height: 28px;
    margin-top: -28px;
    margin-left: 419px;
    border-radius: 5px;
    line-height: 30px;
    line-height: 28px;
    font-size: 14px;
    font-weight: bold;
    color: #fff;
    background: #2059E5;
    text-align: center;
}
@@ -201,50 +249,84 @@
}
.button-blue:active {
    color: #000000;
    background: #002070;
    background: #164cc1;
}
table .sub_title{
    text-align: center;
    font-size: 16px;
}
table .content{
    text-align:center;
    vertical-align: top;
.button-blue:visited {
    background: #00d6cf;
}
.content table{
    width: 250px;
.focus-area-title {
    background: #2c2c64;
}
.content tr td{
    font-size: 12px !important;
    padding: 0 !important;
    max-width: 70px !important;
    width: 70px !important;
}
.kpl tr td{
    padding: 0 !important;
    max-width: 70px !important;
    width: 70px !important;
.focus-area {
    background: #34347c;
}
.table-fxb{
    width: 280px !important;
.plate-container{
  width: 478px;
  overflow: hidden;
  overflow-x: auto;
  white-space: nowrap;
    outline:none;
}
.plate-container div{
    display: inline-block;
    width: 80px;
}
.table-kpl .title{
    width: 40px !important;
    min-width: 30px;
    vertical-align: top;
    padding-top: 10px;
}
.table-kpl{
}
.table-kpl table{
    width: 478px;
    border-style:none !important;
}
.table-kpl .table-content tr td{
    padding-left: 2px;
}
#kpl-best_feng_kou tr td:first-child{
    width: 50px;
    min-width: 50px;
}
.table-fxb tr td:first-child{
    width: 90px !important;
}
.table-fxb tr td:nth-child(2){
    width: 50px !important;
    background: #1CF088;
#kpl-best_feng_kou tr td:nth-child(2){
    width: 30px;
    min-width: 30px;
}
.table-ins{
    width: 200px;
#kpl-feng_kou tr td:first-child{
    width: 50px;
    min-width: 50px;
}
#kpl-feng_kou tr td:nth-child(2){
    width: 45px;
    min-width: 45px;
}
#kpl-feng_xiang tr td:first-child{
    width: 50px;
    min-width: 50px;
}
#kpl-feng_xiang tr td:nth-child(5){
    padding-right:0;
}
output/index.html
@@ -10,9 +10,17 @@
    <body>
        <div class="top">
            <span>
                <h2 style="margin-left: 18px; font-size: 20px;">{{code_name}}</h2>
                <h2 style="margin-left: 18px; font-size: 20px;">{{code_name}}
                    {% if trade_data.trade_state.order  %}
                    <span><a class="button-blue" style="margin-top: -34px;margin-left: 280px;" href="cancel_order://{{code}}" >已撤单</a></span>
                    {% else %}
                    <span><a class="button-blue" style="margin-top: -34px;margin-left: 280px; background: gray" href="javascript:void()" disabled>已撤单</a></span>
                    {% endif %}
                </h2>
            </span>
        </div>
        <!-- 左侧板块 -->
        <div style="float: left;width: 440px;">
        {% if score_data %}
        <div class="table-name">买前评分</div>
        <table>
@@ -161,8 +169,8 @@
            </tr>
            <tr>
                <td>动态M值</td>
                <td>固定M值<span class="num-style ">{{trade_data.m.base}}万</span>&nbsp;&nbsp;&nbsp;动态M值<span
                        class="num-style ">{{trade_data.m.now}}万</span></td>
                <td>固定M值<span class="num-style ">{{trade_data.m_val.base}}万</span>&nbsp;&nbsp;&nbsp;动态M值<span
                        class="num-style ">{{trade_data.m_val.now}}万</span></td>
            </tr>
            <tr>
                <td>买前大单</td>
@@ -204,28 +212,163 @@
            </tr>
        </table>
        {% endif %}
        <div class="table-name">选股宝</div>
        <table>
            {% for k in xgb_code_infos %}
            <tr>
                <td>{{k.date}}</td>
                <td>
    <div class="table-name" style="padding-left: 0">&nbsp;&nbsp;&nbsp;开盘啦</div>
            <table class="table-kpl">
                <tr>
                    <td class="title">历史</td>
                    <td colspan="4">
                        {% if kpl_code_info.code_records %}
                         {% for r in kpl_code_info.code_records %}
                           <span class="num-style">{{r[0]}}</span><span
                            class="num-style">{{r[1]}}</span>&nbsp;&nbsp;&nbsp;&nbsp;
                         {% endfor %}
                        {% endif %}
                    </td>
                </tr>
                <tr>
                    <td class="title">所属板块</td>
                    <td style="padding: 0">
                        <div class="plate-container">
                    {% for item in kpl_code_info.plate %}
                    <div>
                        {% for b in k.blocks %}
                        <span class="num-style ">{{b.name}}</span>&nbsp;共<span
                            class="num-style bold red">{{b.limit_up_count}}</span>只票涨停
                        <br>
                        第<span class="num-style bold red">{{b.index}}</span>涨停,现价<span
                            class="num-style bold red">{{b.price}}</span>元,涨幅<span
                            class="num-style bold red">{{b.rate}}</span>
                        <br>
                        {% endfor %}
                        <span class="num-style">{{item[1]}}</span><br>
                        <span class="num-style">{{item[2]}}%</span>
                    </div>
                </td>
            </tr>
            {% endfor %}
        </table>
        <div class="table-name"><span class="table-title">主动买入</span><span class="button-blue">加入看盘</span></div>
                    {% endfor %}
                    </div>
                    </td>
                </tr>
                                <!-- 历史记录 -->
                <tr>
                    <td class="title" >
                        今天<span class="num-style bold red">{{kpl_code_info.block_records[0][1].limit_up_count}}</span>
                    </td>
                    <td style="padding: 0">
                    <table>
                        <tr>
                            <td colspan="4">
                                <span><b>涨停原因</b></span>&nbsp;<span class="num-style">{{kpl_code_info.block_records[0][1].hot_block}}</span>&nbsp;&nbsp;&nbsp;&nbsp;
                                {% if kpl_code_info.block_records[0][1].blocks %}
                                <span><b>板块</b></span>&nbsp;
                                {% for b in  kpl_code_info.block_records[0][1].blocks %}
                                <span class="num-style">{{b}}</span>&nbsp;
                                {% endfor %}
                                {% endif %}
                                <br>
                                <span><b>涨停时间</b></span>&nbsp;<span
                                    class="num-style">{{kpl_code_info.block_records[0][1].limit_up_time}}</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span><b>板块身位</b></span>&nbsp;<span
                                    class="num-style">龙{{kpl_code_info.block_records[0][1].index}}</span>
                            </td>
                        </tr>
                        <tr >
                            <td style="padding: 0">
                            <table class="table-content">
                                {% for k in kpl_code_info.block_records[0][1].codes %}
                                {% if loop.index0 % 3 ==0 %}
                                <tr>
                                    {% endif %}
                                    <td>
                                        {% if k.limit_up %}
                                        <span><img src="{{base_url}}images/limit_up.png"></span>
                                        {% elif k.open_limit_up %}
                                        <span><img src="{{base_url}}images/stop_up.png"></span>
                                        {% else %}
                                        <span class="icon-null"></span>
                                        {% endif %}
                                        {% if k.ss %}
                                        <span class="num-style">{{k.name}}</span>
                                        {% else %}
                                        <span class="num-style color-not-buy">{{k.name}}</span>
                                        {% endif %}
                                        <span class="num-style">{{k.code}}</span>
                                        {% if k.score %}
                                        <span class="score-card-color yellow">{{k.score}}</span>
                                        {% endif %}
                                    </td>
                                    {% if loop.index0 % 3 ==2 %}
                                </tr>
                                {% elif loop.last %}
                                </tr>
                                {% endif %}
                                {% endfor %}
                            </table>
                            </td>
                        </tr>
                    </table>
                    </td>
                </tr>
                {% for k in kpl_code_info.block_records %}
                {% if loop.index0>0 and k[1].limit_up_count>0 %}
                <tr >
                    <td class="title">
                        {{k[0]}}<span class="num-style bold red">{{k[1].limit_up_count}}</span>
                    </td>
                    <td style="padding: 0">
                    <table>
                        <tr>
                            <td colspan="4">
                                <span>涨停原因</span>&nbsp;<span class="num-style">{{k[1].hot_block}}</span>&nbsp;&nbsp;&nbsp;&nbsp;
                                {% if k[1].blocks %}
                                <span>板块</span>&nbsp;
                                {% for b in  k[1].blocks %}
                                <span class="num-style">{{b}}</span>&nbsp;
                                {% endfor %}
                                {% endif %}
                                <br>
                                {% if k[1].limit_up_time  %}
                                <span>涨停时间</span>&nbsp;<span
                                    class="num-style">{{k[1].limit_up_time}}</span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
                                {% endif %}
                                {% if k[1].index>0  %}
                                <span>板块身位</span>&nbsp; <span class="num-style">龙{{k[1].index}}</span>
                                {% endif %}
                            </td>
                        </tr>
                        <tr>
                            <td style="padding: 0">
                                <table class="table-content">
                                    {% for kk in k[1].codes %}
                                    {% if loop.index0 % 3 ==0 %}
                                    <tr>
                                        {% endif %}
                                        <td>
                                            {% if kk.limit_up %}
                                            <span><img src="{{base_url}}images/limit_up.png"></span>
                                            {% elif kk.open_limit_up %}
                                            <span><img src="{{base_url}}images/stop_up.png"></span>
                                            {% else %}
                                            <span class="icon-null"></span>
                                            {% endif %}
                                            {% if kk.ss %}
                                            <span class="num-style">{{kk.name}}</span>
                                            {% else %}
                                            <span class="num-style color-not-buy">{{kk.name}}</span>
                                            {% endif %}
                                            <span class="num-style">{{kk.code}}</span>
                                            {% if kk.score %}
                                            <span class="score-card-color yellow">{{kk.score}}</span>
                                            {% endif %}
                                        </td>
                                        {% if loop.index0 % 3 ==2 %}
                                    </tr>
                                    {% elif loop.last %}
                                    </tr>
                                    {% endif %}
                                    {% endfor %}
                                </table>
                            </td>
                        </tr>
                    </table>
                    </td>
                </tr>
                {% endif %}
               {% endfor %}
            </table>
        <div class="table-name"><span class="table-title">主动买入</span><span class="button-blue" style="visibility: hidden">加入看盘</span></div>
        <table>
            {% for k in initiative_buy_codes %}
            {% if loop.index0 % 3 ==0 %}
@@ -250,7 +393,7 @@
            {% endif %}
            {% endfor %}
        </table>
        <div class="table-name"><span class="table-title">被动买入</span><span class="button-blue">加入看盘</span></div>
        <div class="table-name"><span class="table-title">被动买入</span><span class="button-blue" style="visibility: hidden">加入看盘</span></div>
        <table>
            {% for k in passive_buy_codes %}
            {% if loop.index0 % 3 ==0 %}
@@ -310,54 +453,15 @@
            {% endif %}
            {% endfor %}
        </table>
        <div class="table-name">市场热度</div>
        <table>
            {% for k in xgb_infos %}
            <tr style="background: #2c2c64;">
                <td colspan="3"><span class="num-style bold red">{{k.block.name}}</span>&nbsp;&nbsp;&nbsp;&nbsp;涨幅<span
                        class="num-style bold red">{{k.block.rate}}</span>
                    ,共
                    <span
                        class="num-style bold red">{{k.block.limit_up_count}}</span>个涨停---------------------------------------
                </td>
            </tr>
            <table>
                {% for code_info in k.codes %}
                {% if loop.index0 % 3 ==0 %}
                <tr>
                    {% endif %}
                    <td>
                        {% if code_info.limit_up %}
                        <span><img src="{{base_url}}images/limit_up.png"></span>
                        {% else %}
                        <span><img src="{{base_url}}images/limit_up.png" style="visibility: hidden;"></span>
                        {% endif %}
                        <!--                     <span class="icon-null"></span> -->
                        <span class="num-style">{{code_info.name}}</span>
                        <span class="num-style">{{code_info.code}}</span>
                        <!-- <span class="score-card-color yellow">228</span> -->
                    </td>
                    {% if loop.index0 % 3 ==2 %}
                </tr>
                {% elif loop.last %}
                </tr>
                {% endif %}
                {% endfor %}
            </table>
            {% endfor %}
        </table>
        <div class="table-name">开盘啦数据</div>
        <table class="kpl">
            <tr>
                <td class="sub_title">最强风口</td>
                <td class="sub_title">市场风口</td>
            </tr>
            <tr>
                <td class="content">
                    <table>
                        <thead>
        </div>
            <div style="float: right;width: 538px;">
            <!-- 第一群 -->
            <div>
                <span>
                    <div class="table-name-right">&nbsp&nbsp&nbsp最强风口</div>
                    <div class="table-name-right">&nbsp&nbsp&nbsp市场风口</div>
                    <table id="kpl-best_feng_kou" class="half-width">
                        <thead>
                            <tr>
                                <td>股票名称</td>
                                <td>强度</td>
@@ -365,103 +469,67 @@
                                <td>所属板块</td>
                            </tr>
                        </thead>
                        <tbody>
                        <tr></tr>
                            {% for code_info in kpl_best_feng_kou %}
                            <tr>
                                <td>{{code_info.name}}</td>
                                <td>{{code_info.weight}}</td>
                                <td>{{code_info.rate}}%</td>
                                <td>{{code_info.hot_block}}</td>
                            </tr>
                            {% endfor %}
                        <tbody>
                        </tbody>
                    </table>
                </td>
                <td class="content">
                    <table>
                </span>
                <span>
                    <table class="half-width" id="kpl-feng_kou">
                        <thead>
                            <tr>
                                <td>股票名称</td>
                                <td>主力净额</td>
                                <td>主净值</td>
                                <td>涨跌幅</td>
                                <td>风口概念</td>
                            </tr>
                        </thead>
                        <tbody>
                            {% for code_info in kpl_feng_kou %}
                            <tr>
                                <td>{{code_info.name}}</td>
                                <td>{{code_info.money}}</td>
                                <td>{{code_info.rate}}%</td>
                                <td>{{code_info.block}}</td>
                            </tr>
                            {% endfor %}
                        </tbody>
                        </tbody>
                    </table>
                </td>
            </tr>
            <tr>
                <td class="sub_title">风向标</td>
                <td class="sub_title">行业涨幅</td>
            </tr>
            <tr>
                <td class="content">
                    <table class = "table-fxb">
                </span>
            </div>
            <!-- 第二群 -->
            <div>
                <div class="table-name-right" style="width: 62%;">&nbsp&nbsp&nbsp风向标</div>
                <div class="table-name-right" style="width: 38%;">&nbsp&nbsp&nbsp行业涨幅</div>
                <span>
                    <table style="width: 62%;float: left;" id="kpl-feng_xiang">
                        <thead>
                            <tr>
                                <td>股票名称</td>
                                <td>涨跌幅</td>
                                <td>所属板块</td>
                                <td>300W净额</td>
                                <td>主力净额</td>
                                <td>300W</td>
                                <td>主净额</td>
                            </tr>
                        </thead>
                        <tbody>
                            {% for code_info in kpl_feng_xiang %}
                            <tr>
                                <td>{{code_info.name}}</td>
                                <td>{{code_info.rate}}%</td>
                                <td>{{code_info.block}}</td>
                                <td>{{code_info.money_300w}}</td>
                                <td>{{code_info.money_main}}</td>
                            </tr>
                            {% endfor %}
                        </tbody>
                    </table>
                </td>
                <td class="content">
                    <table class = "table-ins">
                </span>
                <span>
                    <table style="width: 38%;float: right;"  id="kpl-industry_rank">
                        <thead>
                            <tr>
                                <td>行业名称</td>
                                <td>主力净额</td>
                                <td>涨跌幅</td>
                            </tr>
                        <tr>
                            <td>行业名称</td>
                            <td>主净值</td>
                            <td>涨跌幅</td>
                            <!-- <td>风口概念</td> -->
                        </tr>
                        </thead>
                        <tbody>
                            {% for code_info in kpl_industry_rank %}
                            <tr>
                                <td>{{code_info.name}}</td>
                                <td>{{code_info.money}}</td>
                                <td>{{code_info.rate}}%</td>
                            </tr>
                            {% endfor %}
                        </tbody>
                    </table>
                </td>
            </tr>
        </table>
                </span>
            </div>
        </div>
    </body>
</html>
server.py
@@ -719,40 +719,10 @@
                    # 根据代码获取选股宝热门概念
                    day = tool.get_now_date_str()
                    code = data_process.parse(_str)["data"]["code"]
                    todays =block_info.KPLLimitUpDataRecordManager.list_by_code(code, day)
                    today_datas = []
                    if todays:
                        for data in todays:
                            block = data[2]
                            block_datas = block_info.KPLLimitUpDataRecordManager.list_by_block(block, day)
                            block_datas = list(block_datas)
                            # 根据涨停时间排序
                            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:
                                    today_datas.append(
                                        {"block_name": block, "block_size": len(block_datas), "index": i,
                                         "price": block_datas[i][5], "rate": block_datas[i][6]})
                                    break
                    # 获取前一个交易日
                    last_day = juejin.JueJinManager.get_previous_trading_date(day)
                    lasts = block_info.KPLLimitUpDataRecordManager.list_by_code(code, last_day)
                    last_datas = []
                    if todays:
                        for data in lasts:
                            block = data[2]
                            block_datas = block_info.KPLLimitUpDataRecordManager.list_by_block(block, last_day)
                            block_datas = list(block_datas)
                            # 根据涨停时间排序
                            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:
                                    last_datas.append(
                                        {"block_name": block, "block_size": len(block_datas), "index": i,
                                         "price": block_datas[i][5], "rate": block_datas[i][6]})
                                    break
                    __start_time = time.time()
                    final_data = {'code': code, 'data': code_info_output.get_output_html(code)}
                    return_str = json.dumps({"code": 0, "data": final_data})
                    print("代码信息获取时间",code,round((time.time()-__start_time)*1000))
                    pass
                # 获取最近2个交易日涨停代码
                elif type == 72:
@@ -768,6 +738,18 @@
                                    codes_set.add(d[3])
                        data_dict[day] = list(codes_set)
                    return_str = json.dumps({"code": 0, "data": data_dict})
                elif type == 80:
                    # 撤单
                    data = json.loads(_str)
                    code = data["data"]["code"]
                    if code:
                        return_str = json.dumps({"code": 0})
                        try:
                            l2_data_manager_new.L2TradeDataProcessor.cancel_buy(code, "手动撤销")
                        except Exception as e:
                            return_str = json.dumps({"code": 2, "msg": str(e)})
                    else:
                        return_str = json.dumps({"code": 1, "msg": "请上传代码"})
                elif type == 201:
                    # 加入黑名单
                    data = json.loads(_str)
third_data/block_info.py
@@ -29,12 +29,12 @@
# (代码, 名称, 首次涨停时间, 最近涨停时间, 几板, 涨停原因, 板块, 实际流通, 主力净额)
def __get_blocks(code, limit_up_datas):
def __get_blocks(code, limit_up_datas, filter=True):
    blocks = []
    for data in limit_up_datas:
        if data[0] == code:
            block = data[5]
            if block in kpl_data_manager.INVALID_BLOCKS:
            if block in kpl_data_manager.INVALID_BLOCKS and filter:
                continue
            blocks.append(block)
    return blocks
@@ -71,6 +71,24 @@
    latest_datas = __kplDataManager.get_data(kpl_util.KPLDataType.LIMIT_UP)
    blocks = __get_blocks(code, latest_datas)
    return blocks
def get_target_block(code, filter=False):
    latest_datas = __kplDataManager.get_data(kpl_util.KPLDataType.LIMIT_UP)
    blocks = __get_blocks(code, latest_datas, filter)
    if not blocks:
        blocks = __load_before_block(code)
        # 获取目标板块
    target_block = None
    if blocks:
        for block in blocks:
            if block in kpl_data_manager.INVALID_BLOCKS and filter:
                continue
            target_block = block
            break
    if not target_block:
        return None
    return target_block
# 获取代码所在板块信息
@@ -140,6 +158,8 @@
                code_ = d[3]
                limit_up_codes_info_set.add((code_, d[5]))
                block_codes_set.add(code_)
            elif d[3]==code:
                limit_up_codes_info_set.add((d[3], d[5]))
    # 获取涨停的顺序
    limit_up_index = -1
    limit_up_codes_info_list = list(limit_up_codes_info_set)
third_data/data_server.py
@@ -22,11 +22,24 @@
    def do_GET(self):
        path = self.path
        url = urlparse.urlparse(path)
        response_data = ""
        if url.path == "/get_kpl_data":
            best_feng_kou = self.__kplDataManager.get_data(kpl_util.KPLDataType.BEST_FENG_KOU)
            best_feng_kou=best_feng_kou[:22]
            feng_kou = self.__kplDataManager.get_data(kpl_util.KPLDataType.FENG_KOU)
            feng_kou = feng_kou[:22]
            industry_rank = self.__kplDataManager.get_data(kpl_util.KPLDataType.INDUSTRY_RANK)
            industry_rank = industry_rank[:22]
            feng_xiang = self.__kplDataManager.get_data(kpl_util.KPLDataType.FENG_XIANG)
            feng_xiang = feng_xiang[:22]
            response_data = json.dumps({"code": 0, "data": {"best_feng_kou": best_feng_kou, "feng_kou": feng_kou,
                                                            "industry_rank": industry_rank, "feng_xiang": feng_xiang}})
        self.send_response(200)
        # 发给请求客户端的响应数据
        self.send_header('Content-type', 'application/json')
        self.end_headers()
        self.wfile.write("".encode())
        self.wfile.write(response_data.encode())
    def do_POST(self):
        path = self.path
@@ -39,7 +52,7 @@
    def __process_kpl_data(self, data):
        type_ = data["type"]
        print("开盘啦type:",type_)
        print("开盘啦type:", type_)
        if type_ == KPLDataType.BIDDING.value:
            result_list = kpl_util.parseDaBanData(data["data"], kpl_util.DABAN_TYPE_LIMIT_UP)
            # 竞价取前20
@@ -49,7 +62,7 @@
                result_list = result_list[:20]
                bs = []
                for d in result_list:
                    bs.append((d[0], f"{d[2] // 10000 }万"))
                    bs.append((d[0], f"{d[2] // 10000}万"))
                bidding_money_manager.set_bidding_money(bs[:10])
                self.__kplDataManager.save_data(type_, result_list)
@@ -63,7 +76,7 @@
                        limit_up_time = time.strftime("%H:%M:%S", time.localtime(d[2]))
                        code_price_manager.Buy1PriceManager.set_limit_up_time(code, limit_up_time)
                self.__kplDataManager.save_data(type_, result_list)
                kpl_data_manager.KPLLimitUpDataRecordManager.save_record(tool.get_now_date_str(),result_list)
                kpl_data_manager.KPLLimitUpDataRecordManager.save_record(tool.get_now_date_str(), result_list)
        elif type_ == KPLDataType.OPEN_LIMIT_UP.value:
            result_list = kpl_util.parseDaBanData(data["data"], kpl_util.DABAN_TYPE_OPEN_LIMIT_UP)
            if result_list:
third_data/kpl_api.py
New file
@@ -0,0 +1,28 @@
import json
import requests
def __base_request(url, data):
    headers = {
        "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
        "User-Agent": "Dalvik / 2.1.0(Linux;U;Android 6.0.1;MuMu Build/V417IR)"
    }
    # proxies={'https': '192.168.3.251:9002'}
    # 禁止代理,不然会走本地代理
    response = requests.post(url, data=data, headers=headers, proxies={"http": None, "https": None})
    return response
# 获取代码的板块
def getStockIDPlate(code):
    data = f"a=GetStockIDPlate_New&apiv=w32&c=StockL2Data&StockID={code}&PhoneOSNew=1&UserID=0&DeviceID=a38adabd-99ef-3116-8bb9-6d893c846e23&VerSion=5.8.0.2&Token=0&"
    response = __base_request("https://apphq.longhuvip.com/w1/api/index.php",
                              data=data)
    if response.status_code != 200:
        raise Exception("请求出错")
    result = response.text
    result = json.loads(result)
    if int(result["errcode"]) != 0:
        return None
    return result["ListJX"]
third_data/kpl_data_manager.py
@@ -100,6 +100,13 @@
        mysqldb = mysql_data.Mysqldb()
        return mysqldb.select_one(sql)
    # 获取代码最近的板块,返回[(板块,日期)]
    @staticmethod
    def get_latest_infos(code, count):
        sql = f"SELECT GROUP_CONCAT(_hot_block_name),`_day` FROM (SELECT hb.`_hot_block_name`,hb.`_day` FROM `kpl_limit_up_record` hb WHERE hb.`_code`='{code}' ORDER BY hb.`_day` DESC LIMIT 10) a  GROUP BY a._day ORDER BY a._day DESC LIMIT {count}"
        mysqldb = mysql_data.Mysqldb()
        return mysqldb.select_all(sql)
class KPLDataManager:
    __latest_datas = {}
@@ -110,8 +117,19 @@
        with open(path, 'w') as f:
            f.write(json.dumps(datas))
    def __get_from_file(self, key):
        name = f"{tool.get_now_date_str()}_{key}.log"
    def __get_from_file(self, key, day=tool.get_now_date_str()):
        name = f"{day}_{key}.log"
        path = f"{constant.CACHE_PATH}/{name}"
        if not os.path.exists(path):
            return None
        with open(path, 'r') as f:
            lines = f.readlines()
            if lines:
                return json.loads(lines[0])
        return None
    def get_from_file(self, type, day):
        name = f"{day}_{type.value}.log"
        path = f"{constant.CACHE_PATH}/{name}"
        if not os.path.exists(path):
            return None
@@ -151,4 +169,4 @@
if __name__ == "__main__":
    load_history_limit_up()
    print(KPLLimitUpDataRecordManager.get_latest_infos("000950", 4))
trade/trade_manager.py
@@ -477,4 +477,4 @@
if __name__ == "__main__":
    pass
    set_trade_state("002351",TRADE_STATE_BUY_DELEGATED)