admin
2024-02-21 d1f88af76d8cb3b3751f53a1814081f2c5e997d1
HTML页面完善/添加同花顺加自选功能
10个文件已修改
1个文件已添加
224 ■■■■ 已修改文件
constant.py 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/codes_list.html 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/css/banshuping.css 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/css/index23-05-04.css 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/index23-05-04.html 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/js/code_list.js 38 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
kp_html/kp/js/page.js 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
main.py 34 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test_ths.py 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/ths_util.py 68 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
utils/xgb_api.py 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
constant.py
@@ -1,4 +1,4 @@
SERVER_HOST = "43.138.167.68"
# SERVER_HOST = "192.168.3.122"
WEB_HOST = "192.168.3.252"
IS_TEST = True
IS_TEST = False
kp_html/kp/codes_list.html
@@ -78,16 +78,21 @@
                                            </div>
                                            <div>
                                                <div style="display: flex;justify-content: space-between;align-items: center;">
                                                    <div class="layui-progress" style="background-color: #BBB; width: 88%;" :id="'progress_'+item.code_info[0]">
                                                    <div style="color: red;" :style="{'visibility': item.pay_attention?'visible':'hidden' }">***</div>
                                                    <div class="layui-progress" style="background-color: #BBB; width: 75%;" :id="'progress_'+item.code_info[0]">
                                                      <div class="layui-progress-bar" lay-percent="{{item.percent+'%'}}" ></div>
                                                    </div>
                                                    <button class="layui-btn layui-btn-xs" v-on:click="cancel_order(item.code_info[0])">撤单</button>
                                                    <div>
                                                        <button class="layui-btn layui-btn-xs layui-btn-danger" v-on:click="cancel_order(item.code_info[0])">撤单</button>
                                                        <button class="layui-btn layui-btn-xs" v-on:click="view_details(item.code_info[0])">查看</button>
                                                    </div>
                                                </div>
                                                
                                                
                                                <div>
                                                    还有<span :class="{'red':item.left_count <=4}">{{item.left_count}}</span>笔,还有<span>{{item.left_money}}(封单:{{item.buy1_money}})</span>成交到我们
                                                    大单成交:{{item.big_num_count}}笔/{{item.big_num_money}}
                                                    剩<span :class="{'red':item.left_count <=4}">{{item.left_count}}</span>笔<span>{{item.left_money}}/封单{{item.buy1_money}}</span>,已成大单
                                                     {{item.big_num_count}}笔{{item.big_num_money}}&nbsp; 待成大单{{item.not_deal_big_num_count}}笔{{item.not_deal_big_num_money}}
                                                </div>
                                            </div>
                                            
@@ -273,6 +278,7 @@
                                <div class="column-space"></div>
                                <span style="width: 120px;">{{l2_code_name}}</span>
                                <div class="column-space"></div>
                                <button class="btn" v-on:click="refresh_h_cancel_data">加载H撤</button>
                                <div class="column-space"></div>
                                <button class="btn" v-on:click="refresh_l_cancel_data(0)">加载L前撤</button>
@@ -291,9 +297,9 @@
                                <div style="line-height: 20px;margin-top: 5px;"><input type="checkbox" value="1" checked
                                        v-on:click="hidden_sell_check($event)" /> <label>隐藏卖</label> </div>
                                <div class="column-space"></div>
                                <div style="line-height: 20px;margin-top: 5px;"><input type="checkbox" value="1"
                                <div style="line-height: 20px;margin-top: 5px;"><input type="checkbox" value="1" checked
                                        v-on:click="hidden_canceled_check($event)" /> <label>隐藏已撤</label> </div>
                                <div style="line-height: 20px;margin-top: 5px;margin-left: 5px;"><input type="checkbox" value="1"
                                <div style="line-height: 20px;margin-top: 5px;margin-left: 5px;"><input type="checkbox" value="1" checked
                                        v-on:click="hidden_little_money_check($event)" /> <label>隐藏小金额</label> </div>        
                            </div>
                        </div>
