| | |
| | | SERVER_HOST = "43.138.167.68" |
| | | # SERVER_HOST = "192.168.3.122" |
| | | WEB_HOST = "192.168.3.252" |
| | | IS_TEST = True |
| | | IS_TEST = False |
| | |
| | | <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> |
| | | <button class="btn" v-on:click="refresh_h_cancel_data" style="display: none;">H撤</button> |
| | | <div class="column-space"></div> |
| | | <button class="btn" v-on:click="refresh_l_cancel_data(0)">L前撤</button> |
| | | <button class="btn" v-on:click="refresh_l_cancel_data(0)" style="display: none;">L前撤</button> |
| | | <div class="column-space"></div> |
| | | <button class="btn" v-on:click="refresh_l_cancel_data(1)">L后撤</button> |
| | | <div class="column-space"></div> |
| | | <button class="btn" v-on:click="clear_cancel_mark">清除标记</button> |
| | | <div class="column-space"></div> |
| | | |
| | | <div style="line-height: 20px;margin-top: 5px;"><input |
| | | type="checkbox" value="1" checked |
| | | v-on:click="set_fast_mode($event)" /> <label>极速模式</label> |
| | | </div> |
| | | |
| | | <button class="btn" v-on:click="refresh_l2_data">刷新L2</button> |
| | | <div class="column-space"></div> |
| | | <button class="btn" v-on:click="refresh_trade_progress">成交进度</button> |
| | |
| | | color: #0084ff; |
| | | } |
| | | |
| | | .blue { |
| | | color: #0084ff; |
| | | } |
| | | |
| | | .purple { |
| | | color: #ff80ff; |
| | | } |
| | |
| | | |
| | | |
| | | </div> |
| | | <img class="delete" src="./images/delete.png" alt="" |
| | | style="float: right;margin-top: 12px;margin-right: -8px;" |
| | | @click="del_code_level_1(index)"> |
| | | |
| | | <div style="display:flex;justify-content:space-between;align-items:center"> |
| | | <div> |
| | | <span class="bule">{{item[7]}}</span>(<span |
| | |
| | | |
| | | |
| | | </div> |
| | | <div>代码:<span class="num-style">{{item[0]}}</span> 自由市值:<span |
| | | class="num-style">{{item[9]}}</span></div> |
| | | <div>自由市值:<span |
| | | class="num-style">{{item[9]}}</span> |
| | | |
| | | <button class="layui-btn layui-btn layui-btn-primary" style="width: 140px;" @click="add_to_ths(item[0])">查看</button> |
| | | </div> |
| | | <!-- 交易信息 --> |
| | | <div class="num-style" style="font-size:12px;overflow: hidden;width:260px;" |
| | | v-html="item[12]"></div> |
| | |
| | | <div style="width: 270px;"> |
| | | <button class="layui-btn layui-btn-xs" |
| | | v-on:click="get_l2_subscript_codes">刷新数据</button> |
| | | <span>订阅数量:{{l2_subscript_codes.length}}</span> |
| | | |
| | | |
| | | <div class="l2_subscript_codes scroll-x"> |
| | | |
| | | <span class="label-style" v-for="(item, index) in l2_subscript_codes" |
| | | :class="{'green': item[2]<0, 'red': item[3]&&item[3][3]}" |
| | | :class="{'blue': item[4]==1, 'red': item[4]==2}" |
| | | :style="{'border':item[0]==code?'solid orange 2px':'none'}"> |
| | | <span |
| | | @click="add_to_ths(item[0])">{{new_block_code_special_blocks[item[0]]?'N':''}}{{code_special_blocks[item[0]]?'@':''}}{{item[1]}}({{item[0]}})-【{{item[2]}}%】</span> |
| | | @click="add_to_ths(item[0])">{{new_block_code_special_blocks[item[0]]?'N':''}}{{code_special_blocks[item[0]]?'@':''}}{{item[1]}}({{item[0]}})-<span :class="{'green':!item[6]&&item[4]>0}">【{{item[5]}}%】</span></span> |
| | | |
| | | <img src="images/delete.png" v-on:click="add_to_forbidden(item[0])" /> |
| | | </span> |
| | |
| | | </ul> |
| | | <div class="layui-tab-content"> |
| | | <div class="layui-tab-item"> |
| | | |
| | | <fieldset class="layui-elem-field"> |
| | | <legend>量化板块</legend> |
| | | <div class="layui-field-box"> |
| | | <div style="display: flex;flex-wrap: wrap;"> |
| | | <div class="label-style" |
| | | style="margin: 10px; display: inline-block; max-width: auto;" |
| | | v-for="(item, index) in low_suction_plates"> |
| | | <span>{{item}}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </fieldset> |
| | | |
| | | <fieldset class="layui-elem-field"> |
| | | <legend>板块白名单</legend> |
| | |
| | | |
| | | <table class="layui-table" > |
| | | <thead> |
| | | <th>下单时间</th> |
| | | |
| | | <th>代码</th> |
| | | <th>板块</th> |
| | | <th>下单时间</th> |
| | | <th style="width: 30px;">成本价</th> |
| | | <th>成本涨幅</th> |
| | | |
| | |
| | | <tbody> |
| | | <tr |
| | | v-for="(item, index) in low_suction_place_order_records"> |
| | | <td>{{item[3].time_str}}</td> |
| | | <td>{{item[3].code}}</td> |
| | | <td><span @click="add_to_ths(item[3].code)">{{item[3].code}}({{item[3].code_name}})</span></td> |
| | | <td>{{item[3].plates}}</td> |
| | | <td>{{item[3].time_str}}</td> |
| | | <td>{{item[3].price}}</td> |
| | | <td>{{item[3].rate}}%</td> |
| | | <td>{{item[3].plates_info}}</td> |
| | |
| | | // 费用数据 |
| | | commission_data:{"total_commission":0, "month_commission":0}, |
| | | // L2数据结束索引 |
| | | l2_end_index:null |
| | | |
| | | l2_end_index:null, |
| | | fast_mode: 1 |
| | | }, |
| | | watch: { |
| | | delegated_buy_code_infos: function() { |
| | |
| | | |
| | | var date = $("#date").val(); |
| | | |
| | | http_util.get_l2_datas(app.code, date, app.l2_end_index, function(res) { |
| | | http_util.get_l2_datas(app.code, date, app.l2_end_index, app.fast_mode, function(res) { |
| | | layer.close(index); |
| | | res = JSON.parse(res); |
| | | if (res.code == 0) { |
| | |
| | | app.hidden_little_money = e.currentTarget.checked; |
| | | }, |
| | | |
| | | set_fast_mode: function(e) { |
| | | app.fast_mode = e.currentTarget.checked?1:0; |
| | | }, |
| | | |
| | | hidden_canceled_big_money_check: function(e) { |
| | | app.not_hidden_canceled_big_money = e.currentTarget.checked; |
| | | }, |
| | |
| | | function is_trade_time() { |
| | | var nowdate = new Date(); |
| | | h = nowdate.getHours(); |
| | | m = nowdate.getMinutes(); |
| | | total_m = h * 60 + m; |
| | | if ((total_m >= (9 * 60 + 25) && total_m <= (11 * 60 + 30)) || (total_m >= 13 * 60 && total_m <= 15 * |
| | | 60)) { |
| | | return true; |
| | | } else { |
| | | return false; |
| | | } |
| | | } |
| | | |
| | | var http_util = { |
| | | request_callback: {}, |
| | | getQueryString: function(name) { |
| | |
| | | md5Hash = md5(params_str); |
| | | return md5Hash; |
| | | }, |
| | | // 撤单 |
| | | cancel_order: function(code, success) { |
| | | var data = { |
| | | type: "cancel_order", |
| | |
| | | } |
| | | }); |
| | | }, |
| | | // 同步交易数据 |
| | | sync_trade_data: function(type, success) { |
| | | var data = { |
| | | type: "sync_trade_data", |
| | | data: { |
| | | "type": type |
| | | } |
| | | }; |
| | | |
| | | http_util.socket_request(JSON.stringify(data), function(result) { |
| | | result = JSON.parse(result); |
| | | success(result); |
| | | }); |
| | | }, |
| | | |
| | | |
| | | forbidden_plate: function(plate, callback) { |
| | | http_util.http_request("/kpl/forbidden_plate", { |
| | | plate: plate |
| | |
| | | }, callback); |
| | | }, |
| | | list_forbidden_plate: function(callback) { |
| | | http_util.http_request("/kpl/list_forbidden_plate", { |
| | | }, callback); |
| | | http_util.http_request("/kpl/list_forbidden_plate", {}, callback); |
| | | }, |
| | | list_deleted_forbidden_plate :function(callback){ |
| | | http_util.http_request("/kpl/list_deleted_forbidden_plate", { |
| | | }, callback); |
| | | http_util.http_request("/kpl/list_deleted_forbidden_plate", {}, callback); |
| | | }, |
| | | // 获取板块下的代码 |
| | | get_plate_codes: function(plate, day, callback) { |
| | |
| | | }, |
| | | |
| | | //获取L2的数据 |
| | | get_l2_datas: function(code, date, end_index, callback) { |
| | | get_l2_datas: function(code, date, end_index, fast_mode, callback) { |
| | | var params = { |
| | | code: code |
| | | code: code, |
| | | fast: fast_mode |
| | | } |
| | | if (date) { |
| | | params['date'] = date |
| | |
| | | data = { |
| | | type: "common", |
| | | data: { |
| | | ctype: "get_delegated_buy_code_infos" |
| | | ctype: "get_delegated_buy_code_infos_v2" |
| | | }, |
| | | sign: '' |
| | | } |
| | | http_util.socket_request(JSON.stringify(data), function(result) { |
| | | console.log(result); |
| | | result = JSON.parse(result); |
| | | callback(result); |
| | | }); |
| | |
| | | }, |
| | | // 获取所有L2订阅的列表 |
| | | get_l2_subscript_codes: function(callback) { |
| | | var params = { |
| | | type: "get_huaxin_subscript_codes", |
| | | data: {}, |
| | | sign: '' |
| | | } |
| | | http_util.socket_request(JSON.stringify(params), function(result) { |
| | | result = JSON.parse(result); |
| | | callback(result); |
| | | }); |
| | | // var params = { |
| | | // type: "get_huaxin_subscript_codes", |
| | | // data: {}, |
| | | // sign: '' |
| | | // } |
| | | // http_util.socket_request(JSON.stringify(params), function(result) { |
| | | // result = JSON.parse(result); |
| | | // callback(result); |
| | | // }); |
| | | http_util.http_request("/get_l2_subscript_codes", {}, callback); |
| | | }, |
| | | |
| | | get_big_order_deal_info:function(code, callback){ |
| | |
| | | }, |
| | | |
| | | get_all_special_codes:function(callback){ |
| | | http_util.http_request("/get_all_special_codes", { |
| | | }, callback); |
| | | http_util.http_request("/get_all_special_codes", {}, callback); |
| | | }, |
| | | get_new_blocks_special_codes:function(callback){ |
| | | http_util.http_request("/get_new_blocks_special_codes", { |
| | | }, callback); |
| | | http_util.http_request("/get_new_blocks_special_codes", {}, callback); |
| | | }, |
| | | // 设置累计成交大单的阈值 |
| | | set_total_deal_big_order_threshold_money: function(code, money, callback) { |
| | |
| | | }); |
| | | }, |
| | | |
| | | |
| | | // 设置L后撤单比例 |
| | | set_l_down_rate: function(code, rate, callback) { |
| | | let data = { |
| | | type: "common", |
| | | data: { |
| | | ctype: "set_l_down_rate", |
| | | code: code, |
| | | rate: rate |
| | | }, |
| | | sign: '' |
| | | } |
| | | console.log("请求元数据:", data) |
| | | console.log("请求json数据:", JSON.stringify(data)) |
| | | http_util.socket_request(JSON.stringify(data), function(result) { |
| | | result = JSON.parse(result); |
| | | callback(result); |
| | | }); |
| | | }, |
| | | // 获取委托队列 |
| | | get_trade_queue: function(code, callback) { |
| | | let data = { |
| | | type: "common", |
| | | data: { |
| | | ctype: "get_trade_queue", |
| | | code: code |
| | | }, |
| | | sign: '' |
| | | } |
| | | http_util.socket_request(JSON.stringify(data), function(result) { |
| | | result = JSON.parse(result); |
| | | callback(result); |
| | | }); |
| | | }, |
| | | // 获取已成交的大单 |
| | | get_deal_big_money_list: function(code, callback) { |
| | | let data = { |
| | | type: "common", |
| | | data: { |
| | | ctype: "get_deal_big_money_list", |
| | | code: code |
| | | }, |
| | | sign: '' |
| | | } |
| | | http_util.socket_request(JSON.stringify(data), function(result) { |
| | | result = JSON.parse(result); |
| | | callback(result); |
| | | }); |
| | | }, |
| | | |
| | | |
| | | |
| | |
| | | result = JSON.parse(result); |
| | | callback(result); |
| | | }); |
| | | }, |
| | | get_can_buy_plates:function(callback){ |
| | | let data = { |
| | | ctype: "get_can_buy_plates" |
| | | }; |
| | | var params = { |
| | | type: "common", |
| | | data: data, |
| | | sign: '' |
| | | } |
| | | http_util_of_ls.socket_request(JSON.stringify(params), function(result) { |
| | | result = JSON.parse(result); |
| | | callback(result); |
| | | }); |
| | | } |
| | | |
| | | }; |
| | |
| | | setInterval(function() { |
| | | if (is_trade_time()) { |
| | | app.get_low_suction_place_order_records(); |
| | | app.get_low_suction_plates(); |
| | | } |
| | | |
| | | }, 3000, 3000); |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | |
| | |
| | | new_block_code_special_blocks:{}, |
| | | low_suction_plate_white_list:[], |
| | | low_suction_place_order_records:[], |
| | | low_suction_plates: [] |
| | | |
| | | }, |
| | | watch: { |
| | | want_codes: function() { |
| | |
| | | } |
| | | break; |
| | | case 4: |
| | | case 5: |
| | | { |
| | | case 5: { |
| | | http_util.get_blocks_in_money_info(type%2, function(result) { |
| | | result = JSON.parse(result); |
| | | if (result.code == 0) { |
| | |
| | | for (var i = 0; i < app.first_info |
| | | .limit_up_reason_statistic |
| | | .length; i++) { |
| | | var limit_up_info = app.first_info.limit_up_reason_statistic[i]; |
| | | var limit_up_info = app.first_info |
| | | .limit_up_reason_statistic[i]; |
| | | if (limit_up_info[0] == e[1]) { |
| | | s = limit_up_info; |
| | | break; |
| | |
| | | var temps = new Array(); |
| | | var current_limit_up_reason =null; |
| | | res.data.limit_up_reason_statistic.forEach(function(d) { |
| | | if (app.code_third_blocks&&app.code_third_blocks.match_blocks&&app.code_third_blocks.match_blocks[0].includes(d[0])) { |
| | | if (app.code_third_blocks && app.code_third_blocks |
| | | .match_blocks && app.code_third_blocks |
| | | .match_blocks[0].includes(d[0])) { |
| | | current_limit_up_reason = d; |
| | | } else { |
| | | temps.push(d); |
| | |
| | | if (app.choose_code.first != app.first_info.limit_up_codes[index][0]) { |
| | | app.choose_code.first = app.first_info.limit_up_codes[index][0]; |
| | | app.code = app.first_info.limit_up_codes[index][0]; |
| | | pyjs.add_code_to_ths(app.code); |
| | | app.code_name = app.code + "(" + app.first_info.limit_up_codes[index][1] + |
| | | ")"; |
| | | app.get_score_data(app.first_info.limit_up_codes[index][0], app.first_info |
| | |
| | | if (res.code == 0) { |
| | | res.data.plate.forEach(function(e) { |
| | | var s = null; |
| | | if (app.first_info.limit_up_reason_statistic) { |
| | | if (app.first_info |
| | | .limit_up_reason_statistic) { |
| | | for (var i = 0; i < app.first_info |
| | | .limit_up_reason_statistic |
| | | .length; i++) { |
| | | if (app.first_info |
| | | .limit_up_reason_statistic[ |
| | | i][0] == e[1]) { |
| | | s = app.first_info.limit_up_reason_statistic[i]; |
| | | s = app.first_info |
| | | .limit_up_reason_statistic[ |
| | | i]; |
| | | break; |
| | | } |
| | | } |
| | |
| | | |
| | | // 设置当日涨停原因 |
| | | try{ |
| | | app.kpl_limit_up_reason = app.kpl_code_info.today[0] |
| | | app.kpl_limit_up_reason = app.kpl_code_info |
| | | .today[0] |
| | | [0]; |
| | | }catch(e){ |
| | | } |
| | | } catch (e) {} |
| | | // 将当前涨停原因置顶 |
| | | var limit_up_reason_statistic = app.first_info |
| | | .limit_up_reason_statistic; |
| | |
| | | pyjs.add_code_to_ths(code); |
| | | try{ |
| | | app.set_target_code(code); |
| | | }catch(e){ |
| | | } |
| | | } catch (e) {} |
| | | }, |
| | | show_latest_limit_up_queue:function(time_str){ |
| | | http_util.get_kpl_latest_limit_up_queue_by_time(time_str,function(res){ |
| | |
| | | res.data.sort((a,b)=>a[2] - b[2]); |
| | | res.data.forEach(function(e){ |
| | | let date = new Date(e[2]*1000); |
| | | let hours = String(date.getHours()).padStart(2, '0'); |
| | | let minutes = String(date.getMinutes()).padStart(2, '0'); |
| | | let seconds = String(date.getSeconds()).padStart(2, '0'); |
| | | let hours = String(date.getHours()).padStart(2, |
| | | '0'); |
| | | let minutes = String(date.getMinutes()).padStart(2, |
| | | '0'); |
| | | let seconds = String(date.getSeconds()).padStart(2, |
| | | '0'); |
| | | temp_time_str = `${hours}:${minutes}:${seconds}`; |
| | | datas.push([e[0],e[1],temp_time_str,e[4],e[5],e[6]]); |
| | | datas.push([e[0], e[1], temp_time_str, e[4], e[5], |
| | | e[6] |
| | | ]); |
| | | }); |
| | | app.latest_limit_up_datas = datas; |
| | | layer.open({ |
| | |
| | | |
| | | get_l2_subscript_codes:function(){ |
| | | http_util.get_l2_subscript_codes(function(res){ |
| | | res= JSON.parse(res); |
| | | |
| | | if(res.code == 0){ |
| | | console.log("订阅的代码:", res.data); |
| | | try{ |
| | | res.data.list.sort((a, b) => (b[3][3]?1:0) - (a[3][3]?1:0)); |
| | | res.data.sort((a, b) => b[4] - a[4]); |
| | | }catch(e){ |
| | | |
| | | } |
| | | app.l2_subscript_codes = res.data.list; |
| | | app.l2_subscript_codes = res.data; |
| | | } |
| | | }); |
| | | }, |
| | |
| | | }, |
| | | edit_total_big_order_threshold:function(){ |
| | | // 编辑总大单 |
| | | let threshold_money =app.big_order_deal_info[2][4]? app.big_order_deal_info[2][4] : app.big_order_deal_info[2][2]; |
| | | let threshold_money = app.big_order_deal_info[2][4] ? app.big_order_deal_info[2] |
| | | [4] : app.big_order_deal_info[2][2]; |
| | | var threshold_money_number = 0; |
| | | if(threshold_money.indexOf("万")>=0){ |
| | | threshold_money_number = (parseFloat(threshold_money.replace("万",""))/10000).toFixed(2) |
| | | threshold_money_number = (parseFloat(threshold_money.replace("万", "")) / |
| | | 10000).toFixed(2) |
| | | }else if(threshold_money.indexOf("亿")>=0){ |
| | | threshold_money_number = (parseFloat(threshold_money.replace("亿",""))).toFixed(2) |
| | | threshold_money_number = (parseFloat(threshold_money.replace("亿", ""))) |
| | | .toFixed(2) |
| | | } |
| | | |
| | | layer.prompt({ |
| | | title: '修改累计大单成交阈值(单位:亿)原值:'+app.big_order_deal_info[2][3] |
| | | ,formType: 0, //输入框类型,支持0(文本)默认1(密码)2(多行文本) |
| | | let prompt_index = layer.prompt({ |
| | | title: '修改累计大单成交阈值(单位:亿)原值:' + app.big_order_deal_info[2][3], |
| | | formType: 0, //输入框类型,支持0(文本)默认1(密码)2(多行文本) |
| | | value: threshold_money_number, //初始时的值,默认空字符 |
| | | maxlength: 20, //可输入文本的最大长度,默认500 |
| | | area: ['200px', '150px'] //自定义文本域宽高 |
| | | area: ['200px', '150px'], //自定义文本域宽高 |
| | | success: function(layero, index) { |
| | | $(layero).on('keydown', function(e) { |
| | | if (e.keyCode === 13) { |
| | | // 绑定enter |
| | | var val = $('.layui-layer-input').val(); |
| | | if (isNaN(val)) { |
| | | layer.msg("输入格式有误") |
| | | return; |
| | | } |
| | | let money = parseFloat(val).toFixed(2) * |
| | | 100000000 |
| | | http_util |
| | | .set_total_deal_big_order_threshold_money( |
| | | app.code, money, |
| | | function(res) { |
| | | if (res.code != 0) { |
| | | layer.msg(res.msg) |
| | | return; |
| | | } |
| | | layer.msg("修改成功") |
| | | layer.close(prompt_index) // 关闭当前弹窗 |
| | | app.get_big_order_deal_info(app |
| | | .code); |
| | | setTimeout(function(){ |
| | | app.get_l2_subscript_codes(); |
| | | },100); |
| | | |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | },function(val, index){ |
| | | // 只有当点击确认时才会执行这里 |
| | | if(isNaN(val)){ |
| | |
| | | return; |
| | | } |
| | | let money = parseFloat(val).toFixed(2)*100000000 |
| | | http_util.set_total_deal_big_order_threshold_money(app.code, money, function(res){ |
| | | http_util.set_total_deal_big_order_threshold_money(app.code, money, |
| | | function(res) { |
| | | if(res.code!=0){ |
| | | layer.msg(res.msg) |
| | | return; |
| | |
| | | // }); |
| | | |
| | | }, |
| | | check_low_suction_white_plate:function(event, plate) |
| | | { |
| | | check_low_suction_white_plate: function(event, plate) { |
| | | if(event.target.checked){ |
| | | this.add_low_suction_white_plate(plate); |
| | | }else{ |
| | |
| | | app.low_suction_place_order_records = res.data; |
| | | } |
| | | }); |
| | | }, |
| | | get_low_suction_plates: function() { |
| | | http_util_of_ls.get_can_buy_plates(function(res) { |
| | | console.log("低吸量化板块", JSON.stringify(res.data)) |
| | | if (res.code == 0) { |
| | | app.low_suction_plates = res.data; |
| | | } |
| | | }); |
| | | } |
| | | |
| | | |
| | |
| | | app.statistic_latest_limit_up_block(""); |
| | | app.list_forbidden_buy_plates(); |
| | | app.list_low_suction_white_plate(); |
| | | app.get_low_suction_place_order_records(); |
| | | |
| | | } |
| | | |
| | |
| | | <html> |
| | | <head> |
| | | <meta charset="utf-8"> |
| | | <title>看盘端</title> |
| | | <title>低吸回测</title> |
| | | <link rel="stylesheet" type="text/css" href="./css/index23-05-04.css?_=1" /> |
| | | <link rel="stylesheet" type="text/css" href="layui/css/layui.css" /> |
| | | <script src="js/jquery.min.js"></script> |
| | |
| | | <th>代码</th> |
| | | <th>涨幅</th> |
| | | <th>是否买入</th> |
| | | <th>收盘溢价率</th> |
| | | <th>次日开盘溢价率</th> |
| | | <th>说明</th> |
| | | </thead> |
| | | |
| | |
| | | <td>{{item[1]}}</td> |
| | | <td>{{item[2]}}%</td> |
| | | <td>{{item[3][0]?'是':'否'}}</td> |
| | | <td><span v-if="item.length>4"> {{item[4]}}% </span> <span v-else> -- </span> </td> |
| | | <td><span v-if="item.length>5"> {{item[5]}}% </span> <span v-else> -- </span></td> |
| | | <td> |
| | | <span v-if="item[3][0]"> {{item[3][2]}} </span> |
| | | <span v-else> {{item[3][1]}} </span> |
| | |
| | | # 添加到同花顺 |
| | | threading.Thread(target=lambda: ths_util.add_code_to_zixuan(code), daemon=True).start() |
| | | |
| | | @pyqtSlot(str) |
| | | def open_webview_window(self, data): |
| | | """ |
| | | 打开独立网页窗口 |
| | | :param data: |
| | | :return: |
| | | """ |
| | | data = json.loads(data) |
| | | url = data.get("url") |
| | | title = data.get("title") |
| | | key = data.get("key") |
| | | size = data.get("size") |
| | | common_window = CommonWindow(title, key, size, parent=self.__webview.window()) |
| | | common_window.loadUrl(url) |
| | | common_window.show() |
| | | |
| | | |
| | | class SecondWindowBridgeClass(BaseBridgeClass): |
| | | @pyqtSlot(str) |
| | |
| | | channel = QWebChannel(self.webview.page()) |
| | | self.webview.page().setWebChannel(channel) |
| | | self.python_bridge = SecondWindowBridgeClass(self.webview) |
| | | |
| | | channel.registerObject("Bridge", self.python_bridge) |
| | | |
| | | # win32gui.SetWindowLong(self.winId(), win32con.GWL_WNDPROC, self.handleCustomMessage) |
| | |
| | | (self.pos().x(), self.pos().y(), self.size().width(), self.size().height())) |
| | | except Exception as e: |
| | | print("") |
| | | |
| | | |
| | | class DelegatingWindow(QMainWindow): |
| | | """ |
| | | 加贝控制中心 |
| | | """ |
| | | signal_update_kpl = pyqtSignal(str) |
| | | |
| | | def update_kpl_func(self): |
| | | while True: |
| | | time.sleep(3) |
| | | try: |
| | | self.__update_kpl() |
| | | except: |
| | | pass |
| | | |
| | | def __init__(self, parent=None): |
| | | super(DelegatingWindow, self).__init__(parent) |
| | | self.setWindowTitle('加贝控制中心') |
| | | window_info = setting.get_delegating_window_info() |
| | | if window_info: |
| | | self.move(window_info[0], window_info[1]) |
| | | self.resize(window_info[2], window_info[3]) |
| | | else: |
| | | self.resize(600, 800) |
| | | |
| | | self.webview = QWebEngineView() |
| | | self.webview.settings().setAttribute(QWebEngineSettings.JavascriptEnabled, True) |
| | | self.webview.page().setZoomFactor(1) |
| | | self.setCentralWidget(self.webview) |
| | | |
| | | # JS桥设置 |
| | | channel = QWebChannel(self.webview.page()) |
| | | self.webview.page().setWebChannel(channel) |
| | | self.python_bridge = BaseBridgeClass(self.webview) |
| | | channel.registerObject("Bridge", self.python_bridge) |
| | | |
| | | # 自定义消息处理函数 |
| | | def handleCustomMessage(self, hwnd, msg, wparam, lparam): |
| | | if msg == win32con.WM_USER + 1024: |
| | | # 解析数据 |
| | | # try: |
| | | # code = ctypes.cast(lparam, ctypes.py_object).value |
| | | # print(code) |
| | | # except: |
| | | # pass |
| | | pass |
| | | |
| | | # 处理数据 |
| | | # self.dataReceived.emit(intValue, stringValue) |
| | | |
| | | return win32gui.DefWindowProc(hwnd, msg, wparam, lparam) |
| | | |
| | | def loadUrl(self, url): |
| | | self.webview.load(QUrl(url)) |
| | | |
| | | def closeEvent(self, event): |
| | | try: |
| | | setting.set_delegating_window_info( |
| | | (self.pos().x(), self.pos().y(), self.size().width(), self.size().height())) |
| | | except Exception as e: |
| | | print("") |
| | | |
| | | |
| | | class CommonWindow(QMainWindow): |
| | | """ |
| | | 加贝控制中心 |
| | | """ |
| | | signal_update_kpl = pyqtSignal(str) |
| | | |
| | | def update_kpl_func(self): |
| | | while True: |
| | | time.sleep(3) |
| | | try: |
| | | self.__update_kpl() |
| | | except: |
| | | pass |
| | | |
| | | def __init__(self, title, key, default_size, parent=None): |
| | | """ |
| | | :param title: 标题 |
| | | :param key: 标识 |
| | | :param default_size:(宽, 高) |
| | | :param parent: |
| | | """ |
| | | super(CommonWindow, self).__init__(parent) |
| | | self.setWindowTitle(title) |
| | | window_info = setting.get_window_info(f"{key}_window_info") |
| | | if window_info: |
| | | self.move(window_info[0], window_info[1]) |
| | | self.resize(window_info[2], window_info[3]) |
| | | else: |
| | | self.resize(default_size[0], default_size[1]) |
| | | self.key = key |
| | | |
| | | self.webview = QWebEngineView() |
| | | self.webview.settings().setAttribute(QWebEngineSettings.JavascriptEnabled, True) |
| | | self.webview.page().setZoomFactor(1) |
| | | self.setCentralWidget(self.webview) |
| | | |
| | | # JS桥设置 |
| | | channel = QWebChannel(self.webview.page()) |
| | | self.webview.page().setWebChannel(channel) |
| | | self.python_bridge = BaseBridgeClass(self.webview) |
| | | channel.registerObject("Bridge", self.python_bridge) |
| | | |
| | | # 自定义消息处理函数 |
| | | def handleCustomMessage(self, hwnd, msg, wparam, lparam): |
| | | if msg == win32con.WM_USER + 1024: |
| | | # 解析数据 |
| | | # try: |
| | | # code = ctypes.cast(lparam, ctypes.py_object).value |
| | | # print(code) |
| | | # except: |
| | | # pass |
| | | pass |
| | | |
| | | # 处理数据 |
| | | # self.dataReceived.emit(intValue, stringValue) |
| | | |
| | | return win32gui.DefWindowProc(hwnd, msg, wparam, lparam) |
| | | |
| | | def loadUrl(self, url): |
| | | self.webview.load(QUrl(url)) |
| | | |
| | | def closeEvent(self, event): |
| | | try: |
| | | setting.set_window_info(f"{self.key}_window_info", |
| | | (self.pos().x(), self.pos().y(), self.size().width(), self.size().height())) |
| | | except Exception as e: |
| | | print("") |
| | | self.webview.close() |
| | | |
| | | |
| | | class WebEnginePage(QWebEnginePage): |
| | |
| | | def __show_second_window(): |
| | | self.secondWindow.show() |
| | | |
| | | def __show_delegating_window(): |
| | | self.delegatingWindow.show() |
| | | |
| | | def __show_his_msg_window(): |
| | | self.msgListWindow.loadUrl(URL_MSG_LIST) |
| | | self.msgListWindow.show() |
| | |
| | | action.triggered.connect(__show_second_window) |
| | | view_.addAction(action) |
| | | |
| | | action = QAction("&打开加贝控制中心", self) |
| | | action.triggered.connect(__show_delegating_window) |
| | | view_.addAction(action) |
| | | |
| | | action = QAction("&打开历史消息", self) |
| | | action.triggered.connect(__show_his_msg_window) |
| | | view_.addAction(action) |
| | |
| | | channel.registerObject("Bridge", self.python_bridge) |
| | | # 设置副屏 |
| | | self.secondWindow = SecondWindow(self) |
| | | self.delegatingWindow = DelegatingWindow(self) |
| | | |
| | | self.setCentralWidget(self.webview) |
| | | self.show() |
| | |
| | | else: |
| | | self.secondWindow.loadUrl("http://127.0.0.1:8848/kp/codes_list.html") |
| | | |
| | | self.delegatingWindow.show() |
| | | if not constant.IS_TEST: |
| | | self.delegatingWindow.loadUrl(f"http://{constant.WEB_HOST}/kp/delegating_list.html") |
| | | else: |
| | | self.delegatingWindow.loadUrl("http://127.0.0.1:8848/kp/delegating_list.html") |
| | | # 绑定槽函数 |
| | | self.signal_update_code.connect(self.set_target_code) |
| | | # self.statusBar().showMessage("这是条测试数据额", 10000) |
| | |
| | | [config] |
| | | stay_on_top = 1 |
| | | window_info = [[-1711, 194, 1280, 800], [1473, 621, 320, 195]] |
| | | xgb_window_info = [-1567, 208, 1146, 987] |
| | | xgb_window_info = [-2625, 529, 1920, 1017] |
| | | window_watch_float_info = [146, 419, 435, 220] |
| | | window_tick_info = [280, 40, 800, 1000] |
| | | kp_second_window_info = [-961, 106, 558, 942] |
| | | kp_second_window_info = [-889, 356, 638, 910] |
| | | code_attribute_window_info = [-650, 315, 291, 278] |
| | | client = hxh |
| | | float_frame_auto_focus = 1 |
| | |
| | | only_convertible_bonds = 0 |
| | | screen_scale = 1 |
| | | ths_buy = 1 |
| | | delegating_window_info = [-879, 175, 644, 800] |
| | | trade_queue_window_info = [-1024, 450, 437, 369] |
| | | |
| | | [juejin] |
| | | strategy_id = 95a982ce-fc2d-11ec-8ff3-0a0027000010 |
| | |
| | | return val |
| | | |
| | | |
| | | def set_delegating_window_info(window): |
| | | set_window_info("delegating_window_info", window) |
| | | |
| | | |
| | | def get_delegating_window_info(): |
| | | return get_window_info("delegating_window_info") |
| | | |
| | | |
| | | def set_window_info(key, window): |
| | | """ |
| | | 设置窗口信息 |
| | | :param key: |
| | | :param window: |
| | | :return: |
| | | """ |
| | | cp = __read_setting() |
| | | cp.set("config", key, json.dumps(window)) |
| | | __write_setting(cp) |
| | | |
| | | |
| | | def get_window_info(key): |
| | | """ |
| | | 获取窗口信息 |
| | | :param key: |
| | | :return: |
| | | """ |
| | | cp = __read_setting() |
| | | val = __get_setting(cp, "config", key) |
| | | if val is None: |
| | | return None |
| | | else: |
| | | val = json.loads(val) |
| | | return val |
| | | |
| | | |
| | | # 设置代码属性框信息 |
| | | def set_code_attribute_window_info(window): |
| | | cp = __read_setting() |