| | |
| | | def get_max_volume_in_5days(self, code): |
| | | return self.__max_volume_in_5days.get(code) |
| | | |
| | | def get_volume_rate_refer_in_5days(self, code): |
| | | def get_volume_rate_refer_in_5days(self, code, total_sell_volume=0): |
| | | """ |
| | | 获取今日量与5日最大量的参考值 |
| | | @param total_sell_volume: 当前总卖量 |
| | | @param code: |
| | | @return: |
| | | """ |
| | |
| | | if not max_volume: |
| | | return 0 |
| | | today_volume = self.get_today_volumn(code) |
| | | return round(today_volume / max_volume, 2) |
| | | return round((today_volume + total_sell_volume) / max_volume, 2) |
| | | |
| | | # 获取历史量 |
| | | def get_histry_volumn(self, code): |
| | |
| | | |
| | | except Exception as e1: |
| | | logging.exception(e1) |
| | | pass |
| | | time.sleep(1) |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | |
| | | g_SubBondMarketData = False |
| | | g_SubBondTransaction = False |
| | | g_SubBondOrderDetail = False |
| | | set_codes_data_queue = queue.Queue() |
| | | set_codes_data_queue = queue.Queue(maxsize=10240) |
| | | market_code_dict = {} |
| | | |
| | | ENABLE_NGST = True |
| | |
| | | self.__big_buy_orders = [] |
| | | self.__latest_sell_order = None |
| | | self.__big_sell_orders = [] |
| | | self.big_buy_order_queue = queue.Queue() |
| | | self.big_sell_order_queue = queue.Queue() |
| | | self.big_buy_order_queue = queue.Queue(maxsize=10240) |
| | | self.big_sell_order_queue = queue.Queue(maxsize=10240) |
| | | |
| | | def get_big_buy_orders(self): |
| | | return self.__big_buy_orders |
| | |
| | | self.__clear_data(code) |
| | | |
| | | |
| | | # ---------------------------------RD撤------------------------------- |
| | | # 扫入下单大单撤 |
| | | class RDCancelBigNumComputer: |
| | | __db = 0 |
| | | __redis_manager = redis_manager.RedisManager(0) |
| | | |
| | | __instance = None |
| | | |
| | | # 下单位之后的封单中的大单 |
| | | __watch_indexes_cache = {} |
| | | |
| | | def __new__(cls, *args, **kwargs): |
| | | if not cls.__instance: |
| | | cls.__instance = super(RDCancelBigNumComputer, cls).__new__(cls, *args, **kwargs) |
| | | cls.__load_datas() |
| | | return cls.__instance |
| | | |
| | | @classmethod |
| | | def __get_redis(cls): |
| | | return cls.__redis_manager.getRedis() |
| | | |
| | | @classmethod |
| | | def __load_datas(cls): |
| | | keys = RedisUtils.keys(cls.__get_redis(), "radical_big_order_watch-*") |
| | | for k in keys: |
| | | code = k.split("-")[1] |
| | | val = RedisUtils.get(cls.__get_redis(), k) |
| | | val = json.loads(val) |
| | | cls.__watch_indexes_cache[code] = set(val) |
| | | |
| | | def set_watch_indexes(self, code, indexes): |
| | | l2_log.d_cancel_debug(code, f"扫入大单监听:{indexes}") |
| | | self.__watch_indexes_cache[code] = set(indexes) |
| | | RedisUtils.setex_async(self.__db, f"radical_big_order_watch-{code}", tool.get_expire(), |
| | | json.dumps(list(indexes))) |
| | | |
| | | def need_cancel(self, code, start_index, end_index): |
| | | """ |
| | | 是否需要撤单 |
| | | @param code: |
| | | @param start_index: |
| | | @param end_index: |
| | | @return: 是否需要撤单,撤单索引, 消息 |
| | | """ |
| | | watch_indexes = self.__watch_indexes_cache.get(code) |
| | | if not watch_indexes: |
| | | return False,None, "无大单监听" |
| | | total_datas = local_today_datas.get(code) |
| | | 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["num"] * float(val["price"]) < 5000: |
| | | 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 None: |
| | | continue |
| | | if buy_index in watch_indexes: |
| | | return True, data, f"大单撤单({buy_index})" |
| | | return False,None, "无大单撤单" |
| | | |
| | | |
| | | def __clear_data(self, code): |
| | | if code in self.__watch_indexes_cache: |
| | | self.__watch_indexes_cache.pop(code) |
| | | RedisUtils.delete_async(self.__db, f"radical_big_order_watch-{code}") |
| | | |
| | | def clear_data(self, code): |
| | | self.__clear_data(code) |
| | | |
| | | |
| | | # 新F撤,根据成交数据来撤 |
| | | class FCancelBigNumComputer: |
| | | __db = 0 |
| | |
| | | transaction_progress, cancel_buy_strategy, place_order_single_data_manager |
| | | from l2.cancel_buy_strategy import DCancelBigNumComputer, \ |
| | | LatestCancelIndexManager, \ |
| | | NewGCancelBigNumComputer, JCancelBigNumComputer, L2DataComputeUtil |
| | | NewGCancelBigNumComputer, JCancelBigNumComputer, L2DataComputeUtil, RDCancelBigNumComputer |
| | | 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, \ |
| | | local_latest_datas, local_today_canceled_buyno_map, local_today_sellno_map |
| | |
| | | f"J撤出错 参数:buy_single_index-{_buy_single_index} buy_exec_index-{_buy_exec_index} 错误原因:{str(e)}") |
| | | return None, "" |
| | | |
| | | # RD撤 |
| | | def rd_cancel(_buy_single_index, _buy_exec_index): |
| | | try: |
| | | b_need_cancel, b_cancel_data, extra_msg = RDCancelBigNumComputer().need_cancel(code, start_index, |
| | | end_index) |
| | | if b_need_cancel and b_cancel_data: |
| | | return b_cancel_data, f"RD撤({extra_msg})", trade_constant.CANCEL_TYPE_RD |
| | | except Exception as e: |
| | | async_log_util.error(logger_l2_error, |
| | | f"RD撤出错 参数:buy_single_index-{_buy_single_index} buy_exec_index-{_buy_exec_index} 错误原因:{str(e)}") |
| | | return None, "", trade_constant.CANCEL_TYPE_RD |
| | | |
| | | if start_index < 0: |
| | | start_index = 0 |
| | | |
| | |
| | | if order_begin_pos.buy_volume_rate is None: |
| | | order_begin_pos.buy_volume_rate = 0.2 |
| | | cancel_data, cancel_msg, cancel_type = None, "", None |
| | | if not cancel_data: |
| | | cancel_data, cancel_msg = g_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index) |
| | | cancel_type = trade_constant.CANCEL_TYPE_G |
| | | # 依次处理 |
| | | if not cancel_data: |
| | | cancel_data, cancel_msg, cancel_type = l_cancel(order_begin_pos.buy_single_index, |
| | | order_begin_pos.buy_exec_index) |
| | | # B撤 |
| | | if not cancel_data: |
| | | cancel_data, cancel_msg = b_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index) |
| | | cancel_type = trade_constant.CANCEL_TYPE_G |
| | | if not cancel_data: |
| | | cancel_data, cancel_msg = h_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index) |
| | | cancel_type = trade_constant.CANCEL_TYPE_H |
| | | # J撤 |
| | | if not cancel_data: |
| | | cancel_data, cancel_msg = j_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index) |
| | | cancel_type = trade_constant.CANCEL_TYPE_J |
| | | if order_begin_pos.mode == OrderBeginPosInfo.MODE_RADICAL: |
| | | |
| | | if not cancel_data: |
| | | cancel_data, cancel_msg, cancel_type = rd_cancel(order_begin_pos.buy_single_index, |
| | | order_begin_pos.buy_exec_index) |
| | | |
| | | # 扫入下单只有L撤 |
| | | if not cancel_data: |
| | | cancel_data, cancel_msg, cancel_type = l_cancel(order_begin_pos.buy_single_index, |
| | | order_begin_pos.buy_exec_index) |
| | | else: |
| | | if not cancel_data: |
| | | cancel_data, cancel_msg = g_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index) |
| | | cancel_type = trade_constant.CANCEL_TYPE_G |
| | | # 依次处理 |
| | | if not cancel_data: |
| | | cancel_data, cancel_msg, cancel_type = l_cancel(order_begin_pos.buy_single_index, |
| | | order_begin_pos.buy_exec_index) |
| | | # B撤 |
| | | if not cancel_data: |
| | | cancel_data, cancel_msg = b_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index) |
| | | cancel_type = trade_constant.CANCEL_TYPE_G |
| | | if not cancel_data: |
| | | cancel_data, cancel_msg = h_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index) |
| | | cancel_type = trade_constant.CANCEL_TYPE_H |
| | | # J撤 |
| | | if not cancel_data: |
| | | cancel_data, cancel_msg = j_cancel(order_begin_pos.buy_single_index, order_begin_pos.buy_exec_index) |
| | | cancel_type = trade_constant.CANCEL_TYPE_J |
| | | |
| | | if cancel_data and not DCancelBigNumComputer().has_auto_cancel_rules(code): |
| | | l2_log.debug(code, "触发撤单,撤单位置:{} ,撤单原因:{}", cancel_data["index"], cancel_msg) |
| | |
| | | l2_log.debug(code, "处理买入成功2") |
| | | params_desc = cls.__l2PlaceOrderParamsManagerDict[code].get_buy_rank_desc() |
| | | l2_log.debug(code, params_desc) |
| | | #################清除本次下单的大单数据############### |
| | | EveryLimitupBigDealOrderManager.clear(code) |
| | | ############记录下单时的数据############ |
| | | try: |
| | | jx_blocks, jx_blocks_by = KPLCodeJXBlockManager().get_jx_blocks_cache( |
| | |
| | | can, need_clear_data, reason, is_valid_exec_index = True, False, "扫入下单", True |
| | | else: |
| | | return False |
| | | #can, need_clear_data, reason, is_valid_exec_index = cls.__can_buy_first(code) |
| | | # can, need_clear_data, reason, is_valid_exec_index = cls.__can_buy_first(code) |
| | | |
| | | # 删除虚拟下单 |
| | | if code in cls.unreal_buy_dict: |
| | |
| | | # 是否是交易队列触发 |
| | | # 扫入下单只有L撤能撤单 |
| | | if order_begin_pos and order_begin_pos.mode == OrderBeginPosInfo.MODE_RADICAL and cancel_type not in { |
| | | trade_constant.CANCEL_TYPE_L_DOWN, trade_constant.CANCEL_TYPE_L}: |
| | | trade_constant.CANCEL_TYPE_L_DOWN, trade_constant.CANCEL_TYPE_L, trade_constant.CANCEL_TYPE_RD}: |
| | | l2_log.cancel_debug(code, "撤单中断,原因:{}", "扫入下单不是L撤") |
| | | return False |
| | | # 加绿只有L撤/人撤生效 |
| | |
| | | block_info=radical_result[3]) |
| | | if ordered: |
| | | radical_buy_data_manager.BlockPlaceOrderRecordManager().add_record(code, radical_result[2]) |
| | | # 监听大单 |
| | | RDCancelBigNumComputer().set_watch_indexes(code, radical_result[4]) |
| | | return |
| | | |
| | | if RadicalBuyDealCodesManager.radical_buy_blocks_dict.get(code): |
| | | if RadicalBuyDealCodesManager().get_code_blocks(code): |
| | | # 已经扫入下过单 |
| | | return |
| | | |
| | | if not constant.CAN_COMMON_BUY: |
| | |
| | | @param code: |
| | | @param start_index: |
| | | @param end_index: |
| | | @return: (是否获取到信号, 信号位置, 扫入板块/消息, 扫入板块大单流入信息) |
| | | @return: (是否获取到信号, 信号位置, 扫入板块/消息, 扫入板块大单流入信息, 需要监听的大单) |
| | | """ |
| | | |
| | | # 激进买信号的时间 |
| | |
| | | def __can_order(): |
| | | # 判断是否是板上放量 |
| | | if cls.__is_at_limit_up_buy(code, start_index): |
| | | return False, None, "板上放量" |
| | | return False, None, "板上放量", None |
| | | total_datas = local_today_datas[code] |
| | | limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) |
| | | bigger_money = l2_data_util.get_big_money_val(limit_up_price, tool.is_ge_code(code)) |
| | |
| | | |
| | | if constant.CAN_RADICAL_BUY_NEED_BIG_ORDER_EVERYTIME: |
| | | # 每次下单都需要大单 |
| | | total_deal_money = EveryLimitupBigDealOrderManager.get_big_buy_deal_order_money(code) |
| | | current_big_order_deal_money_info = EveryLimitupBigDealOrderManager.get_big_buy_deal_order_money_info( |
| | | code) |
| | | if current_big_order_deal_money_info: |
| | | total_deal_money = current_big_order_deal_money_info[0] |
| | | if current_big_order_deal_money_info and tool.trade_time_sub(tool.get_now_time_str(), |
| | | current_big_order_deal_money_info[1]) > 60: |
| | | # 60s以上的大单不看 |
| | | total_deal_money = 0 |
| | | else: |
| | | # 只需要总成交的大单 |
| | | total_deal_money = BigOrderDealManager().get_total_buy_money(code) |
| | |
| | | THRESHOLD_MONEY = 2990000 |
| | | if total_deal_money >= THRESHOLD_MONEY: |
| | | min_num = int(5000 / limit_up_price) |
| | | |
| | | # 需要监听的大单 |
| | | watch_indexes = set() |
| | | # 总委托大单金额 |
| | | total_delegating_big_money = 0 |
| | | single_index = None |
| | |
| | | order_money = dealing_active_order_info[2] + round(val["price"], 2) * val["num"] * 100 |
| | | if order_money >= bigger_money: |
| | | total_delegating_big_money += order_money |
| | | watch_indexes.add(i) |
| | | if total_delegating_big_money + total_deal_money >= THRESHOLD_MONEY: |
| | | single_index = i |
| | | break |
| | |
| | | if int(val["orderNo"]) <= radical_data[1]: |
| | | # 主动买单后的数据不算 |
| | | continue |
| | | |
| | | watch_indexes.add(i) |
| | | total_delegating_big_money += round(val["price"], 2) * val["num"] * 100 |
| | | if total_delegating_big_money + total_deal_money >= THRESHOLD_MONEY: |
| | | single_index = i |
| | | break |
| | | if single_index is not None: |
| | | return True, single_index, "有大单" |
| | | return False, None, "无大单" |
| | | return True, single_index, "有大单", watch_indexes |
| | | return False, None, "无大单", watch_indexes |
| | | |
| | | radical_data = RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict.get(code) |
| | | record_codes = radical_buy_data_manager.BlockPlaceOrderRecordManager().get_codes() |
| | |
| | | # 如果板上放量不可买入就需要删除信号 |
| | | if not constant.CAN_RADICAL_BUY_AT_LIMIT_UP and code in RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict: |
| | | RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict.pop(code) |
| | | return True, result[1], radical_data[2], radical_data[3] |
| | | return True, result[1], radical_data[2], radical_data[3], result[3] |
| | | return result |
| | | |
| | | @classmethod |
| | |
| | | # data['SellNo'], data['ExecType'])) |
| | | |
| | | if code not in cls.__dealing_order_info_dict: |
| | | # 数据格式[订单号,总股数,成交金额,成交开始时间,成交结束时间, 最近的成交价格] |
| | | cls.__dealing_order_info_dict[code] = [data[6], data[2], data[2] * data[1], data[3], data[3], data[1]] |
| | | # 数据格式[订单号,总股数,成交金额,成交开始时间,成交结束时间, 最近的成交价格, 最近的卖单号] |
| | | cls.__dealing_order_info_dict[code] = [data[6], data[2], data[2] * data[1], data[3], data[3], data[1], data[7]] |
| | | else: |
| | | if cls.__dealing_order_info_dict[code][0] == data[6]: |
| | | # 成交同一个订单号 |
| | |
| | | cls.__dealing_order_info_dict[code][2] += data[2] * data[1] |
| | | cls.__dealing_order_info_dict[code][4] = data[3] |
| | | cls.__dealing_order_info_dict[code][5] = data[1] |
| | | cls.__dealing_order_info_dict[code][6] = data[7] |
| | | else: |
| | | # 保存上一条数据 |
| | | async_log_util.info(hx_logger_l2_transaction_desc, f"{code}#{cls.__dealing_order_info_dict[code]}") |
| | |
| | | |
| | | # 初始化本条数据 |
| | | cls.__dealing_order_info_dict[code] = [data[6], data[2], data[2] * data[1], data[3], data[3], |
| | | data[1]] |
| | | data[1], data[7]] |
| | | # 统计主动买(买单号大于卖单号) |
| | | try: |
| | | if data[6] > data[7]: |
| | |
| | | buy_datas, bigger_buy_datas = HuaXinBuyOrderManager.statistic_big_buy_data(code, datas, limit_up_price) |
| | | if buy_datas: |
| | | BigOrderDealManager().add_buy_datas(code, buy_datas) |
| | | EveryLimitupBigDealOrderManager.add_big_buy_order_deal(code, [(x[0], x[2]) for x in buy_datas]) |
| | | active_big_buy_orders = [] |
| | | if buy_datas: |
| | | for x in buy_datas: |
| | | if x[0] > x[6]: |
| | | # (买单号, 成交金额, 最后成交时间) |
| | | active_big_buy_orders.append((x[0], x[2], x[4])) |
| | | EveryLimitupBigDealOrderManager.add_big_buy_order_deal(code, active_big_buy_orders) |
| | | try: |
| | | is_placed_order = l2_data_manager.TradePointManager.is_placed_order(order_begin_pos) |
| | | if is_placed_order: |
| | |
| | | from l2 import l2_data_manager_new, l2_log, code_price_manager, l2_data_util, transaction_progress, \ |
| | | l2_data_source_util, l2_data_log |
| | | from l2.cancel_buy_strategy import GCancelBigNumComputer, \ |
| | | DCancelBigNumComputer |
| | | DCancelBigNumComputer, RDCancelBigNumComputer |
| | | from l2.code_price_manager import Buy1PriceManager |
| | | from l2.huaxin import huaxin_target_codes_manager, l2_huaxin_util |
| | | from l2.huaxin.huaxin_target_codes_manager import HuaXinL1TargetCodesManager |
| | |
| | | from api.outside_api_command_callback import OutsideApiCommandCallback |
| | | from trade.huaxin.huaxin_trade_record_manager import DelegateRecordManager |
| | | from trade.order_statistic import DealAndDelegateWithBuyModeDataManager |
| | | from trade.buy_radical.radical_buy_data_manager import RadicalBuyDataManager, RadicalBuyBlockManager |
| | | from trade.buy_radical.radical_buy_data_manager import RadicalBuyDataManager, RadicalBuyBlockManager, \ |
| | | EveryLimitupBigDealOrderManager |
| | | from trade.sell.sell_rule_manager import TradeRuleManager |
| | | from trade.trade_data_manager import RadicalBuyDealCodesManager |
| | | from trade.trade_manager import CodesTradeStateManager |
| | |
| | | except Exception as e: |
| | | logger_debug.exception(e) |
| | | |
| | | def OnLimitUpActiveBuy(self, code, transaction_datas): |
| | | def __process_limit_up_active_buy(self, code, transaction_datas): |
| | | """ |
| | | 处理涨停主动买 |
| | | @param code: |
| | | @param transaction_datas: |
| | | @return: 是否清除本次上板数据 |
| | | """ |
| | | __start_time = time.time() |
| | | try: |
| | | # 判断是否处于可下单状态 |
| | | state = CodesTradeStateManager().get_trade_state_cache(code) |
| | | if not trade_util.is_can_order_by_state(state): |
| | | # 不处于可下单状态 |
| | | return |
| | | return True |
| | | |
| | | # 判断最近60个交易日有无涨停 |
| | | # 判断昨日是否涨停过 |
| | | async_log_util.info(logger_l2_radical_buy, f"涨停主动买:{code}-{transaction_datas[-1]}") |
| | | deal_codes = RadicalBuyDealCodesManager().get_deal_codes() |
| | | # 判断今日扫入的代码数量是否大于阈值 |
| | |
| | | MAX_COUNT = 4 if radical_buy_setting is None else radical_buy_setting[0] |
| | | if len(deal_codes) >= MAX_COUNT: |
| | | async_log_util.info(logger_l2_radical_buy, f"扫入成交代码个数大于{MAX_COUNT}个:{code}-{deal_codes}") |
| | | return |
| | | |
| | | return True |
| | | if code in deal_codes: |
| | | async_log_util.info(logger_l2_radical_buy, f"该代码已经成交:{code}") |
| | | return |
| | | return True |
| | | |
| | | # 单票是否可买 |
| | | can_buy_result = RadicalBuyDataManager.is_code_can_buy(code) |
| | |
| | | async_log_util.info(logger_l2_radical_buy, f"计算板块结果:{code}-{radical_result}") |
| | | result_cache = (time.time() + 3, radical_result) |
| | | self.__radical_buy_by_blocks_result_cache[code] = result_cache |
| | | RadicalBuyDealCodesManager.radical_buy_blocks_dict[code] = radical_result[0] |
| | | RadicalBuyDealCodesManager().set_code_blocks(code, radical_result[0]) |
| | | # 取缓存 |
| | | result = result_cache[1] |
| | | if result[0]: |
| | |
| | | # ---------------判断板块是否还可以买入---------------- |
| | | f_buy_blocks = radical_buy_data_manager.is_block_can_radical_buy(code, buy_blocks, deal_codes) |
| | | if not f_buy_blocks: |
| | | return |
| | | return True |
| | | buy_blocks = f_buy_blocks |
| | | except Exception as e: |
| | | logger_debug.exception(e) |
| | |
| | | mode)) |
| | | if not can_buy: |
| | | async_log_util.info(logger_l2_radical_buy, f"当前时间段已不能扫入:{code}-{msg}") |
| | | return |
| | | return True |
| | | |
| | | # -----根据成交比例判断是否可买------ |
| | | result_by_volume = radical_buy_strategy.process_limit_up_active_buy_deal(code, transaction_datas) |
| | |
| | | radical_buy_data_manager.ExcludeIndexComputeCodesManager.add_code(code) |
| | | async_log_util.info(logger_l2_radical_buy, |
| | | f"09:32之前不交易:{code}") |
| | | return |
| | | return True |
| | | # 判断是否开得太高 |
| | | open_price = L1DataManager.get_open_price(code) |
| | | if not radical_buy_strategy.is_can_buy_with_open_price(code, open_price): |
| | | async_log_util.info(logger_l2_radical_buy, |
| | | f"开得太高:{code}") |
| | | radical_buy_data_manager.ExcludeIndexComputeCodesManager.add_code(code) |
| | | return |
| | | return True |
| | | radical_buy_data_manager.ExcludeIndexComputeCodesManager.remove_code(code) |
| | | |
| | | if result_by_volume[0] == radical_buy_strategy.BUY_MODE_DIRECT and not tool.is_sh_code(code): |
| | |
| | | # 下单成功 |
| | | radical_buy_data_manager.BlockPlaceOrderRecordManager().add_record(code, buy_blocks) |
| | | radical_buy_strategy.clear_latest_deal_active_buy_order(code) |
| | | RDCancelBigNumComputer().clear_data(code) |
| | | return True |
| | | else: |
| | | RadicalBuyDealCodesManager.buy_by_l2_delegate_expire_time_dict[code] = ( |
| | | time.time() + 30, transaction_datas[-1][6], buy_blocks, |
| | | l2_huaxin_util.convert_time(transaction_datas[-1][3]), buy_blocks_with_money) |
| | | return False |
| | | else: |
| | | async_log_util.info(logger_l2_radical_buy, f"不能下单:{code}-{result_by_volume}") |
| | | return False |
| | | else: |
| | | volume_rate = code_volumn_manager.CodeVolumeManager().get_volume_rate(code) |
| | | async_log_util.info(logger_l2_radical_buy, f"没有可扫入的板块:{code},量比:{volume_rate}") |
| | | return True |
| | | else: |
| | | async_log_util.info(logger_l2_radical_buy, f"目前代码不可交易:{code}-{can_buy_result[1]}") |
| | | return True |
| | | except Exception as e: |
| | | async_log_util.info(logger_debug, f"激进买计算异常:{str(e)}") |
| | | logger_debug.exception(e) |
| | |
| | | if use_time > 0.005: |
| | | async_log_util.info(logger_debug, f"扫入处理时长:{code}-{use_time}") |
| | | |
| | | def OnLimitUpActiveBuy(self, code, transaction_datas): |
| | | can_clear_before_data = self.__process_limit_up_active_buy(code, transaction_datas) |
| | | if can_clear_before_data: |
| | | # 清除 |
| | | EveryLimitupBigDealOrderManager.clear(code) |
| | | |
| | | |
| | | |
| | | |
| | | # 回调 |
| | | my_l2_data_callback = MyL2DataCallback() |
| | |
| | | # 非正常票 |
| | | continue |
| | | |
| | | if juejin_result_dict[code][2] < 3: |
| | | # 小于3块 |
| | | if juejin_result_dict[code][2] < 3 or juejin_result_dict[code][2] > 40: |
| | | # 小于3块/大于40块 |
| | | continue |
| | | index += 1 |
| | | fdatas.append( |
| | |
| | | from code_attribute.code_volumn_manager import CodeVolumeManager |
| | | from db import redis_manager_delegate as redis_manager |
| | | from db.redis_manager_delegate import RedisUtils |
| | | from l2.huaxin import l2_huaxin_util |
| | | from l2.l2_transaction_data_manager import BigOrderDealManager, HuaXinBuyOrderManager |
| | | from log_module import async_log_util |
| | | from log_module.log import logger_l2_radical_buy, logger_debug, logger_l2_radical_buy_data |
| | |
| | | if volume_rate < 0.8: |
| | | return False, f"处于首板老{history_index + 1},量比({volume_rate})<0.8" |
| | | |
| | | # 前排最多允许1个炸板 |
| | | limit_up_timestamp = cls.__get_limit_up_timestamp(code) |
| | | # 获取当前的板块, 不要忽略开1的数据 |
| | | current_index, current_before_codes_info = cls.__get_current_index(code, block, set(), |
| | | limit_up_time=limit_up_timestamp, |
| | | ignore_open_limit_up=False) |
| | | if history_index - current_index >1: |
| | | return False, f"前排只允许一个炸板:炸板个数-{history_index - current_index}" |
| | | return True, f"处于首板老{history_index + 1}" |
| | | |
| | | @classmethod |
| | |
| | | else: |
| | | return False, f"量比-{volume_rate}, 总大单成交金额({deal_big_order_money})<{threshold_money}", before_time |
| | | else: |
| | | current_big_order_deal_money = EveryLimitupBigDealOrderManager.get_big_buy_deal_order_money(code) |
| | | current_big_order_deal_money = 0 |
| | | current_big_order_deal_money_info = EveryLimitupBigDealOrderManager.get_big_buy_deal_order_money_info(code) |
| | | if current_big_order_deal_money_info: |
| | | if tool.trade_time_sub(tool.get_now_time_str(), current_big_order_deal_money_info[1]) > 60: |
| | | # 60s以上的大单不看 |
| | | current_big_order_deal_money = 0 |
| | | else: |
| | | current_big_order_deal_money = current_big_order_deal_money_info[0] |
| | | if current_big_order_deal_money + delegating_big_order_money >= threshold_money: |
| | | return True, f"量比-{volume_rate}, 本次大单成交金额({current_big_order_deal_money})+委托大单金额({delegating_big_order_money})>={threshold_money}", before_time |
| | | else: |
| | |
| | | cls.__deal_big_order_infos_dict[code].clear() |
| | | |
| | | @classmethod |
| | | def clear(cls, code): |
| | | cls.open_limit_up(code) |
| | | |
| | | @classmethod |
| | | def add_big_buy_order_deal(cls, code, order_infos: list): |
| | | """ |
| | | 加入大单成交 |
| | | @param code: |
| | | @param order_infos:[(订单号,金额)] |
| | | @param order_infos:[(订单号,金额, 最后成交时间)] |
| | | @return: |
| | | """ |
| | | if code not in cls.__deal_big_order_infos_dict: |
| | |
| | | return sum([x[1] for x in cls.__deal_big_order_infos_dict[code]]) |
| | | return 0 |
| | | |
| | | @classmethod |
| | | def get_big_buy_deal_order_money_info(cls, code): |
| | | if cls.__deal_big_order_infos_dict.get(code): |
| | | return sum([x[1] for x in cls.__deal_big_order_infos_dict[code]]), l2_huaxin_util.convert_time( |
| | | cls.__deal_big_order_infos_dict[code][-1][2]) |
| | | return None |
| | | |
| | | |
| | | def __get_deal_reasons(code): |
| | | """ |
| | |
| | | if limit_up_reason: |
| | | reasons.add(limit_up_reason) |
| | | if not limit_up_reason: |
| | | radical_buy_deal_blocks = RadicalBuyDealCodesManager.radical_buy_blocks_dict.get(code) |
| | | radical_buy_deal_blocks = RadicalBuyDealCodesManager().get_code_blocks(code) |
| | | if radical_buy_deal_blocks: |
| | | reasons |= radical_buy_deal_blocks |
| | | return reasons |
| | |
| | | __latest_deal_active_buy_order = {} |
| | | |
| | | |
| | | def __get_deal_rate_by(code, huaxin_timestamp): |
| | | """ |
| | | |
| | | @param code: 代码 |
| | | @param huaxin_timestamp: 华鑫成交时间戳 |
| | | @return:买入方式, 消息 |
| | | """ |
| | | """ |
| | | 获取备用成交比例 |
| | | @param code: |
| | | @return: |
| | | """ |
| | | refer_sell_data = L2MarketSellManager().get_refer_sell_data(code, l2_huaxin_util.convert_time( |
| | | huaxin_timestamp)) |
| | | async_log_util.info(logger_l2_radical_buy, f"参考总卖额(备用):{code}-{refer_sell_data}") |
| | | if refer_sell_data: |
| | | # 如果总卖额大于500w,成交到一半就直接扫 |
| | | if refer_sell_data[1] >= 500 * 1e4: |
| | | THRESH_HOLD_VOLUME = refer_sell_data[2] |
| | | if refer_sell_data[4] and len(refer_sell_data[4]) < 10: |
| | | # 小于10挡,最后一档才是涨停价 |
| | | if refer_sell_data[4][-1][1] > 0: |
| | | THRESH_HOLD_VOLUME = refer_sell_data[4][-1][1] |
| | | |
| | | refer_sell_time = refer_sell_data[0] |
| | | # 获取最近的主动买成交量 |
| | | limit_up_deal_infos = HuaXinSellOrderStatisticManager.get_latest_6s_active_buy_deal_volumes( |
| | | code) |
| | | async_log_util.info(logger_l2_radical_buy, f"最近涨停主动买成交(备用):{code}-{limit_up_deal_infos}") |
| | | deal_volume = 0 |
| | | for i in range(0, len(limit_up_deal_infos)): |
| | | # >=统计到的总卖 |
| | | if int(refer_sell_time.replace(":", "")) > int( |
| | | limit_up_deal_infos[i][0].replace(":", "")): |
| | | break |
| | | deal_volume += limit_up_deal_infos[i][1] |
| | | async_log_util.info(logger_l2_radical_buy, f"成交量(备用):{deal_volume}/{THRESH_HOLD_VOLUME}") |
| | | deal_rate = round(deal_volume / THRESH_HOLD_VOLUME, 2) |
| | | if deal_rate >= 0.5: |
| | | return BUY_MODE_DIRECT, f"达到买入条件(备用):比例-{deal_rate}" |
| | | else: |
| | | return BUY_MODE_NONE, f"尚未达到买入比例(备用):{deal_rate}" |
| | | else: |
| | | return BUY_MODE_BY_L2, f"总卖额小于500w(备用)({refer_sell_data[1]})" |
| | | else: |
| | | return BUY_MODE_NONE, "尚未获取到总卖额(备用)" |
| | | |
| | | |
| | | def clear_latest_deal_active_buy_order(code): |
| | | """ |
| | | 清除最近主动成交的订单信息 |
| | |
| | | if refer_sell_data: |
| | | refer_sell_money = refer_sell_data[1] |
| | | |
| | | |
| | | # 处于涨停卖的委托订单总手数 |
| | | selling_num = L2LimitUpSellDataManager.get_delegating_sell_num(code) |
| | | if selling_num is None: |
| | | selling_num = 0 |
| | | if selling_num is not None: |
| | | # 总卖 = 涨停主动买成交的累计金额 + 处于委托状态的涨停卖金额 |
| | | total_sell = __deal_active_buy_total_money[code] + selling_num * price |
| | | if total_sell == 0: |
| | | total_sell = 1 |
| | | rate = round(__deal_active_buy_total_money[code] / total_sell, 2) |
| | | # 获取当前的成交量比 |
| | | limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) |
| | | volume_rate = code_volumn_manager.CodeVolumeManager().get_volume_rate(code, total_sell_volume=int( |
| | | total_sell / limit_up_price), |
| | | with_info=False) |
| | | if volume_rate is None: |
| | | volume_rate = 0.5 |
| | | # 总卖 = 涨停主动买成交的累计金额 + 处于委托状态的涨停卖金额 |
| | | total_sell = __deal_active_buy_total_money[code] + selling_num * price |
| | | if total_sell == 0: |
| | | total_sell = 1 |
| | | rate = round(__deal_active_buy_total_money[code] / total_sell, 2) |
| | | # 获取当前的成交量比 |
| | | limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) |
| | | volume_rate = code_volumn_manager.CodeVolumeManager().get_volume_rate_refer_in_5days(code, |
| | | total_sell_volume=int( |
| | | total_sell / limit_up_price)) |
| | | if volume_rate is None: |
| | | volume_rate = 0.5 |
| | | |
| | | THRESHOLD_RATE = radical_buy_data_manager.get_volume_rate_threshold(code, volume_rate) |
| | | if rate >= THRESHOLD_RATE: |
| | | # 根据大单判断是否可以扫 |
| | | big_order_deal_result = radical_buy_data_manager.is_big_order_deal_enough(code, volume_rate, refer_sell_money) |
| | | if big_order_deal_result[0]: |
| | | return BUY_MODE_DIRECT, f"剩余涨停总卖额-{selling_num * price},原涨停总卖-{total_sell},已成交额-{__deal_active_buy_total_money[code]},成交比例-{rate}/{THRESHOLD_RATE}" |
| | | else: |
| | | # 无大单成交就只能通过L2下单 |
| | | return BUY_MODE_BY_L2, f"无大单成交-{big_order_deal_result[1]},原涨停总卖-{total_sell},已成交额-{__deal_active_buy_total_money[code]},成交比例-{rate}/{THRESHOLD_RATE} " |
| | | else: |
| | | return BUY_MODE_NONE, f"被动卖成交比例未达到:剩余涨停总卖额-{selling_num * price},原涨停总卖-{total_sell},已成交额-{__deal_active_buy_total_money[code]},成交比例-{rate}/{THRESHOLD_RATE}" |
| | | else: |
| | | # 根据量比与大单成交数量判断是否可扫 |
| | | volume_rate = code_volumn_manager.CodeVolumeManager().get_volume_rate(code, with_info=False) |
| | | if volume_rate is None: |
| | | volume_rate = 0.5 |
| | | THRESHOLD_RATE = radical_buy_data_manager.get_volume_rate_threshold(code, volume_rate) |
| | | if rate >= THRESHOLD_RATE: |
| | | # 根据大单判断是否可以扫 |
| | | big_order_deal_result = radical_buy_data_manager.is_big_order_deal_enough(code, volume_rate, refer_sell_money) |
| | | result = __get_deal_rate_by(code, huaxin_timestamp) |
| | | if result[0] == BUY_MODE_DIRECT: |
| | | if big_order_deal_result[0]: |
| | | return result |
| | | else: |
| | | return BUY_MODE_BY_L2, big_order_deal_result[1] |
| | | big_order_deal_result = radical_buy_data_manager.is_big_order_deal_enough(code, volume_rate, |
| | | refer_sell_money) |
| | | if big_order_deal_result[0]: |
| | | return BUY_MODE_DIRECT, f"剩余涨停总卖额-{selling_num * price},原涨停总卖-{total_sell},已成交额-{__deal_active_buy_total_money[code]},成交比例-{rate}/{THRESHOLD_RATE}, 大单信息-{big_order_deal_result}" |
| | | else: |
| | | return result |
| | | # 无大单成交就只能通过L2下单 |
| | | return BUY_MODE_BY_L2, f"无大单成交-{big_order_deal_result},原涨停总卖-{total_sell},已成交额-{__deal_active_buy_total_money[code]},成交比例-{rate}/{THRESHOLD_RATE} " |
| | | else: |
| | | return BUY_MODE_NONE, f"被动卖成交比例未达到:剩余涨停总卖额-{selling_num * price},原涨停总卖-{total_sell},已成交额-{__deal_active_buy_total_money[code]},成交比例-{rate}/{THRESHOLD_RATE}" |
| | | |
| | | |
| | | def is_can_buy_with_open_price(code, open_price): |
| | |
| | | |
| | | # D撤 |
| | | CANCEL_TYPE_D = 11 |
| | | |
| | | # RD撤 |
| | | CANCEL_TYPE_RD = 12 |
| | |
| | | __redis_manager = redis_manager.RedisManager(2) |
| | | __deal_codes_cache = set() |
| | | __instance = None |
| | | __mysqldb = Mysqldb() |
| | | # 根据L2数据来激进买入的有效时间:{"code":(有效截至时间, 买单号, 扫入的板块, 最近成交时间)} |
| | | buy_by_l2_delegate_expire_time_dict = {} |
| | | # 仅仅买的板块 |
| | | radical_buy_blocks_dict = {} |
| | | __radical_buy_blocks_dict = {} |
| | | |
| | | def __new__(cls, *args, **kwargs): |
| | | if not cls.__instance: |
| | | cls.__instance = super(RadicalBuyDealCodesManager, cls).__new__(cls, *args, **kwargs) |
| | | cls.__instance.__load_data() |
| | | cls.__load_data() |
| | | |
| | | return cls.__instance |
| | | |
| | | @classmethod |
| | | def __load_data(cls): |
| | | __redis = cls.__get_redis() |
| | | result = RedisUtils.smembers(cls.__get_redis(), "radical_buy_deal_codes") |
| | | if result: |
| | | cls.__deal_codes_cache = set(result) |
| | | keys = RedisUtils.keys(cls.__get_redis(), "radical_buy_blocks-*") |
| | | if keys: |
| | | for k in keys: |
| | | code = k.split("-")[1] |
| | | val = RedisUtils.get(cls.__get_redis(), k) |
| | | val = json.loads(val) |
| | | cls.__radical_buy_blocks_dict[code] = set(val) |
| | | cls.__deal_codes_cache = set(result) |
| | | |
| | | def set_code_blocks(self, code, blocks): |
| | | self.__radical_buy_blocks_dict[code] = set(blocks) |
| | | RedisUtils.setex_async(self.__db, f"radical_buy_blocks-{code}", tool.get_expire(), json.dumps(list(blocks))) |
| | | |
| | | def get_code_blocks(self, code): |
| | | return self.__radical_buy_blocks_dict.get(code) |
| | | |
| | | @classmethod |
| | | def __get_redis(cls): |
| | |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | print(AccountMoneyManager().get_deal_count()) |
| | | pass |