| | |
| | | @classmethod |
| | | def save(cls, code, val, unit): |
| | | redis = _redisManager.getRedis() |
| | | redis.setex("zyltgb-{}".format(code), 60 * 60 * 24 * 10, |
| | | redis.setex("zyltgb-{}".format(code), tool.get_expire(), |
| | | round(float(val) * 100000000) if int(unit) == 0 else round( |
| | | float(val) * 10000)) |
| | | |
| | |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | print(is_same_code_with_price("000617", 17.89)) |
| | | redis = _redisManager.getRedis() |
| | | keys = redis.keys("zyltgb-*") |
| | | for key in keys: |
| | | redis.delete(key) |
| | |
| | | |
| | | |
| | | # 获取股性 |
| | | # 返回(是否涨停,首板溢价率是否大于0.6) |
| | | # 返回(是否涨停,首板溢价率,首板炸板溢价率) |
| | | def get_nature(record_datas): |
| | | limit_up = is_have_limit_up(record_datas) |
| | | limit_up_count = get_first_limit_up_count(record_datas) |
| | | premium_rate = get_limit_up_premium_rate(record_datas) |
| | | result = (limit_up, premium_rate >= 0.6, premium_rate) |
| | | |
| | | open_premium_rate = get_open_limit_up_premium_rate(record_datas) |
| | | result = (limit_up_count, premium_rate, open_premium_rate) |
| | | return result |
| | | |
| | | |
| | | # 获取涨幅 |
| | | def get_lowest_price_rate(record_datas): |
| | | datas = copy.deepcopy(record_datas) |
| | | datas.sort(key=lambda x: x["bob"]) |
| | | datas = datas[-15:] |
| | | low_price = datas[0]["close"] |
| | | date = None |
| | | datas = datas[-10:] |
| | | for data in datas: |
| | | if low_price > data["close"]: |
| | | low_price = data["close"] |
| | | limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(data["pre_close"])) |
| | | if abs(limit_up_price - data["high"]) < 0.01: |
| | | date = data['bob'].strftime("%Y-%m-%d") |
| | | return (datas[-1]["close"] - low_price) / low_price, date |
| | | return round((datas[-1]["close"] - data["close"]) / data["close"], 4), date |
| | | return 0, '' |
| | | |
| | | |
| | | # 是否有涨停 |
| | | def is_have_limit_up(datas): |
| | | def get_first_limit_up_count(datas): |
| | | datas = copy.deepcopy(datas) |
| | | count = 0 |
| | | for i in range(len(datas)): |
| | | item = datas[i] |
| | | limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(item["pre_close"])) |
| | | if abs(limit_up_price - item["close"]) < 0.01: |
| | | return True, item['bob'].strftime("%Y-%m-%d") |
| | | return False, '' |
| | | # 获取首板涨停次数 |
| | | if __is_limit_up(item) and i>0 and not __is_limit_up(datas[i-1]): |
| | | # 首板涨停 |
| | | count+=1 |
| | | |
| | | return count |
| | | |
| | | |
| | | # 是否破前高 |
| | |
| | | return max_volume, average_volume |
| | | |
| | | |
| | | # 是否涨停 |
| | | def __is_limit_up(data): |
| | | limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(data["pre_close"])) |
| | | return abs(limit_up_price - data["close"]) < 0.001 |
| | | |
| | | |
| | | # 首板涨停溢价率 |
| | | def get_limit_up_premium_rate(datas): |
| | | datas = copy.deepcopy(datas) |
| | |
| | | for i in range(0, len(datas)): |
| | | item = datas[i] |
| | | limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(item["pre_close"])) |
| | | if abs(limit_up_price - item["close"]) < 0.001 and abs( |
| | | limit_up_price - datas[i - 1]["close"]) >= 0.001 and 0 < i < len(datas) - 1: |
| | | # 首板涨停 |
| | | rate = (datas[i + 1]["high"] - datas[i + 1]["pre_close"]) / datas[i + 1]["pre_close"] |
| | | first_rate_list.append(rate) |
| | | if abs(limit_up_price - item["close"]) < 0.001: |
| | | if 0 < i < len(datas) - 1 and not __is_limit_up(datas[i - 1]): |
| | | # 首板涨停 |
| | | rate = (datas[i + 1]["high"] - datas[i + 1]["pre_close"]) / datas[i + 1]["pre_close"] |
| | | first_rate_list.append(rate) |
| | | if not first_rate_list: |
| | | return 0 |
| | | return None |
| | | count = 0 |
| | | for rate in first_rate_list: |
| | | if rate >= 0.01: |
| | | count += 1 |
| | | return count / len(first_rate_list) |
| | | |
| | | |
| | | # 首板炸板溢价率 |
| | | def get_open_limit_up_premium_rate(datas): |
| | | datas = copy.deepcopy(datas) |
| | | datas.sort(key=lambda x: x["bob"]) |
| | | first_rate_list = [] |
| | | for i in range(0, len(datas)): |
| | | item = datas[i] |
| | | limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(item["pre_close"])) |
| | | |
| | | if abs(limit_up_price - item["high"]) < 0.001 and abs(limit_up_price - item["close"]) > 0.001: |
| | | # |
| | | limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(datas[i - 1]["pre_close"])) |
| | | if 0 < i < len(datas) - 1 and not __is_limit_up(datas[i - 1]): |
| | | # 前一天未涨停 |
| | | rate = (datas[i + 1]["high"] - item["high"]) / item["high"] |
| | | first_rate_list.append(rate) |
| | | if not first_rate_list: |
| | | return None |
| | | count = 0 |
| | | for rate in first_rate_list: |
| | | if rate >= 0.01: |
| | |
| | | L2_MIN_MONEY = 500000 |
| | | # 每个L2设备的代码数量 |
| | | L2_CODE_COUNT_PER_DEVICE = 6 |
| | | |
| | | # 买入分数分档 |
| | | BUY_SCORE_RANK_0 = 170 |
| | | BUY_SCORE_RANK_1 = 220 |
| | | BUY_SCORE_RANK_2 = 240 |
| | | BUY_SCORE_RANK_3 = 260 |
| | | |
| | |
| | | import l2.l2_data_util |
| | | import log |
| | | from l2 import l2_data_source_util |
| | | from trade import deal_big_money_manager |
| | | |
| | | |
| | | def export_l2_excel(code, date=None): |
| | |
| | | return file_name |
| | | |
| | | |
| | | def test(code): |
| | | progresses = log.export_trade_progress(code) |
| | | local_today_datas = log.load_l2_from_log("2023-04-04") |
| | | datas = local_today_datas[code] |
| | | num_operate_map = {} |
| | | l2.l2_data_util.load_num_operate_map(num_operate_map, code, datas) |
| | | for progress in progresses: |
| | | deal_big_money_manager.set_trade_progress(code, progress, datas, num_operate_map[code]) |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | codes = ["600573"] |
| | | for code in codes: |
| | | export_l2_excel(code) |
| | | export_l2_excel("600072") |
| | |
| | | |
| | | |
| | | if __name__ == '__main__': |
| | | print(get_can_listen_pos()) |
| | | set_price_pre("601858", 27.67) |
| | |
| | | """ |
| | | from tkinter import * |
| | | from tkinter.messagebox import * |
| | | |
| | | import numpy |
| | | import tkintertable |
| | | |
| | | import win32gui |
| | |
| | | for i in range(0, len(content)): |
| | | text.tag_add('error', "{}.{}".format(line, i)) |
| | | |
| | | def sync_target_codes(): |
| | | server.sync_target_codes_to_ths() |
| | | |
| | | def click(): |
| | | text.delete('1.0', END) |
| | | |
| | |
| | | |
| | | btn = Button(frame, text="运行环境检测", command=click) |
| | | btn.place(x=5, y=5) |
| | | |
| | | btn = Button(frame, text="同步THS目标标的", command=sync_target_codes) |
| | | btn.place(x=100, y=5) |
| | | |
| | | frame.grid(row=1, column=2) |
| | | |
| | |
| | | |
| | | def re_distribute_buy_win(): |
| | | try: |
| | | juejin.distribute_buy_win() |
| | | if tool.trade_time_sub(tool.get_now_time_str(), "09:30:00") > 0: |
| | | raise Exception("只能9:30之前重新分配窗口") |
| | | datas = JueJinManager.get_codes_limit_rate(gpcode_manager.get_gp_list()) |
| | | matrix = numpy.array(datas) |
| | | codes = matrix[:, 0].tolist() |
| | | trade_gui.re_distribute_buy_win(codes) |
| | | refresh_trade_buy_win_data() |
| | | showinfo("提示", "分配完成") |
| | | except Exception as e: |
| | |
| | | normal = False |
| | | try: |
| | | trade_gui.THSGuiTrade.checkEnv() |
| | | cl_win.configure(text="正常", foreground="#008000") |
| | | cancel_win_num = trade_gui.THSGuiTrade.getCancelBuyWins() |
| | | cl_win.configure(text=f"正常({len(cancel_win_num)})", foreground="#008000") |
| | | except Exception as e: |
| | | normal = False |
| | | cl_win.configure(text="异常:{}".format(str(e)), foreground="#FF7F27") |
| | |
| | | width = 800 |
| | | height = 360 |
| | | frame = Frame(root, {"height": height, "width": width, "bg": "#DDDDDD"}) |
| | | cl = Label(frame, text="L2采集状态", bg="#DDDDDD") |
| | | trade_info= "" |
| | | for_color = "#008000" |
| | | if constant.TEST: |
| | | trade_info += "测试环境" |
| | | for_color = "#FF7F27" |
| | | else: |
| | | trade_info += "正式环境" |
| | | trade_info += " " |
| | | if constant.TRADE_ENABLE: |
| | | trade_info += "初始允许交易" |
| | | else: |
| | | trade_info += "初始禁止交易" |
| | | for_color = "#FF7F27" |
| | | |
| | | cl = Label(frame, text=f"{trade_info}", bg="#DDDDDD",foreground=f"{for_color}") |
| | | cl.place(x=5, y=5) |
| | | |
| | | accept_l2 = IntVar() |
| | |
| | | import authority |
| | | import decimal |
| | | |
| | | from trade import trade_gui, l2_trade_util |
| | | from trade import trade_gui, l2_trade_util, trade_manager |
| | | from l2.cancel_buy_strategy import L2LimitUpSellStatisticUtil |
| | | from l2_code_operate import L2CodeOperate |
| | | from log import logger_juejin_tick, logger_system |
| | | from trade.trade_data_manager import CodeActualPriceProcessor |
| | | from trade.trade_queue_manager import JueJinBuy1VolumnManager |
| | |
| | | global_data_loader.load_volumn() |
| | | |
| | | # 9点25之前删除所有代码 |
| | | if tool.trade_time_sub(tool.get_now_time_str(), "09:25:00") <= 0: |
| | | if tool.trade_time_sub(tool.get_now_time_str(), "09:25:00") <= 0 or True: |
| | | # 删除L2监听代码 |
| | | gpcode_manager.clear_listen_codes() |
| | | # 删除首板代码 |
| | |
| | | l2_trade_util.WhiteListCodeManager.clear() |
| | | # 清空想要买 |
| | | gpcode_manager.WantBuyCodesManager.clear() |
| | | # 清空分数禁止代码 |
| | | trade_manager.ForbiddenBuyCodeByScoreManager.clear() |
| | | |
| | | |
| | | # 每日初始化 |
| | |
| | | # 今日实时涨停 |
| | | global_data_loader.add_limit_up_codes([], True) |
| | | # 主要获取收盘价 |
| | | get_latest_info(None) |
| | | __get_latest_info(None) |
| | | # 获取60天最大量与昨日量 |
| | | global_util.today_volumn.clear() |
| | | global_util.max60_volumn.clear() |
| | |
| | | t1.start() |
| | | |
| | | # 多个时间点获取收盘价 |
| | | gmapi.schedule(schedule_func=get_latest_info, date_rule='1d', time_rule='08:30:00') |
| | | gmapi.schedule(schedule_func=get_latest_info, date_rule='1d', time_rule='08:50:00') |
| | | gmapi.schedule(schedule_func=get_latest_info, date_rule='1d', time_rule='09:28:00') |
| | | gmapi.schedule(schedule_func=get_current_info, date_rule='1d', time_rule='09:25:00') |
| | | gmapi.schedule(schedule_func=get_current_info, date_rule='1d', time_rule='09:29:00') |
| | | gmapi.schedule(schedule_func=__get_latest_info, date_rule='1d', time_rule='08:30:00') |
| | | gmapi.schedule(schedule_func=__get_latest_info, date_rule='1d', time_rule='08:50:00') |
| | | gmapi.schedule(schedule_func=__get_latest_info, date_rule='1d', time_rule='09:28:00') |
| | | gmapi.schedule(schedule_func=__get_current_info, date_rule='1d', time_rule='09:25:00') |
| | | gmapi.schedule(schedule_func=__get_current_info, date_rule='1d', time_rule='09:29:00') |
| | | re_subscribe_tick() |
| | | # re_subscribe_bar() |
| | | |
| | |
| | | gpcode_manager.init_listen_code_by_pos(client, i) |
| | | |
| | | |
| | | def get_latest_info(context): |
| | | def __get_latest_info(context): |
| | | # 初始化内容 |
| | | clients = authority.get_l2_clients() |
| | | for c in clients: |
| | |
| | | |
| | | |
| | | # 获取最新的信息 |
| | | def get_current_info(): |
| | | def __get_current_info(): |
| | | data = gpcode_manager.get_gp_list() |
| | | results = JueJinManager.get_gp_current_info(data) |
| | | logger_juejin_tick.debug("定时获取:{}", results) |
| | |
| | | symbol = result['symbol'] |
| | | # 保存最新价 |
| | | symbol = symbol.split(".")[1] |
| | | accpt_price(symbol, price) |
| | | |
| | | |
| | | # 设置收盘价 |
| | |
| | | # L2LimitUpMoneyStatisticUtil.verify_num(data_[0], data_[2], data_[1]) |
| | | |
| | | # print(tick["created_at"],tick["quotes"][0]["bid_v"]) |
| | | |
| | | accpt_price(symbol, price) |
| | | __prices_now[symbol] = price |
| | | |
| | | |
| | | # 获取到现价 |
| | | def accpt_price(code, price, price_from="juejin"): |
| | | return |
| | | gpcode_manager.set_price(code, price) |
| | | # 获取收盘价 |
| | | pricePre = gpcode_manager.get_price_pre(code) |
| | | if pricePre is not None: |
| | | rate = round((price - pricePre) * 100 / pricePre, 1) |
| | | if rate >= 7: |
| | | logger_juejin_tick.info("{}-{}-{}", code, price, rate) |
| | | if not gpcode_manager.is_listen_old(code) and not gpcode_manager.is_operate( |
| | | code) and not gpcode_manager.is_listen_full(): |
| | | L2CodeOperate.get_instance().add_operate(1, code, "现价变化,rate-{} from-{}".format(rate, price_from)) |
| | | # 进入监控 |
| | | elif rate < 5: |
| | | # 移除监控 |
| | | if gpcode_manager.is_listen_old(code) and not gpcode_manager.is_operate(code): |
| | | L2CodeOperate.get_instance().add_operate(0, code, "现价变化,rate-{} from-{}".format(rate, price_from)) |
| | | |
| | | |
| | | # 获取到现价 |
| | | def accept_prices(prices): |
| | | # 获取首板代码 |
| | | first_codes = gpcode_manager.get_first_gp_codes() |
| | | |
| | | print("价格代码数量:", len(prices)) |
| | | |
| | | __actualPriceProcessor.save_current_price_codes_count(len(prices)) |
| | | # 采集的代码数量不对 |
| | | if len(gpcode_manager.get_gp_list()) - len(prices) > 10: |
| | | return |
| | | now_str = tool.get_now_time_str() |
| | | now_strs = now_str.split(":") |
| | | now_second = int(now_strs[0]) * 60 * 60 + int(now_strs[1]) * 60 + int(now_strs[2]) |
| | | start = 60 * 60 * 9 + 31 * 60 |
| | | if False: |
| | | for d in prices: |
| | | code, price = d["code"], float(d["price"]) |
| | | accpt_price(code, price, "ths") |
| | | else: |
| | | _code_list = [] |
| | | _delete_list = [] |
| | | for d in prices: |
| | | code, price = d["code"], float(d["price"]) |
| | | gpcode_manager.set_price(code, price) |
| | | # 获取收盘价 |
| | | pricePre = gpcode_manager.get_price_pre(code) |
| | | if pricePre is not None: |
| | | rate = round((price - pricePre) * 100 / pricePre, 2) |
| | | if first_codes and code in first_codes: |
| | | rate = rate / 2 |
| | | if rate >= 0: |
| | | # 暂存涨幅为正的代码 |
| | | _code_list.append((rate, code)) |
| | | else: |
| | | # 暂存涨幅为负的代码 |
| | | _delete_list.append((rate, code)) |
| | | try: |
| | | __actualPriceProcessor.process_rate(code, rate, now_str) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | |
| | | try: |
| | | __actualPriceProcessor.save_current_price(code, price, |
| | | gpcode_manager.get_limit_up_price_by_preprice( |
| | | pricePre) == tool.to_price( |
| | | decimal.Decimal(d["price"]))) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | |
| | | # -------------------------------处理交易位置分配--------------------------------- |
| | | # 排序 |
| | | new_code_list = sorted(_code_list, key=lambda e: (e.__getitem__(0), e.__getitem__(1)), reverse=True) |
| | | # 预填充下单代码 |
| | | _buy_win_codes = [] |
| | | for d in new_code_list: |
| | | _buy_win_codes.append(d[1]) |
| | | for d in _delete_list: |
| | | _buy_win_codes.append(d[1]) |
| | | try: |
| | | trade_gui.THSBuyWinManagerNew.fill_codes(_buy_win_codes) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | pass |
| | | |
| | | # -------------------------------处理L2监听--------------------------------- |
| | | |
| | | client_ids = client_manager.getValidL2Clients() |
| | | # 最多填充的代码数量 |
| | | max_count = len(client_ids) * constant.L2_CODE_COUNT_PER_DEVICE |
| | | if max_count == 0: |
| | | max_count = constant.L2_CODE_COUNT_PER_DEVICE |
| | | |
| | | _delete_list = [] |
| | | for item in new_code_list: |
| | | if l2_trade_util.is_in_forbidden_trade_codes(item[1]) or item[0] < 0: |
| | | _delete_list.append(item) |
| | | |
| | | for item in _delete_list: |
| | | new_code_list.remove(item) |
| | | # 截取前几个代码填充 |
| | | add_list = new_code_list[:max_count] |
| | | # 后面的代码全部删除 |
| | | _delete_list.extend(new_code_list[max_count:]) |
| | | |
| | | add_code_list = [] |
| | | del_code_list = [] |
| | | for d in add_list: |
| | | add_code_list.append(d[1]) |
| | | |
| | | for d in _delete_list: |
| | | del_code_list.append(d[1]) |
| | | |
| | | # 后面的代码数量 |
| | | # 先删除应该删除的代码 |
| | | for code in del_code_list: |
| | | if gpcode_manager.is_listen_old(code): |
| | | # 判断是否在监听里面 |
| | | L2CodeOperate.get_instance().add_operate(0, code, "现价变化") |
| | | # 增加应该增加的代码 |
| | | for code in add_code_list: |
| | | if not gpcode_manager.is_listen_old(code): |
| | | L2CodeOperate.get_instance().add_operate(1, code, "现价变化") |
| | | |
| | | # 获取卡位数量 |
| | | free_count = gpcode_manager.get_free_listen_pos_count() |
| | | if free_count < 2: |
| | | # 空闲位置不足 |
| | | listen_codes = gpcode_manager.get_listen_codes() |
| | | for code in listen_codes: |
| | | if not gpcode_manager.is_in_gp_pool(code): |
| | | client_id, pos = gpcode_manager.get_listen_code_pos(code) |
| | | gpcode_manager.set_listen_code_by_pos(client_id, pos, "") |
| | | free_count += 1 |
| | | if free_count > 2: |
| | | break |
| | | |
| | | print(add_code_list, del_code_list) |
| | | |
| | | |
| | | def on_bar(context, bars): |
| | | print("on_bar", bars) |
| | |
| | | elif action == 'accpt_price': |
| | | try: |
| | | datas = jsonValue["data"] |
| | | for data in datas: |
| | | accpt_price(data["code"], float(data["price"])) |
| | | # for data in datas: |
| | | # accpt_price(data["code"], float(data["price"])) |
| | | except Exception as e: |
| | | print(str(e)) |
| | | |
| | |
| | | return gmapi.get_trading_dates("SHSE", start_date, end_date) |
| | | |
| | | |
| | | def trade(code, volume): |
| | | account_id, s_id, token = getAccountInfo() |
| | | gmapi.set_token(token) |
| | | gmapi.set_account_id(account_id) |
| | | result = gmapi.order_volume(symbol=code, volume=volume, side=gmapi.OrderSide_Sell, |
| | | order_type=gmapi.OrderType_Market, position_effect=gmapi.PositionEffect_Close) |
| | | print(result) |
| | | |
| | | |
| | | # 获取近90天的最大量与最近的量 |
| | | def get_volumns(codes): |
| | | end = datetime.datetime.now() |
| | |
| | | return max_volume, max_volume, max_volume_date.strftime("%Y-%m-%d") |
| | | |
| | | |
| | | # 是否有涨停 |
| | | def is_have_limit_up(datas): |
| | | for i in range(len(datas)): |
| | | item = datas[i] |
| | | limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(item["pre_close"])) |
| | | if abs(limit_up_price - item["close"]) < 0.01: |
| | | return True |
| | | return False |
| | | |
| | | |
| | | # 首板涨停溢价率 |
| | | def get_limit_up_money_percent(datas): |
| | | datas.sort(key=lambda x: x["bob"]) |
| | | first_rate_list = [] |
| | | for i in range(0, len(datas)): |
| | | item = datas[i] |
| | | limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(item["pre_close"])) |
| | | if abs(limit_up_price - item["close"]) < 0.001 and abs( |
| | | limit_up_price - datas[i - 1]["close"]) >= 0.001 and 0 < i < len(datas) - 1: |
| | | # 首板涨停 |
| | | rate = (datas[i + 1]["high"] - datas[i + 1]["pre_close"]) / datas[i + 1]["pre_close"] |
| | | first_rate_list.append(rate) |
| | | if not first_rate_list: |
| | | return 1 |
| | | count = 0 |
| | | for rate in first_rate_list: |
| | | if rate >= 0.01: |
| | | count += 1 |
| | | return count / len(first_rate_list) |
| | | |
| | | |
| | | # 根据涨幅高低分配交易窗口 |
| | | def distribute_buy_win(): |
| | | if tool.trade_time_sub(tool.get_now_time_str(), "09:30:00") > 0: |
| | | raise Exception("只能9:30之前重新分配窗口") |
| | | |
| | | datas = JueJinManager.get_codes_limit_rate(gpcode_manager.get_gp_list()) |
| | | matrix = numpy.array(datas) |
| | | codes = matrix[:, 0].tolist() |
| | | trade_gui.THSBuyWinManagerNew.fill_codes(codes) |
| | | |
| | | |
| | | if __name__ == '__main__': |
| | | print(JueJinManager.get_trading_dates("2023-03-01", "2023-03-29")) |
| | | init_data() |
| | |
| | | # 计算净大单 |
| | | @classmethod |
| | | def __compute_left_big_num(cls, code, buy_single_index, start_index, end_index, total_data, volume_rate_index): |
| | | # 获取大单的最小手数 |
| | | left_big_num = 0 |
| | | # 点火大单数量 |
| | | fire_count = cls.__sCancelParamsManager.get_max_exclude_count(volume_rate_index) |
| | | return cls.compute_left_big_num(code, buy_single_index, start_index, end_index, total_data, fire_count, constant.S_CANCEL_MIN_MONEY) |
| | | |
| | | # 计算未撤的总手数 |
| | | @classmethod |
| | | def compute_left_big_num(cls, code, buy_single_index, start_index, end_index, total_data, fire_count, min_money_w): |
| | | # 获取大单的最小手数 |
| | | left_big_num = 0 |
| | | for i in range(start_index, end_index + 1): |
| | | data = total_data[i] |
| | | val = data["val"] |
| | | # 去除非大单 |
| | | if val["num"] * float(val["price"]) <= constant.S_CANCEL_MIN_MONEY * 100: |
| | | if val["num"] * float(val["price"]) <= min_money_w * 100: |
| | | continue |
| | | |
| | | if L2DataUtil.is_limit_up_price_buy(val): |
| | |
| | | buy_volume_rate_index, |
| | | volume_rate_index, |
| | | need_cancel=True): |
| | | if start_index >= 217: |
| | | print("进入调试") |
| | | # 只守护30s |
| | | buy_exec_time = total_data[buy_exec_index]["val"]["time"] |
| | | if tool.trade_time_sub(total_data[start_index]["val"]["time"], |
| | |
| | | if int(total_data[buy_single_index]["val"]["time"].replace(":", "")) <= int( |
| | | buy_time.replace(":", "")): |
| | | # 买入时间在囊括范围内 |
| | | if tool.trade_time_sub(tool.trade_time_add_second(buy_exec_time, range_seconds),buy_time) >= 0: |
| | | if tool.trade_time_sub(tool.trade_time_add_second(buy_exec_time, range_seconds), |
| | | buy_time) >= 0: |
| | | cancel_num += data["re"] * int(val["num"]) |
| | | |
| | | # 保存数据 |
| | | |
| | | if need_cancel: |
| | | |
| | | if cancel_num / max(buy_num, 1) > cancel_rate_threshold: |
| | | rate__ = round(cancel_num / max(buy_num, 1), 2) |
| | | if rate__ > cancel_rate_threshold: |
| | | l2_log.trade_record(code, "S撤范围", "'start_index':{} , 'end_index':{} ,'range_seconds':{}", |
| | | buy_single_index, |
| | | i, |
| | | range_seconds) |
| | | l2_log.trade_record(code, "S撤", "'index':{} , 'rate':{} , 'target_rate':{}", i, rate__, |
| | | cancel_rate_threshold) |
| | | return True, total_data[i] |
| | | finally: |
| | | |
| | |
| | | local_today_num_operate_map) |
| | | if buy_index is not None and buy_index in watch_indexs_dict: |
| | | cancel_num += data["re"] * val["num"] |
| | | if cancel_num / total_nums > cancel_rate_threshold: |
| | | rate__ = round(cancel_num / total_nums, 2) |
| | | if rate__ > cancel_rate_threshold: |
| | | indexs__ = list(watch_indexs_dict.keys()) |
| | | indexs__.sort() |
| | | l2_log.trade_record(code, "H撤范围", "'start_index':{},'end_index':{}, 'count':{}", |
| | | indexs__[0], indexs__[-1], |
| | | len(watch_indexs_dict.keys())) |
| | | l2_log.trade_record(code, "H撤", "'index':{} , 'rate':{} ,'target_rate':{}", i, rate__, |
| | | cancel_rate_threshold) |
| | | return True, data |
| | | finally: |
| | | l2_log.cancel_debug(code, "H级撤单计算结果 范围:{}-{} 处理进度:{} 取消计算结果:{}/{} 目标撤单比例:{}", start_index, end_index, |
| | |
| | | |
| | | final_watch_list = list(watch_set) |
| | | final_watch_list.sort(key=lambda x: x[0]) |
| | | logger_l2_h_cancel.info(f"code-{code} H撤监控执行位相邻单:{final_watch_list}") |
| | | logger_l2_h_cancel.info(f"code-{code} H撤监控执行位相邻单:{final_watch_list} 目标计算数量:{MIN_H_COUNT}") |
| | | # 保存计算范围 |
| | | cls.__save_watch_index_set_after_exec(code, final_watch_list, process_index, total_count, big_num_count, |
| | | finished) |
| | |
| | | |
| | | import tool |
| | | from db import redis_manager |
| | | from log import logger_trade_queue_price_info |
| | | |
| | | |
| | | class Buy1PriceManager: |
| | | __redisManager = redis_manager.RedisManager(1) |
| | | __latest_data = {} |
| | | |
| | | @classmethod |
| | | def __get_redis(cls): |
| | |
| | | |
| | | # 处理 |
| | | @classmethod |
| | | def process(cls, code, buy_1_price, time_str, limit_up_price): |
| | | def process(cls, code, buy_1_price, time_str, limit_up_price, sell_1_price, sell_1_volumn): |
| | | data_str = f"{buy_1_price},{time_str},{limit_up_price},{sell_1_price},{sell_1_volumn}" |
| | | if cls.__latest_data.get(code) == data_str: |
| | | return |
| | | cls.__latest_data[code] = data_str |
| | | # 记录日志 |
| | | logger_trade_queue_price_info.info( |
| | | f"code={code} data: time_str-{time_str}, buy_1_price-{buy_1_price},limit_up_price-{limit_up_price},sell_1_price-{sell_1_price},sell_1_volumn-{sell_1_volumn}") |
| | | # 买1价格不能小于1块 |
| | | if float(buy_1_price) < 1.0: |
| | | return |
| | | |
| | | is_limit_up = abs(float(limit_up_price) - float(buy_1_price)) < 0.01 |
| | | old_limit_up_time, old_open_limit_up_time = cls.__get_buy1_price_info(code) |
| | | if old_limit_up_time and old_open_limit_up_time: |
| | | return |
| | | if is_limit_up and old_limit_up_time is None: |
| | | if is_limit_up and old_limit_up_time is None and float(sell_1_price) < 0.1 and int(sell_1_volumn) <= 0: |
| | | # 卖1消失,买1为涨停价则表示涨停 |
| | | cls.__save_buy1_price_info(code, time_str, None) |
| | | elif old_limit_up_time and not is_limit_up and old_open_limit_up_time is None: |
| | | # 有涨停时间,当前没有涨停,之前没有打开涨停 |
| | |
| | | # 获取涨停信息 |
| | | # 返回涨停时间与炸板时间 |
| | | @classmethod |
| | | def get_limit_up_info(cls,code): |
| | | def get_limit_up_info(cls, code): |
| | | old_limit_up_time, old_open_limit_up_time = cls.__get_buy1_price_info(code) |
| | | return old_limit_up_time, old_open_limit_up_time |
| | | |
| | | |
| | | # 设置涨停时间 |
| | | @classmethod |
| | | def set_limit_up_time(cls, code, time_str): |
| | | limit_up_time, open_limit_up_time = cls.get_limit_up_info(code) |
| | | if limit_up_time is None: |
| | | cls.__save_buy1_price_info(code, time_str, None) |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | code = "000333" |
| | | limit_up_price = "54.00" |
| | | Buy1PriceManager.process("000333", "53.00", "09:56:00", limit_up_price) |
| | | print(Buy1PriceManager.is_can_buy(code)) |
| | | Buy1PriceManager.process("000333", "54.00", "09:57:00", limit_up_price) |
| | | print(Buy1PriceManager.is_can_buy(code)) |
| | | Buy1PriceManager.process("000333", "53.00", "09:58:00", limit_up_price) |
| | | print(Buy1PriceManager.is_can_buy(code)) |
| | | Buy1PriceManager.process("000333", "54.00", "09:59:00", limit_up_price) |
| | | print(Buy1PriceManager.is_can_buy(code)) |
| | | print(Buy1PriceManager.get_limit_up_info("002777")) |
| | |
| | | import code_data_util |
| | | import code_volumn_manager |
| | | import constant |
| | | import global_data_loader |
| | | import global_util |
| | | import gpcode_manager |
| | | import industry_codes_sort |
| | |
| | | from db import redis_manager |
| | | import ths_industry_util |
| | | import tool |
| | | from third_data import hot_block, hot_block_data_process |
| | | from trade import trade_data_manager, trade_manager, trade_queue_manager, l2_trade_factor, l2_trade_util, \ |
| | | trade_result_manager, first_code_score_manager |
| | | from l2 import safe_count_manager, l2_data_manager, l2_data_log, l2_log, l2_data_source_util, code_price_manager |
| | |
| | | from l2.l2_data_util import local_today_datas, L2DataUtil, load_l2_data, local_today_num_operate_map, local_latest_datas |
| | | import l2.l2_data_util |
| | | from log import logger_l2_trade, logger_l2_trade_cancel, logger_l2_trade_buy, logger_l2_process, logger_l2_error, \ |
| | | logger_buy_score |
| | | logger_place_order_score |
| | | |
| | | # TODO l2数据管理 |
| | | from trade.trade_data_manager import CodeActualPriceProcessor |
| | |
| | | score_dict[code] = score |
| | | return score_dict |
| | | |
| | | |
| | | @classmethod |
| | | # 数据处理入口 |
| | | # datas: 本次截图数据 |
| | |
| | | cls.__l2PlaceOrderParamsManagerDict[code] = l2_trade_factor.L2PlaceOrderParamsManager(code, is_first_code, |
| | | volume_rate, |
| | | volume_rate_index, |
| | | score) |
| | | score, |
| | | total_datas[-1][ |
| | | 'val']['time']) |
| | | cls.volume_rate_info[code] = (volume_rate, volume_rate_index) |
| | | |
| | | latest_time = add_datas[len(add_datas) - 1]["val"]["time"] |
| | |
| | | |
| | | if cancel_data: |
| | | l2_log.debug(code, "触发撤单,撤单位置:{} ,撤单原因:{}", cancel_data["index"], cancel_msg) |
| | | l2_log.trade_record(code, "撤单", "'index':{} , 'msg':'{}'", cancel_data["index"], cancel_msg) |
| | | # 撤单 |
| | | if cls.cancel_buy(code, cancel_msg): |
| | | _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time, |
| | |
| | | if code in cls.unreal_buy_dict: |
| | | cls.unreal_buy_dict.pop(code) |
| | | |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos( |
| | | code) |
| | | if not can: |
| | | l2_log.debug(code, "不可以下单,原因:{}", reason) |
| | | if need_clear_data: |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos( |
| | | code) |
| | | trade_result_manager.real_cancel_success(code, buy_single_index, buy_exec_index, |
| | | local_today_datas.get(code)) |
| | | return |
| | | else: |
| | | l2_log.debug(code, "可以下单,原因:{}", reason) |
| | | logger_buy_score.info(f"{code}:{cls.__l2PlaceOrderParamsManagerDict[code].score_info}") |
| | | |
| | | try: |
| | | l2_log.debug(code, "开始执行买入") |
| | | trade_manager.start_buy(code, capture_timestamp, last_data, |
| | |
| | | ################下单成功处理################ |
| | | trade_result_manager.real_buy_success(code) |
| | | l2_log.debug(code, "执行买入成功") |
| | | params_desc = cls.__l2PlaceOrderParamsManagerDict[code].get_buy_rank_desc() |
| | | l2_log.debug(code, params_desc) |
| | | l2_log.trade_record(code, "下单", |
| | | "'buy_start_index':{} ,'buy_exec_index':{},'volume_reate':{},'score':{},'desc':'{}'", |
| | | buy_single_index, buy_exec_index, cls.volume_rate_info[code][0], |
| | | cls.__l2PlaceOrderParamsManagerDict[code].score, params_desc) |
| | | except Exception as e: |
| | | l2_log.debug(code, "执行买入异常:{}", str(e)) |
| | | pass |
| | |
| | | def __can_buy_first(cls, code): |
| | | if not trade_manager.TradeStateManager.is_can_buy(): |
| | | return False, True, f"今日已禁止交易" |
| | | limit_up_info = code_price_manager.Buy1PriceManager.get_limit_up_info(code) |
| | | if limit_up_info[0] is None and False: |
| | | total_data = local_today_datas.get(code) |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos( |
| | | code) |
| | | # 之前没有涨停过 |
| | | # 统计买入信号位到当前位置没有撤的大单金额 |
| | | min_money_w = l2_data_util.get_big_money_val(float(total_data[buy_single_index]["val"]["price"])) // 10000 |
| | | left_big_num = l2.cancel_buy_strategy.SecondCancelBigNumComputer.compute_left_big_num(code, |
| | | buy_single_index, |
| | | buy_exec_index, |
| | | total_data[-1][ |
| | | "index"], |
| | | total_data, |
| | | 0, min_money_w) |
| | | if left_big_num > 0: |
| | | # 重新获取分数与分数索引 |
| | | limit_up_time = limit_up_time_manager.get_limit_up_time(code) |
| | | if limit_up_time is None: |
| | | limit_up_time = tool.get_now_time_str() |
| | | score = first_code_score_manager.get_score(code, cls.volume_rate_info[code][0], limit_up_time, True, |
| | | left_big_num) |
| | | cls.__l2PlaceOrderParamsManagerDict[code].set_score(score) |
| | | |
| | | logger_place_order_score.info("code={},data='score_index':{},'score_info':{}", code, |
| | | cls.__l2PlaceOrderParamsManagerDict[code].score_index, |
| | | cls.__l2PlaceOrderParamsManagerDict[code].score_info) |
| | | |
| | | if not gpcode_manager.WantBuyCodesManager.is_in(code): |
| | | |
| | | # 查看分数等级 |
| | | score_index = cls.__l2PlaceOrderParamsManagerDict[code].score_index |
| | | score = cls.__l2PlaceOrderParamsManagerDict[code].score |
| | | score_info = cls.__l2PlaceOrderParamsManagerDict[code].score_info |
| | | |
| | | zyltgb = global_util.zyltgb_map.get(code) |
| | | if zyltgb is None: |
| | | global_data_loader.load_zyltgb() |
| | | zyltgb = global_util.zyltgb_map.get(code) |
| | | # 区分大票,小票 |
| | | if zyltgb >= 80 * 100000000: |
| | | if cls.volume_rate_info[code][0] < 0.5: |
| | | return False, True, f"大市值:量大于50%才下单,量比:{cls.volume_rate_info[code][0]}" |
| | | elif zyltgb <= 35 * 100000000: |
| | | # 获取板块中的票的数量 |
| | | if score_info[1][5]["limit_up_codes_count"] < 2: |
| | | return False, True, f"小市值:板块中必须2个涨停才能买,板块{score_info[1][5]['target_block_info'][0]}-涨停数{score_info[1][5]['limit_up_codes_count']}" |
| | | |
| | | # 尾盘偷跑票 |
| | | limit_up_time = score_info[1][7] |
| | | if limit_up_time is None: |
| | | limit_up_time = tool.get_now_time_str() |
| | | if int(limit_up_time.replace(":", "")) > int("143000"): |
| | | if not score_info[1][3][6][0]: |
| | | return False, True, f"尾盘偷跑:无任何形态" |
| | | if score_info[1][5]["limit_up_codes_count"] > 1: |
| | | return False, True, f"尾盘偷跑:板块{score_info[1][5]['target_block_info'][0]}-涨停数{score_info[1][5]['limit_up_codes_count']}" |
| | | if float(gpcode_manager.get_limit_up_price(code)) > 30: |
| | | return False, True, f"尾盘偷跑:股价大于30" |
| | | |
| | | if score_index < 0: |
| | | return False, True, f"分值:{score}未达到需要买入的分数线" |
| | | if score_index >= 3: |
| | | return False, True, f"分值:{score}未达到主动买入分数线" |
| | | return True, False, "" |
| | | # if -1 < score_index < 3 and (0.499 <= cls.volume_rate_info[code][0] <= 0.949): |
| | | # return True, False, f"分值:{score}达到主动买入的分数线且量足够,买入等级:f{score_index},量比:{cls.volume_rate_info[code][0]}" |
| | | is_limited_up = gpcode_manager.FirstCodeManager.is_limited_up(code) |
| | |
| | | count = data["count"] |
| | | data = data["data"] |
| | | # 获取涨停价 |
| | | return day, client, channel, code, capture_time, process_time, data,count |
| | | return day, client, channel, code, capture_time, process_time, data, count |
| | | |
| | | |
| | | # 元数据是否有差异 |
| | |
| | | return new_index_list[start_index], new_index_list[start_index:start_index + len(queues)] |
| | | return None, None |
| | | |
| | | # 3个数据以上的不需要判断最近的一次未涨停时间 |
| | | if len(queueList) >= 3: |
| | | latest_not_limit_up_time = None |
| | | |
| | | # 判断匹配的位置是否可信 |
| | | def is_trust(indexes): |
| | | cha = [] |
| | |
| | | from log import logger_l2_trade_cancel, logger_l2_trade_buy, logger_l2_trade |
| | | from log import logger_l2_trade_cancel, logger_l2_trade_buy, logger_trade_record, logger_l2_trade |
| | | |
| | | threadIds = {} |
| | | |
| | | |
| | | def debug( code, content, *args): |
| | | def debug(code, content, *args): |
| | | logger_l2_trade.debug(("thread-id={} code={} ".format(threadIds.get(code), code) + content).format(*args)) |
| | | |
| | | |
| | |
| | | def cancel_debug(code, content, *args): |
| | | logger_l2_trade_cancel.debug( |
| | | ("thread-id={} code={} ".format(threadIds.get(code), code) + content).format(*args)) |
| | | |
| | | |
| | | # 交易记录 |
| | | def trade_record(code, type, content, *args): |
| | | logger_trade_record.debug( |
| | | ("thread-id={} code={} type={} data=".format(threadIds.get(code), code, type) + content).format(*args)) |
| | |
| | | else: |
| | | return False |
| | | |
| | | |
| | | # 获取大资金的金额 |
| | | def get_big_money_val(limit_up_price): |
| | | if limit_up_price > 3.0: |
| | | return 300 * 10000 |
| | | else: |
| | | max_money = limit_up_price * 10000 |
| | | return max_money * 0.95 |
| | | |
| | | |
| | | # if int(val["num"]) >= constant.BIG_MONEY_NUM: |
| | |
| | | except Exception as e: |
| | | pass |
| | | |
| | | @unittest.skip("跳过此单元测试") |
| | | # @unittest.skip("跳过此单元测试") |
| | | def test_trade(self): |
| | | code = "002524" |
| | | code = "603843" |
| | | clear_trade_data(code) |
| | | l2.l2_data_util.load_l2_data(code) |
| | | total_datas = deepcopy(l2.l2_data_util.local_today_datas[code]) |
| | |
| | | l2.l2_data_util.local_today_num_operate_map[code].clear() |
| | | |
| | | print("id:", id(l2.l2_data_util.local_today_datas)) |
| | | safe_count_manager.BuyL2SafeCountManager.get_safe_count = mock.Mock(return_value=16) |
| | | l2_trade_factor.L2TradeFactorUtil.compute_m_value = mock.Mock(return_value=(14699952, "")) |
| | | # safe_count_manager.BuyL2SafeCountManager.get_safe_count = mock.Mock(return_value=16) |
| | | # l2_trade_factor.L2TradeFactorUtil.compute_m_value = mock.Mock(return_value=(14699952, "")) |
| | | # pos_list.insert(41,(225,306)) |
| | | # pos_list.insert(63, (345, 423)) |
| | | # pos_list.insert(66, (440, 447)) |
| | |
| | | filter=lambda record: record["extra"].get("name") == "buy_1_volumn_record", |
| | | rotation="00:00", compression="zip", enqueue=True) |
| | | |
| | | logger.add(self.get_path("ths", "trade_queue_price_info"), |
| | | filter=lambda record: record["extra"].get("name") == "trade_queue_price_info", |
| | | rotation="00:00", compression="zip", enqueue=True) |
| | | |
| | | logger.add(self.get_path("ths", "day_volumn"), |
| | | filter=lambda record: record["extra"].get("name") == "day_volumn", |
| | | rotation="00:00", compression="zip", enqueue=True) |
| | |
| | | filter=lambda record: record["extra"].get("name") == "debug", |
| | | rotation="00:00", compression="zip", enqueue=True) |
| | | |
| | | logger.add(self.get_path("score", "buy_score"), |
| | | filter=lambda record: record["extra"].get("name") == "buy_score", |
| | | logger.add(self.get_path("trade", "trade_record"), |
| | | filter=lambda record: record["extra"].get("name") == "trade_record", |
| | | rotation="00:00", compression="zip", enqueue=True) |
| | | |
| | | logger.add(self.get_path("score", "place_order_score"), |
| | | filter=lambda record: record["extra"].get("name") == "place_order_score", |
| | | rotation="00:00", compression="zip", enqueue=True) |
| | | |
| | | def get_path(self, dir_name, log_name): |
| | |
| | | |
| | | logger_buy_1_volumn_record = __mylogger.get_logger("buy_1_volumn_record") |
| | | |
| | | logger_trade_queue_price_info = __mylogger.get_logger("trade_queue_price_info") |
| | | |
| | | logger_day_volumn = __mylogger.get_logger("day_volumn") |
| | | |
| | | logger_buy_win_distibute = __mylogger.get_logger("buy_win_distibute") |
| | |
| | | |
| | | logger_debug = __mylogger.get_logger("debug") |
| | | |
| | | logger_buy_score = __mylogger.get_logger("buy_score") |
| | | logger_trade_record = __mylogger.get_logger("trade_record") |
| | | |
| | | logger_place_order_score = __mylogger.get_logger("place_order_score") |
| | | |
| | | class LogUtil: |
| | | @classmethod |
| | |
| | | |
| | | def export_logs(code): |
| | | code_name = gpcode_manager.get_code_name(code) |
| | | date = "2023-03-20" # datetime.datetime.now().strftime("%Y-%m-%d") |
| | | date = datetime.datetime.now().strftime("%Y-%m-%d") |
| | | target_dir = f"D:/logs/gp/l2/export/{code}_{code_name}_{date}" |
| | | if os.path.exists(target_dir): |
| | | shutil.rmtree(target_dir) |
| | | os.makedirs(target_dir) |
| | | log_names = ["l2_process", "l2_trade", "l2_trade_cancel", "l2_process_time", "l2_trade_buy", "cancel/h_cancel"] |
| | | log_names = ["l2_process", "l2_trade", "l2_trade_cancel", "l2_process_time", "l2_trade_buy", "l2_trade_buy_progress", "cancel/h_cancel"] |
| | | # 导出交易日志 |
| | | for log_name in log_names: |
| | | key = f"code={code}" |
| | | if log_name == "l2_process" or log_name == "l2_process_time" or log_name == "cancel/h_cancel": |
| | | if log_name == "l2_process" or log_name == "l2_process_time" or log_name == "cancel/h_cancel" or log_name == "l2_trade_buy_progress": |
| | | key = code |
| | | target_path = f"{target_dir}/{log_name}.{code}_{code_name}.{date}.log" |
| | | # 创建文件夹 |
| | |
| | | LogUtil.extract_log_from_key(key, f"D:/logs/gp/l2/{log_name}.{date}.log", |
| | | target_path) |
| | | |
| | | def export_trade_progress(code): |
| | | path =f"D:/logs/gp/l2/l2_trade_buy_progress.{tool.get_now_date_str()}.log" |
| | | index_set=set() |
| | | with open(path,mode='r',encoding="utf-8") as f: |
| | | lines = f.readlines() |
| | | for line in lines: |
| | | if line.find(f"code-{code}") > -1 and line.find("确定交易进度成功")>-1: |
| | | index= line.split("index-")[1].split(" ")[0] |
| | | index_set.add(int(index)) |
| | | results = list(index_set) |
| | | results.sort() |
| | | return results |
| | | |
| | | |
| | | |
| | | |
| | | # 加载买入得分记录 |
| | | def load_buy_score_recod(code): |
| | | path = f"D:/logs/gp/score/buy_score.{tool.get_now_date_str()}.log" |
| | | path = f"D:/logs/gp/trade/trade_record.{tool.get_now_date_str()}.log" |
| | | fdatas = [] |
| | | with open(path, 'r', encoding="utf-8") as f: |
| | | lines = f.readlines() |
| | | for line in lines: |
| | | data_index = line.find("{}:".format(code)) |
| | | if data_index > 0: |
| | | data_index = line.find(":", data_index) |
| | | time_str = line[10:19] |
| | | line = line[data_index + 1:] |
| | | fdatas.append((time_str, eval(line))) |
| | | if os.path.exists(path): |
| | | with open(path, 'r', encoding="utf-8") as f: |
| | | lines = f.readlines() |
| | | for line in lines: |
| | | data_index = line.find(f"code={code}") |
| | | if data_index > 0: |
| | | time_str = line[11:19] |
| | | data = line[line.find("data=") + 5:] |
| | | type = line[line.find("type=") + 5:line.find(" ", line.find("type="))] |
| | | fdatas.append((time_str, type, eval("{"+data+"}"))) |
| | | return fdatas |
| | | |
| | | |
| | | if __name__ == '__main__': |
| | | load_buy_score_recod("002213") |
| | | print(logger_place_order_score.info("002681")) |
| | | |
| | | |
| | | |
| | | # logger_l2_h_cancel.info("test") |
| | | # logger_l2_process_time.info("test123") |
| | | # logger_buy_score.info("测试") |
| | |
| | | # 图像识别类 |
| | | class OcrUtil: |
| | | __ocr = CnOcr() |
| | | reader = easyocr.Reader(['ch_sim','en'], gpu=False) |
| | | reader = easyocr.Reader(['ch_sim', 'en'], gpu=False) |
| | | |
| | | @classmethod |
| | | def ocr(cls, mat): |
| | |
| | | # 下单参数信息 |
| | | # 选股宝 |
| | | # 市场热度 |
| | | 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]) |
New file |
| | |
| | | body{ |
| | | font-size: 14px; |
| | | } |
| | | |
| | | h2{ |
| | | font-size:20px; |
| | | } |
| | | |
| | | table tr td{ |
| | | font-size: 13px; |
| | | padding-right: 20px; |
| | | } |
| | |
| | | import gpcode_manager |
| | | import authority |
| | | import juejin |
| | | import limit_up_time_manager |
| | | from l2 import l2_data_manager_new, l2_data_manager, l2_data_log, l2_log, code_price_manager |
| | | import l2_data_util |
| | | from l2.cancel_buy_strategy import HourCancelBigNumComputer, L2LimitUpMoneyStatisticUtil |
| | |
| | | from third_data import hot_block_data_process |
| | | from ths import l2_listen_pos_health_manager |
| | | from trade import trade_gui, trade_data_manager, trade_manager, l2_trade_util, deal_big_money_manager, \ |
| | | first_code_score_manager |
| | | first_code_score_manager, current_price_process_manager |
| | | import l2_code_operate |
| | | from code_data_util import ZYLTGBUtil |
| | | import l2.transaction_progress |
| | |
| | | # 保存未筛选的首板代码 |
| | | new_add_codes = gpcode_first_screen_manager.set_target_no_screen_codes(codes) |
| | | # 保存自由流通股本 |
| | | zyltgb_list = [] |
| | | for data in dataList: |
| | | code = data["code"] |
| | | if code in global_util.zyltgb_map: |
| | | continue |
| | | zyltgb_list.append( |
| | | {"code": code, "zyltgb": data["zyltgb"], "zyltgb_unit": data["zyltgbUnit"]}) |
| | | if zyltgb_list: |
| | | ZYLTGBUtil.save_list(zyltgb_list) |
| | | global_data_loader.load_zyltgb() |
| | | if dataList: |
| | | zyltgb_list = [] |
| | | for data in dataList: |
| | | code = data["code"] |
| | | if code in global_util.zyltgb_map: |
| | | continue |
| | | zyltgb_list.append( |
| | | {"code": code, "zyltgb": data["zyltgb"], "zyltgb_unit": data["zyltgbUnit"]}) |
| | | if zyltgb_list: |
| | | ZYLTGBUtil.save_list(zyltgb_list) |
| | | global_data_loader.load_zyltgb() |
| | | |
| | | bad_codes = set() |
| | | |
| | |
| | | need_get_volumn = True |
| | | if need_get_volumn: |
| | | volumes_data = juejin.get_volumns_by_code(code, 150) |
| | | volumes = juejin.parse_max_volume(volumes_data[:60], code_nature_analyse.is_new_top( |
| | | gpcode_manager.get_limit_up_price(code), volumes_data[:60])) |
| | | volumes = juejin.parse_max_volume(volumes_data[:90], code_nature_analyse.is_new_top( |
| | | gpcode_manager.get_limit_up_price(code), volumes_data[:90])) |
| | | logger_first_code_record.info("{} 获取到首板60天最大量:{}", code, volumes) |
| | | code_volumn_manager.set_histry_volumn(code, volumes[0], volumes[1], volumes[2]) |
| | | # 判断K线形态 |
| | |
| | | if not gpcode_manager.is_in_gp_pool(lc): |
| | | # 移除代码 |
| | | l2_code_operate.L2CodeOperate.get_instance().add_operate(0, lc, "代码被移除") |
| | | |
| | | if new_add_codes: |
| | | # 低分值代码禁止交易 |
| | | for code in new_add_codes: |
| | | try: |
| | | score, score_list = first_code_score_manager.get_score(code, 0, None, False) |
| | | if score < 0: |
| | | trade_manager.ForbiddenBuyCodeByScoreManager.add_code(code) |
| | | # elif score >= 200: |
| | | # # 如果没有涨停过 |
| | | # limit_up_time = limit_up_time_manager.get_limit_up_time(code) |
| | | # if limit_up_time is None and int(tool.get_now_time_str().replace(":","")) > int("113000"): |
| | | # gpcode_manager.WantBuyCodesManager.add_code(code) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | |
| | | # if dataList and int(tool.get_now_time_str().replace(":","")) > int("113000"): |
| | | # for data in dataList: |
| | | # code = data["code"] |
| | | # if gpcode_manager.WantBuyCodesManager.is_in(code): |
| | | # score, score_list = first_code_score_manager.get_score(code, 0, None, False) |
| | | # if score < 200: |
| | | # gpcode_manager.WantBuyCodesManager.remove_code(code) |
| | | |
| | | # 保存现价 |
| | | if dataList: |
| | |
| | | buy_time = data["buyTime"] |
| | | buy_one_price = data["buyOnePrice"] |
| | | buy_one_volumn = data["buyOneVolumn"] |
| | | sell_one_price = data["sellOnePrice"] |
| | | sell_one_volumn = data["sellOneVolumn"] |
| | | |
| | | buy_queue = data["buyQueue"] |
| | | if buy_one_price is None: |
| | | print('买1价没有,', code) |
| | | limit_up_price = gpcode_manager.get_limit_up_price(code) |
| | | |
| | | if limit_up_price is not None: |
| | | code_price_manager.Buy1PriceManager.process(code, buy_one_price, buy_time, limit_up_price) |
| | | code_price_manager.Buy1PriceManager.process(code, buy_one_price, buy_time, limit_up_price, |
| | | sell_one_price, sell_one_volumn) |
| | | _start_time = time.time() |
| | | msg += "买1价格处理:" + f"{_start_time - __start_time} " |
| | | |
| | |
| | | volumn = item["volume"] |
| | | volumnUnit = item["volumeUnit"] |
| | | code_volumn_manager.save_today_volumn(item["code"], volumn, volumnUnit) |
| | | juejin.accept_prices(datas) |
| | | current_price_process_manager.accept_prices(datas) |
| | | elif type == 50: |
| | | data = data_process.parse(_str)["data"] |
| | | if data is not None: |
| | |
| | | # 加入白名单 |
| | | data = json.loads(_str) |
| | | codes = data["data"]["codes"] |
| | | for code in codes: |
| | | l2_trade_util.WhiteListCodeManager.add_code(code) |
| | | name = gpcode_manager.get_code_name(code) |
| | | if not name: |
| | | results = juejin.JueJinManager.get_gp_codes_names([code]) |
| | | if results: |
| | | gpcode_manager.CodesNameManager.add_first_code_name(code, results[code]) |
| | | return_str = json.dumps({"code": 0}) |
| | | try: |
| | | for code in codes: |
| | | # 自由流通市值>50亿,股价高于30块的不能加白名单 |
| | | limit_up_price = gpcode_manager.get_limit_up_price(code) |
| | | if float(limit_up_price) > 30: |
| | | raise Exception("股价高于30元") |
| | | # zyltgb = global_util.zyltgb_map.get(code) |
| | | # if zyltgb is None: |
| | | # global_data_loader.load_zyltgb() |
| | | # zyltgb = global_util.zyltgb_map.get(code) |
| | | # if zyltgb > 50 * 100000000: |
| | | # raise Exception("自由流通股本大于50亿") |
| | | |
| | | l2_trade_util.WhiteListCodeManager.add_code(code) |
| | | name = gpcode_manager.get_code_name(code) |
| | | if not name: |
| | | results = juejin.JueJinManager.get_gp_codes_names([code]) |
| | | if results: |
| | | gpcode_manager.CodesNameManager.add_first_code_name(code, results[code]) |
| | | return_str = json.dumps({"code": 0}) |
| | | except Exception as e: |
| | | return_str = json.dumps({"code": 1, "msg": str(e)}) |
| | | |
| | | elif type == 203: |
| | | # 移除黑名单 |
| | | data = json.loads(_str) |
| | |
| | | else: |
| | | trade_manager.TradeStateManager.close_buy() |
| | | return_str = json.dumps({"code": 0, "msg": ("开启成功" if is_open else "关闭成功")}) |
| | | elif type == 502: |
| | | can_buy = trade_manager.TradeStateManager.is_can_buy() |
| | | return_str = json.dumps({"code": 0, "data": {"can_buy": can_buy}}) |
| | | |
| | | sk.send(return_str.encode()) |
| | | |
| | |
| | | for code in codes: |
| | | try: |
| | | global_data_loader.load_zyltgb() |
| | | limit_up_price = float(gpcode_manager.get_limit_up_price(code)) |
| | | limit_up_price = float(gpcode_manager.get_limit_up_price(code)) |
| | | volumes_data = juejin.get_volumns_by_code(code, 150) |
| | | volumes_data = volumes_data[1:] |
| | | volumes = juejin.parse_max_volume(volumes_data[:60], |
| | |
| | | client.connect(ip_port) |
| | | data = {"type": 70, "day": day, "data": datas} |
| | | client.send(json.dumps(data).encode("gbk")) |
| | | result = client.recv(1024) |
| | | client.close() |
| | | |
| | | |
| | |
| | | from db import mysql_data |
| | | import limit_up_time_manager |
| | | import gpcode_manager |
| | | from l2 import code_price_manager |
| | | |
| | | __redisManager = redis_manager.RedisManager(0) |
| | | INVALID_BLOCKS = ["其他", "ST股", "ST摘帽", "业绩增长", "业绩预增", "公告", "次新股"] |
| | | |
| | | |
| | | def __get_redis(): |
| | |
| | | |
| | | @classmethod |
| | | def save(cls, day, datas): |
| | | cls.latest_datas = datas |
| | | |
| | | mysqldb = mysql_data.Mysqldb() |
| | | # 统计代码所属板块 |
| | | code_block_dict = {} |
| | |
| | | code_block_dict[code] = set() |
| | | code_block_dict[code].add(data[0]) |
| | | |
| | | # 如果本次和上次相差的代码且之前有过涨停就判断为炸板 |
| | | if cls.latest_datas: |
| | | latest_codes = set() |
| | | for data in cls.latest_datas: |
| | | for code_info in data[2]: |
| | | code = code_info[0][1].split(".")[0] |
| | | latest_codes.add(code) |
| | | now_codes = set(code_block_dict.keys()) |
| | | del_set = latest_codes - now_codes |
| | | for code in del_set: |
| | | # 获取之前是否涨停过 |
| | | results = cls.list_by_code(code, tool.get_now_date()) |
| | | if results: |
| | | first_limit_up_time = results[0][8] |
| | | if len(first_limit_up_time) > 6: |
| | | # 之前涨停过,更新炸板时间 |
| | | for result in results: |
| | | mysqldb.execute( |
| | | f"update xgb_hot_block set _open_limit_up_time='{tool.get_now_time_str()}',_update_time=now() where _id='{result[0]}'") |
| | | cls.latest_datas = datas |
| | | for data in datas: |
| | | for code_info in data[2]: |
| | | code = code_info[0][1].split(".")[0] |
| | |
| | | limit_up_time = code_info[4] |
| | | if len(limit_up_time) <= 6: |
| | | limit_up_time = '' |
| | | # 00/60开头代码 有涨停时间 |
| | | if code.find("00") == 0 or code.find("60") == 0: |
| | | if len(limit_up_time) > 6: |
| | | code_price_manager.Buy1PriceManager.set_limit_up_time(code, limit_up_time) |
| | | |
| | | if not result: |
| | | mysqldb.execute( |
| | | f"insert into xgb_hot_block(_id,_day,_block_name,_code,_limit_up_time,_price,_rate,_update_time,_first_limit_up_time,_code_name) values('{_id}','{day}','{data[0]}','{code}','{code_info[4]}','{code_info[2]}','{code_info[3]}',now(),'{limit_up_time}','{code_info[0][0]}')") |
| | |
| | | mysqldb.execute( |
| | | f"update xgb_hot_block set _limit_up_time='{code_info[4]}',_price='{code_info[2]}',_rate='{code_info[3]}',_update_time=now(),_code_name='{code_info[0][0]}' where _id='{_id}'") |
| | | if (not result[8] or len(result[8]) <= 6) and len(limit_up_time) >= 6: |
| | | # 没有首次涨停时间 |
| | | mysqldb.execute( |
| | | f"update xgb_hot_block set _first_limit_up_time='{limit_up_time}',_update_time=now() where _id='{_id}'") |
| | | |
| | | cls.__last_datas[_id] = code_info |
| | | # 获取原来的代码所属板块,删除之前错误的板块 |
| | | old_datas = XGBHotBlockDataManager.list_by_code(code, day) |
| | |
| | | return mysqldb.select_all(f"select * from xgb_hot_block where _block_name='{block_name}' and _day='{day}'") |
| | | |
| | | @staticmethod |
| | | def list_blocks(days): |
| | | def list_blocks_with_day(days): |
| | | mysqldb = mysql_data.Mysqldb() |
| | | sql = "select distinct(_block_name) from xgb_hot_block where " |
| | | sql = "select _block_name,_day from xgb_hot_block where " |
| | | wheres = [] |
| | | for day in days: |
| | | wheres.append(f"_day = '{day}'") |
| | | sql += " or ".join(wheres) |
| | | sql += " group by _block_name,_day" |
| | | |
| | | results = mysqldb.select_all(sql) |
| | | fresult = set() |
| | | for result in results: |
| | | fresult.add(result[0]) |
| | | return fresult |
| | | return results |
| | | |
| | | @staticmethod |
| | | def get_latest_blocks(code): |
| | | wheres = [] |
| | | for b in INVALID_BLOCKS: |
| | | wheres.append(f"hb.`_block_name` != '{b}'") |
| | | wheres = " and ".join(wheres) |
| | | sql = f"SELECT GROUP_CONCAT(_block_name) FROM (SELECT hb.`_block_name`,hb.`_day` FROM `xgb_hot_block` hb WHERE hb.`_code`='{code}' AND {wheres} ORDER BY hb.`_day` DESC LIMIT 10) a GROUP BY a._day ORDER BY a._day DESC LIMIT 1" |
| | | mysqldb = mysql_data.Mysqldb() |
| | | return mysqldb.select_one(sql) |
| | | |
| | | |
| | | class XGBDataUtil: |
| | |
| | | start_date = start_date.strftime("%Y-%m-%d") |
| | | days = juejin.JueJinManager.get_trading_dates(start_date, end_date) |
| | | days = days[0 - day_count:] |
| | | results = XGBHotBlockDataManager.list_blocks(days) |
| | | results = XGBHotBlockDataManager.list_blocks_with_day(days) |
| | | __blocks_dict[now_day] = results |
| | | return results |
| | | |
| | | |
| | | # 加载之前的板块 |
| | | __before_block_dict = {} |
| | | |
| | | |
| | | def __load_before_block(code): |
| | | if code not in __before_block_dict: |
| | | blocks = XGBHotBlockDataManager.get_latest_blocks(code) |
| | | if blocks: |
| | | blocks = blocks[0].split(',') |
| | | __before_block_dict[code] = blocks |
| | | |
| | | return __before_block_dict.get(code) |
| | | |
| | | |
| | | def __get_code_from_code_info(code_info): |
| | | code = code_info[0][1].split(".")[0] |
| | | return code |
| | | |
| | | |
| | | # 获取代码所在板块信息 |
| | | def get_info(code): |
| | | blocks = get_code_blocks(code) |
| | | # 判断是否有新概念 |
| | | # 新概念 |
| | | new_block = None |
| | | latest_blocks = get_latest_block(15) |
| | | if blocks: |
| | | for block in blocks: |
| | | if block not in latest_blocks: |
| | | new_block = block |
| | | break |
| | | # # 如果板块中的涨停票数》=2才算新题材,暂时取消 |
| | | # count = 0 |
| | | # if XGBHotBlockDataManager.latest_datas: |
| | | # for b in XGBHotBlockDataManager.latest_datas: |
| | | # if b[0] == new_block: |
| | | # for code_data in b[2]: |
| | | # if len(code_data[4]) > 6: |
| | | # count += 0 |
| | | # if count < 1: |
| | | # # 板块中最低有 |
| | | # new_block = None |
| | | # if not new_block: |
| | | # break |
| | | if not blocks: |
| | | blocks = __load_before_block(code) |
| | | latest_blocks_info = get_latest_block(15) |
| | | # 统计板块出现次数 |
| | | |
| | | # 获取目标板块 |
| | | target_block = None |
| | | if blocks: |
| | | for block in blocks: |
| | | if block == '公告' or block == '其他': |
| | | if block in INVALID_BLOCKS: |
| | | continue |
| | | target_block = block |
| | | break |
| | | if not target_block: |
| | | return None |
| | | |
| | | # 统计板块中的平均涨幅 |
| | | total_rates = 0 |
| | | total_count = 0 |
| | | target_block_rate = 0 |
| | | if XGBHotBlockDataManager.latest_datas: |
| | | for b in XGBHotBlockDataManager.latest_datas: |
| | | if b[0] != target_block: |
| | | continue |
| | | if b[1]: |
| | | target_block_rate = float(b[1].strip().replace("%", '')) |
| | | for code_info in b[2]: |
| | | code__ = __get_code_from_code_info(code_info) |
| | | rate = float(code_info[3].strip().replace("%", '')) |
| | | if code__ != code: |
| | | total_rates += rate |
| | | total_count += 1 |
| | | |
| | | # 统计板块出现的次数 |
| | | target_block_histry_count = 0 |
| | | if blocks: |
| | | for block_info in latest_blocks_info: |
| | | if block_info[0] != target_block: |
| | | continue |
| | | target_block_histry_count += 1 |
| | | |
| | | # 是否出现过高位板 |
| | | high_block_info = None |
| | | high_block_infos = [] |
| | | for block in blocks: |
| | | if block == '公告' or block == '其他': |
| | | continue |
| | |
| | | has_high, high_code_info = XGBDataUtil.is_has_high_code(block, XGBHotBlockDataManager.latest_datas) |
| | | if has_high: |
| | | high_block_info = (high_code_info[0], high_code_info[1]) |
| | | high_block_infos.append(high_block_info) |
| | | |
| | | limit_up_codes_set = set() |
| | | limit_up_codes_info_set = set() |
| | | # 板块下的代码数量 |
| | | block_codes_set = set() |
| | | if XGBHotBlockDataManager.latest_datas: |
| | | for block in XGBHotBlockDataManager.latest_datas: |
| | | if block[0] == target_block: |
| | | for code_data in block[2]: |
| | | code_ = code_data[0][1].split('.')[0] |
| | | if len(code_data[4]) > 6: |
| | | limit_up_codes_set.add(code_data[0][1].split('.')[0]) |
| | | limit_up_codes_info_set.add((code_, code_data[4])) |
| | | block_codes_set.add(code_) |
| | | # 获取涨停的顺序 |
| | | limit_up_index = -1 |
| | | limit_up_codes_info_list = list(limit_up_codes_info_set) |
| | | limit_up_codes_info_list.sort(key=lambda x: x[1]) |
| | | for i in range(0, len(limit_up_codes_info_list)): |
| | | if limit_up_codes_info_list[i][0] == code: |
| | | limit_up_index = i |
| | | if limit_up_index < 0: |
| | | limit_up_index = len(limit_up_codes_info_list) |
| | | |
| | | # 涨停代码集合 |
| | | limit_up_codes_set = set([k[0] for k in limit_up_codes_info_list]) |
| | | |
| | | limit_up_codes_set.discard(code) |
| | | limit_up_count = len(limit_up_codes_set) |
| | | block_codes_set.discard(code) |
| | | limit_up_codes_count = len(block_codes_set) |
| | | |
| | | total_datas = XGBHotBlockDataManager.total_datas |
| | | break_codes = set() |
| | | re_limit_codes = set() |
| | | for data in total_datas: |
| | | block = data[2] |
| | | if block != target_block: |
| | |
| | | code = data[3] |
| | | limit_up_time = data[4] |
| | | first_limit_up_time = data[8] |
| | | open_limit_up_time = data[10] |
| | | if len(limit_up_time) <= 6 and first_limit_up_time and len(first_limit_up_time) > 6: |
| | | break_codes.add(code) |
| | | if len(limit_up_time) > 6 and open_limit_up_time and len(open_limit_up_time) > 6: |
| | | re_limit_codes.add(code) |
| | | |
| | | # 排除自己 |
| | | break_codes.discard(code) |
| | | # 排除已经涨停的代码 |
| | | break_codes = break_codes.difference(limit_up_codes_set) |
| | | # 炸板个数 |
| | | break_size = len(break_codes) |
| | | return target_block, limit_up_count, break_size, new_block, high_block_info |
| | | |
| | | # 炸板回封数量 |
| | | re_limit_up_size = len(re_limit_codes) |
| | | fresult = { |
| | | # 目标板块信息(板块名称,板块涨幅,历史板块出现次数) |
| | | "target_block_info": (target_block, target_block_rate, target_block_histry_count), |
| | | # 涨停顺序 |
| | | "limit_up_index": limit_up_index, |
| | | # 涨停代码数量 |
| | | "limit_up_codes_count": limit_up_codes_count, |
| | | # 板块代码涨幅信息 |
| | | "block_codes_rates_info": (total_rates, total_count), |
| | | # 炸板代码数量 |
| | | "break_size": break_size, |
| | | # 炸板回封数量 |
| | | "re_limit_up_size": re_limit_up_size, |
| | | # 高位版信息 |
| | | "high_block_infos": high_block_infos, |
| | | } |
| | | |
| | | return fresult |
| | | |
| | | |
| | | # 保存数据 |
| | |
| | | if __name__ == "__main__": |
| | | # XGBHotBlockDataManager.total_datas=XGBHotBlockDataManager.list_all("2023-03-23") |
| | | # get_info('002230') |
| | | print(get_latest_block()) |
| | | print(get_latest_block()) |
| | | print(__load_before_block("603163")) |
| | |
| | | import json |
| | | |
| | | |
| | | def parse_kpl_datas(results): |
| | | start_y = -1 |
| | | end_x = -1 |
| | |
| | | fdatas.append((temp[2][:6], temp[1])) |
| | | temp = [] |
| | | return fdatas |
| | | |
| | | |
| | | # 涨停代码: |
| | | # (代码,名称,首次涨停时间,最近涨停时间,几板,涨停原因,板块,实际流通,主力净额) |
| | | # (0,1,6,25,9,16,11,15,12) |
| | | # 竞价代码: |
| | | # (代码,名称,涨停委买额,板块,竞价成交额,实际流通) |
| | | # (0,1,18,11,22,15) |
| | | # 炸板: |
| | | # (代码,名称,涨幅,板块,实际流通) |
| | | # (0,1,4,11,15) |
| | | # 跌停: |
| | | # (代码,名称,板块,实际流通) |
| | | # (0,1,11,15) |
| | | # 曾跌停: |
| | | # (代码,名称,涨幅,板块,实际流通) |
| | | # (0,1,4,11,15) |
| | | |
| | | TYPE_BIDDING = 8 |
| | | TYPE_LIMIT_UP = 1 |
| | | TYPE_OPEN_LIMIT_UP = 2 |
| | | TYPE_LIMIT_DOWN = 3 |
| | | TYPE_EVER_LIMIT_DOWN = 5 |
| | | |
| | | |
| | | def __parseItemData(data, type): |
| | | if type == TYPE_BIDDING: |
| | | return data[0], data[1], data[18], data[11], data[22], data[15] |
| | | elif type == TYPE_LIMIT_UP: |
| | | return data[0], data[1], data[6], data[25], data[9], data[16], data[11], data[15], data[12] |
| | | elif type == TYPE_OPEN_LIMIT_UP: |
| | | return data[0], data[1], data[4], data[11], data[15] |
| | | elif type == TYPE_LIMIT_DOWN: |
| | | return data[0], data[1], data[11], data[15] |
| | | elif type == TYPE_EVER_LIMIT_DOWN: |
| | | return data[0], data[1], data[4], data[11], data[15] |
| | | |
| | | return None |
| | | |
| | | |
| | | def parseData(data, type): |
| | | data = json.loads(data) |
| | | if data["errcode"] != 0: |
| | | raise Exception(f"解析数据出错,errcode:{data['errcode']}") |
| | | list_ = data["list"] |
| | | fresult_ = [] |
| | | for d in list_: |
| | | pdata = __parseItemData(d, type) |
| | | if pdata: |
| | | fresult_ .append(pdata) |
| | | return fresult_ |
New file |
| | |
| | | static function OnBeforeRequest(oSession: Session) { |
| | | |
| | | |
| | | if(oSession.fullUrl.Contains("https://apphis.longhuvip.com/w1/api/index.php")){ |
| | | var requestBody = oSession.GetRequestBodyAsString(); |
| | | if(requestBody&&requestBody.Contains("&st=30")){ |
| | | oSession.utilReplaceInRequest("&st=30", "&st=100"); |
| | | FiddlerObject.log("页码替换为100"); |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | static function OnBeforeResponse(oSession: Session) { |
| | | if (m_Hide304s && oSession.responseCode == 304) { |
| | | oSession["ui-hide"] = "true"; |
| | | } |
| | | if(oSession.fullUrl.Contains("https://apphis.longhuvip.com/w1/api/index.php")){ |
| | | var requestBody = oSession.GetRequestBodyAsString(); |
| | | var a; |
| | | var pidType; |
| | | var index; |
| | | var day; |
| | | if(requestBody){ |
| | | var ps = requestBody.Split("&"); |
| | | for(var p in ps){ |
| | | if(ps[p].Contains("a=")){ |
| | | a = ps[p].Replace("a=",""); |
| | | } |
| | | else if(ps[p].Contains("PidType=")){ |
| | | pidType = ps[p].Replace("PidType=",""); |
| | | } |
| | | else if(ps[p].Contains("Index=")){ |
| | | index = ps[p].Replace("Index=",""); |
| | | }else if(ps[p].Contains("Day=")){ |
| | | day = ps[p].Replace("Day=",""); |
| | | } |
| | | |
| | | |
| | | } |
| | | } |
| | | FiddlerObject.log("a:"+a+" pidType:"+pidType +" index:"+index); |
| | | if(a){ |
| | | var responseStringOriginal = oSession.GetResponseBodyAsString(); |
| | | var fso; |
| | | var file; |
| | | fso = new ActiveXObject("Scripting.FileSystemObject"); |
| | | //文件保存路径,可自定义 |
| | | //第二个参数含义:1=ForReading(以只读方式打开),2=ForWriting (以写方式打开),8=ForAppending(以添加方式打开,写入的内容将添加到文件末尾) |
| | | if(parseInt(index)==0) |
| | | { |
| | | file = fso.OpenTextFile("D:/kpl/"+day+"_"+a+"_"+pidType+".log",2 ,true, true); |
| | | }else{ |
| | | file = fso.OpenTextFile("D:/kpl/"+day+"_"+a+"_"+pidType+".log",8 ,true, true); |
| | | } |
| | | file.writeLine(responseStringOriginal); |
| | | file.close(); |
| | | } |
| | | } |
| | | } |
New file |
| | |
| | | import json |
| | | import time |
| | | from datetime import datetime |
| | | |
| | | import requests |
| | | import juejin |
| | | from third_data import hot_block |
| | | |
| | | |
| | | def get_data(day): |
| | | url = f"https://flash-api.xuangubao.cn/api/surge_stock/stocks?date={day.replace('-', '')}&normal=true&uplimit=true" |
| | | result = requests.get(url) |
| | | result = result.content.decode('utf-8') |
| | | result = json.loads(result) |
| | | if result['code'] != 20000: |
| | | raise Exception("获取失败") |
| | | items = result["data"]["items"] |
| | | block_codes = {} |
| | | for item in items: |
| | | # 代码名称,几天几板,现价,涨幅,涨停时间,换手,自由市值 |
| | | data = [(item[1], item[0]), item[11], item[2], item[3], item[6], item[10], item[4]] |
| | | # 转换格式 |
| | | data[3] = f"{'+' if data[3] > 0 else '-'}" + f"{round(data[3] * 100,2)}%" |
| | | if data[4] > 0: |
| | | data[4] = datetime.fromtimestamp(data[4]).strftime("%H:%M:%S") |
| | | else: |
| | | data[4] = '--' |
| | | data[5] = f"{round(data[5] * 100, 2)}%" |
| | | data[6] = f"{round(data[6] / 100000000, 2)}亿" |
| | | |
| | | blocks = [] |
| | | for b in item[8]: |
| | | blocks.append(b['name']) |
| | | for b in blocks: |
| | | if b not in block_codes: |
| | | block_codes[b] = [] |
| | | block_codes[b].append(data) |
| | | |
| | | return block_codes |
| | | |
| | | |
| | | if __name__ == '__main__': |
| | | date = '2022-07-22' |
| | | for i in range(100): |
| | | date = juejin.JueJinManager.get_previous_trading_date(date) |
| | | print(date) |
| | | results = get_data(date) |
| | | fresults = [] |
| | | for key in results: |
| | | #print("--------",key) |
| | | #for data in results[key]: |
| | | # print(data) |
| | | fresults.append((key,None,results[key])) |
| | | |
| | | print(fresults) |
| | | hot_block.upload_data(date,fresults) |
| | | time.sleep(5) |
| | |
| | | time_2 = get_time_as_second(time_str_2) |
| | | if time_1 < split_time < time_2: |
| | | time_2 = time_2 - 90 * 60 |
| | | elif time_2 < split_time < time_1: |
| | | time_2 = time_2 + 90 * 60 |
| | | |
| | | return time_1 - time_2 |
| | | |
| | |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | print(trade_time_add_second("11:29:59", 1)) |
| | | print(trade_time_add_second("11:29:59", 5)) |
| | | print(trade_time_add_second("10:29:59", 10)) |
| | | print(trade_time_add_second("13:29:59", 60)) |
| | | print(trade_time_sub("13:18:00", "09:00:00")//60) |
| | | print(trade_time_sub("09:00:00","13:18:00") // 60) |
| | | print(trade_time_sub("09:00:00", "09:30:00") // 60) |
| | | print(trade_time_sub("09:30:00", "09:00:00") // 60) |
| | | # print(trade_time_sub("11:29:59", 5)) |
| | | # print(trade_time_sub("10:29:59", 10)) |
| | | # print(trade_time_add_second("13:29:59", 60)) |
New file |
| | |
| | | """ |
| | | 现价处理器 |
| | | """ |
| | | # 获取到现价 |
| | | import decimal |
| | | import logging |
| | | |
| | | import client_manager |
| | | import constant |
| | | import gpcode_manager |
| | | import tool |
| | | from l2_code_operate import L2CodeOperate |
| | | from trade import trade_manager, trade_gui, l2_trade_util |
| | | from trade.trade_data_manager import CodeActualPriceProcessor |
| | | |
| | | __actualPriceProcessor = CodeActualPriceProcessor() |
| | | |
| | | |
| | | def accept_prices(prices): |
| | | # 获取首板代码 |
| | | first_codes = gpcode_manager.get_first_gp_codes() |
| | | |
| | | print("价格代码数量:", len(prices)) |
| | | |
| | | __actualPriceProcessor.save_current_price_codes_count(len(prices)) |
| | | # 采集的代码数量不对 |
| | | if len(gpcode_manager.get_gp_list()) - len(prices) > 10: |
| | | return |
| | | now_str = tool.get_now_time_str() |
| | | now_strs = now_str.split(":") |
| | | if True: |
| | | _code_list = [] |
| | | _delete_list = [] |
| | | for d in prices: |
| | | code, price = d["code"], float(d["price"]) |
| | | gpcode_manager.set_price(code, price) |
| | | # 获取收盘价 |
| | | pricePre = gpcode_manager.get_price_pre(code) |
| | | if pricePre is not None: |
| | | rate = round((price - pricePre) * 100 / pricePre, 2) |
| | | if first_codes and code in first_codes: |
| | | rate = rate / 2 |
| | | if rate >= 0 and not trade_manager.ForbiddenBuyCodeByScoreManager.is_in(code): |
| | | # 暂存涨幅为正的代码 |
| | | _code_list.append((rate, code)) |
| | | else: |
| | | # 暂存涨幅为负的代码 |
| | | _delete_list.append((rate, code)) |
| | | try: |
| | | __actualPriceProcessor.process_rate(code, rate, now_str) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | |
| | | try: |
| | | __actualPriceProcessor.save_current_price(code, price, |
| | | gpcode_manager.get_limit_up_price_by_preprice( |
| | | pricePre) == tool.to_price( |
| | | decimal.Decimal(d["price"]))) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | |
| | | # -------------------------------处理交易位置分配--------------------------------- |
| | | # 排序 |
| | | new_code_list = sorted(_code_list, key=lambda e: (e.__getitem__(0), e.__getitem__(1)), reverse=True) |
| | | # 预填充下单代码 |
| | | _buy_win_codes = [] |
| | | for d in new_code_list: |
| | | _buy_win_codes.append(d[1]) |
| | | for d in _delete_list: |
| | | _buy_win_codes.append(d[1]) |
| | | try: |
| | | trade_gui.THSBuyWinManagerNew.fill_codes(_buy_win_codes) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | pass |
| | | |
| | | # -------------------------------处理L2监听--------------------------------- |
| | | |
| | | client_ids = client_manager.getValidL2Clients() |
| | | # 最多填充的代码数量 |
| | | max_count = len(client_ids) * constant.L2_CODE_COUNT_PER_DEVICE |
| | | if max_count == 0: |
| | | max_count = constant.L2_CODE_COUNT_PER_DEVICE |
| | | |
| | | _delete_list = [] |
| | | for item in new_code_list: |
| | | if l2_trade_util.is_in_forbidden_trade_codes(item[1]) or item[0] < 0: |
| | | _delete_list.append(item) |
| | | |
| | | for item in _delete_list: |
| | | new_code_list.remove(item) |
| | | # 截取前几个代码填充 |
| | | add_list = new_code_list[:max_count] |
| | | # 后面的代码全部删除 |
| | | _delete_list.extend(new_code_list[max_count:]) |
| | | |
| | | add_code_list = [] |
| | | del_code_list = [] |
| | | for d in add_list: |
| | | add_code_list.append(d[1]) |
| | | |
| | | for d in _delete_list: |
| | | del_code_list.append(d[1]) |
| | | |
| | | # 后面的代码数量 |
| | | # 先删除应该删除的代码 |
| | | for code in del_code_list: |
| | | if gpcode_manager.is_listen_old(code): |
| | | # 判断是否在监听里面 |
| | | L2CodeOperate.get_instance().add_operate(0, code, "现价变化") |
| | | # 增加应该增加的代码 |
| | | for code in add_code_list: |
| | | if not gpcode_manager.is_listen_old(code): |
| | | L2CodeOperate.get_instance().add_operate(1, code, "现价变化") |
| | | |
| | | # 获取卡位数量 |
| | | free_count = gpcode_manager.get_free_listen_pos_count() |
| | | if free_count < 2: |
| | | # 空闲位置不足 |
| | | listen_codes = gpcode_manager.get_listen_codes() |
| | | for code in listen_codes: |
| | | if not gpcode_manager.is_in_gp_pool(code): |
| | | client_id, pos = gpcode_manager.get_listen_code_pos(code) |
| | | gpcode_manager.set_listen_code_by_pos(client_id, pos, "") |
| | | free_count += 1 |
| | | if free_count > 2: |
| | | break |
| | | |
| | | print(add_code_list, del_code_list) |
| | |
| | | __last_progress[code] = progress |
| | | # 计算从开始位置到成交位置 |
| | | c_index, deal_num = __get_deal_compute_progress(code) |
| | | process_index = c_index |
| | | for i in range(c_index + 1, progress): |
| | | data = total_data[i] |
| | | val = data['val'] |
| | | process_index = i |
| | | # 是否有大单 |
| | | if not l2_data_util.is_big_money(val): |
| | | continue |
| | |
| | | # 是否已经取消 |
| | | cancel_data = __get_cancel_data(code, data, local_today_num_operate_map) |
| | | if cancel_data is None: |
| | | deal_num += val["num"] |
| | | deal_num += val["num"] * data["re"] |
| | | __save_traded_index(code, data["index"]) |
| | | __set_deal_compute_progress(code, progress, deal_num) |
| | | |
| | | __set_deal_compute_progress(code, process_index, deal_num) |
| | | |
| | | |
| | | def get_deal_big_money_num(code): |
| | |
| | | # bidding 是否满足竞价 |
| | | # deal_big_money 成交大金额是否满足 |
| | | # code_nature = (是否有涨停,是否有溢价) |
| | | # hot_block(板块中涨停票个数(包含自己),板块炸板票个数, 新板块名称 , 高位板信息) |
| | | # hot_block(板块中涨停票个数(包含自己),板块炸板票个数,板块炸板回封个数, (板块名称,出现次数), 高位板信息) |
| | | # zyltgb自由流通市值是否大于250亿 |
| | | # limit_price 涨停价是否大于100块 |
| | | # limit_up_time 是否10点之前涨停 |
| | |
| | | deal_big_money_rate): |
| | | score_list = [] |
| | | if zyltgb: |
| | | zyltgbs = [0, 10, 31, 51, 101, 150, 250, 1000000] |
| | | zyltgb_score = [15, 25, 15, 5, -5, -55, -1000] |
| | | for i in range(1, len(zyltgbs)): |
| | | if zyltgbs[i - 1] <= zyltgb / 100000000 < zyltgbs[i]: |
| | | score_list.append(zyltgb_score[i - 1]) |
| | | zyltgb_y = round(zyltgb / 100000000, 0) |
| | | if zyltgb_y <= 80: |
| | | score_list.append(max(int(round(0.5 * zyltgb_y - 10, 0)), -10)) |
| | | else: |
| | | score_list.append(max(int(round(30 - 5 * ((zyltgb_y-80)//20), 0)), -10)) |
| | | else: |
| | | score_list.append(0) |
| | | |
| | | if limit_price: |
| | | score_list.append(-1000) |
| | | else: |
| | | score_list.append(0) |
| | | score_list.append(max(int(round(-1 * limit_price + 31, 0)), -69)) |
| | | |
| | | # 开盘前竞价 |
| | | if bidding: |
| | |
| | | if k_form[6]: |
| | | k_score.append(0) |
| | | else: |
| | | k_score.append(0) |
| | | k_score.append(20) |
| | | |
| | | # 是否天量大阳 |
| | | if k_form[7] and not k_form[1]: |
| | |
| | | |
| | | nature_score = [] |
| | | |
| | | # 首板涨停次数,首板溢价率,首板开板溢价率 |
| | | if code_nature is None: |
| | | code_nature = [True, False] |
| | | |
| | | if not code_nature[0]: |
| | | nature_score.append(5) |
| | | code_nature = [0, 0, 0] |
| | | if code_nature[0] <= 0: |
| | | nature_score.append(20) |
| | | else: |
| | | nature_score.append(min(10 + code_nature[0], 20)) |
| | | if code_nature[1]: |
| | | nature_score.append(min(int(round(code_nature[1] * 20 - 10)), 10)) |
| | | else: |
| | | nature_score.append(0) |
| | | if code_nature[1]: |
| | | nature_score.append(20) |
| | | if code_nature[2]: |
| | | nature_score.append(min(int(round(code_nature[2] * 20 - 10)), 10)) |
| | | else: |
| | | nature_score.append(0) |
| | | |
| | | score_list.append(nature_score) |
| | | |
| | | hot_block_score = [] |
| | | # 板块中只有自己涨停,且无炸板 |
| | | if hot_block[1] >= 2 and hot_block[2] == 0: |
| | | hot_block_score.append(30) |
| | | elif hot_block[3] and not k_form[6]: |
| | | # 有新题材,且没有K线形态 |
| | | hot_block_score.append(30) |
| | | elif hot_block[1] == 1 and hot_block[2] == 0: |
| | | hot_block_score.append(20) |
| | | elif hot_block[4] is not None and not k_form[6]: |
| | | # 有高位板且无K线形态 |
| | | hot_block_score.append(20) |
| | | # --------------- 板块------------------ |
| | | # 板块 - 代码平均涨幅 |
| | | __average_rate = round(hot_block["block_codes_rates_info"][0] / hot_block["block_codes_rates_info"][1], 2) |
| | | if hot_block["target_block_info"][0] == "无板块": |
| | | hot_block_score.append(5) |
| | | else: |
| | | hot_block_score.append(0) |
| | | hot_block_score.append(min(int(round(__average_rate * 2 - 10)), 10)) |
| | | # 板块 - 涨停只数 |
| | | if hot_block["limit_up_codes_count"] <= 1: |
| | | hot_block_score.append(1) |
| | | else: |
| | | hot_block_score.append(max(12 - hot_block["limit_up_codes_count"], 2)) |
| | | # 板块 - 板块涨幅 |
| | | hot_block_score.append(min(int(round(hot_block["target_block_info"][1] * 2)), 10)) |
| | | # 板块 - 第几只涨停 |
| | | if hot_block["limit_up_index"] <= 0: |
| | | hot_block_score.append(25) |
| | | else: |
| | | hot_block_score.append(max(60 - hot_block["limit_up_index"] * 5, 10)) |
| | | # 板块 - 高位板 |
| | | high_score = 0 |
| | | for high_info in hot_block["high_block_infos"]: |
| | | c_count = int(high_info[1][-2:-1]) |
| | | high_score += min(2 * c_count - 2, 10) |
| | | hot_block_score.append(high_score) |
| | | # 板块 - 板块历史出现次数 |
| | | if hot_block["target_block_info"][2] <= 1: |
| | | hot_block_score.append(10) |
| | | else: |
| | | hot_block_score.append(max(-3 * hot_block["target_block_info"][2] + 20, -10)) |
| | | |
| | | score_list.append(hot_block_score) |
| | | # --------------- 板块结束----------------- |
| | | |
| | | # 量 |
| | | volume_score = [0, 40, 50, 60, 50, 40, 20, 0, -25] |
| | | volume_rates = [0, 0.349, 0.499, 0.649, 0.799, 0.949, 1.099, 1.249, 1.399] |
| | | volume_add = False |
| | | for i in range(1, len(volume_rates)): |
| | | if volume_rates[i - 1] <= volume_rate < volume_rates[i]: |
| | | score_list.append(volume_score[i - 1]) |
| | | volume_add = True |
| | | break |
| | | if not volume_add: |
| | | score_list.append(volume_score[-1]) |
| | | if volume_rate <= 0.5: |
| | | score_list.append(int(round(100 * volume_rate))) |
| | | elif volume_rate < 0.6: |
| | | score_list.append(50) |
| | | elif volume_rate < 0.7: |
| | | score_list.append(55) |
| | | elif volume_rate <= 1.0: |
| | | score_list.append(60) |
| | | else: |
| | | score_list.append(max(int(round(-100 * volume_rate + 160, 0)), -20)) |
| | | |
| | | # 初始化为当前时间 |
| | | limit_up_time_m = tool.trade_time_sub(tool.get_now_time_str(), "09:00:00") // 60 |
| | | |
| | | if limit_up_time: |
| | | times = ["10:00:00", "11:30:00", "14:00:00", "15:00:00"] |
| | | time_scores = [5, 4, 3, 2] |
| | | for i in range(0, len(times)): |
| | | if int(times[i].replace(":", "")) >= int(limit_up_time.replace(":", "")): |
| | | score_list.append(time_scores[i]) |
| | | break |
| | | limit_up_time_m = tool.trade_time_sub(limit_up_time, "09:00:00") // 60 |
| | | |
| | | if limit_up_time_m < 240: |
| | | # 14:30之前适用 |
| | | score_list.append(min(int(0 - round(limit_up_time_m / 15) + 12), 10)) |
| | | elif limit_up_time_m <= 270: |
| | | # 15:00之前加 |
| | | score_list.append(100) |
| | | else: |
| | | score_list.append(0) |
| | | |
| | | # 大单成交 |
| | | deal_big_money_rates = [0, 0.00001, 0.5, 1, 1.2, 1.5, 10000] |
| | | deal_big_money_scores = [0, -20, -10, 20, 30, 40] |
| | | for i in range(1, len(deal_big_money_rates)): |
| | | if deal_big_money_rate < deal_big_money_rates[i]: |
| | | score_list.append(deal_big_money_scores[i - 1]) |
| | | if deal_big_money_rate < 1: |
| | | score_list.append(0) |
| | | else: |
| | | d_score = int(round(10 * deal_big_money_rate, 0)) |
| | | d_score = min(d_score, 60) |
| | | score_list.append(d_score) |
| | | |
| | | score = 0 |
| | | for s in score_list: |
| | |
| | | return score, score_list |
| | | |
| | | |
| | | def get_score(code, volume_rate, limit_up_time, with_source_data=False): |
| | | def get_score(code, volume_rate, limit_up_time, with_source_data=False, estimate_deal_big_money_num=0): |
| | | source_datas = [] |
| | | |
| | | # 获取自由流通股本 |
| | |
| | | |
| | | hot_block = hot_block_data_process.get_info(code) |
| | | if hot_block is None: |
| | | hot_block = ('无板块', 1, 0, None, None) |
| | | else: |
| | | # 加上自己 |
| | | hot_block = (hot_block[0], hot_block[1] + 1, hot_block[2], hot_block[3], hot_block[4]) |
| | | 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": [], |
| | | } |
| | | # 将代码本身的信息包含进去 |
| | | hot_block["limit_up_codes_count"] = hot_block["limit_up_codes_count"] + 1 |
| | | pre_close_price = gpcode_manager.get_price_pre(code) |
| | | hot_block["block_codes_rates_info"] = ( |
| | | hot_block["block_codes_rates_info"][0] + round((limit_price - pre_close_price) * 100 / pre_close_price, 2), |
| | | hot_block["block_codes_rates_info"][1] + 1) |
| | | |
| | | source_datas.append(hot_block) |
| | | |
| | |
| | | |
| | | # 获取成交大单 |
| | | deal_big_num = deal_big_money_manager.get_deal_big_money_num(code) |
| | | if estimate_deal_big_money_num > 0: |
| | | deal_big_num = estimate_deal_big_money_num |
| | | m = l2_trade_factor.L2TradeFactorUtil.get_base_safe_val(zyltgb) |
| | | source_datas.append((deal_big_num * limit_price * 100, m)) |
| | | deal_big_num_rate = (deal_big_num * limit_price * 100) / m |
| | |
| | | for i in range(0, len(k_form)): |
| | | k_form_1.append(k_form[i][0]) |
| | | |
| | | result = __get_score(zyltgb, limit_price > 100, bidding, k_form_1, code_nature, hot_block, |
| | | result = __get_score(zyltgb, limit_price, bidding, k_form_1, code_nature, hot_block, |
| | | volume_rate, limit_up_time, deal_big_num_rate) |
| | | if with_source_data: |
| | | return result, source_datas |
| | |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | global_data_loader.load_zyltgb() |
| | | score = get_score("603829", 1.2, "15:00:01", True) |
| | | print(score) |
| | | limit_price = 35 |
| | | prices = [0, 5, 10, 20, 30, 40, 50, 10000] |
| | | price_scores = [20, 15, 10, 0, -10, -20, -1000] |
| | | for i in range(1, len(prices)): |
| | | if prices[i] > limit_price: |
| | | print(price_scores[i - 1]) |
| | | break |
| | |
| | | import constant |
| | | import global_data_loader |
| | | import global_util |
| | | import gpcode_manager |
| | | import limit_up_time_manager |
| | | |
| | | |
| | | # 下单参数 |
| | | import tool |
| | | from l2 import code_price_manager |
| | | |
| | | |
| | | class L2PlaceOrderParamsManager: |
| | | |
| | | # 获取买入等级描述 |
| | | def get_buy_rank_desc(self): |
| | | continue_count = self.get_begin_continue_buy_count() |
| | | time_range = self.get_time_range() |
| | | desc = "" |
| | | if self.buy_rank == 0: |
| | | desc = f"买入信号({continue_count})" |
| | | elif self.buy_rank == 1: |
| | | desc = f"买入信号({continue_count})+M值≥1000万" |
| | | elif self.buy_rank == 2: |
| | | desc = f"买入信号({continue_count})+M值≥1000万+至少含1笔大单" |
| | | elif self.buy_rank == 3: |
| | | desc = f"买入信号({continue_count})+M值≥1000万+至少含2笔大单" |
| | | else: |
| | | desc = "常规买入" |
| | | desc += f"+囊括时间{time_range}s" |
| | | return desc |
| | | |
| | | # 获取买入等级 |
| | | # 0:买入信号 |
| | | # 1:买入信号+M1000万 |
| | | # 2:买入信号+M1000万+1笔大单 |
| | | # 3:买入信号+M1000+2笔大单 |
| | | # 100:执行之前固有方案 |
| | | def get_buy_rank(self): |
| | | # 判断有没有炸开 |
| | | if code_price_manager.Buy1PriceManager.is_can_buy(self.code): |
| | | # 回封 |
| | | if self.score_index == 0: |
| | | return 0 |
| | | elif self.score_index == 1: |
| | | return 1 |
| | | elif self.score_index == 2: |
| | | return 2 |
| | | else: |
| | | return 100 |
| | | else: |
| | | # 首封 |
| | | if tool.trade_time_sub(self.now_time, "10:30:00") < 0 or tool.trade_time_sub(self.now_time, "14:00:00") > 0: |
| | | if self.score_index == 0: |
| | | return 1 |
| | | elif self.score_index == 1: |
| | | return 2 |
| | | elif self.score_index == 2: |
| | | return 3 |
| | | else: |
| | | return 100 |
| | | else: |
| | | if self.score_index == 0: |
| | | return 2 |
| | | elif self.score_index == 1: |
| | | return 3 |
| | | elif self.score_index == 2: |
| | | return 100 |
| | | else: |
| | | return 100 |
| | | |
| | | # 得分 |
| | | def __init__(self, code, is_first_code, volume_rate, volume_rate_index, score): |
| | | def __init__(self, code, is_first_code, volume_rate, volume_rate_index, score, now_time=tool.get_now_time_str()): |
| | | self.code = code |
| | | self.is_first_code = is_first_code |
| | | score_ranks = [200, 190, 180, 100] |
| | | score_ranks = [constant.BUY_SCORE_RANK_3, constant.BUY_SCORE_RANK_2, constant.BUY_SCORE_RANK_1, |
| | | constant.BUY_SCORE_RANK_0] |
| | | self.score = score[0][0] |
| | | self.score_info = score |
| | | # 为分数设置等级 |
| | |
| | | score_index = i |
| | | break |
| | | self.score_index = score_index |
| | | # 只要加入想买单的,全部执行主动买入一星方案 |
| | | if gpcode_manager.WantBuyCodesManager.is_in(code) and self.score_index >= 3: |
| | | self.score_index = 2 |
| | | |
| | | self.volume_rate = volume_rate |
| | | self.volume_rate_index = volume_rate_index |
| | | self.now_time = now_time |
| | | self.buy_rank = self.get_buy_rank() |
| | | |
| | | # 设置分数 |
| | | def set_score(self, score): |
| | | score_ranks = [constant.BUY_SCORE_RANK_3, constant.BUY_SCORE_RANK_2, constant.BUY_SCORE_RANK_1, |
| | | constant.BUY_SCORE_RANK_0] |
| | | self.score = score[0][0] |
| | | self.score_info = score |
| | | # 为分数设置等级 |
| | | score_index = -1 |
| | | for i in range(0, len(score_ranks)): |
| | | if self.score >= score_ranks[i]: |
| | | score_index = i |
| | | break |
| | | self.score_index = score_index |
| | | |
| | | # 获取信号连续买笔数 |
| | | |
| | |
| | | # 获取时间计算范围,返回s |
| | | def get_time_range(self): |
| | | ts = [pow(3, 1), pow(3, 1), pow(3, 1), pow(3, 2), pow(3, 2), pow(3, 3), pow(3, 3), pow(3, 3)] |
| | | if -1 < self.score_index < 3: |
| | | return ts[0] |
| | | volume_rate_index = self.volume_rate_index |
| | | if self.volume_rate_index >= len(ts): |
| | | volume_rate_index = -1 |
| | |
| | | # 获取需要的大单个数 |
| | | def get_big_num_count(self): |
| | | if self.is_first_code: |
| | | if self.score_index == 0: |
| | | if self.buy_rank < 2: |
| | | return 0 |
| | | elif self.score_index == 1: |
| | | return 0 |
| | | elif self.score_index == 2: |
| | | elif self.buy_rank == 2: |
| | | return 1 |
| | | elif self.score_index < 0: |
| | | return 65535 |
| | | elif self.buy_rank == 3: |
| | | return 2 |
| | | counts = [3, 1, 1, 1, 0, 0, 0, 0] |
| | | volume_rate_index = self.volume_rate_index |
| | | if self.volume_rate_index >= len(counts): |
| | |
| | | |
| | | def get_safe_count(self): |
| | | if self.is_first_code: |
| | | if 3 > self.score_index > -1: |
| | | if self.buy_rank < 4: |
| | | return 2 |
| | | elif self.score_index < 0: |
| | | return 65535 |
| | | base_count, min_count, max_count = L2TradeFactorUtil.get_safe_buy_count(self.code, True) |
| | | rate = self.get_safe_count_rate() |
| | | count = int(round(base_count * (1 + rate))) |
| | |
| | | # 获取m值影响比例 |
| | | @classmethod |
| | | def get_m_val_rate(cls, volume_rate_index): |
| | | rates = [0.0, 0.0, 0.0, -0.3, -0.4, -0.5, -0.6, -0.7] |
| | | rates = [0.0, -0.1, -0.2, -0.3, -0.4, -0.5, -0.6, -0.7] |
| | | if volume_rate_index >= len(rates): |
| | | volume_rate_index = -1 |
| | | return rates[volume_rate_index] |
| | |
| | | # 获取m值 |
| | | def get_m_val(self): |
| | | if self.is_first_code: |
| | | if self.score_index == 0: |
| | | if self.buy_rank == 0: |
| | | return 0, "" |
| | | elif self.score_index == 1: |
| | | elif self.buy_rank < 4: |
| | | return 1000 * 10000, "" |
| | | elif self.score_index == 2: |
| | | return 1000 * 10000, "" |
| | | elif self.score_index < 0: |
| | | return 65535 * 10000, "" |
| | | # 获取固定m值 |
| | | zyltgb = global_util.zyltgb_map.get(self.code) |
| | | if zyltgb is None: |
| | |
| | | # 获取买时间范围(距离执行位),返回s |
| | | @staticmethod |
| | | def get_buy_time_range(volume_rate_index): |
| | | seconds = [pow(2, 1), pow(2, 2), pow(2, 3), pow(2, 4), pow(2, 4), pow(2, 5), pow(2, 6), pow(2, 6)] |
| | | # rates = [0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6] |
| | | seconds = [pow(2, 1), pow(2, 2), pow(2, 3), pow(2, 4), pow(2, 5), pow(2, 5), pow(2, 4), pow(2, 4)] |
| | | if volume_rate_index >= len(seconds): |
| | | volume_rate_index = -1 |
| | | return seconds[volume_rate_index] |
| | |
| | | MAX_VAL = 13 |
| | | if not gb: |
| | | # 默认8笔 |
| | | return MIN_VAL,MIN_VAL, MAX_VAL |
| | | return MIN_VAL, MIN_VAL, MAX_VAL |
| | | count = gb // 100000000 |
| | | if True: |
| | | if count < 8: |
| | |
| | | |
| | | import array |
| | | import logging |
| | | import re |
| | | import threading |
| | | import time |
| | | import random |
| | | |
| | | import numpy |
| | | import win32gui |
| | | import win32con |
| | | |
| | | import constant |
| | | from ocr import ocr_util |
| | | from trade import l2_trade_util |
| | | from db import redis_manager |
| | | from log import * |
| | | from tool import async_call |
| | | from utils import win32_util |
| | | from utils import win32_util, capture_util |
| | | |
| | | |
| | | class THSGuiTrade(object): |
| | |
| | | # raise Exception(error) |
| | | |
| | | # TODO 暂时不验证涨停价 |
| | | if not constant.TEST: |
| | | if abs(float(limit_up_price_now) - float(limit_up_price)) >= 0.01: |
| | | error = "涨停价验证出错 {}-{}".format(limit_up_price, limit_up_price_now) |
| | | raise Exception(error) |
| | | # if not constant.TEST: |
| | | # if abs(float(limit_up_price_now) - float(limit_up_price)) >= 0.01: |
| | | # error = "涨停价验证出错 {}-{}".format(limit_up_price, limit_up_price_now) |
| | | # raise Exception(error) |
| | | |
| | | # 开始交易,买入按钮ID:0x000003EE |
| | | # buy_hwnd = win32gui.GetDlgItem(win, 0x000003EE) |
| | |
| | | self.buy_cancel_locks[w] = threading.RLock() |
| | | |
| | | |
| | | |
| | | |
| | | class THSGuiUtil: |
| | | @classmethod |
| | | def getText(cls, hwnd): |
| | |
| | | if win in win_set: |
| | | win_set.remove(win) |
| | | if len(win_set) > 0: |
| | | return win_set.pop() |
| | | win_list = list(win_set) |
| | | random.shuffle(win_list) |
| | | return win_list[0] |
| | | |
| | | # 没有剩余的窗口,新增加窗口 |
| | | raise Exception("没有剩余窗口") |
| | |
| | | THSGuiUtil.set_buy_window_code(cls.get_trade_win(win), code) |
| | | time.sleep(0.5) |
| | | code_name_win = cls.__get_code_name(win) |
| | | if code_name == code_name_win: |
| | | is_success = True |
| | | break |
| | | if code_name == code_name_win or code_name_win.find(code_name) > -1: |
| | | if cls.__is_buy_limit_up_price(win): |
| | | is_success = True |
| | | break |
| | | else: |
| | | cls.__del_code_win(code) |
| | | THSGuiUtil.set_buy_window_code(cls.get_trade_win(win), "") |
| | | raise Exception("不是买涨停价") |
| | | if is_success: |
| | | logger_buy_win_distibute.info(f"新分配窗口成功:{code}-{win}") |
| | | else: |
| | |
| | | name = name.replace(" ", "") |
| | | return tool.strQ2B(name) |
| | | |
| | | # 是否是涨停价 |
| | | @classmethod |
| | | def __is_buy_limit_up_price(cls, win): |
| | | trade_win = cls.get_trade_win(win) |
| | | if trade_win is None: |
| | | return None |
| | | price_win = win32gui.GetDlgItem(trade_win, 0x00000409) |
| | | ocr_result = ocr_util.OcrUtil.ocr_with_key(capture_util.window_capture(price_win), "涨停价|张停价") |
| | | if ocr_result: |
| | | return True |
| | | return False |
| | | |
| | | @classmethod |
| | | def fill_codes(cls, codes): |
| | | name_codes = gpcode_manager.get_name_codes() |
| | |
| | | new_delete_codes.append(code) |
| | | |
| | | cancel_wins = THSGuiTrade.getCancelBuyWins() |
| | | add_codes_num = len(cancel_wins)*10 |
| | | add_codes_num = len(cancel_wins) * 10 |
| | | add_codes = new_codes[0:add_codes_num] |
| | | del_codes = new_codes[add_codes_num:] |
| | | del_codes.extend(new_delete_codes) |
| | |
| | | print("分配的窗口:", win, THSGuiUtil.is_win_exist(win)) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | |
| | | |
| | | # 根据涨幅高低分配交易窗口 |
| | | def re_distribute_buy_win(codes): |
| | | THSBuyWinManagerNew.fill_codes(codes) |
| | | |
| | | |
| | | class GUITest: |
| | |
| | | |
| | | |
| | | if __name__ == '__main__': |
| | | pass |
| | | # try: |
| | | # THSGuiTrade().cancel_buy_again("000637") |
| | | # except Exception as e: |
| | | # print(e) |
| | | print(THSGuiTrade().cancel_buy("000582")) |
| | | print(ocr_util.OcrUtil.ocr_with_key(capture_util.window_capture(0x000314EA), "涨停价|张停价")) |
| | | |
| | | # THSGuiTrade().buy("600613", 10.29) |
| | |
| | | |
| | | from db import mysql_data, redis_manager |
| | | from trade import trade_data_manager, l2_trade_util |
| | | from trade.trade_gui import THSBuyWinManagerNew, THSGuiTrade |
| | | import trade.trade_gui |
| | | import time as t |
| | | from l2 import l2_data_manager, l2_data_log |
| | | |
| | |
| | | # 买成功 |
| | | TRADE_STATE_BUY_SUCCESS = 12 |
| | | |
| | | guiTrade = THSGuiTrade() |
| | | guiTrade = trade.trade_gui.THSGuiTrade() |
| | | |
| | | latest_trade_delegate_data = [] |
| | | |
| | |
| | | return True |
| | | else: |
| | | return False |
| | | |
| | | |
| | | # 根据分数禁止买的票管理 |
| | | class ForbiddenBuyCodeByScoreManager: |
| | | __redisManager = redis_manager.RedisManager(2) |
| | | __key = "forbidden_codes_by_score" |
| | | |
| | | @classmethod |
| | | def __get_redis(cls): |
| | | return cls.__redisManager.getRedis() |
| | | |
| | | @classmethod |
| | | def add_code(cls, code): |
| | | cls.__get_redis().sadd(cls.__key,code) |
| | | |
| | | @classmethod |
| | | def remove_code(cls, code): |
| | | cls.__get_redis().srem(cls.__key, code) |
| | | |
| | | @classmethod |
| | | def is_in(cls, code): |
| | | return cls.__get_redis().sismember(cls.__key, code) |
| | | |
| | | @classmethod |
| | | def clear(cls): |
| | | cls.__get_redis().delete(cls.__key) |
| | | |
| | | |
| | | |
| | | # 获取交易状态 |
| | |
| | | l2_data_manager.TradePointManager.delete_buy_cancel_point(code) |
| | | l2_data_manager.TradePointManager.delete_buy_point(code) |
| | | # 移除交易窗口分配 |
| | | THSBuyWinManagerNew.cancel_distribute_win_for_code(code) |
| | | trade.trade_gui.THSBuyWinManagerNew.cancel_distribute_win_for_code(code) |
| | | # 交易成功时间过去3s之后,且当前委托列表里面还有该代码数据就再次执行撤单 |
| | | if tool.trade_time_sub(tool.get_now_time_str(), _time) > 3: |
| | | # 获取到当前是否委托 |
| | |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | cancel_buy_again("000637") |
| | | pass |