| | |
| | | from code_attribute.code_nature_analyse import LatestMaxVolumeManager, HighIncreaseCodeManager, CodeNatureRecordManager |
| | | from db.redis_manager_delegate import RedisUtils |
| | | from l2.l2_sell_manager import L2MarketSellManager |
| | | from l2.l2_transaction_data_manager import HuaXinTransactionDataManager |
| | | from l2.l2_transaction_data_manager import HuaXinBuyOrderManager |
| | | from ths import client_manager |
| | | import constant |
| | | from trade.deal_big_money_manager import DealOrderNoManager |
| | |
| | | |
| | | # 保存运行时数据 |
| | | def save_running_data(): |
| | | HuaXinTransactionDataManager().sync_dealing_data_to_db() |
| | | HuaXinBuyOrderManager().sync_dealing_data_to_db() |
| | | |
| | | |
| | | |
| | |
| | | from l2.huaxin import l2_huaxin_util |
| | | from l2.l2_data_manager import OrderBeginPosInfo |
| | | from l2.l2_sell_manager import L2LimitUpSellManager |
| | | from l2.l2_transaction_data_manager import HuaXinTransactionDataManager |
| | | from l2.l2_transaction_data_manager import HuaXinBuyOrderManager |
| | | from log_module import async_log_util |
| | | from trade.deal_big_money_manager import DealOrderNoManager |
| | | from trade.sell.sell_rule_manager import TradeRuleManager |
| | |
| | | |
| | | def set_real_place_position(code, index, buy_single_index=None, is_default=True): |
| | | # DCancelBigNumComputer().set_real_order_index(code, index) |
| | | SecondCancelBigNumComputer().set_real_place_order_index(code, index) |
| | | SCancelBigNumComputer().set_real_place_order_index(code, index) |
| | | LCancelBigNumComputer().set_real_place_order_index(code, index, buy_single_index=buy_single_index, |
| | | is_default=is_default) |
| | | HourCancelBigNumComputer().set_real_place_order_index(code, index, buy_single_index) |
| | |
| | | FCancelBigNumComputer().set_real_order_index(code, index, is_default) |
| | | |
| | | |
| | | class SecondCancelBigNumComputer: |
| | | class SCancelBigNumComputer: |
| | | __db = 0 |
| | | __redis_manager = redis_manager.RedisManager(0) |
| | | __sCancelParamsManager = l2_trade_factor.SCancelParamsManager |
| | | __s_big_num_cancel_compute_data_cache = {} |
| | | __s_cancel_real_place_order_index_cache = {} |
| | | # 成交位置 |
| | | __s_cancel_transaction_index_cache = {} |
| | | # H撤是否初始化数据,当真实下单位置与成交位到来时才进行赋值 |
| | | __s_cancel_inited_data = {} |
| | | __s_down_watch_indexes_dict = {} |
| | | |
| | | __instance = None |
| | | |
| | | def __new__(cls, *args, **kwargs): |
| | | if not cls.__instance: |
| | | cls.__instance = super(SecondCancelBigNumComputer, cls).__new__(cls, *args, **kwargs) |
| | | cls.__instance = super(SCancelBigNumComputer, cls).__new__(cls, *args, **kwargs) |
| | | cls.__load_datas() |
| | | return cls.__instance |
| | | |
| | |
| | | def __load_datas(cls): |
| | | __redis = cls.__get_redis() |
| | | try: |
| | | keys = RedisUtils.keys(__redis, "s_big_num_cancel_compute_data-*") |
| | | for k in keys: |
| | | code = k.split("-")[-1] |
| | | val = RedisUtils.get(__redis, k) |
| | | val = json.loads(val) |
| | | tool.CodeDataCacheUtil.set_cache(cls.__s_big_num_cancel_compute_data_cache, code, val) |
| | | |
| | | keys = RedisUtils.keys(__redis, "s_cancel_real_place_order_index-*") |
| | | for k in keys: |
| | | code = k.split("-")[-1] |
| | |
| | | tool.CodeDataCacheUtil.set_cache(cls.__s_cancel_real_place_order_index_cache, code, val) |
| | | finally: |
| | | RedisUtils.realse(__redis) |
| | | |
| | | # 保存结束位置 |
| | | def __save_compute_data(self, code, process_index, buy_num, cancel_num): |
| | | CodeDataCacheUtil.set_cache(self.__s_big_num_cancel_compute_data_cache, code, |
| | | (process_index, buy_num, cancel_num)) |
| | | key = "s_big_num_cancel_compute_data-{}".format(code) |
| | | RedisUtils.setex_async(self.__db, key, tool.get_expire(), |
| | | json.dumps((process_index, buy_num, cancel_num))) |
| | | |
| | | def __get_compute_data(self, code): |
| | | key = "s_big_num_cancel_compute_data-{}".format(code) |
| | | val = RedisUtils.get(self.__get_redis(), key) |
| | | if val is None: |
| | | return -1, 0, 0 |
| | | val = json.loads(val) |
| | | return val[0], val[1], val[2] |
| | | |
| | | def __get_compute_data_cache(self, code): |
| | | cache_result = CodeDataCacheUtil.get_cache(self.__s_big_num_cancel_compute_data_cache, code) |
| | | if cache_result[0]: |
| | | return cache_result[1] |
| | | return -1, 0, 0 |
| | | |
| | | def __del_compute_data_cache(self, code): |
| | | CodeDataCacheUtil.clear_cache(self.__s_big_num_cancel_compute_data_cache, code) |
| | | key = "s_big_num_cancel_compute_data-{}".format(code) |
| | | RedisUtils.delete_async(self.__db, key) |
| | | |
| | | # 设置真实下单位置 |
| | | def __save_real_place_order_index(self, code, index): |
| | |
| | | return None |
| | | |
| | | def __clear_data(self, code): |
| | | CodeDataCacheUtil.clear_cache(self.__s_big_num_cancel_compute_data_cache, code) |
| | | CodeDataCacheUtil.clear_cache(self.__s_cancel_real_place_order_index_cache, code) |
| | | CodeDataCacheUtil.clear_cache(self.__s_cancel_transaction_index_cache, code) |
| | | CodeDataCacheUtil.clear_cache(self.__s_cancel_inited_data, code) |
| | | CodeDataCacheUtil.clear_cache(self.__s_down_watch_indexes_dict, code) |
| | | |
| | | ks = ["s_big_num_cancel_compute_data-{}".format(code), "s_cancel_real_place_order_index-{}".format(code)] |
| | | for key in ks: |
| | | RedisUtils.delete_async(self.__db, key) |
| | |
| | | # 设置真实下单位置 |
| | | def set_real_place_order_index(self, code, index): |
| | | self.__save_real_place_order_index(code, index) |
| | | |
| | | # 设置成交进度位 |
| | | def set_transaction_index(self, code, index): |
| | | self.__s_cancel_transaction_index_cache[code] = index |
| | | |
| | | def clear_data(self): |
| | | ks = ["s_big_num_cancel_compute_data-*", "s_cancel_real_place_order_index-*"] |
| | |
| | | code = k.split("-")[1] |
| | | self.__clear_data(code) |
| | | |
| | | # 计算净大单 |
| | | def __compute_left_big_num(self, code, buy_single_index, start_index, end_index, total_data, volume_rate_index): |
| | | # 点火大单数量 |
| | | fire_count = self.__sCancelParamsManager.get_max_exclude_count(volume_rate_index) |
| | | return self.compute_left_big_num(code, buy_single_index, start_index, end_index, total_data, fire_count, |
| | | constant.S_CANCEL_MIN_MONEY) |
| | | |
| | | # 计算未撤的总手数 |
| | | def compute_left_big_num(self, 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"]) <= min_money_w * 100: |
| | | continue |
| | | |
| | | if L2DataUtil.is_limit_up_price_buy(val): |
| | | if i - buy_single_index < fire_count: |
| | | # 点火大单不算 |
| | | left_big_num += 0 |
| | | else: |
| | | left_big_num += val["num"] * data["re"] |
| | | elif L2DataUtil.is_limit_up_price_buy_cancel(val): |
| | | # 查询买入位置 |
| | | buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(data, |
| | | local_today_buyno_map.get( |
| | | code)) |
| | | if buy_index is not None and start_index <= buy_index <= end_index: |
| | | if buy_index - buy_single_index < fire_count: |
| | | left_big_num -= 0 |
| | | else: |
| | | left_big_num -= val["num"] * data["re"] |
| | | elif buy_index is None: |
| | | # 有部分撤销从而导致的无法溯源,这时就需要判断预估买入时间是否在a_start_index到a_end_index的时间区间 |
| | | min_space, max_space = l2_data_util.compute_time_space_as_second(val["cancelTime"], |
| | | val["cancelTimeUnit"]) |
| | | # 只判断S级撤销,只有s级撤销才有可能相等 |
| | | if max_space - min_space <= 1: |
| | | buy_time = tool.trade_time_add_second(val["time"], 0 - min_space) |
| | | if int(total_data[start_index]["val"]["time"].replace(":", "")) <= int( |
| | | buy_time.replace(":", "")) <= int( |
| | | total_data[end_index]["val"]["time"].replace(":", "")): |
| | | left_big_num -= val["num"] * data["re"] |
| | | return left_big_num |
| | | |
| | | def need_cancel(self, code, buy_single_index, buy_exec_index, start_index, end_index, total_data, is_first_code, |
| | | buy_volume_rate_index, |
| | | volume_rate_index, |
| | | need_cancel=True): |
| | | |
| | | if buy_single_index is None or buy_exec_index is None: |
| | | return False, "尚未找到下单位置" |
| | | |
| | | # 只守护30s |
| | | buy_exec_time = total_data[buy_exec_index]["val"]["time"] |
| | | if tool.trade_time_sub(total_data[start_index]["val"]["time"], |
| | | buy_exec_time) > constant.S_CANCEL_EXPIRE_TIME: |
| | | return False, None |
| | | l2_log.cancel_debug(code, "S级是否需要撤单,数据范围:{}-{} ", start_index, end_index) |
| | | l2_log.s_cancel_debug(code, "S级是否需要撤单,数据范围:{}-{} ", start_index, end_index) |
| | | real_place_order_index = self.__s_cancel_real_place_order_index_cache.get(code) |
| | | transaction_index = self.__s_cancel_transaction_index_cache.get(code) |
| | | |
| | | if real_place_order_index and transaction_index: |
| | | # S撤计算范围:成交位-真实下单位 |
| | | if not self.__s_cancel_inited_data.get(code): |
| | | l2_log.s_cancel_debug(code, "S撤初始化,成交位:{} 下单位:{}", transaction_index, real_place_order_index) |
| | | # 清除之前的计算数据 |
| | | self.__s_cancel_inited_data[code] = True |
| | | self.__del_compute_data_cache(code) |
| | | # 计算未撤单的订单手数 |
| | | left_big_num = 0 |
| | | for i in range(transaction_index + 1, real_place_order_index): |
| | | data = total_data[i] |
| | | val = data["val"] |
| | | if val["num"] * float(val["price"]) <= constant.S_CANCEL_MIN_MONEY * 100: |
| | | continue |
| | | # 获取 |
| | | if L2DataUtil.is_limit_up_price_buy(val): |
| | | left_big_num += val["num"] * data["re"] |
| | | elif L2DataUtil.is_limit_up_price_buy_cancel(val): |
| | | # 查询买入位置 |
| | | buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(data, |
| | | local_today_buyno_map.get( |
| | | code)) |
| | | if buy_index is not None and transaction_index + 1 <= buy_index <= real_place_order_index and i < start_index: |
| | | left_big_num -= val["num"] * data["re"] |
| | | l2_log.s_cancel_debug(code, "S撤初始化结果,left_big_num:{}", left_big_num) |
| | | self.__save_compute_data(code, real_place_order_index, left_big_num, 0) |
| | | # 保存信息 |
| | | process_index_old, buy_num, cancel_num = self.__get_compute_data_cache(code) |
| | | process_index = process_index_old |
| | | cancel_rate_threshold = self.__sCancelParamsManager.get_cancel_rate(volume_rate_index) |
| | | try: |
| | | for i in range(start_index, end_index + 1): |
| | | data = total_data[i] |
| | | val = data["val"] |
| | | process_index = i |
| | | if process_index_old >= i: |
| | | # 已经处理过的数据不需要处理 |
| | | continue |
| | | if L2DataUtil.is_limit_up_price_buy_cancel(val): |
| | | if val["num"] * float(val["price"]) <= constant.S_CANCEL_MIN_MONEY * 100: |
| | | continue |
| | | # 查询买入位置 |
| | | buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(data, |
| | | local_today_buyno_map.get( |
| | | code)) |
| | | if buy_index is not None and transaction_index < buy_index < real_place_order_index: |
| | | cancel_num += total_data[buy_index]["re"] * int(total_data[buy_index]["val"]["num"]) |
| | | if need_cancel: |
| | | rate__ = round(cancel_num / max(buy_num, 1), 2) |
| | | if rate__ > cancel_rate_threshold: |
| | | return True, total_data[i] |
| | | finally: |
| | | # 保存处理进度与数据 |
| | | self.__save_compute_data(code, process_index, buy_num, cancel_num) |
| | | else: |
| | | # S测计算位置为信号起始位置执行位1s之后 |
| | | if tool.trade_time_sub(total_data[end_index]["val"]["time"], |
| | | total_data[buy_exec_index]["val"]["time"]) > constant.S_CANCEL_EXPIRE_TIME: |
| | | # 结束位置超过了执行位置60s,需要重新确认结束位置 |
| | | for i in range(end_index, start_index - 1, -1): |
| | | if total_data[end_index]["val"]["time"] != total_data[i]["val"]["time"]: |
| | | end_index = i |
| | | break |
| | | # 获取处理进度 |
| | | process_index_old, buy_num, cancel_num = self.__get_compute_data_cache(code) |
| | | |
| | | # 如果start_index与buy_single_index相同,即是下单后的第一次计算 |
| | | # 需要查询买入信号之前的同1s是否有涨停撤的数据 |
| | | process_index = process_index_old |
| | | |
| | | if process_index_old == -1: |
| | | # 第1次计算需要计算买入信号-执行位的净值 |
| | | left_big_num = self.__compute_left_big_num(code, buy_single_index, buy_single_index, buy_exec_index, |
| | | total_data, volume_rate_index) |
| | | buy_num += left_big_num |
| | | # 设置买入信号-买入执行位的数据不需要处理 |
| | | process_index = buy_exec_index |
| | | # 强制固定为1s |
| | | range_seconds = 1 # self.__sCancelParamsManager.get_buy_time_range(buy_volume_rate_index) |
| | | # 获取真实下单位置 |
| | | place_order_index = self.__get_real_place_order_index_cache(code) |
| | | |
| | | cancel_rate_threshold = self.__sCancelParamsManager.get_cancel_rate(volume_rate_index) |
| | | try: |
| | | for i in range(start_index, end_index + 1): |
| | | data = total_data[i] |
| | | val = data["val"] |
| | | process_index = i |
| | | if process_index_old >= i: |
| | | # 已经处理过的数据不需要处理 |
| | | continue |
| | | if val["num"] * float(val["price"]) <= constant.S_CANCEL_MIN_MONEY * 100: |
| | | continue |
| | | |
| | | if L2DataUtil.is_limit_up_price_buy(val): |
| | | |
| | | if place_order_index is not None and place_order_index < data["index"]: |
| | | # 不能比下单位置后 |
| | | continue |
| | | # 如果在囊括时间范围内就可以计算买 |
| | | if tool.trade_time_sub(val["time"], buy_exec_time) <= range_seconds: |
| | | buy_num += data["re"] * int(val["num"]) |
| | | elif L2DataUtil.is_limit_up_price_buy_cancel(val): |
| | | # 查询买入位置 |
| | | buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(data, |
| | | local_today_buyno_map.get( |
| | | code)) |
| | | if buy_index is not None and buy_single_index <= buy_index: |
| | | if place_order_index and place_order_index >= buy_index: |
| | | cancel_num += total_data[buy_index]["re"] * int(total_data[buy_index]["val"]["num"]) |
| | | # 买入时间在囊括范围内 |
| | | elif tool.trade_time_sub(tool.trade_time_add_second(buy_exec_time, range_seconds), |
| | | total_data[buy_index]["val"]["time"]) >= 0: |
| | | cancel_num += total_data[buy_index]["re"] * int(total_data[buy_index]["val"]["num"]) |
| | | elif buy_index is None: |
| | | # 有部分撤销从而导致的无法溯源,这时就需要判断预估买入时间是否在a_start_index到a_end_index的时间区间 |
| | | min_space, max_space = l2_data_util.compute_time_space_as_second(val["cancelTime"], |
| | | val["cancelTimeUnit"]) |
| | | # 只判断S级撤销,只有s级撤销才有可能相等 |
| | | if max_space - min_space <= 1: |
| | | buy_time = tool.trade_time_add_second(val["time"], 0 - min_space) |
| | | 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: |
| | | cancel_num += data["re"] * int(val["num"]) |
| | | |
| | | # 保存数据 |
| | | if need_cancel: |
| | | rate__ = round(cancel_num / max(buy_num, 1), 2) |
| | | if rate__ > cancel_rate_threshold: |
| | | return True, total_data[i] |
| | | finally: |
| | | |
| | | l2_log.cancel_debug(code, "S级大单 范围:{}-{} 取消计算结果:{}/{},比例:{} 目标比例:{} 计算时间范围:{}", start_index, end_index, |
| | | cancel_num, |
| | | buy_num, round(cancel_num / max(buy_num, 1), 2), cancel_rate_threshold, |
| | | range_seconds) |
| | | |
| | | # 保存处理进度与数据 |
| | | self.__save_compute_data(code, process_index, buy_num, cancel_num) |
| | | return False, None |
| | | |
| | | # 撤单成功 |
| | | def cancel_success(self, code): |
| | | self.__clear_data(code) |
| | |
| | | def place_order_success(self, code): |
| | | self.__clear_data(code) |
| | | |
| | | # S前撤实现 |
| | | def __need_cancel_for_up(self, code, big_sell_order_info, total_datas): |
| | | trade_index, is_default = TradeBuyQueue().get_traded_index(code) |
| | | real_order_index = self.__get_real_place_order_index_cache(code) |
| | | if real_order_index is None and big_sell_order_info[0] < 500000: |
| | | return True, "没找到真实下单位置就有大卖单" |
| | | start_order_no = big_sell_order_info[1][0][3][1] |
| | | total_num = 0 |
| | | for i in range(trade_index, real_order_index): |
| | | data = total_datas[i] |
| | | val = data['val'] |
| | | if not L2DataUtil.is_limit_up_price_buy(val): |
| | | continue |
| | | if int(val['orderNo']) < start_order_no: |
| | | continue |
| | | left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, i, |
| | | total_datas, |
| | | local_today_canceled_buyno_map.get( |
| | | code)) |
| | | if left_count > 0: |
| | | total_num += val["num"] |
| | | total_money = total_num * 100 * big_sell_order_info[1][-1][2] |
| | | total_deal_money = sum([x[1] * x[2] for x in big_sell_order_info[1]]) |
| | | deal_rate = round(total_deal_money / total_money, 4) |
| | | if deal_rate >= 0.3: |
| | | return True, f"成交比例:{deal_rate}({total_deal_money}/{total_money})" |
| | | |
| | | # 计算S后撤监听的数据范围 |
| | | def __compute_down_cancel_watch_index(self, code, big_sell_order_info, total_datas): |
| | | trade_index, is_default = TradeBuyQueue().get_traded_index(code) |
| | | real_order_index = self.__get_real_place_order_index_cache(code) |
| | | start_order_no = big_sell_order_info[1][-1][4][1] |
| | | latest_deal_time = l2_huaxin_util.convert_time(big_sell_order_info[1][-1][4][0], with_ms=True) |
| | | if code in self.__s_down_watch_indexes_dict: |
| | | # 更新囊括范围后1s内不能再次更新 |
| | | if tool.trade_time_sub_with_ms(latest_deal_time, self.__s_down_watch_indexes_dict[code][0]) <= 1000: |
| | | return |
| | | |
| | | watch_index_info = [] |
| | | for i in range(trade_index, real_order_index): |
| | | data = total_datas[i] |
| | | val = data['val'] |
| | | if not L2DataUtil.is_limit_up_price_buy(val): |
| | | continue |
| | | if int(val['orderNo']) < start_order_no: |
| | | continue |
| | | if val['num'] * float(val['price']) < 5000: |
| | | continue |
| | | left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, i, |
| | | total_datas, |
| | | local_today_canceled_buyno_map.get( |
| | | code)) |
| | | if left_count > 0: |
| | | watch_index_info.append((i, val['num'])) |
| | | watch_index_info.sort(key=lambda x: x[1], reverse=True) |
| | | watch_indexes = set([x[0] for x in watch_index_info[:5]]) |
| | | l2_log.s_cancel_debug(code, f"S后计算那概括范围:{watch_indexes} 最近成交的卖单信息:{big_sell_order_info[1][-1]}") |
| | | if watch_indexes: |
| | | # 保存卖单信息 |
| | | self.__s_down_watch_indexes_dict[code] = (latest_deal_time, watch_indexes) |
| | | |
| | | # big_sell_order_info格式:[总共的卖单金额, 大卖单详情列表] |
| | | def set_big_sell_order_info_for_cancel(self, code, big_sell_order_info,order_begin_pos: OrderBeginPosInfo): |
| | | if order_begin_pos is None or order_begin_pos.buy_exec_index is None or order_begin_pos.buy_exec_index < 0: |
| | | return False, "还未下单" |
| | | |
| | | if big_sell_order_info[0] < 500000 or not big_sell_order_info[1]: |
| | | return False, "无大单卖" |
| | | |
| | | # 获取最新的成交时间 |
| | | total_datas = local_today_datas.get(code) |
| | | latest_trade_time = l2_huaxin_util.convert_time(big_sell_order_info[1][-1][4][0]) |
| | | if tool.trade_time_sub(latest_trade_time, total_datas[order_begin_pos.buy_single_index]['val']['time']) < 180: |
| | | return self.__need_cancel_for_up(code, big_sell_order_info, total_datas) |
| | | else: |
| | | self.__compute_down_cancel_watch_index(code, big_sell_order_info, total_datas) |
| | | return False, "超过S前守护范围" |
| | | |
| | | def need_cancel_for_down(self, code, start_index, end_index): |
| | | watch_index_info = self.__s_down_watch_indexes_dict.get(code) |
| | | if not watch_index_info: |
| | | return False, "没获取到囊括范围" |
| | | total_datas = local_today_datas.get(code) |
| | | if tool.trade_time_sub(total_datas[-1]["val"]["time"], watch_index_info[0].split(".")[0]) > 9: |
| | | return False, "超过守护时间" |
| | | |
| | | watch_indexes = watch_index_info[1] |
| | | watch_order_nos = set([total_datas[d]['val']['orderNo'] for d in watch_indexes]) |
| | | # 计算是否有撤单 |
| | | need_compute = False |
| | | for i in range(start_index, end_index + 1): |
| | | data = total_datas[i] |
| | | val = data['val'] |
| | | if not L2DataUtil.is_limit_up_price_buy_cancel(val): |
| | | continue |
| | | if val['orderNo'] in watch_order_nos: |
| | | need_compute = True |
| | | break |
| | | if not need_compute: |
| | | return False, "没有监听范围内的单撤单" |
| | | # 计算撤单比例 |
| | | total_num = 0 |
| | | cancel_num = 0 |
| | | for index in watch_indexes: |
| | | total_num += total_datas[index]["val"]['num'] |
| | | left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, index, |
| | | total_datas, |
| | | local_today_canceled_buyno_map.get( |
| | | code)) |
| | | if left_count <= 0: |
| | | cancel_num += total_datas[index]["val"]['num'] |
| | | cancel_rate = round(cancel_num / total_num, 4) |
| | | if cancel_rate >= 0.25: |
| | | return True, f"达到撤单比例:{cancel_rate} 监听范围:{watch_index_info}" |
| | | |
| | | return False, "没达到撤单比例" |
| | | |
| | | |
| | | # --------------------------------H撤------------------------------- |
| | | class HourCancelBigNumComputer: |
| | | __db = 0 |
| | | __redis_manager = redis_manager.RedisManager(0) |
| | | __tradeBuyQueue = TradeBuyQueue() |
| | | __SecondCancelBigNumComputer = SecondCancelBigNumComputer() |
| | | __SCancelBigNumComputer = SCancelBigNumComputer() |
| | | |
| | | # 计算触发位置 |
| | | __start_compute_index_dict = {} |
| | |
| | | return |
| | | if self.__cancel_watch_indexs_cache.get(code): |
| | | return |
| | | real_place_order_index = self.__SecondCancelBigNumComputer.get_real_place_order_index_cache(code) |
| | | real_place_order_index = self.__SCancelBigNumComputer.get_real_place_order_index_cache(code) |
| | | if not real_place_order_index: |
| | | l2_log.h_cancel_debug(code, "尚未找到真实下单位置") |
| | | return |
| | |
| | | start_compute_index = self.__start_compute_index_dict.get(code) |
| | | if start_compute_index is None: |
| | | return False |
| | | real_place_order_index = self.__SecondCancelBigNumComputer.get_real_place_order_index_cache(code) |
| | | real_place_order_index = self.__SCancelBigNumComputer.get_real_place_order_index_cache(code) |
| | | total_datas = local_today_datas.get(code) |
| | | if real_place_order_index and real_place_order_index > transaction_index: |
| | | # 成交位置离我们真实下单的位置只有5笔没撤的大单就需要计算H撤的囊括范围了 |
| | |
| | | # 成交位附近临近大单索引 |
| | | __near_by_trade_progress_index_cache = {} |
| | | |
| | | __SecondCancelBigNumComputer = SecondCancelBigNumComputer() |
| | | __SCancelBigNumComputer = SCancelBigNumComputer() |
| | | |
| | | # L后囊括范围未撤单/未成交的总手数 |
| | | __total_l_down_not_deal_num_dict = {} |
| | |
| | | RedisUtils.setex_async(self.__db, f"l_cancel_real_place_order_index-{code}", tool.get_expire(), index) |
| | | if buy_single_index is not None: |
| | | if code in self.__last_trade_progress_dict: |
| | | self.compute_watch_index(code, buy_single_index, max(buy_single_index, self.__last_trade_progress_dict[code] + 1), index) |
| | | self.compute_watch_index(code, buy_single_index, |
| | | max(buy_single_index, self.__last_trade_progress_dict[code] + 1), index) |
| | | else: |
| | | self.compute_watch_index(code, buy_single_index, buy_single_index, index) |
| | | |
| | |
| | | fnum = val["num"] |
| | | if i == trade_progress: |
| | | # 需要减去已经成交的数据 |
| | | dealing_info = HuaXinTransactionDataManager.get_dealing_order_info(code) |
| | | dealing_info = HuaXinBuyOrderManager.get_dealing_order_info(code) |
| | | if dealing_info: |
| | | if str(val["orderNo"]) == str(dealing_info[0]): |
| | | fnum -= dealing_info[1] // 100 |
| | |
| | | code)) |
| | | if left_count > 0: |
| | | total_deal_num += val["num"] * left_count |
| | | dealing_info = HuaXinTransactionDataManager.get_dealing_order_info(code) |
| | | dealing_info = HuaXinBuyOrderManager.get_dealing_order_info(code) |
| | | if dealing_info: |
| | | if str(total_datas[trade_index]["val"]["orderNo"]) == str(dealing_info[0]): |
| | | total_deal_num += (total_datas[trade_index]["val"]["num"] - dealing_info[1] // 100) |
| | |
| | | __db = 0 |
| | | __redis_manager = redis_manager.RedisManager(0) |
| | | __cancel_real_order_index_cache = {} |
| | | __SecondCancelBigNumComputer = SecondCancelBigNumComputer() |
| | | __SCancelBigNumComputer = SCancelBigNumComputer() |
| | | |
| | | __instance = None |
| | | |
| | |
| | | time_sub = tool.trade_time_sub(tool.get_now_time_str(), |
| | | total_datas[order_begin_pos.buy_exec_index]["val"]["time"]) |
| | | if 2 < time_sub < 30 * 60: |
| | | real_place_order_index = self.__SecondCancelBigNumComputer.get_real_place_order_index_cache(code) |
| | | real_place_order_index = self.__SCancelBigNumComputer.get_real_place_order_index_cache(code) |
| | | if not real_place_order_index: |
| | | return False, "尚未找到真实下单位置" |
| | | total_left_count = 0 |
| | |
| | | trade_result_manager, current_price_process_manager, trade_data_manager, trade_huaxin, trade_record_log_util |
| | | from l2 import l2_data_manager, l2_log, l2_data_source_util, code_price_manager, \ |
| | | transaction_progress, cancel_buy_strategy, l2_data_log |
| | | from l2.cancel_buy_strategy import SecondCancelBigNumComputer, HourCancelBigNumComputer, DCancelBigNumComputer, \ |
| | | from l2.cancel_buy_strategy import SCancelBigNumComputer, HourCancelBigNumComputer, DCancelBigNumComputer, \ |
| | | LCancelBigNumComputer, LatestCancelIndexManager, LCancelRateManager, GCancelBigNumComputer |
| | | from l2.l2_data_manager import L2DataException, OrderBeginPosInfo |
| | | from l2.l2_data_util import local_today_datas, L2DataUtil, local_today_num_operate_map, local_today_buyno_map, \ |
| | |
| | | __trade_log_placr_order_info_dict = {} # 下单信息保存 |
| | | # 初始化 |
| | | __TradePointManager = l2_data_manager.TradePointManager() |
| | | __SecondCancelBigNumComputer = SecondCancelBigNumComputer() |
| | | __SCancelBigNumComputer = SCancelBigNumComputer() |
| | | __HourCancelBigNumComputer = HourCancelBigNumComputer() |
| | | __LCancelBigNumComputer = LCancelBigNumComputer() |
| | | __GCancelBigNumComputer = GCancelBigNumComputer() |
| | |
| | | _start_time = round(t.time() * 1000) |
| | | # S撤单计算,看秒级大单撤单 |
| | | try: |
| | | b_need_cancel, b_cancel_data = cls.__SecondCancelBigNumComputer.need_cancel(code, _buy_single_index, |
| | | _buy_exec_index, |
| | | start_index, |
| | | end_index, total_data, |
| | | code_volumn_manager.get_volume_rate_index( |
| | | buy_volume_rate), |
| | | cls.volume_rate_info[code][ |
| | | 1], |
| | | is_first_code) |
| | | b_need_cancel, b_cancel_msg = cls.__SCancelBigNumComputer.need_cancel_for_down(code, start_index,end_index) |
| | | if b_need_cancel: |
| | | return b_cancel_data, "S大单撤销比例触发阈值" |
| | | async_log_util.error(logger_debug, f"{code} S后撤单:{b_cancel_msg}") |
| | | # return total_data[end_index], f"S后撤({b_cancel_msg})" |
| | | return None, None |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | async_log_util.error(logger_l2_error, |
| | |
| | | |
| | | from db import redis_manager |
| | | from db.redis_manager_delegate import RedisUtils |
| | | from l2 import l2_log |
| | | from l2.huaxin import l2_huaxin_util |
| | | |
| | | from log_module import async_log_util |
| | | from log_module.log import hx_logger_l2_transaction_desc |
| | | from log_module.log import hx_logger_l2_transaction_desc, hx_logger_l2_transaction_sell_order |
| | | |
| | | from utils import tool |
| | | |
| | | |
| | | class HuaXinTransactionDataManager: |
| | | # 成交数据统计 |
| | | class HuaXinBuyOrderManager: |
| | | __db = 0 |
| | | __instance = None |
| | | __redis_manager = redis_manager.RedisManager(0) |
| | | |
| | | |
| | | # 正在成交的订单 |
| | | __dealing_order_info_dict = {} |
| | |
| | | |
| | | def __new__(cls, *args, **kwargs): |
| | | if not cls.__instance: |
| | | cls.__instance = super(HuaXinTransactionDataManager, cls).__new__(cls, *args, **kwargs) |
| | | cls.__instance = super(HuaXinBuyOrderManager, cls).__new__(cls, *args, **kwargs) |
| | | cls.__load_datas() |
| | | return cls.__instance |
| | | |
| | |
| | | return None |
| | | |
| | | |
| | | # 卖单统计数据 |
| | | class HuaXinSellOrderStatisticManager: |
| | | # 最近的大卖单成交,格式:{code:[卖单信息,...]} |
| | | __latest_sell_order_info_list_dict = {} |
| | | |
| | | # 大单卖单号的集合,格式:{code:{卖单号}} |
| | | __big_sell_order_ids_dict = {} |
| | | |
| | | # 大卖单的卖单号->卖单信息映射 |
| | | __big_sell_order_info_dict = {} |
| | | |
| | | # 最近的卖单, 格式{code:[卖单号,总手数,价格,('开始时间',买单号),('结束时间',买单号)]} |
| | | __latest_sell_order_dict = {} |
| | | |
| | | @classmethod |
| | | def add_transaction_datas(cls, code, datas): |
| | | # q.append((data['SecurityID'], data['TradePrice'], data['TradeVolume'], |
| | | # data['OrderTime'], data['MainSeq'], data['SubSeq'], data['BuyNo'], |
| | | # data['SellNo'], data['ExecType'])) |
| | | if code not in cls.__latest_sell_order_info_list_dict: |
| | | cls.__latest_sell_order_info_list_dict[code] = [] |
| | | if code not in cls.__big_sell_order_ids_dict: |
| | | cls.__big_sell_order_ids_dict[code] = set() |
| | | if code not in cls.__big_sell_order_info_dict: |
| | | cls.__big_sell_order_info_dict[code] = {} |
| | | for d in datas: |
| | | cls.__latest_sell_order_info_list_dict[code].append(d) |
| | | if code not in cls.__latest_sell_order_dict: |
| | | cls.__latest_sell_order_dict[code] = [d[7], d[2], d[1], (d[3], d[6]), (d[3], d[6])] |
| | | else: |
| | | if cls.__latest_sell_order_dict[code][0] == d[7]: |
| | | cls.__latest_sell_order_dict[code][1] += d[2] |
| | | cls.__latest_sell_order_dict[code][2] = d[1] |
| | | cls.__latest_sell_order_dict[code][4] = (d[3], d[6]) |
| | | else: |
| | | # 封存数据,计算新起点 |
| | | l2_log.info(code, hx_logger_l2_transaction_sell_order, f"{cls.__latest_sell_order_dict[code]}") |
| | | # 大于50w加入卖单 |
| | | info = cls.__latest_sell_order_dict[code] |
| | | if info[1] * info[2] >= 500000: |
| | | cls.__big_sell_order_ids_dict[code].add(info[0]) |
| | | cls.__big_sell_order_info_dict[code][info[0]] = info |
| | | |
| | | cls.__latest_sell_order_dict[code] = [d[7], d[2], d[1], (d[3], d[6]), (d[3], d[6])] |
| | | latest_time = l2_huaxin_util.convert_time(datas[-1][3], with_ms=True) |
| | | min_time = tool.trade_time_add_millionsecond(latest_time, -1000) |
| | | min_time_int = int(min_time.replace(":", "").replace(".", "")) |
| | | # 计算最近1s的大单成交 |
| | | total_datas = cls.__latest_sell_order_info_list_dict.get(code) |
| | | start_index = 0 |
| | | |
| | | total_sell_info = [0, None] # 总资金,开始成交信息,结束成交信息 |
| | | latest_sell_order_info = cls.__latest_sell_order_dict[code] |
| | | big_sell_order_ids = cls.__big_sell_order_ids_dict[code] |
| | | # print("大卖单", big_sell_order_ids) |
| | | big_sell_orders = [] |
| | | temp_sell_order_ids = set() |
| | | for i in range(len(datas) - 1, -1, -1): |
| | | d = datas[i] |
| | | if d[7] != latest_sell_order_info[0]: |
| | | # 不是最近的成交且不是大单直接过滤 |
| | | if d[7] not in big_sell_order_ids: |
| | | continue |
| | | else: |
| | | if d[7] not in temp_sell_order_ids: |
| | | big_sell_orders.append(cls.__big_sell_order_info_dict[code].get(d[7])) |
| | | temp_sell_order_ids.add(d[7]) |
| | | else: |
| | | # 是最近的但不是大单需要过滤 |
| | | if latest_sell_order_info[1] * latest_sell_order_info[2] < 500000: |
| | | continue |
| | | else: |
| | | if latest_sell_order_info[0] not in temp_sell_order_ids: |
| | | big_sell_orders.append(latest_sell_order_info) |
| | | temp_sell_order_ids.add(latest_sell_order_info[0]) |
| | | |
| | | if min_time_int > int(l2_huaxin_util.convert_time(d[3], with_ms=True).replace(":", "").replace(".", "")): |
| | | start_index = i |
| | | break |
| | | # 统计最近1s的大卖单数据 |
| | | total_sell_info[0] += int(d[1] * d[2]) |
| | | big_sell_orders.reverse() |
| | | total_sell_info[1] = big_sell_orders |
| | | cls.__latest_sell_order_info_list_dict[code] = cls.__latest_sell_order_info_list_dict[code][start_index:] |
| | | return total_sell_info |
| | |
| | | import logging |
| | | import time |
| | | |
| | | from code_attribute import gpcode_manager |
| | | from l2 import l2_data_util, l2_data_manager, l2_data_source_util, transaction_progress |
| | | from l2 import l2_data_util, l2_data_manager, transaction_progress |
| | | from l2.cancel_buy_strategy import FCancelBigNumComputer, LCancelBigNumComputer, LCancelRateManager, \ |
| | | GCancelBigNumComputer, SecondCancelBigNumComputer, HourCancelBigNumComputer, DCancelBigNumComputer |
| | | GCancelBigNumComputer, SCancelBigNumComputer, HourCancelBigNumComputer, DCancelBigNumComputer |
| | | from l2.l2_data_manager_new import L2TradeDataProcessor |
| | | from l2.l2_data_util import L2DataUtil, local_today_canceled_buyno_map |
| | | from l2.l2_transaction_data_manager import HuaXinTransactionDataManager |
| | | from l2.l2_data_util import L2DataUtil |
| | | from l2.l2_transaction_data_manager import HuaXinBuyOrderManager, HuaXinSellOrderStatisticManager |
| | | from log_module import async_log_util |
| | | from log_module.log import hx_logger_l2_debug, logger_l2_trade_buy_queue, logger_debug, hx_logger_l2_upload |
| | | from msg import push_msg_manager, buy_order_msg_manager |
| | | from msg import buy_order_msg_manager |
| | | from trade import current_price_process_manager, trade_manager |
| | | from trade.deal_big_money_manager import DealOrderNoManager |
| | | from utils import tool |
| | | |
| | | |
| | | class HuaXinTransactionDatasProcessor: |
| | |
| | | order_begin_pos = None |
| | | except Exception as e: |
| | | async_log_util.error(hx_logger_l2_debug, str(e)) |
| | | try: |
| | | # 统计卖单 |
| | | big_sell_order_info = HuaXinSellOrderStatisticManager.add_transaction_datas(code, datas) |
| | | need_cancel, cancel_msg = SCancelBigNumComputer().set_big_sell_order_info_for_cancel(code, |
| | | big_sell_order_info, |
| | | order_begin_pos) |
| | | if need_cancel: |
| | | async_log_util.error(logger_debug, f"{code} S前撤单:{cancel_msg}") |
| | | # L2TradeDataProcessor.cancel_buy(code, f"S后撤:{cancel_msg}") |
| | | |
| | | except Exception as e: |
| | | async_log_util.error(logger_debug, f"卖单统计异常:{str(e)}") |
| | | |
| | | # 计算已经成交的大单 |
| | | big_money_count = 0 |
| | |
| | | if data: |
| | | buy_num = data["val"]["num"] * 100 |
| | | # 统计成交单 |
| | | deal_info = HuaXinTransactionDataManager.statistic_deal_desc(code, d, buy_num) |
| | | deal_info = HuaXinBuyOrderManager.statistic_deal_desc(code, d, buy_num) |
| | | if deal_info and deal_info[1]: |
| | | data = buyno_map.get(f"{deal_info[0]}") |
| | | print("已经成交索引:", data["index"]) |
| | |
| | | |
| | | LCancelBigNumComputer().set_trade_progress(code, order_begin_pos.buy_single_index, buy_progress_index, |
| | | total_datas) |
| | | SecondCancelBigNumComputer().set_transaction_index( |
| | | code, |
| | | buy_progress_index) |
| | | if order_begin_pos and order_begin_pos.buy_exec_index and order_begin_pos.buy_exec_index > -1: |
| | | HourCancelBigNumComputer().set_transaction_index(code, order_begin_pos.buy_single_index, |
| | | buy_progress_index) |
| | |
| | | # if cresult[0] and not DCancelBigNumComputer().has_auto_cancel_rules(code): |
| | | # L2TradeDataProcessor.cancel_buy(code, f"下单30s内排单不足:{cresult[1]}") |
| | | |
| | | cresult = FCancelBigNumComputer().need_cancel_for_deal_fast_with_total_sell(code, buy_progress_index, order_begin_pos) |
| | | cresult = FCancelBigNumComputer().need_cancel_for_deal_fast_with_total_sell(code, |
| | | buy_progress_index, |
| | | order_begin_pos) |
| | | if cresult[0] and not DCancelBigNumComputer().has_auto_cancel_rules(code): |
| | | L2TradeDataProcessor.cancel_buy(code, f"3s内成交太多:{cresult[1]}") |
| | | |
| | | # ---------------------------------判断板块是否跟上来了------------------------------- |
| | | try: |
| | | pass |
| | | # order_begin_pos = l2_data_manager.TradePointManager().get_buy_compute_start_data_cache(code) |
| | | # volume_rate = 0 |
| | | # volume_info = L2TradeDataProcessor.volume_rate_info.get(code) |
| | | # if volume_info: |
| | | # volume_rate = volume_info[0] |
| | | # need_cancel, msg = UCancelBigNumComputer().need_cancel(code, buy_progress_index, order_begin_pos, |
| | | # kpl_data_manager.KPLLimitUpDataRecordManager.get_current_reason_codes_dict(), |
| | | # volume_rate) |
| | | # if need_cancel: |
| | | # L2TradeDataProcessor.cancel_buy(code, msg) |
| | | except Exception as e: |
| | | logger_debug.exception(e) |
| | | if buy_progress_index_changed: |
| | | # 交易进度变化,判断到真实下单位置的距离 |
| | | real_order_index = SecondCancelBigNumComputer().get_real_place_order_index_cache(code) |
| | | if real_order_index and real_order_index >= buy_progress_index: |
| | | # 发送下单消息 |
| | | try: |
| | | buy_order_msg_manager.almost_deal(code, real_order_index, buy_progress_index) |
| | | buy_order_msg_manager.follow_not_enough(code, order_begin_pos.buy_exec_index, |
| | | real_order_index) |
| | | except Exception as e: |
| | | logger_debug.exception(e) |
| | | # ---------------------------------成交进度位变化------------------------------- |
| | | # if buy_progress_index_changed: |
| | | # # 交易进度变化,判断到真实下单位置的距离 |
| | | # real_order_index = SCancelBigNumComputer().get_real_place_order_index_cache(code) |
| | | # if real_order_index and real_order_index >= buy_progress_index: |
| | | # # 发送下单消息 |
| | | # try: |
| | | # buy_order_msg_manager.almost_deal(code, real_order_index, buy_progress_index) |
| | | # buy_order_msg_manager.follow_not_enough(code, order_begin_pos.buy_exec_index, |
| | | # real_order_index) |
| | | # except Exception as e: |
| | | # logger_debug.exception(e) |
| | | else: |
| | | pass |
| | | if order_begin_pos and order_begin_pos.buy_exec_index and order_begin_pos.buy_exec_index > -1: |
| | |
| | | logger.add(self.get_hx_path("l2", "transaction"), |
| | | filter=lambda record: record["extra"].get("name") == "hx_l2_transaction", |
| | | rotation="00:00", compression="zip", enqueue=True) |
| | | |
| | | logger.add(self.get_hx_path("l2", "transaction_sell_order"), |
| | | filter=lambda record: record["extra"].get("name") == "hx_l2_transaction_sell_order", |
| | | rotation="00:00", compression="zip", enqueue=True) |
| | | |
| | | logger.add(self.get_hx_path("l2", "transaction_desc"), |
| | | filter=lambda record: record["extra"].get("name") == "hx_l2_transaction_desc", |
| | | rotation="00:00", compression="zip", enqueue=True) |
| | |
| | | # -------------------------------华鑫日志--------------------------------- |
| | | hx_logger_l2_orderdetail = __mylogger.get_logger("hx_l2_orderdetail") |
| | | hx_logger_l2_transaction = __mylogger.get_logger("hx_l2_transaction") |
| | | hx_logger_l2_transaction_sell_order = __mylogger.get_logger("hx_l2_transaction_sell_order") |
| | | hx_logger_l2_transaction_desc = __mylogger.get_logger("hx_l2_transaction_desc") |
| | | hx_logger_l2_market_data = __mylogger.get_logger("hx_l2_market_data") |
| | | hx_logger_l2_upload = __mylogger.get_logger("hx_l2_upload") |
| | |
| | | from third_data import kpl_util, kpl_data_manager, block_info |
| | | from third_data.code_plate_key_manager import LimitUpCodesPlateKeyManager, CodePlateKeyBuyManager |
| | | from third_data.kpl_data_manager import KPLDataManager |
| | | from trade import trade_data_manager, current_price_process_manager, l2_trade_util, trade_manager |
| | | from trade import trade_data_manager, current_price_process_manager, l2_trade_util, trade_manager, l2_trade_factor |
| | | import l2.l2_data_manager_new, l2.l2_data_manager, l2.l2_data_util, l2.cancel_buy_strategy |
| | | |
| | | |
| | |
| | | l2.l2_data_manager_new.L2TradeDataProcessor.process_add_datas(code, total_datas[indexs[0]:indexs[1] + 1], 0, |
| | | 0) |
| | | |
| | | @unittest.skip("跳过此单元测试") |
| | | def test_place_order(self): |
| | | code = "002241" |
| | | def test_s_cancel(self): |
| | | code = "603363" |
| | | l2.l2_data_util.load_l2_data(code) |
| | | total_datas = deepcopy(l2.l2_data_util.local_today_datas[code]) |
| | | huaxin_delegate_postion_manager.place_order(code, 17.36, 100, total_datas[753]) |
| | | huaxin_delegate_postion_manager.get_l2_place_order_position(code, total_datas[755:1038]) |
| | | l2.l2_data_util.local_today_datas[code] = l2.l2_data_util.local_today_datas[code][:222] |
| | | l2.cancel_buy_strategy.SCancelBigNumComputer().set_real_place_order_index(code, 153) |
| | | |
| | | TradeBuyQueue.get_traded_index = mock.Mock(return_value=(117, False)) |
| | | order_begin_pos = l2_data_manager.OrderBeginPosInfo(buy_single_index=117, buy_exec_index=122) |
| | | sell_order_info = [1517999, [[2996226, 300000, 5.06, (10223471, 4876395), (10223471, 4876395)]]] |
| | | l2.cancel_buy_strategy.SCancelBigNumComputer().set_big_sell_order_info_for_cancel(code, sell_order_info, |
| | | order_begin_pos) |
| | | |
| | | sell_order_info = [508507, [[5564445, 100100, 5.08, (10372994, 4876545), (10372994, 4876546)]]] |
| | | l2.cancel_buy_strategy.SCancelBigNumComputer().set_big_sell_order_info_for_cancel(code, sell_order_info, |
| | | order_begin_pos) |
| | | l2.cancel_buy_strategy.SCancelBigNumComputer().set_big_sell_order_info_for_cancel(code, sell_order_info, |
| | | order_begin_pos) |
| | | l2.cancel_buy_strategy.SCancelBigNumComputer().need_cancel_for_down(code, 154, 222) |
| | | |
| | | @unittest.skip("跳过此单元测试") |
| | | def test_h_cancel(self): |
| | |
| | | from huaxin_client.trade_transform_protocol import TradeResponse |
| | | from l2 import l2_data_manager_new, l2_log, code_price_manager, l2_data_util, l2_data_manager, transaction_progress, \ |
| | | l2_data_source_util, cancel_buy_strategy |
| | | from l2.cancel_buy_strategy import LCancelBigNumComputer, GCancelBigNumComputer, SecondCancelBigNumComputer, \ |
| | | from l2.cancel_buy_strategy import LCancelBigNumComputer, GCancelBigNumComputer, SCancelBigNumComputer, \ |
| | | LCancelRateManager, DCancelBigNumComputer |
| | | from l2.code_price_manager import Buy1PriceManager |
| | | from l2.huaxin import huaxin_target_codes_manager |
| | |
| | | from l2.l2_data_manager import TradePointManager |
| | | from l2.l2_data_util import L2DataUtil |
| | | from l2.l2_sell_manager import L2MarketSellManager |
| | | from l2.l2_transaction_data_manager import HuaXinTransactionDataManager |
| | | from l2.l2_transaction_data_manager import HuaXinBuyOrderManager |
| | | from l2.l2_transaction_data_processor import HuaXinTransactionDatasProcessor |
| | | from log_module import async_log_util, log_export |
| | | from log_module.log import hx_logger_contact_debug, hx_logger_trade_callback, \ |
| | |
| | | continue |
| | | trade_index, is_default = transaction_progress.TradeBuyQueue().get_traded_index(code) |
| | | # 下单位置 |
| | | place_order_index = SecondCancelBigNumComputer().get_real_place_order_index_cache(code) |
| | | place_order_index = SCancelBigNumComputer().get_real_place_order_index_cache(code) |
| | | |
| | | # 获取剩下的笔数 |
| | | total_left_num = 0 |
| | |
| | | trade_index, is_default = transaction_progress.TradeBuyQueue().get_traded_index(code) |
| | | trade_speed = transaction_progress.TradeBuyQueue().get_trade_speed(code) |
| | | # 下单位置 |
| | | place_order_index = SecondCancelBigNumComputer().get_real_place_order_index_cache(code) |
| | | place_order_index = SCancelBigNumComputer().get_real_place_order_index_cache(code) |
| | | fdata = {} |
| | | if trade_index and place_order_index: |
| | | # 有成交进度位与下单位 |
| | |
| | | if trade_index is None: |
| | | trade_index = 0 |
| | | # 下单位置 |
| | | place_order_index = SecondCancelBigNumComputer().get_real_place_order_index_cache(code) |
| | | place_order_index = SCancelBigNumComputer().get_real_place_order_index_cache(code) |
| | | # 计算信号位置到真实下单位置的总买(不管是否已撤) |
| | | total_nums = 0 |
| | | for i in range(order_begin_pos.buy_single_index, place_order_index): |
| | |
| | | total_left_count += left_count |
| | | total_left_num += val["num"] * left_count |
| | | # 获取正在成交 |
| | | dealing_info = HuaXinTransactionDataManager.get_dealing_order_info(code) |
| | | dealing_info = HuaXinBuyOrderManager.get_dealing_order_info(code) |
| | | if dealing_info: |
| | | if str(total_datas[trade_index]["val"]["orderNo"]) == str(dealing_info[0]): |
| | | total_left_num += (total_datas[trade_index]["val"]["num"] - dealing_info[1] // 100) |
| | |
| | | |
| | | from code_attribute.gpcode_manager import MustBuyCodesManager |
| | | from l2 import l2_data_manager |
| | | from l2.cancel_buy_strategy import HourCancelBigNumComputer, SecondCancelBigNumComputer, \ |
| | | from l2.cancel_buy_strategy import HourCancelBigNumComputer, SCancelBigNumComputer, \ |
| | | LCancelBigNumComputer, DCancelBigNumComputer, GCancelBigNumComputer, FCancelBigNumComputer |
| | | from l2.l2_data_manager import OrderBeginPosInfo |
| | | from l2.l2_data_util import local_today_datas, local_today_num_operate_map, L2DataUtil |
| | |
| | | # 虚拟撤成功 |
| | | def virtual_cancel_success(code, buy_single_index, buy_exec_index, total_datas): |
| | | l2_data_manager.TradePointManager().delete_buy_point(code) |
| | | SecondCancelBigNumComputer().cancel_success(code) |
| | | SCancelBigNumComputer().cancel_success(code) |
| | | LCancelBigNumComputer().cancel_success(code) |
| | | GCancelBigNumComputer().cancel_success(code) |
| | | # dask.compute(f1, f2, f5, f6, f7, f8) |
| | |
| | | |
| | | def s_cancel(code): |
| | | try: |
| | | SecondCancelBigNumComputer().place_order_success(code) |
| | | SCancelBigNumComputer().place_order_success(code) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | | logger_l2_error.exception(e) |
| | |
| | | def real_cancel_success(code, buy_single_index, buy_exec_index, total_datas): |
| | | # 取消买入标识 |
| | | l2_data_manager.TradePointManager().delete_buy_point(code) |
| | | SecondCancelBigNumComputer().cancel_success(code) |
| | | SCancelBigNumComputer().cancel_success(code) |
| | | LCancelBigNumComputer().cancel_success(code) |
| | | FCancelBigNumComputer().cancel_success(code) |
| | | GCancelBigNumComputer().cancel_success(code) |
| | |
| | | return int(ts[0]) * 3600 + int(ts[1]) * 60 + int(ts[2]) |
| | | |
| | | |
| | | def get_time_as_millionsecond(time_str): |
| | | s_str,ms_str = time_str.split(".") |
| | | ts = s_str.split(":") |
| | | return int(ts[0]) * 3600 + int(ts[1]) * 60 + int(ts[2])*1000 + int(ms_str) |
| | | |
| | | |
| | | # 将秒数格式化为时间 |
| | | def time_seconds_format(seconds): |
| | | h = seconds // 3600 |
| | | m = seconds % 3600 // 60 |
| | | s = seconds % 60 |
| | | return "{0:0>2}:{1:0>2}:{2:0>2}".format(h, m, s) |
| | | |
| | | |
| | | def time_millionseconds_format(millionseconds): |
| | | ms = millionseconds % 1000 |
| | | seconds = millionseconds // 1000 |
| | | h = seconds // 3600 |
| | | m = seconds % 3600 // 60 |
| | | s = seconds % 60 |
| | | return "{0:0>2}:{1:0>2}:{2:0>2}.{3:0>3}".format(h, m, s, ms) |
| | | |
| | | |
| | | # 交易時間的差值 |
| | |
| | | time_2 = time_2 - 90 * 60 |
| | | elif time_2 < split_time < time_1: |
| | | time_2 = time_2 + 90 * 60 |
| | | |
| | | return time_1 - time_2 |
| | | |
| | | def trade_time_sub_with_ms(time_str_1, time_str_2): |
| | | split_time = get_time_as_second("11:30:00")*1000 |
| | | time_1 = get_time_as_millionsecond(time_str_1) |
| | | time_2 = get_time_as_millionsecond(time_str_2) |
| | | if time_1 < split_time < time_2: |
| | | time_2 = time_2 - 90 * 60*1000 |
| | | elif time_2 < split_time < time_1: |
| | | time_2 = time_2 + 90 * 60*1000 |
| | | |
| | | return time_1 - time_2 |
| | | |
| | |
| | | if s >= 11 * 3600 + 30 * 60 > s_: |
| | | s += 90 * 60 |
| | | return time_seconds_format(s) |
| | | |
| | | |
| | | def trade_time_add_millionsecond(time_str, millionsecond): |
| | | s_str, ms_str = time_str.split(".") |
| | | ts = s_str.split(":") |
| | | s_ = int(ts[0]) * 3600 + int(ts[1]) * 60 + int(ts[2]) |
| | | ms_ = s_ * 1000 |
| | | ms_ += int(ms_str) |
| | | ms = ms_ + millionsecond |
| | | # 是否在11:30:00 |
| | | if ms >= 11 * 3600 * 1000 + 30 * 60 * 1000 > ms_: |
| | | ms += 90 * 60 * 1000 |
| | | return time_millionseconds_format(ms) |
| | | |
| | | |
| | | def compute_buy1_real_time(time_): |
| | |
| | | if count < 100: |
| | | count = 100 |
| | | return count |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | print(trade_time_add_millionsecond("10:36:00.123", 1000)) |
| | | print(trade_time_add_millionsecond("11:29:59.123", 1888)) |