kp_html/kp/css/banshuping.css
@@ -568,7 +568,7 @@
.delegated_codes_info>div>div:last-child{
    position: relative;
    width: 410px;
    width: 450px;
}
.delegated_codes_info .layui-progress{
    margin-bottom: 5px;
kp_html/kp/css/index23-05-04.css
@@ -310,6 +310,9 @@
.white{
    color: #fff;
}
.orange{
    color: #FF8020;
}
.num-card-color1 {
    background: #ed96f3;
kp_html/kp/index23-05-04.html
@@ -138,7 +138,7 @@
                                <tr  v-if="yesterday_block_info">
                                    <td><span  class="bold">同原因昨日涨停</span></td>
                                    <td class="budinggundong">
                                        <div>
                                        <div style="max-height: 100px;" class="scroll-y">
                                            <span v-for="(item,i) in yesterday_block_info.data.yesterday"
                                                class="label-style" >{{item[1]}}({{item[0]}})(<span :class="{'red': item[2]>0,'green':item[2]<0,'white':item[2]==0}">{{item[2]}}%</span>)
                                                </span>
@@ -149,7 +149,7 @@
                                <tr  v-if="yesterday_block_info">
                                    <td><span  class="bold">同原因今日涨停</span></td>
                                    <td class="budinggundong">
                                        <div>
                                        <div style="max-height: 90px;" class="scroll-y">
                                            <span v-for="(item,i) in yesterday_block_info.data.current"
                                                class="label-style">{{item[1]}}({{item[0]}})</span>
                                        </div>
@@ -229,11 +229,11 @@
            <!-- 首板梯队 -->
            <div>
                <!-- 待买池 -->
                <div class="table-name plate-container"
                <div class="table-name plate-container scroll-y"
                    style="float: left;width: 100%;text-align: center; background: #000;height:150px">
                    <span v-for="(item,i) in first_info.limit_up_reason_statistic"
                        v-on:click="show_want_codes(item[0])">
                        <span class="num-style red">{{item[0]}}({{item[1]}}&{{item[2]}})</span>&nbsp;&nbsp;&nbsp;&nbsp;
                        <span class="num-style red" :class="{'orange': kpl_limit_up_reason == item[0]}">{{item[0]}}({{item[1]}}&{{item[2]}})</span>&nbsp;&nbsp;&nbsp;&nbsp;
                    </span>
                </div>
                <!-- 左侧 -->
kp_html/kp/js/code_list.js
@@ -42,10 +42,10 @@
            data_type: 0,
            trade_progress_index: -1,
            latest_real_order_index: -1,
            hidden_canceled: false,
            hidden_canceled: true,
            //隐藏撤单
            hidden_cancel:true,
            hidden_little_money:false,
            hidden_little_money:true,
            hidden_sell:true,
            l2_datas: [],
            l2_colors_class: ["color-single-start", "color-single-exec", "color-cancel",
@@ -82,7 +82,7 @@
                if(is_trade_time()){
                    app.get_delegated_buy_code_infos();
                }
            },1000*5);
            },1000*3);
        },
        methods: {
            change_data_type: function(type) {
@@ -143,8 +143,14 @@
                    alert("没有获取到代码")
                    return;
                }
                var index = layer.load(1, {
                  shade: [0.1,'#fff'] //0.1透明度的白色背景
                });
                http_util.get_l2_datas(app.code, function(res) {
                    console.log("获取到数据:",res)
                    layer.close(index);
                    console.log("获取到L2数据:",res)
                    res = JSON.parse(res);
                    if (res.code == 0) {
                        var real_order_index = -1;
@@ -167,6 +173,7 @@
                        console.log("最近真实下单位置:", real_order_index);
                        app.latest_real_order_index = real_order_index;
                        app.l2_datas = res.data.data;
                        console.log("L2数据:",app.l2_datas);
                        var code_name = res.data.code_name;
                        var code_ = res.data.code;
                        app.l2_code_name = code_ + " " + code_name;
@@ -195,6 +202,9 @@
                            }
                        });
                        app.delegated_buy_code_infos = result.data
                    }else{
                        console.log("已挂买单错误:",result.msg);
                        app.delegated_buy_code_infos=[];
                    }
                });
            },
