| | |
| | | API_TRADE_ENABLE = True |
| | | # 每只票买的金额 |
| | | BUY_MONEY_PER_CODE = 8000 |
| | | # L2数据来源 |
| | | L2_SOURCE_TYPE_THS = "ths" |
| | | L2_SOURCE_TYPE_HUAXIN = "huaxin" |
| | | L2_SOURCE_TYPE = L2_SOURCE_TYPE_THS |
| | | |
| | | # D撤单 |
| | | # 守护时间 |
| | | D_CANCEL_EXPIRE_TIME = 120 |
| | | D_CANCEL_RATE = 0.5 |
| | | |
| | | # L撤 |
| | | L_CANCEL_MAX_WATCH_COUNT = 5 |
| | | # 撤单比例 |
| | | L_CANCEL_RATE = 0.6 |
| | | # 最小金额 |
| | | L_CANCEL_MIN_MONEY = 98 |
| | |
| | | |
| | | from third_data.history_k_data_util import HistoryKDatasUtils |
| | | from trade import trade_gui, l2_trade_util, trade_manager |
| | | from l2.cancel_buy_strategy import L2LimitUpSellStatisticUtil |
| | | from l2.cancel_buy_strategy import L2LimitUpSellStatisticUtil, LCancelBigNumComputer |
| | | from log import logger_juejin_tick, logger_system |
| | | from trade.trade_data_manager import CodeActualPriceProcessor |
| | | from trade.trade_queue_manager import JueJinBuy1VolumnManager |
| | |
| | | # 清空暂停交易代码 |
| | | gpcode_manager.PauseBuyCodesManager.clear() |
| | | |
| | | LCancelBigNumComputer.clear() |
| | | |
| | | |
| | | # 每日初始化 |
| | | def everyday_init(): |
| | |
| | | # 守护30s以外的数据 |
| | | if time_space <= constant.S_CANCEL_EXPIRE_TIME: |
| | | return False, None |
| | | # 获取成交进度 |
| | | # 获取成交进度 |
| | | origin_progress_index, latest_progress_index = cls.__get_traded_progress(code) |
| | | if latest_progress_index is None: |
| | | latest_progress_index = -1 |
| | | # 监听的数据 |
| | | watch_indexs_dict = {} |
| | | total_nums = 0 |
| | |
| | | if datas: |
| | | for indexs in datas: |
| | | index = indexs[0] |
| | | if index < latest_progress_index: |
| | | continue |
| | | watch_indexs_dict[index] = indexs |
| | | total_nums += total_data[index]["val"]["num"] * indexs[2] |
| | | |
| | |
| | | process_index = start_index |
| | | # 是否有观测的数据撤单 |
| | | has_watch_canceled = False |
| | | # 获取之前已经撤单的数据 |
| | | old_canceld_indexs = cls.__get_watch_canceled_index(code) |
| | | # 重新计算撤单 |
| | | cancel_num = 0 |
| | | if old_canceld_indexs: |
| | | for d in old_canceld_indexs: |
| | | nx = int(d.split("-")[0]) |
| | | num = int(d.split("-")[1]) |
| | | if nx < latest_progress_index: |
| | | continue |
| | | cancel_num += total_data[nx]["re"] * num |
| | | |
| | | try: |
| | | for i in range(start_index, end_index + 1): |
| | | if i <= processed_index: |
| | |
| | | now_rate = round(cancel_num / total_nums, 4) |
| | | if now_rate < cancel_rate_threshold and cancel_rate_threshold - now_rate < 0.1: |
| | | # 距离撤单在5%以内 |
| | | kp_client_msg_manager.add_msg(code, f"逼近H撤({now_rate*100}%/{cancel_rate_threshold*100}%),需要人工判别。") |
| | | kp_client_msg_manager.add_msg(code, |
| | | f"逼近H撤({now_rate * 100}%/{cancel_rate_threshold * 100}%),需要人工判别。") |
| | | |
| | | return False, None |
| | | |
| | |
| | | return watch_indexs_dict, cls.__get_watch_canceled_index(code) |
| | | |
| | | |
| | | # ---------------------------------D撤------------------------------- |
| | | # 计算 成交位->真实下单位置 总共还剩下多少手没有撤单 |
| | | # 成交位变化之后重新计算 |
| | | class DCancelBigNumComputer: |
| | | __redis_manager = redis_manager.RedisManager(0) |
| | | |
| | | @classmethod |
| | | def __getRedis(cls): |
| | | return cls.__redis_manager.getRedis() |
| | | |
| | | @classmethod |
| | | def __set_real_order_index(cls, code, index): |
| | | cls.__getRedis().setex(f"d_cancel_real_order_index-{code}", index) |
| | | |
| | | @classmethod |
| | | def __get_real_order_index(cls, code): |
| | | val = cls.__getRedis().get(f"d_cancel_real_order_index-{code}") |
| | | if val: |
| | | return int(val) |
| | | return None |
| | | |
| | | # 设置成交位 |
| | | @classmethod |
| | | def set_trade_progress(cls, code, index, buy_exec_index, total_data, local_today_num_operate_map, m_value, |
| | | limit_up_price): |
| | | # 离下单执行位2分钟内的有效 |
| | | if tool.trade_time_sub(total_data[-1]['val']['time'], total_data[buy_exec_index]['val']['time']) > constant.D_CANCEL_EXPIRE_TIME: |
| | | return False, "超过D撤守护时间" |
| | | |
| | | real_order_index = cls.__get_real_order_index(code) |
| | | if not real_order_index: |
| | | return False, "尚未获取到真实下单位置" |
| | | |
| | | left_num = 0 |
| | | for i in range(index, real_order_index + 1): |
| | | data = total_data[i] |
| | | val = data['val'] |
| | | if not L2DataUtil.is_limit_up_price_buy(val): |
| | | continue |
| | | if val['num'] * val['price'] < 5900: |
| | | continue |
| | | |
| | | left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count(code, i, |
| | | total_data, |
| | | local_today_num_operate_map) |
| | | left_num += val['num'] * left_count |
| | | |
| | | # 剩下的不足动态M值的1/2 |
| | | rate = round(limit_up_price * left_num * 100 / m_value, 3) |
| | | if rate < constant.D_CANCEL_RATE: |
| | | return True, f"D撤比例为:{rate}" |
| | | return False, "" |
| | | |
| | | # 设置真实的下单位置 |
| | | @classmethod |
| | | def set_real_order_index(cls, code, index): |
| | | pass |
| | | |
| | | |
| | | # ---------------------------------L撤------------------------------- |
| | | # 计算成交位置之后的大单(特定笔数)的撤单比例 |
| | | class LCancelBigNumComputer: |
| | | __redis_manager = redis_manager.RedisManager(0) |
| | | __last_trade_progress_dict = {} |
| | | |
| | | @classmethod |
| | | def __getRedis(cls): |
| | | return cls.__redis_manager.getRedis() |
| | | |
| | | @classmethod |
| | | def __add_watch_index(cls, code, index): |
| | | cls.__getRedis().sadd(f"l_cancel_watch_index-{code}", index) |
| | | cls.__getRedis().expire(f"l_cancel_watch_index-{code}", tool.get_expire()) |
| | | |
| | | @classmethod |
| | | def __del_watch_index(cls, code, index): |
| | | cls.__getRedis().srem(f"l_cancel_watch_index-{code}", index) |
| | | |
| | | @classmethod |
| | | def __get_watch_indexes(cls, code): |
| | | return cls.__getRedis().smembers(f"l_cancel_watch_index-{code}") |
| | | |
| | | @classmethod |
| | | def del_watch_index(cls, code): |
| | | cls.__getRedis().delete(f"l_cancel_watch_index-{code}") |
| | | |
| | | @classmethod |
| | | def clear(cls): |
| | | keys = cls.__getRedis().keys(f"l_cancel_watch_index-*") |
| | | for k in keys: |
| | | cls.__getRedis().delete(k) |
| | | |
| | | # 设置成交位置,成交位置变化之后相应的监听数据也会发生变化 |
| | | @classmethod |
| | | def set_trade_progress(cls, code, index, total_data): |
| | | old_watch_indexes = cls.__get_watch_indexes(code) |
| | | if cls.__last_trade_progress_dict.get(code) == index and len( |
| | | old_watch_indexes) >= constant.L_CANCEL_MAX_WATCH_COUNT: |
| | | # 成交进度尚未发生变化且已经监听到了足够的数据 |
| | | return |
| | | |
| | | watch_indexes = set() |
| | | for i in range(index + 1, total_data[-1]["index"] + 1): |
| | | data = total_data[i] |
| | | val = data['val'] |
| | | if not L2DataUtil.is_limit_up_price_buy(val): |
| | | continue |
| | | if val["num"] * float(val["price"]) <= constant.L_CANCEL_MIN_MONEY * 100: |
| | | continue |
| | | cancel_datas = local_today_num_operate_map.get( |
| | | "{}-{}-{}".format(val["num"], "1", val["price"])) |
| | | canceled = False |
| | | if cancel_datas: |
| | | for cancel_data in cancel_datas: |
| | | buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data(code, cancel_data, |
| | | local_today_num_operate_map) |
| | | if buy_index == index: |
| | | canceled = True |
| | | break |
| | | if not canceled: |
| | | watch_indexes.add(index) |
| | | if len(watch_indexes) >= constant.L_CANCEL_MAX_WATCH_COUNT: |
| | | break |
| | | # 数据维护 |
| | | add_indexes = watch_indexes - old_watch_indexes |
| | | delete_indexes = old_watch_indexes - watch_indexes |
| | | for i in add_indexes: |
| | | cls.__add_watch_index(code, i) |
| | | for i in delete_indexes: |
| | | cls.__del_watch_index(code, i) |
| | | |
| | | @classmethod |
| | | def need_cancel(cls, code, buy_exec_index, start_index, end_index, total_data, local_today_num_operate_map, |
| | | is_first_code): |
| | | time_space = tool.trade_time_sub(total_data[start_index]["val"]["time"], |
| | | total_data[buy_exec_index]["val"]["time"]) |
| | | # 守护30s以外的数据 |
| | | if time_space <= constant.S_CANCEL_EXPIRE_TIME: |
| | | return False, None |
| | | watch_indexes = cls.__get_watch_indexes(code) |
| | | if not watch_indexes: |
| | | return False, None |
| | | |
| | | for i in range(start_index, end_index + 1): |
| | | data = total_data[i] |
| | | val = data["val"] |
| | | if L2DataUtil.is_limit_up_price_buy_cancel(val): |
| | | # 查询买入位置 |
| | | buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data(code, data, |
| | | local_today_num_operate_map) |
| | | if buy_index is not None and buy_index in watch_indexes: |
| | | # 计算撤单比例 |
| | | canceled_count = 0 |
| | | total_count = 0 |
| | | for wi in watch_indexes: |
| | | left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count(code, |
| | | wi, |
| | | total_data, |
| | | local_today_num_operate_map) |
| | | canceled_count += (total_data[wi]["re"] - left_count) |
| | | total_count += total_data[wi]["re"] |
| | | if canceled_count / total_count >= constant.L_CANCEL_RATE: |
| | | return True, data |
| | | |
| | | return False, None |
| | | |
| | | |
| | | # --------------------------------封单额变化撤------------------------ |
| | | # 涨停封单额统计 |
| | | class L2LimitUpMoneyStatisticUtil: |
New file |
| | |
| | | """ |
| | | 华鑫LV2处理工具类 |
| | | """ |
| | | |
| | | # 处理逐笔委托 |
| | | # item逐笔委托 |
| | | # (data['SecurityID'], data['Price'], data['Volume'], data['Side'], data['OrderType'], |
| | | # data['OrderTime'],data['MainSeq'], data['SubSeq'], data['OrderNO'], data['OrderStatus']) |
| | | import decimal |
| | | |
| | | import tool |
| | | from l2.l2_data_util import L2DataUtil |
| | | |
| | | |
| | | def __convert_order(item, limit_up_price): |
| | | time_str = f"{item[5]}" |
| | | if time_str.startswith("9"): |
| | | time_str = f"0{time_str}" |
| | | time_ = f"{time_str[0:2]}:{time_str[2:4]}:{time_str[4:6]}" |
| | | price = item["Price"] |
| | | if price <= 0: |
| | | # 深证的买撤无价格数据,需要去查找价格数据,暂时设置为涨停价 |
| | | price = limit_up_price |
| | | |
| | | limitPrice = 1 if abs(limit_up_price - price) < 0.001 else 0 |
| | | operateType = 0 |
| | | if item[''] == 'D': |
| | | if item[3] == '1': |
| | | # 买撤 |
| | | operateType = 1 |
| | | else: |
| | | # 卖撤 |
| | | operateType = 3 |
| | | else: |
| | | if item[3] == '1': |
| | | # 买 |
| | | operateType = 0 |
| | | else: |
| | | # 卖 |
| | | operateType = 2 |
| | | return {"time": time_, "price": price, "num": item[2] // 100, "limitPrice": limitPrice, |
| | | "operateType": operateType, "cancelTime": 0, "cancelTimeUnit": 0, "orderNo": item[8], |
| | | "mainSeq": item[6], "subSeq": item[7]} |
| | | |
| | | |
| | | # 处理l2数据 |
| | | def __format_l2_data(origin_datas, code, limit_up_price): |
| | | datas = [] |
| | | dataIndexs = {} |
| | | same_time_num = {} |
| | | for item in origin_datas: |
| | | # 解析数据 |
| | | time = item["time"] |
| | | if time in same_time_num: |
| | | same_time_num[time] = same_time_num[time] + 1 |
| | | else: |
| | | same_time_num[time] = 1 |
| | | |
| | | price = item["price"] |
| | | num = item["num"] |
| | | limitPrice = item["limitPrice"] |
| | | # 涨停价 |
| | | if limit_up_price is not None: |
| | | if abs(price - limit_up_price) < 0.001: |
| | | limitPrice = 1 |
| | | else: |
| | | limitPrice = 0 |
| | | item["limitPrice"] = "{}".format(limitPrice) |
| | | operateType = item["operateType"] |
| | | # 不需要非涨停买与买撤 |
| | | if int(item["limitPrice"]) != 1 and (int(operateType) == 0 or int(operateType) == 1): |
| | | continue |
| | | key = "{}-{}-{}".format(code, item["mainSeq"], item["subSeq"]) |
| | | if key in dataIndexs: |
| | | # 数据重复次数+1 |
| | | datas[dataIndexs[key]]['re'] = datas[dataIndexs[key]]['re'] + 1 |
| | | else: |
| | | # 数据重复次数默认为1 |
| | | datas.append({"key": key, "val": item, "re": 1}) |
| | | dataIndexs.setdefault(key, len(datas) - 1) |
| | | # TODO 测试的时候开启,方便记录大单数据 |
| | | # l2_data_util.save_big_data(code, same_time_num, data) |
| | | return datas |
| | | |
| | | |
| | | def get_format_l2_datas(code, origin_datas, limit_up_price): |
| | | # 先转变数据格式 |
| | | datas = [__convert_order(x, limit_up_price) for x in origin_datas] |
| | | return __format_l2_data(datas, code, limit_up_price) |
| | |
| | | from db import redis_manager |
| | | import ths_industry_util |
| | | import tool |
| | | from l2.huaxin import l2_huaxin_util |
| | | from third_data.code_plate_key_manager import CodePlateKeyBuyManager |
| | | from trade import trade_manager, trade_queue_manager, l2_trade_factor, l2_trade_util, \ |
| | | trade_result_manager, first_code_score_manager |
| | |
| | | from l2.cancel_buy_strategy import SecondCancelBigNumComputer, HourCancelBigNumComputer, L2LimitUpMoneyStatisticUtil, \ |
| | | L2LimitUpSellStatisticUtil |
| | | from l2.l2_data_manager import L2DataException, TradePointManager |
| | | from l2.l2_data_util import local_today_datas, L2DataUtil, local_today_num_operate_map, local_latest_datas |
| | | from l2.l2_data_util import local_today_datas, L2DataUtil, local_today_num_operate_map,local_today_buyno_map, local_latest_datas |
| | | import l2.l2_data_util |
| | | from log import logger_l2_trade_buy, logger_l2_process, \ |
| | | logger_place_order_score |
| | |
| | | # 数据不正常需要禁止交易 |
| | | l2_trade_util.forbidden_trade(code) |
| | | # 纠正数据 |
| | | datas = l2.l2_data_util.L2DataUtil.correct_data(code, local_latest_datas.get(code), datas) |
| | | if constant.L2_SOURCE_TYPE == constant.L2_SOURCE_TYPE_THS: |
| | | # 同花顺需要纠正数据,其他渠道不需要 |
| | | datas = l2.l2_data_util.L2DataUtil.correct_data(code, local_latest_datas.get(code), datas) |
| | | _start_index = 0 |
| | | if local_today_datas.get(code) is not None and len( |
| | | local_today_datas[code]) > 0: |
| | |
| | | # 拼接数据 |
| | | local_today_datas[code].extend(add_datas) |
| | | l2.l2_data_util.load_num_operate_map(local_today_num_operate_map, code, add_datas) |
| | | l2.l2_data_util.load_buy_no_map(local_today_buyno_map, code, add_datas) |
| | | |
| | | # 第1条数据是否为09:30:00 |
| | | if add_datas[0]["val"]["time"] == "09:30:00": |
| | |
| | | cls.__buy_and_cancel_map[code][buy_index] = cancel_index |
| | | |
| | | @classmethod |
| | | def __get_cancel_index(cls, code, buy_index): |
| | | def __get_cancel_index_cache(cls, code, buy_index): |
| | | if code not in cls.__buy_and_cancel_map: |
| | | return None |
| | | return cls.__buy_and_cancel_map[code].get(buy_index) |
| | | |
| | | @classmethod |
| | | def __get_buy_index(cls, code, cancel_index): |
| | | def __get_buy_index_cache(cls, code, cancel_index): |
| | | if code not in cls.__cancel_and_buy_map: |
| | | return None |
| | | return cls.__cancel_and_buy_map[code].get(cancel_index) |
| | |
| | | # 小时 |
| | | return __time * 3600, (__time + 1) * 3600 |
| | | |
| | | # 根据买撤数据(与今日总的数据)计算买入数据 |
| | | # 华鑫渠道的L2,根据买撤数据查找买入数据 |
| | | @classmethod |
| | | def get_buy_index_with_cancel_data(cls, code, cancel_data, local_today_num_operate_map): |
| | | key = "{}-{}-{}".format(cancel_data["val"]["num"], "1", cancel_data["val"]["price"]) |
| | | cancel_datas = local_today_num_operate_map.get(key) |
| | | try: |
| | | cancel_datas.sort(key=lambda t: t["index"]) |
| | | except Exception as e: |
| | | print("测试") |
| | | for item in cancel_datas: |
| | | cls.__get_buy_index_with_cancel_data(code, item, local_today_num_operate_map) |
| | | |
| | | return cls.__get_buy_index_with_cancel_data(code, cancel_data, local_today_num_operate_map) |
| | | |
| | | @classmethod |
| | | def __get_buy_index_with_cancel_data(cls, code, cancel_data, local_today_num_operate_map): |
| | | buy_index = cls.__get_buy_index(code, cancel_data["index"]) |
| | | if buy_index is not None: |
| | | return buy_index |
| | | |
| | | min_space, max_space = cls.__compute_time_space_as_second(cancel_data["val"]["cancelTime"], |
| | | cancel_data["val"]["cancelTimeUnit"]) |
| | | max_time = tool.trade_time_add_second(cancel_data["val"]["time"], 0 - min_space) |
| | | min_time = tool.trade_time_add_second(cancel_data["val"]["time"], 0 - max_space) |
| | | def __get_buy_index_with_cancel_data_by_huaxin_l2(cls, code, cancel_data, local_today_num_operate_map): |
| | | buy_datas = local_today_num_operate_map.get( |
| | | "{}-{}-{}".format(cancel_data["val"]["num"], "0", cancel_data["val"]["price"])) |
| | | if buy_datas is None: |
| | | # 无数据 |
| | | return None |
| | | # orderNo |
| | | for bd in buy_datas: |
| | | # 根据订单号做匹配 |
| | | if bd["val"]["orderNo"] == cancel_data["val"]["orderNo"]: |
| | | return bd |
| | | return None |
| | | |
| | | # 同花顺渠道的L2,根据买撤数据查找买入数据 |
| | | @classmethod |
| | | def __get_buy_index_with_cancel_data_by_ths_l2(cls, code, cancel_data, local_today_num_operate_map): |
| | | buy_datas = local_today_num_operate_map.get( |
| | | "{}-{}-{}".format(cancel_data["val"]["num"], "0", cancel_data["val"]["price"])) |
| | | if buy_datas is None: |
| | | # 无数据 |
| | | return None |
| | | min_space, max_space = cls.__compute_time_space_as_second(cancel_data["val"]["cancelTime"], |
| | | cancel_data["val"]["cancelTimeUnit"]) |
| | | max_time = tool.trade_time_add_second(cancel_data["val"]["time"], 0 - min_space) |
| | | min_time = tool.trade_time_add_second(cancel_data["val"]["time"], 0 - max_space) |
| | | # 匹配到的index |
| | | suit_indexes = [] |
| | | for i in range(0, len(buy_datas)): |
| | |
| | | if int(data["val"]["num"]) != int(cancel_data["val"]["num"]): |
| | | continue |
| | | # 如果能找到对应的买撤就需要返回 |
| | | cancel_index = cls.__get_cancel_index(code, data["index"]) |
| | | cancel_index = cls.__get_cancel_index_cache(code, data["index"]) |
| | | if cancel_index is not None and cancel_index != cancel_data["index"]: |
| | | continue |
| | | |
| | |
| | | return suit_indexes[0] |
| | | return None |
| | | |
| | | @classmethod |
| | | def __get_buy_index_with_cancel_data(cls, code, cancel_data, local_today_num_operate_map): |
| | | buy_index = cls.__get_buy_index_cache(code, cancel_data["index"]) |
| | | if buy_index is not None: |
| | | return buy_index |
| | | return cls.__get_buy_index_with_cancel_data_by_ths_l2(code, cancel_data, local_today_num_operate_map) |
| | | |
| | | # 根据买撤数据(与今日总的数据)计算买入数据 |
| | | @classmethod |
| | | def get_buy_index_with_cancel_data(cls, code, cancel_data, local_today_num_operate_map): |
| | | key = "{}-{}-{}".format(cancel_data["val"]["num"], "1", cancel_data["val"]["price"]) |
| | | cancel_datas = local_today_num_operate_map.get(key) |
| | | try: |
| | | cancel_datas.sort(key=lambda t: t["index"]) |
| | | except Exception as e: |
| | | print("测试") |
| | | for item in cancel_datas: |
| | | # 提前做计算 |
| | | cls.__get_buy_index_with_cancel_data(code, item, local_today_num_operate_map) |
| | | |
| | | return cls.__get_buy_index_with_cancel_data(code, cancel_data, local_today_num_operate_map) |
| | | |
| | | # 获取没撤的笔数 |
| | | @classmethod |
| | | def get_limit_up_buy_no_canceled_count(cls, code, index, total_data, local_today_num_operate_map): |
| | | data = None |
| | | try: |
| | | data = total_data[index] |
| | | except: |
| | | print("") |
| | | val = data["val"] |
| | | # 判断当前买是否已经买撤 |
| | | cancel_datas = local_today_num_operate_map.get( |
| | | "{}-{}-{}".format(val["num"], "1", val["price"])) |
| | | canceled = False |
| | | if cancel_datas: |
| | | for cancel_data in cancel_datas: |
| | | |
| | | buy_index = cls.get_buy_index_with_cancel_data(code, cancel_data, local_today_num_operate_map) |
| | | if buy_index == index: |
| | | canceled = True |
| | | count = data["re"] - cancel_data["re"] |
| | | if count > 0: |
| | | return count |
| | | break |
| | | if not canceled: |
| | | count = data["re"] |
| | | return count |
| | | return 0 |
| | | |
| | | # if __name__ == "__main__": |
| | | # code = "000925" |
| | |
| | | # 用于加快数据处理,用空换时间 |
| | | local_today_num_operate_map = {} |
| | | |
| | | # 买入订单号映射,只有原生的L2数据才有 |
| | | local_today_buyno_map = {} |
| | | |
| | | |
| | | def load_l2_data(code, force=False): |
| | | redis = _redisManager.getRedis() |
| | |
| | | # local_today_datas[code] = new_datas |
| | | # 根据今日数据加载 |
| | | load_num_operate_map(local_today_num_operate_map, code, local_today_datas.get(code), force) |
| | | load_buy_no_map(local_today_buyno_map, code, local_today_datas.get(code), force) |
| | | return data_normal |
| | | return True |
| | | |
| | |
| | | if local_today_num_operate_map[code].get(key) is None: |
| | | local_today_num_operate_map[code].setdefault(key, []) |
| | | local_today_num_operate_map[code].get(key).append(data) |
| | | |
| | | |
| | | # 将数据根据orderNo分类,原生数据才有 |
| | | def load_buy_no_map(local_today_buyno_map, code, source_datas, clear=False): |
| | | # 只有原生L2数据才会有此操作 |
| | | if constant.L2_SOURCE_TYPE != constant.L2_SOURCE_TYPE_HUAXIN: |
| | | return |
| | | if local_today_buyno_map.get(code) is None: |
| | | local_today_buyno_map[code] = {} |
| | | if clear: |
| | | local_today_buyno_map[code] = {} |
| | | |
| | | for data in source_datas: |
| | | if data["val"]["operateType"] != 0: |
| | | continue |
| | | # 只填充买入数据 |
| | | key = "{}".format(data["val"]["orderNo"]) |
| | | if local_today_buyno_map[code].get(key) is None: |
| | | local_today_buyno_map[code].setdefault(key, []) |
| | | local_today_buyno_map[code].get(key).append(data) |
| | | |
| | | |
| | | @tool.async_call |
| | |
| | | log.logger_l2_data.info("{}-{}", code, add_datas) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | saveL2Data(code, add_datas) |
| | | # 暂时不将数据保存到redis |
| | | # saveL2Data(code, add_datas) |
| | | |
| | | |
| | | # 设置最新的l2数据采集的数量 |
| | |
| | | # 保存到数据库,更新re的数据 |
| | | save_list.append(_ldata) |
| | | if len(save_list) > 0: |
| | | saveL2Data(code, save_list, "保存纠正数据") |
| | | # 暂时不将数据保存到redis |
| | | # saveL2Data(code, save_list, "保存纠正数据") |
| | | local_latest_datas[code] = latest_data |
| | | return _datas |
| | | |
| | |
| | | return min_time, max_time |
| | | |
| | | |
| | | # 根据买撤数据(与今日总的数据)计算买入数据 |
| | | def get_buy_data_with_cancel_data(cancel_data, local_today_num_operate_map): |
| | | min_space, max_space = compute_time_space_as_second(cancel_data["val"]["cancelTime"], |
| | | cancel_data["val"]["cancelTimeUnit"]) |
| | | max_time = __sub_time(cancel_data["val"]["time"], min_space) |
| | | min_time = __sub_time(cancel_data["val"]["time"], max_space) |
| | | buy_datas = local_today_num_operate_map.get( |
| | | "{}-{}-{}".format(cancel_data["val"]["num"], "0", cancel_data["val"]["price"])) |
| | | if buy_datas is None: |
| | | # 无数据 |
| | | return None, None |
| | | for i in range(0, len(buy_datas)): |
| | | data = buy_datas[i] |
| | | if int(data["val"]["operateType"]) != 0: |
| | | continue |
| | | if int(data["val"]["num"]) != int(cancel_data["val"]["num"]): |
| | | continue |
| | | if min_space == 0 and max_space == 0: |
| | | if compare_time(data["val"]["time"], min_time) == 0: |
| | | return data["index"], data |
| | | |
| | | elif compare_time(data["val"]["time"], min_time) > 0 and compare_time(data["val"]["time"], max_time) <= 0: |
| | | return data["index"], data |
| | | return None, None |
| | | |
| | | |
| | | # 判断卖撤的卖信号是否在目标信号之前 |
| | | def is_sell_index_before_target(sell_cancel_data, target_data, local_today_num_operate_map): |
| | | min_space, max_space = compute_time_space_as_second(sell_cancel_data["val"]["cancelTime"], |
| | |
| | | import init |
| | | 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 l2.cancel_buy_strategy import HourCancelBigNumComputer, L2LimitUpMoneyStatisticUtil, LCancelBigNumComputer |
| | | import l2.l2_data_util |
| | | |
| | | import ths_industry_util |
| | |
| | | codes.append(code) |
| | | dataList.append(item) |
| | | # 保存自由流通股本 |
| | | zyltgb_list.append({"code": code, "zyltgb": item["zyltgb"],"zyltgb_unit": item["zyltgbUnit"]}) |
| | | zyltgb_list.append( |
| | | {"code": code, "zyltgb": item["zyltgb"], "zyltgb_unit": item["zyltgbUnit"]}) |
| | | else: |
| | | # 获取涨停价 |
| | | _limit_up_price = gpcode_manager.get_limit_up_price(code) |
| | |
| | | volumes_data) |
| | | gpcode_manager.FirstCodeManager.add_record(codes) |
| | | if new_add_codes: |
| | | gpcode_manager.set_first_gp_codes_with_data(HistoryKDatasUtils.get_gp_latest_info(codes,fields = "symbol,sec_name,sec_type,sec_level")) |
| | | gpcode_manager.set_first_gp_codes_with_data(HistoryKDatasUtils.get_gp_latest_info(codes, |
| | | fields="symbol,sec_name,sec_type,sec_level")) |
| | | # 加入首板历史记录 |
| | | |
| | | logger_first_code_record.info("新增首板:{}", new_add_codes) |
| | |
| | | code), |
| | | l2.l2_data_util.local_today_num_operate_map.get( |
| | | code)) |
| | | LCancelBigNumComputer.set_trade_progress(code, buy_progress_index, |
| | | l2.l2_data_util.local_today_datas.get( |
| | | code)) |
| | | |
| | | logger_l2_trade_buy_queue.info("获取成交位置成功: code-{} index-{} 数据-{}", code, |
| | | buy_progress_index, |
| | | json.dumps(buy_queue_result_list)) |
| | |
| | | volumes_data = volumes_data[1:] |
| | | volumes = init.parse_max_volume(volumes_data[:60], |
| | | code_nature_analyse.is_new_top(limit_up_price, |
| | | volumes_data[:60])) |
| | | volumes_data[:60])) |
| | | logger_first_code_record.info("{} 获取到首板60天最大量:{}", code, volumes) |
| | | code_volumn_manager.set_histry_volumn(code, volumes[0], volumes[1], volumes[2]) |
| | | # 判断K线形态 |
New file |
| | |
| | | """ |
| | | 华鑫成交记录管理 |
| | | """ |
| | | |
| | | |
| | | # |
| | | # buy_orderno_map 买入数据map |
| | | # 返回代码:成交进度数据的字典 |
| | | def process(datas, total_buyno_map): |
| | | buyno_dict = {} |
| | | last_no_dict = {} |
| | | for d in datas: |
| | | code = d[0] |
| | | if code not in buyno_dict: |
| | | buyno_dict[code] = [] |
| | | if last_no_dict.get(code) == d[6]: |
| | | continue |
| | | last_no_dict[code] = d[6] |
| | | buyno_dict[code].append(d[6]) |
| | | fresults_dict = {} |
| | | for code in buyno_dict: |
| | | if code not in total_buyno_map: |
| | | continue |
| | | buyno_list = buyno_dict[code] |
| | | buyno_list.reverse() |
| | | for b in buyno_list: |
| | | if b in total_buyno_map[code]: |
| | | fresults_dict[code] = total_buyno_map[code][b] |
| | | break |
| | | return fresults_dict |
| | |
| | | import dask |
| | | |
| | | from l2 import l2_data_manager |
| | | from l2.cancel_buy_strategy import HourCancelBigNumComputer, SecondCancelBigNumComputer, L2LimitUpSellStatisticUtil |
| | | from l2.cancel_buy_strategy import HourCancelBigNumComputer, SecondCancelBigNumComputer, L2LimitUpSellStatisticUtil, \ |
| | | LCancelBigNumComputer |
| | | from l2.l2_data_util import local_today_datas, local_today_num_operate_map |
| | | from l2.safe_count_manager import BuyL2SafeCountManager |
| | | from log import logger_l2_error |
| | |
| | | logging.exception(e) |
| | | logger_l2_error.exception(e) |
| | | |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set,volume_rate = l2_data_manager.TradePointManager.get_buy_compute_start_data( |
| | | @dask.delayed |
| | | def l_cancel(code): |
| | | try: |
| | | LCancelBigNumComputer.del_watch_index(code) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | logger_l2_error.exception(e) |
| | | |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, volume_rate = l2_data_manager.TradePointManager.get_buy_compute_start_data( |
| | | code) |
| | | |
| | | f1 = clear_max_buy1_volume(code) |
| | | f2 = safe_count(code, buy_single_index, buy_exec_index) |
| | | f3 = h_cancel(code, buy_single_index, buy_exec_index) |
| | | dask.compute(f1, f2, f3) |
| | | f4 = l_cancel(code) |
| | | dask.compute(f1, f2, f3, f4) |
| | | l2_data_manager.TradePointManager.delete_buy_cancel_point(code) |
| | | |
| | | |