| | |
| | | from l2.l2_transaction_data_manager import HuaXinTransactionDataManager |
| | | from log_module import async_log_util |
| | | from trade.deal_big_money_manager import DealOrderNoManager |
| | | from trade.sell.sell_rule_manager import TradeRuleManager |
| | | from utils import tool |
| | | from l2.transaction_progress import TradeBuyQueue |
| | | from trade import trade_queue_manager, l2_trade_factor, trade_record_log_util |
| | |
| | | class DCancelBigNumComputer: |
| | | __db = 0 |
| | | __redis_manager = redis_manager.RedisManager(0) |
| | | __cancel_real_order_index_cache = {} |
| | | |
| | | __instance = None |
| | | |
| | |
| | | def __load_datas(cls): |
| | | __redis = cls.__get_redis() |
| | | try: |
| | | keys = RedisUtils.keys(__redis, "d_cancel_real_order_index-*") |
| | | for k in keys: |
| | | code = k.split("-")[-1] |
| | | val = RedisUtils.get(__redis, k) |
| | | CodeDataCacheUtil.set_cache(cls.__cancel_real_order_index_cache, code, int(val)) |
| | | pass |
| | | finally: |
| | | RedisUtils.realse(__redis) |
| | | |
| | |
| | | def __get_redis(cls): |
| | | return cls.__redis_manager.getRedis() |
| | | |
| | | def __set_real_order_index(self, code, index): |
| | | CodeDataCacheUtil.set_cache(self.__cancel_real_order_index_cache, code, index) |
| | | RedisUtils.setex_async(self.__db, f"d_cancel_real_order_index-{code}", tool.get_expire(), f"{index}") |
| | | # 是否有撤买的规则 |
| | | def has_auto_cancel_rules(self, code): |
| | | rules = self.get_auto_cancel_rules(code) |
| | | return True if rules else False |
| | | |
| | | def __del_real_order_index(self, code): |
| | | CodeDataCacheUtil.clear_cache(self.__cancel_real_order_index_cache, code) |
| | | RedisUtils.delete_async(self.__db, f"d_cancel_real_order_index-{code}") |
| | | def get_auto_cancel_rules(self, code): |
| | | rules = TradeRuleManager().list_can_excut_rules_cache([TradeRuleManager.TYPE_BUY_CANCEL], code) |
| | | return rules |
| | | |
| | | def __get_real_order_index(self, code): |
| | | val = RedisUtils.get(self.__db, f"d_cancel_real_order_index-{code}") |
| | | if val: |
| | | return int(val) |
| | | return None |
| | | |
| | | def __get_real_order_index_cache(self, code): |
| | | cache_result = CodeDataCacheUtil.get_cache(self.__cancel_real_order_index_cache, code) |
| | | if cache_result[0]: |
| | | return cache_result[1] |
| | | return None |
| | | |
| | | def clear(self, code=None): |
| | | if code: |
| | | self.__del_real_order_index(code) |
| | | else: |
| | | keys = RedisUtils.keys(self.__get_redis(), "d_cancel_real_order_index-*") |
| | | if keys: |
| | | for k in keys: |
| | | code = k.replace("d_cancel_real_order_index-", "") |
| | | self.__del_real_order_index(code) |
| | | |
| | | # 设置成交位 |
| | | def set_trade_progress(self, code, index, buy_exec_index, total_data, m_base_value, |
| | | limit_up_price): |
| | | # 离下单执行位2分钟内的有效 |
| | | sub_time = tool.trade_time_sub(total_data[-1]['val']['time'], total_data[buy_exec_index]['val']['time']) |
| | | if sub_time > constant.D_CANCEL_EXPIRE_TIME or sub_time < constant.D_CANCEL_START_TIME: |
| | | return False, "超过D撤守护时间" |
| | | |
| | | real_order_index = self.__get_real_order_index_cache(code) |
| | | if not real_order_index: |
| | | return False, "尚未获取到真实下单位置" |
| | | |
| | | left_num = 0 |
| | | for i in range(index + 1, real_order_index): |
| | | 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_v2(code, i, |
| | | total_data, |
| | | local_today_canceled_buyno_map.get( |
| | | code)) |
| | | left_num += val['num'] * left_count |
| | | # 剩下的不足动态M值的1/2 |
| | | rate = round(float(limit_up_price) * left_num * 100 / m_base_value, 3) |
| | | l2_log.d_cancel_debug(code, |
| | | f"成交进度({index})到下单位置({real_order_index})的剩余笔数:{left_num},撤单比例:{rate},m值:{m_base_value}") |
| | | if rate < constant.D_CANCEL_RATE: |
| | | l2_log.cancel_debug(code, "D撤撤单,比例为:{},目标比例{}", rate, constant.D_CANCEL_RATE) |
| | | return True, f"D撤比例为:{rate}" |
| | | return False, "" |
| | | |
| | | # 设置真实的下单位置 |
| | | def set_real_order_index(self, code, index): |
| | | self.__set_real_order_index(code, index) |
| | | l2_log.d_cancel_debug(code, f"下单位置设置:{index}") |
| | | |
| | | def place_order_success(self, code): |
| | | self.clear(code) |
| | | |
| | | def cancel_success(self, code): |
| | | self.clear(code) |
| | | def need_cancel(self, code, buy1_volume): |
| | | rules = self.get_auto_cancel_rules(code) |
| | | if rules: |
| | | for r in rules: |
| | | if r.buy1_volume >= buy1_volume: |
| | | # 量低于 |
| | | return True, r.id_ |
| | | return False, None |
| | | |
| | | |
| | | # ---------------------------------L撤------------------------------- |
| | |
| | | |
| | | def __set_real_order_index(self, code, index, is_default): |
| | | CodeDataCacheUtil.set_cache(self.__real_order_index_cache, code, (index, is_default)) |
| | | RedisUtils.setex_async(self.__db, f"f_cancel_real_order_index-{code}", tool.get_expire(), json.dumps((index, is_default))) |
| | | RedisUtils.setex_async(self.__db, f"f_cancel_real_order_index-{code}", tool.get_expire(), |
| | | json.dumps((index, is_default))) |
| | | |
| | | def __del_real_order_index(self, code): |
| | | CodeDataCacheUtil.clear_cache(self.__real_order_index_cache, code) |
| | |
| | | # 统计未撤订单的数量与金额 |
| | | total_datas = local_today_datas.get(code) |
| | | # 是否是下单5分钟内 |
| | | if tool.trade_time_sub(tool.get_now_time_str(),total_datas[real_order_index]['val']['time']) > 5*60: |
| | | if tool.trade_time_sub(tool.get_now_time_str(), total_datas[real_order_index]['val']['time']) > 5 * 60: |
| | | return False, "下单超过5分钟" |
| | | |
| | | total_left_count = 0 |
| | |
| | | total_left_count += left_count |
| | | total_left_num += val["num"] * left_count |
| | | limit_up_price = gpcode_manager.get_limit_up_price(code) |
| | | if total_left_count < 10 and limit_up_price and total_left_num * float(limit_up_price) < 1000*100: |
| | | return True, f"剩余笔数({total_left_count})/金额({round(total_left_num * float(limit_up_price)*100)})不足,成交进度:{trade_index},真实下单位置:{real_order_index}" |
| | | if total_left_count < 10 and limit_up_price and total_left_num * float(limit_up_price) < 1000 * 100: |
| | | return True, f"剩余笔数({total_left_count})/金额({round(total_left_num * float(limit_up_price) * 100)})不足,成交进度:{trade_index},真实下单位置:{real_order_index}" |
| | | return False, "不满足撤单条件" |
| | | |
| | | |
| | | |
| | | |
| | | |
| | | # ---------------------------------G撤------------------------------- |