@@ -412,9 +422,13 @@
                app.origin_code = code;
                app.code_name = code;
            },
            load_data:function(){
            load_data:function(refresh_l2){
                if(app.origin_code){
                    app.get_score_data(app.origin_code,null,null);
                    app.get_score_data(app.origin_code,null,function(e){
                        if(refresh_l2){
                            app.refresh_l2_data();
                        }
                    });
                    app.get_l2_cant_buy_reasons(app.origin_code); 
                }
            },
@@ -423,6 +437,18 @@
                    layer.msg("撤单成功");
                });
            },
            view_details:function(code){
                pyjs.add_code_to_ths(code);
                // 设置目标代码
                app.set_target_code(code);
                // 点击选择L2选项
                app.change_data_type(1);
                // 将目标票传递到首页
                pyjs.set_target_code(code);
                app.load_data(true);
            },
            get_l2_cant_buy_reasons:function(code){
                http_util.get_l2_cant_buy_reasons(code,function(res){
                    res = JSON.parse(res);
kp_html/kp/js/page.js
@@ -89,6 +89,8 @@
                trade_data: {
                    order: 0
                },
                // 代码的开盘啦涨停原因
                kpl_limit_up_reason:'',
                default_score_data: {
                    volume: {
                        "score": 0,
@@ -456,6 +458,18 @@
                        res = JSON.parse(res)
                        if (res.code == 0) {
                            app.first_info = res.data
                            var temps = new Array();
                            app.first_info.limit_up_reason_statistic.forEach(function(d){
                                if(d[0]==app.kpl_limit_up_reason){
                                    current_limit_up_reason = d;
                                }else{
                                    temps.push(d);
                                }
                            });
                            if(current_limit_up_reason){
                                temps.unshift(current_limit_up_reason);
                            }
                            app.first_info.limit_up_reason_statistic = temps;
                            // if (app.choose_code.first) {
                            //     app.get_plate_info(app.choose_code.first, is_auto_refresh);
                            // } else if (app.first_info.limit_up_codes) {
@@ -614,10 +628,30 @@
                    //请求板块
                    setTimeout(function(){
                        http_util.get_kpl_block_info(code,function(res){
                            console.log("板块请求结果:",res);
                            res = JSON.parse(res)
                            console.log("板块请求结果:",res);
                            if(res.code==0){
                                app.kpl_code_info = res.data;
                                // 设置当日涨停原因
                                app.kpl_limit_up_reason = app.kpl_code_info.today[0][0];
                                // 将当前涨停原因置顶
                                var limit_up_reason_statistic =  app.first_info.limit_up_reason_statistic;
                                var current_limit_up_reason;
                                if(limit_up_reason_statistic){
                                    var temps = new Array();
                                    limit_up_reason_statistic.forEach(function(d){
                                        if(d[0]==app.kpl_limit_up_reason){
                                            current_limit_up_reason = d;
                                        }else{
                                            temps.push(d);
                                        }
                                    });
                                    if(current_limit_up_reason){
                                        temps.unshift(current_limit_up_reason);
                                    }
                                    app.first_info.limit_up_reason_statistic = temps;
                                }
                            }
                        });
                        app.get_last_trade_day_reasons(code);
main.py
@@ -3,6 +3,7 @@
import json
import logging
import multiprocessing
import queue
import threading
import time
from multiprocessing import freeze_support
@@ -23,7 +24,7 @@
import constant
import gui_wx
from network_delegate_manager import LocalKanPanNetworkDelegate
from utils import network_util, xgb_api
from utils import network_util, xgb_api, ths_util
import setting
from utils import tool
import win32_util
@@ -34,6 +35,8 @@
freeze_support()
URL_MSG_LIST = f"http://{constant.WEB_HOST}/kp/msg_list.html"
window_msg_queue = queue.Queue()
class BaseBridgeClass(QObject):
@@ -91,7 +94,7 @@
                if k == "sign":
                    continue
                if type(text_json[k]) == dict or type(text_json[k]) == list:
                    params.append(f"{k}={json.dumps(text_json[k], separators=(',',':'))}")
                    params.append(f"{k}={json.dumps(text_json[k], separators=(',', ':'))}")
                else:
                    params.append(f"{k}={text_json[k]}")
            params.sort()
@@ -113,6 +116,18 @@
    @pyqtSlot(result=str)
    def get_client(self):
        return setting.get_client()
    @pyqtSlot(str)
    def add_code_to_ths(self, code):
        # 添加到同花顺
        threading.Thread(target=lambda: ths_util.add_code_to_zixuan(code),daemon=True).start()
class SecondWindowBridgeClass(BaseBridgeClass):
    @pyqtSlot(str)
    def set_target_code(self, code):
        # 设置目标代码
        window_msg_queue.put_nowait({"type": "set_target_code", "data": {"code": code}})
class JSBridgeClass(BaseBridgeClass):
@@ -245,7 +260,7 @@
        # JS桥设置
        channel = QWebChannel(self.webview.page())
        self.webview.page().setWebChannel(channel)
        self.python_bridge = BaseBridgeClass(self.webview)
        self.python_bridge = SecondWindowBridgeClass(self.webview)
        channel.registerObject("Bridge", self.python_bridge)
        # self.signal_update_kpl.connect(self.set_kpl_data)
@@ -309,6 +324,18 @@
        self.wx_pipe.send(json.dumps({"type": "set_code", "code": code}))
        self.webview.page().runJavaScript(f"app.set_target_code('{code}')")
        self.secondWindow.set_target_code(code)
    def read_window_msg(self):
        while True:
            try:
                data = window_msg_queue.get()
                if data["type"] == "set_target_code":
                    code = data["data"]["code"]
                    self.signal_update_code.emit(code)
            except:
                pass
            finally:
                pass
    # 菜单及菜单点击事件
    def __menu(self):
@@ -470,6 +497,7 @@
        threading.Thread(target=KPLLimitUpDataManager().run, daemon=True).start()
        threading.Thread(target=xgb_api.run, daemon=True).start()
        threading.Thread(target=self.read_window_msg, daemon=True).start()
    def closeEvent(self, event):
        event.accept()
test_ths.py
New file
@@ -0,0 +1,5 @@
from utils import ths_util
if __name__ == "__main__":
    pass
utils/ths_util.py
@@ -1,5 +1,6 @@
import time
# 获取同花顺副屏幕1句柄
import win32api
import win32con
import win32_util
@@ -85,5 +86,72 @@
        time.sleep(space_time)
# 将代码加入自选
def input_code(hwnd, num_str):
    for c in num_str:
        code = -1
        if c == '0':
            code = 48
        elif c == '1':
            code = 49
        elif c == '2':
            code = 50
        elif c == '3':
            code = 51
        elif c == '4':
            code = 52
        elif c == '5':
            code = 53
        elif c == '6':
            code = 54
        elif c == '7':
            code = 55
        elif c == '8':
            code = 56
        elif c == '9':
            code = 57
        win32gui.SendMessage(hwnd, win32con.WM_KEYDOWN, code, 0)
        win32gui.PostMessage(hwnd, win32con.WM_KEYUP, code, 0)
        time.sleep(0.1)
def add_code_to_zixuan(num_str):
    hwnds = win32_util.search_window("看盘页面")
    if hwnds:
        origin_hwnd = hwnds[0]
        for w in hwnds:
            title = win32_util.getText(w)
            if title.find("同花顺")>=0:
                origin_hwnd = w
                break
        input_code(origin_hwnd, num_str[:1])
        # Afx:00400000:0
        hwnds = []
        try:
            hwnd = win32gui.GetDesktopWindow()
            temp = None
            while True:
                if temp and win32gui.IsWindowVisible(temp):
                    classname = win32gui.GetClassName(temp)
                    if classname == 'Afx:00400000:0':
                        hwnds.append(temp)
                temp = win32gui.FindWindowEx(hwnd, temp, None, None)
                if not temp:
                    break
        except:
            pass
        hwnd = win32gui.FindWindowEx(hwnds[0], None, "Edit", "")
        print(hwnd)
        input_code(hwnd, num_str[1:])
        time.sleep(0.5)
        win32gui.SendMessage(hwnds[0], win32con.WM_KEYDOWN, win32con.VK_RETURN, 0)
        win32gui.PostMessage(hwnds[0], win32con.WM_KEYUP, win32con.VK_RETURN, 0)
        time.sleep(0.2)
        win32gui.SetForegroundWindow(origin_hwnd)
        win32api.keybd_event(win32con.VK_INSERT, 0, 0, 0)  # 按下键
        win32api.keybd_event(win32con.VK_INSERT, 0, win32con.KEYEVENTF_KEYUP, 0)
if __name__ == "__main__":
    print(get_ths_main_content_hwnd())
utils/xgb_api.py
@@ -1,4 +1,5 @@
import json
import logging
import time
import requests
@@ -97,8 +98,13 @@
                for r in reasons:
                    code_names = []
                    for l in __limit_up_codes_infos:
                        if r[0] in [ll["name"] for ll in l[8]]:
                            code_names.append(l[1])
                        try:
                            if l[8]:
                                if r[0] in [ll["name"] for ll in l[8]]:
                                    code_names.append(l[1])
                        except Exception as e:
                            logging.exception(e)
                            print(l)
                    r.append(code_names)
                # 涨停原因
                return reasons, item[5], XGBApi.get_code_blocks(code), round(item[4] / 100000000, 2)