| | |
| | | # 下单参数信息 |
| | | # 选股宝 |
| | | # 市场热度 |
| | | import os |
| | | import sys |
| | | |
| | | import code_volumn_manager |
| | | import constant |
| | | import global_data_loader |
| | | import global_util |
| | | import gpcode_manager |
| | |
| | | import tool |
| | | from l2 import l2_data_manager, l2_data_util, transaction_progress, l2_data_manager_new, code_price_manager |
| | | from third_data import hot_block_data_process |
| | | from trade import first_code_score_manager, l2_trade_factor |
| | | from trade 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 |
| | | |
| | | base_output_content = {} |
| | | |
| | | |
| | | def __get_base_html_content(): |
| | | print("路径", sys.path[0]) |
| | | if base_output_content.get('css') is None: |
| | | __base_html_content = "" |
| | | with open("./output/css/style.css", mode='r') as f: |
| | | lines = f.readlines() |
| | | for line in lines: |
| | | __base_html_content += line |
| | | base_output_content['css'] = __base_html_content |
| | | |
| | | return f"<head><style>{base_output_content['css']}</style></head>" |
| | | |
| | | |
| | | def __format_data(code_info, score_info, buy_params_info, xgb_code_info, xgb_infos, codes_score, trade_info): |
| | | html = "" |
| | | html += f"<h2>{code_info[1]} {code_info[0]}</h2><br>" |
| | | |
| | | |
| | | html = __get_base_html_content() |
| | | html += "<body>" |
| | | html += f"<h2>{code_info[1]} {code_info[0]} ({code_info[2]})</h2><br>" |
| | | |
| | | if score_info: |
| | | html += "<b>-----买前评分-------</b><br>" |
| | | score_types = ["换手量能", "竞价强度", "资金力度", "日线形态", "历史股性", "板块热度", "上板时间", "市值大小", "股价大小"] |
| | | html += "<table style='font-size:25px'>" |
| | | html += "<table>" |
| | | for i in range(0, len(score_info[1])): |
| | | html += f"<tr><td>{score_types[i]}</td><td>{score_info[1][i]}</td><td>{score_info[2][i]}</td></tr>" |
| | | html += f"<tr><td><b>评分求和:</td><td>{score_info[0]}</b></td><td></td></tr>" |
| | | html += f"</table><br>" |
| | | |
| | | html += "\n" |
| | | if buy_params_info: |
| | | html += "<b><br>-----交易参数-------<br></b><table>" |
| | | titles = ["买入意愿", "安全笔数", "动态M值", "买前大单", "成交进度", "买入信号", "买入执行位"] |
| | | for i in range(0, len(titles)): |
| | | html += f"<tr><td>{titles[i]}:</td><td>{buy_params_info[i]}</td></tr>" |
| | | html += "</table><br>" |
| | | |
| | | html += "\n" |
| | | if xgb_code_info: |
| | | html += "<b><br>-----选股宝---------<br></b>" |
| | | xgb_code_info_dates = ["今天", "昨天", "前天", "之前"] |
| | | for i in range(0, len(xgb_code_info)): |
| | | html += f"{xgb_code_info_dates[i]}:<br>" |
| | | if xgb_code_info[i]: |
| | | html += f"{xgb_code_info_dates[i]}:<br>" |
| | | for info in xgb_code_info[i]: |
| | | if i == 0: |
| | | html += f"【<font color='red'>{info[0]}</font>】,共【<font color='red'>{info[1]}</font>】只票涨停<br>第【<font color='red'>{info[2]}</font>】涨停,现价【<font color='red'>{info[3]}</font>】元,涨幅【<font color='red'>{info[4]}</font>】<br><br>" |
| | | else: |
| | | html += f"【{info[0]}】,共【{info[1]}】只票涨停<br>第【{info[2]}】涨停,现价【{info[3]}】元,涨幅【{info[4]}】<br><br>" |
| | | else: |
| | | html += f"无<br>" |
| | | html += "\n" |
| | | if codes_score[0]: |
| | | html += "<b>-----主动买入-------</b><br>" |
| | | html += "<table>" |
| | | for i in range(0, len(codes_score[0])): |
| | | if i % 4 == 0: |
| | | if i % 3 == 0: |
| | | html += "<tr>" |
| | | html += f"<td><font color='red'>{codes_score[0][i][1]}:{codes_score[0][i][2]}</font></td>" |
| | | if i % 4 == 3 or i == len(codes_score[0]) - 1: |
| | | html += f"<td><font color='red'>{'*' if codes_score[0][i][3] else ''}{codes_score[0][i][1]}({codes_score[0][i][0]}):{codes_score[0][i][2]}</font></td>" |
| | | if i % 3 == 2 or i == len(codes_score[0]) - 1: |
| | | html += "</tr>" |
| | | html += "</table><br>" |
| | | html += "</table><br>\n" |
| | | |
| | | if codes_score[1]: |
| | | html += "<b>-----被动买入-------</b><br>" |
| | | html += "<table>" |
| | | for i in range(0, len(codes_score[1])): |
| | | if i % 4 == 0: |
| | | if i % 3 == 0: |
| | | html += "<tr>" |
| | | html += f"<td><font color='#000080'>{codes_score[1][i][1]}:{codes_score[1][i][2]}</font></td>" |
| | | if i % 4 == 3 or i == len(codes_score[1]) - 1: |
| | | html += f"<td><font color='#000080'>{'*' if codes_score[1][i][3] else ''}{codes_score[1][i][1]}({codes_score[1][i][0]}):{codes_score[1][i][2]}</font></td>" |
| | | if i % 3 == 2 or i == len(codes_score[1]) - 1: |
| | | html += "</tr>" |
| | | html += "</table><br>" |
| | | html += "</table><br>\n" |
| | | |
| | | if codes_score[2]: |
| | | if codes_score[2] and False: |
| | | html += "<b>-----不买入-------</b><br>" |
| | | html += "<table>" |
| | | for i in range(0, len(codes_score[2])): |
| | |
| | | html += f"<td>{codes_score[2][i][1]}:{codes_score[2][i][2]}</td>" |
| | | if i % 4 == 3 or i == len(codes_score[1]) - 1: |
| | | html += "</tr>" |
| | | html += "</table><br>" |
| | | html += "</table><br>\n" |
| | | |
| | | if trade_info: |
| | | html += "<b>-----今日挂撤记录-------</b><br>" |
| | | html += "<br>今日是否炸板:" |
| | | if trade_info[0]: |
| | | if trade_info[0] is not None: |
| | | html += f"炸板-{trade_info[0]}" |
| | | else: |
| | | html += f"未炸板" |
| | |
| | | for i in range(0, len(trade_info[1])): |
| | | if i % 2 == 0: |
| | | html += "<tr>" |
| | | html += f"<td>第{i + 1}次下单 评分{trade_info[1][i][1][0][0]} {trade_info[1][i][0]} </td>" |
| | | html += f"<td>{trade_info[1][i]}</td>" |
| | | if i % 2 == 1 or i == len(codes_score[0]) - 1: |
| | | html += "</tr>" |
| | | html += "</table><br>" |
| | | html += "<br>" |
| | | html += "<br>\n" |
| | | |
| | | if xgb_infos: |
| | | html += "<b><br>-----市场热度-------<br></b><table>" |
| | | for info in xgb_infos: |
| | | html += f"<tr><td><font size='3'>{info[0]}</font><br><div style='margin-left:100px;'>{info[1]}</div></td></tr>" |
| | | html += "</tr>" |
| | | html += f"<tr><td>{info[0]}<br><div style=''>{info[1]}</div></td></tr>" |
| | | html += "</table>" |
| | | html += "<br><br>" |
| | | html += "</body>" |
| | | return html |
| | | |
| | | |
| | | def get_output_html(code): |
| | | day = tool.get_now_date_str() |
| | | is_target_code = gpcode_manager.FirstCodeManager.is_in_first_record(code) |
| | | code_info = [code, gpcode_manager.get_code_name(code)] |
| | | code_extra_infos=[] |
| | | if l2_trade_util.BlackListCodeManager.is_in(code): |
| | | code_extra_infos.append("黑名单") |
| | | if l2_trade_util.WhiteListCodeManager.is_in(code): |
| | | code_extra_infos.append("白名单") |
| | | # 获取白名单,黑名单 |
| | | if trade_manager. gpcode_manager.WantBuyCodesManager.is_in(code): |
| | | code_extra_infos.append("想买单") |
| | | |
| | | code_info = [code, gpcode_manager.get_code_name(code),",".join(code_extra_infos)] |
| | | score_info = None |
| | | buy_params_info = None |
| | | xgb_infos = None |
| | | total_datas = l2_data_util.local_today_datas.get(code) |
| | | if total_datas is None: |
| | | l2_data_util.load_l2_data(code) |
| | | total_datas = l2_data_util.local_today_datas.get(code) |
| | | if is_target_code: |
| | | limit_up_price = gpcode_manager.get_limit_up_price(code) |
| | | limit_up_time = limit_up_time_manager.get_limit_up_time(code) |
| | |
| | | # 竞价强度 |
| | | score_list_new.append(score_list[2]) |
| | | score_source_list_new.append(f"开盘啦今日委停【{score_source_list[2] if score_source_list[2] else 0}万】") |
| | | total_datas = l2_data_util.local_today_datas.get(code) |
| | | if total_datas is None: |
| | | l2_data_util.load_l2_data(code) |
| | | total_datas = l2_data_util.local_today_datas.get(code) |
| | | |
| | | # 资金力度 |
| | | deal_indexes = trade.deal_big_money_manager.get_traded_indexes(code) |
| | | deal_info = "" |
| | |
| | | |
| | | for n in range(0, len(score_source_list[4])): |
| | | if n == 0: |
| | | if not score_source_list[4][n]: |
| | | nature_source.append("无涨停") |
| | | nature_source.append(f"涨停次数【{score_source_list[4][n]}】") |
| | | elif n == 1: |
| | | if score_source_list[4][n]: |
| | | nature_source.append(f"首板溢价率【{round(score_source_list[4][n], 2)}】") |
| | | else: |
| | | nature_source.append("有涨停") |
| | | if n == 1: |
| | | nature_source.append(f"首板溢价率【{round(score_source_list[4][2],2)}】") |
| | | nature_source.append(f"无首板") |
| | | elif n == 2: |
| | | if score_source_list[4][n]: |
| | | nature_source.append(f"首板炸板溢价率【{round(score_source_list[4][n], 2)}】") |
| | | else: |
| | | nature_source.append(f"无首板炸板") |
| | | |
| | | score_list_new.append(nature_score) |
| | | score_source_list_new.append(",".join(nature_source)) |
| | |
| | | hot_block_source = [] |
| | | for k in score_list[5]: |
| | | hot_block_score += k |
| | | for n in range(0, len(score_source_list[5])): |
| | | if n == 1: |
| | | hot_block_source.append(f"【{score_source_list[5][0]}】共{score_source_list[5][n]}个涨停") |
| | | elif n == 2: |
| | | hot_block_source.append(f"共{score_source_list[5][n]}个炸板") |
| | | elif n == 4: |
| | | if score_source_list[5][n]: |
| | | hot_block_source.append(f"【{score_source_list[5][n][0][0]}】{score_source_list[5][n][1]}") |
| | | hot_block_source_data = score_source_list[5] |
| | | for k in hot_block_source_data: |
| | | hot_block = { |
| | | # 目标板块信息(板块名称,板块涨幅,历史板块出现次数) |
| | | "target_block_info": ("无板块", 0, 0), |
| | | # 涨停顺序 |
| | | "limit_up_index": 0, |
| | | # 涨停代码数量 |
| | | "limit_up_codes_count": 0, |
| | | # 板块代码涨幅信息 |
| | | "block_codes_rates_info": (0, 0), |
| | | # 炸板代码数量 |
| | | "break_size": 0, |
| | | # 炸板回封数量 |
| | | "re_limit_up_size": 0, |
| | | # 高位版信息 |
| | | "high_block_infos": [], |
| | | } |
| | | if k == "block_codes_rates_info": |
| | | hot_block_source.append(f"平均涨幅:【{round(hot_block_source_data[k][0]/hot_block_source_data[k][1],2)}%】") |
| | | elif k == "limit_up_codes_count": |
| | | hot_block_source.append(f"板块涨停数量:【{hot_block_source_data[k]}】") |
| | | elif k == "target_block_info": |
| | | hot_block_source.append(f"板块涨幅:【{hot_block_source_data[k][1]}%】") |
| | | elif k == "limit_up_index": |
| | | hot_block_source.append(f"第【{hot_block_source_data[k]+1}】只涨停") |
| | | elif k == "high_block_infos": |
| | | for info in hot_block_source_data[k]: |
| | | hot_block_source.append(f"{info[0][1]}{info[1]}") |
| | | if k == "target_block_info": |
| | | hot_block_source.append(f"【{hot_block_source_data[k][0]}】概念出现【{hot_block_source_data[k][2]}】次") |
| | | score_list_new.append(hot_block_score) |
| | | score_source_list_new.append(",".join(hot_block_source)) |
| | | |
| | |
| | | score_source_list)) |
| | | buy_params_info = [] |
| | | if -1 < __L2PlaceOrderParamsManager.score_index < 3: |
| | | buy_params_info.append("<font color='red'>【主动买入】</font>") |
| | | temp = "<font color='red'>【主动买入】" |
| | | if __L2PlaceOrderParamsManager.score_index == 0: |
| | | temp += "***" |
| | | elif __L2PlaceOrderParamsManager.score_index == 1: |
| | | temp += "**" |
| | | else: |
| | | temp += "*" |
| | | temp += "</font>" |
| | | buy_params_info.append(temp) |
| | | |
| | | elif __L2PlaceOrderParamsManager.score_index < 0: |
| | | buy_params_info.append("【不执行买入】") |
| | | else: |
| | |
| | | # 获取板块中的代码 |
| | | block_codes_set = set() |
| | | for d in block[2]: |
| | | code = d[0][1].split(".")[0] |
| | | block_codes_set.add(code) |
| | | _code = d[0][1].split(".")[0] |
| | | block_codes_set.add(_code) |
| | | |
| | | if codes: |
| | | codes_data_html = "<table><tr>" |
| | |
| | | # 不是该板块数据 |
| | | continue |
| | | count += 1 |
| | | codes_data_html += "<td>" |
| | | codes_data_html += "<td style = 'text-decoration:underline;'>" |
| | | # 如果代码涨停时间或者没有在最新的代码中 |
| | | if (len(code_data[2]) < 6 or code_data[0] not in block_codes_set) and len(code_data[3]) > 6: |
| | | # 炸板 |
| | |
| | | if count % 4 == 0: |
| | | codes_data_html += "</tr><tr>" |
| | | codes_data_html += "</tr></table>" |
| | | xgb_infos.append((f"***【{block[0]}】,涨幅【{block[1]}】,共【{limit_up_count}】个涨停", codes_data_html)) |
| | | _info = (f"***【{block[0]}】,涨幅【{block[1]}】,共【{limit_up_count}】个涨停", codes_data_html) |
| | | is_target_block = False |
| | | if xgb_code_info: |
| | | for _code_info in xgb_code_info[0]: |
| | | if len(_code_info) > 0 and _code_info[0] == block[0]: |
| | | is_target_block = True |
| | | break |
| | | if is_target_block: |
| | | xgb_infos.insert(0, _info) |
| | | else: |
| | | xgb_infos.append(_info) |
| | | |
| | | codes_score = __load_codes_scores() |
| | | trade_info = __load_trade_record(code) |
| | | trade_info = __load_trade_record(code, total_datas) |
| | | return __format_data(code_info, score_info, buy_params_info, xgb_code_info, xgb_infos, codes_score, trade_info) |
| | | |
| | | |
| | | def __load_codes_scores(): |
| | | # 获取所有监听中的代码 |
| | | codes = gpcode_manager.get_first_gp_codes() |
| | | scores = l2_data_manager_new.L2TradeDataProcessor.get_code_scores() |
| | | scores = {} # l2_data_manager_new.L2TradeDataProcessor.get_code_scores() |
| | | for code in codes: |
| | | if code not in scores: |
| | | # 获取分数 |
| | | limit_up_time = limit_up_time_manager.get_limit_up_time(code) |
| | | if limit_up_time is None: |
| | | continue |
| | | volume_rate, volume_info = code_volumn_manager.get_volume_rate(code, True) |
| | | (score, score_list), score_source_list = first_code_score_manager.get_score(code, volume_rate, |
| | | limit_up_time, |
| | | True) |
| | | scores[code] = score |
| | | try: |
| | | limit_up_time = limit_up_time_manager.get_limit_up_time(code) |
| | | volume_rate, volume_info = code_volumn_manager.get_volume_rate(code, True) |
| | | (score, score_list), score_source_list = first_code_score_manager.get_score(code, volume_rate, |
| | | limit_up_time, |
| | | True) |
| | | scores[code] = score |
| | | except: |
| | | pass |
| | | # 筛选180分以上的代码 |
| | | scores_list = [] |
| | | for code in scores: |
| | | code_name = gpcode_manager.get_code_name(code) |
| | | scores_list.append((code, code_name, scores[code])) |
| | | # 获取现价,判断是否涨停 |
| | | current_price_info = global_util.cuurent_prices.get(code) |
| | | is_limit_up = True |
| | | if current_price_info is not None and not current_price_info[1]: |
| | | is_limit_up = False |
| | | else: |
| | | is_limit_up = True |
| | | scores_list.append((code, code_name, scores[code], is_limit_up)) |
| | | scores_list.sort(key=lambda x: x[2], reverse=True) |
| | | fscores_list = [[], [], []] |
| | | for score in scores_list: |
| | | if score[2] >= 180: |
| | | if score[2] >= constant.BUY_SCORE_RANK_1: |
| | | fscores_list[0].append(score) |
| | | elif score[2] >= 100: |
| | | elif score[2] >= constant.BUY_SCORE_RANK_0: |
| | | fscores_list[1].append(score) |
| | | else: |
| | | fscores_list[2].append(score) |
| | |
| | | return fscores_list |
| | | |
| | | |
| | | def __load_trade_record(code): |
| | | def __load_trade_record(code, total_datas): |
| | | def format_l2_data(item): |
| | | return f"{item['val']['time']}#{item['val']['num']}手#{round(item['val']['num'] * float(item['val']['price']) * 100 / 10000, 1)}万" |
| | | |
| | | # 获取炸板信息 |
| | | limit_up_info = code_price_manager.Buy1PriceManager.get_limit_up_info(code) |
| | | break_time = limit_up_info[1] |
| | | records = log.load_buy_score_recod(code) |
| | | return break_time, records |
| | | records =[] |
| | | try: |
| | | records = log.load_buy_score_recod(code) |
| | | except: |
| | | pass |
| | | records_new = [] |
| | | index = 0 |
| | | if records: |
| | | try: |
| | | for record in records: |
| | | time_ = record[0] |
| | | type = record[1] |
| | | data = record[2] |
| | | if type == '下单': |
| | | index += 1 |
| | | temp = f"第{index}次下单:【{time_}】&【{data['score']}分】,{data.get('desc')}" |
| | | records_new.append(temp) |
| | | elif type == 'S撤': |
| | | # index':378 , 'rate':0.51 , 'target_rate':0.49 |
| | | pass |
| | | elif type == 'S撤范围': |
| | | start = format_l2_data(total_datas[data['start_index']]) |
| | | end = format_l2_data(total_datas[data['end_index']]) |
| | | range_seconds = data['range_seconds'] |
| | | temp = f"第{index}次撤单:S撤囊括范围:【起始位:{start}】至【截止位:{end}】囊括时间【{range_seconds}】秒" |
| | | elif type == 'H撤范围': |
| | | start = format_l2_data(total_datas[data['start_index']]) |
| | | end = format_l2_data(total_datas[data['end_index']]) |
| | | count = data['count'] |
| | | temp = f"H撤囊括范围:【起始位:{start}】至【截止位:{end}】物理笔数共【{count}】笔" |
| | | elif type == 'H撤': |
| | | # 'start_index':339,'end_index':464, 'count':17 |
| | | pass |
| | | elif type == '撤单': |
| | | temp = f"第{index}次撤单:【{time_}】{data['msg']}" |
| | | records_new.append(temp) |
| | | except: |
| | | pass |
| | | |
| | | return break_time, records_new |
| | | |
| | | |
| | | if __name__ == '__main__': |
| | | code = "002410" |
| | | day = '2023-03-27' |
| | | xgb_datas = hot_block_data_process.XGBHotBlockDataManager.list_by_code(code, day) |
| | | datas = [] |
| | | if xgb_datas: |
| | | for data in xgb_datas: |
| | | block = data[2] |
| | | block_datas = hot_block_data_process.XGBHotBlockDataManager.list_by_block(block, day) |
| | | block_datas = list(block_datas) |
| | | limit_up_count = 0 |
| | | limit_up_time = None |
| | | for d in block_datas: |
| | | if len(d[4]) > 6: |
| | | limit_up_count += 1 |
| | | if d[3] == code: |
| | | limit_up_time = d[4] |
| | | |
| | | # 根据涨停时间排序 |
| | | block_datas.sort(key=lambda d: (d[4] if len(d[4]) > 6 else '15:00:00')) |
| | | |
| | | for i in range(len(block_datas)): |
| | | if block_datas[i][3] == code: |
| | | datas.append((block, limit_up_count, (i + 1) if limit_up_time is not None else (limit_up_count + 1), |
| | | block_datas[i][5], block_datas[i][6])) |
| | | break |
| | | st="8天3板" |
| | | print(st[-2:-1]) |