| | |
| | | if code_list_type == outside_api_command_manager.CODE_LIST_WANT: |
| | | if operate == outside_api_command_manager.OPERRATE_SET: |
| | | gpcode_manager.WantBuyCodesManager().add_code(code) |
| | | # 加想买单要从黑名单移除 |
| | | l2_trade_util.remove_from_forbidden_trade_codes(code) |
| | | name = gpcode_manager.get_code_name(code) |
| | | if not name: |
| | | results = HistoryKDatasUtils.get_gp_codes_names([code]) |
| | |
| | | # 设置买入金额和数量 |
| | | normal = data["normal"] |
| | | radical = data["radical"] |
| | | BuyMoneyAndCountSetting().set_normal_buy_data(normal[0],json.loads( normal[1])) |
| | | BuyMoneyAndCountSetting().set_radical_buy_data(radical[0],json.loads( radical[1])) |
| | | BuyMoneyAndCountSetting().set_normal_buy_data(normal[0], json.loads(normal[1])) |
| | | BuyMoneyAndCountSetting().set_radical_buy_data(radical[0], json.loads(radical[1])) |
| | | data = { |
| | | "normal": BuyMoneyAndCountSetting().get_normal_buy_setting(), |
| | | "radical": BuyMoneyAndCountSetting().get_radical_buy_setting() |
| | |
| | | # 设置买入金额和数量 |
| | | data = { |
| | | "normal": BuyMoneyAndCountSetting().get_normal_buy_setting(), |
| | | "radical": BuyMoneyAndCountSetting().get_radical_buy_setting() |
| | | "radical": BuyMoneyAndCountSetting().get_radical_buy_setting(), |
| | | "moneys":constant.AVAILABLE_BUY_MONEYS |
| | | } |
| | | self.send_response({"code": 0, "data": data, "msg": f""}, |
| | | client_id, |
| | |
| | | |
| | | # L2数据是否载入完成 |
| | | L2_DATA_IS_LOADED = False |
| | | |
| | | # 可买入的金额 |
| | | AVAILABLE_BUY_MONEYS = [5000, 20000, 50000] |
| | |
| | | for d in codes_data: |
| | | code = d[0] |
| | | codes.add(code) |
| | | self.codes_volume_and_price_dict[code] = (d[1], d[2], d[3], d[4]) |
| | | self.l2_data_upload_manager.set_order_fileter_condition(code, d[1], round(float(d[2]), 2), d[3], d[4]) |
| | | self.codes_volume_and_price_dict[code] = (d[1], d[2], d[3], d[4], d[5]) |
| | | self.l2_data_upload_manager.set_order_fileter_condition(code, d[1], round(float(d[2]), 2), d[3], d[4], d[5]) |
| | | logger_l2_codes_subscript.info("华鑫L2订阅总数:{}", len(codes)) |
| | | add_codes = codes - self.subscripted_codes |
| | | del_codes = self.subscripted_codes - codes |
| | |
| | | |
| | | # 设置订单过滤条件 |
| | | # special_price:过滤的1手的价格 |
| | | def set_order_fileter_condition(self, code, min_volume, limit_up_price, shadow_price, buy_volume): |
| | | def set_order_fileter_condition(self, code, min_volume, limit_up_price, shadow_price, buy_volume, special_volumes): |
| | | if not special_volumes: |
| | | special_volumes = set() |
| | | if code not in self.filter_order_condition_dict: |
| | | # (最小的量, 涨停价格, 影子单价格, 买的量, 废弃使用, 特殊的量集合) |
| | | self.filter_order_condition_dict[code] = [(min_volume, limit_up_price, shadow_price, buy_volume, |
| | | min_volume // 50)] |
| | | min_volume // 50, set(special_volumes))] |
| | | huaxin_l2_log.info(logger_local_huaxin_l2_subscript, |
| | | f"({code})常规过滤条件设置:{self.filter_order_condition_dict[code]}") |
| | | |
| | |
| | | |
| | | # 所有的涨停卖 |
| | | if item[1] == filter_condition[0][1]: |
| | | return item |
| | | |
| | | if item[3] != '1': |
| | | # 涨停卖 |
| | | return item |
| | | elif item[2] in filter_condition[0][5]: |
| | | # 涨停满足特殊的手数 |
| | | return item |
| | | return None |
| | | return item |
| | | # 过滤订单 |
| | |
| | | if cancel_result[0]: |
| | | L2TradeDataProcessor.cancel_buy(code, f"F撤:{cancel_result[1]}", |
| | | cancel_type=trade_constant.CANCEL_TYPE_F) |
| | | return |
| | | else: |
| | | l2_log.f_cancel_debug(code, f"获取真实成交位的F撤未生效:{cancel_result[1]}") |
| | | except Exception as e: |
| | | logger_debug.exception(e) |
| | | # 判断与执行位置的间隔时间 |
| | | if order_begin_pos.mode != OrderBeginPosInfo.MODE_RADICAL: |
| | | # 非扫入下单要判断执行位置与真实下单位的间隔时间 |
| | | total_datas = local_today_datas.get(code) |
| | | if tool.trade_time_sub_with_ms(L2DataUtil.get_time_with_ms(total_datas[index]["val"]), L2DataUtil.get_time_with_ms(total_datas[order_begin_pos.buy_exec_index]["val"])) > 2000: |
| | | L2TradeDataProcessor.cancel_buy(code, f"真实下单位({index})与执行位({order_begin_pos.buy_exec_index})相差2s以上", |
| | | cancel_type=trade_constant.CANCEL_TYPE_F) |
| | | return |
| | | |
| | | |
| | | # 处理华鑫L2数据 |
| | | @classmethod |
| | |
| | | continue |
| | | findexes.add(index) |
| | | return findexes |
| | | |
| | | # 统计买入净买量,不计算在买入信号之前的买撤单 |
| | | @classmethod |
| | | def __sum_buy_num_for_order_3(cls, code, compute_start_index, compute_end_index, origin_num, origin_count, |
| | | threshold_money, buy_single_index, max_num_set, at_limit_up=False): |
| | | _start_time = t.time() |
| | | total_datas = local_today_datas[code] |
| | | # is_first_code = gpcode_manager.FirstCodeManager().is_in_first_record_cache(code) |
| | | |
| | | buy_nums = origin_num |
| | | buy_count = origin_count |
| | | limit_up_price = gpcode_manager.get_limit_up_price(code) |
| | | if limit_up_price is None: |
| | | raise Exception("涨停价无法获取") |
| | | limit_up_price = float(limit_up_price) |
| | | |
| | | threshold_num = None |
| | | # 大目标手数(满足这个就不需要看安全笔数) |
| | | threshold_max_num = None |
| | | |
| | | # 目标订单数量 |
| | | threshold_count = cls.__l2PlaceOrderParamsManagerDict[code].get_safe_count() |
| | | |
| | | # 最大间隔时间ms |
| | | max_space_time_ms = cls.__l2PlaceOrderParamsManagerDict[code].get_time_range() * 1000 |
| | | |
| | | # ----------------调整板上下单的m值与安全笔数---------------- |
| | | if at_limit_up: |
| | | # 板上买,获取最近一次闪电下单的总卖额 |
| | | sell_data = cls.__latest_fast_place_order_info_dict.get(code) |
| | | if sell_data: |
| | | # 有过闪电下单 |
| | | # 总卖的一半作为m值 |
| | | threshold_num = int(sell_data[1] / (limit_up_price * 100)) // 2 |
| | | threshold_max_num = 1 |
| | | # 信号为之前有待成交的大单(不是正在成交) |
| | | trade_index, is_default = cls.__TradeBuyQueue.get_traded_index(code) |
| | | if not is_default and trade_index is not None: |
| | | temp_big_num = int(30000 / limit_up_price) |
| | | for i in range(trade_index + 1, buy_single_index): |
| | | data = total_datas[i] |
| | | val = data['val'] |
| | | if not L2DataUtil.is_limit_up_price_buy(val): |
| | | continue |
| | | # 判断是否有大单未成交 |
| | | if temp_big_num > val["num"]: |
| | | continue |
| | | |
| | | left_count = l2_data_source_util.L2DataSourceUtils.get_limit_up_buy_no_canceled_count_v2(code, |
| | | data[ |
| | | "index"], |
| | | total_datas, |
| | | local_today_canceled_buyno_map.get( |
| | | code)) |
| | | if left_count > 0: |
| | | # 安全笔数与囊括时间范围修改 |
| | | threshold_count = 3 |
| | | max_space_time_ms = 9 * 1000 |
| | | break |
| | | |
| | | if not threshold_num: |
| | | # 目标手数 |
| | | threshold_num = round(threshold_money / (limit_up_price * 100)) |
| | | if not threshold_max_num: |
| | | threshold_max_num = int(threshold_num * 1.2) |
| | | |
| | | # place_order_count = trade_data_manager.PlaceOrderCountManager().get_place_order_count(code) |
| | | |
| | | # buy_single_time_seconds = L2DataUtil.get_time_as_second(total_datas[buy_single_index]["val"]["time"]) |
| | | |
| | | # 可以触发买,当有涨停买信号时才会触发买 |
| | | trigger_buy = True |
| | | |
| | | # 如果大单含有率大于50%,则时间囊括范围提高到3s |
| | | if max_num_set and origin_count: |
| | | if len(max_num_set) / origin_count > 0.5: |
| | | max_space_time_ms = 3 * 1000 |
| | | |
| | | # 最大买量 |
| | | max_buy_num = 0 |
| | | max_buy_num_set = set(max_num_set) |
| | | |
| | | # 需要的最小大单笔数 |
| | | big_num_count = cls.__l2PlaceOrderParamsManagerDict[code].get_big_num_count() |
| | | |
| | | # 较大单的手数 |
| | | bigger_num = round(5000 / limit_up_price) |
| | | |
| | | not_buy_msg = "" |
| | | is_ge_code = tool.is_ge_code(code) |
| | | for i in range(compute_start_index, compute_end_index + 1): |
| | | data = total_datas[i] |
| | | _val = total_datas[i]["val"] |
| | | trigger_buy = False |
| | | # 必须为连续2秒内的数据 |
| | | if L2DataUtil.time_sub_as_ms(_val, total_datas[buy_single_index]["val"]) > max_space_time_ms: |
| | | cls.__TradePointManager.delete_buy_point(code) |
| | | if i == compute_end_index: |
| | | # 数据处理完毕 |
| | | return None, buy_nums, buy_count, None, max_buy_num_set, f"【{i}】信号不连续,囊括时间-{max_space_time_ms}ms" |
| | | else: |
| | | # 计算买入信号,不能同一时间开始计算 |
| | | for ii in range(buy_single_index + 1, compute_end_index + 1): |
| | | if total_datas[buy_single_index]["val"]["time"] != total_datas[ii]["val"]["time"]: |
| | | return None, buy_nums, buy_count, ii, max_buy_num_set, f"【{i}】信号不连续,囊括时间-{max_space_time_ms}ms" |
| | | # 涨停买 |
| | | if L2DataUtil.is_limit_up_price_buy(_val): |
| | | if l2_data_util.is_big_money(_val, is_ge_code): |
| | | max_buy_num_set.add(i) |
| | | if _val["num"] >= bigger_num: |
| | | trigger_buy = True |
| | | # 只统计59万以上的金额 |
| | | buy_nums += int(_val["num"]) * int(total_datas[i]["re"]) |
| | | buy_count += int(total_datas[i]["re"]) |
| | | if (buy_nums >= threshold_num and buy_count >= threshold_count) or buy_nums >= threshold_max_num: |
| | | l2_log.info(code, logger_l2_trade_buy, |
| | | f"{code}获取到买入执行点:{i} 统计纯买手数:{buy_nums} 目标纯买手数:{threshold_num}/{threshold_max_num} 统计纯买单数:{buy_count} 目标纯买单数:{threshold_count}, 大单数量:{len(max_buy_num_set)}") |
| | | elif L2DataUtil.is_limit_up_price_buy_cancel(_val): |
| | | if _val["num"] >= bigger_num: |
| | | # 只统计59万以上的金额 |
| | | # 涨停买撤 |
| | | # 判断买入位置是否在买入信号之前 |
| | | buy_index = l2_data_source_util.L2DataSourceUtils.get_buy_index_with_cancel_data_v2(total_datas[i], |
| | | local_today_buyno_map.get( |
| | | code)) |
| | | if buy_index is not None: |
| | | # 找到买撤数据的买入点 |
| | | if buy_index >= buy_single_index: |
| | | buy_nums -= int(_val["num"]) * int(data["re"]) |
| | | buy_count -= int(data["re"]) |
| | | # 大单撤销 |
| | | max_buy_num_set.discard(buy_index) |
| | | l2_log.buy_debug(code, "{}数据在买入信号之后 撤买纯买手数:{} 目标手数:{}", i, buy_nums, threshold_num) |
| | | else: |
| | | l2_log.buy_debug(code, "{}数据在买入信号之前,买入位:{}", i, buy_index) |
| | | if total_datas[buy_single_index]["val"]["time"] == total_datas[buy_index]["val"]["time"]: |
| | | # 同一秒,当作买入信号之后处理 |
| | | buy_nums -= int(_val["num"]) * int(data["re"]) |
| | | buy_count -= int(data["re"]) |
| | | # 大单撤销 |
| | | max_buy_num_set.discard(buy_index) |
| | | l2_log.buy_debug(code, "{}数据买入位与预估买入位在同一秒", i) |
| | | else: |
| | | # 未找到买撤数据的买入点 |
| | | l2_log.buy_debug(code, "未找到买撤数据的买入点: 位置-{} 数据-{}", i, data) |
| | | buy_nums -= int(_val["num"]) * int(total_datas[i]["re"]) |
| | | buy_count -= int(total_datas[i]["re"]) |
| | | l2_log.buy_debug(code, "位置-{},总手数:{},目标手数:{}", i, |
| | | buy_nums, threshold_num) |
| | | |
| | | max_buy_num_set_count = 0 |
| | | max_buy_num_set = cls.__filter_not_deal_indexes(code, max_buy_num_set) |
| | | for i1 in max_buy_num_set: |
| | | max_buy_num_set_count += total_datas[i1]["re"] |
| | | |
| | | if buy_nums < threshold_num: |
| | | not_buy_msg = f"【{i}】纯买额不足,{buy_nums}/{threshold_num}" |
| | | continue |
| | | |
| | | if buy_count < threshold_count: |
| | | not_buy_msg = f"【{i}】安全笔数不够,{buy_count}/{threshold_count}" |
| | | continue |
| | | |
| | | if not trigger_buy: |
| | | not_buy_msg = f"【{i}】没有买单触发" |
| | | continue |
| | | |
| | | if max_buy_num_set_count < big_num_count: |
| | | not_buy_msg = f"【{i}】大单数量不足,{max_buy_num_set_count}/{big_num_count}" |
| | | continue |
| | | |
| | | try: |
| | | info = cls.__trade_log_placr_order_info_dict[code] |
| | | info.set_trade_factor(threshold_money, threshold_count, list(max_buy_num_set)) |
| | | except Exception as e: |
| | | async_log_util.error(logger_l2_error, f"记录交易因子出错:{str(e)}") |
| | | |
| | | return i, buy_nums, buy_count, None, max_buy_num_set, "可以下单" |
| | | |
| | | l2_log.buy_debug(code, "尚未获取到买入执行点,起始计算位置:{} 统计纯买手数:{} 目标纯买手数:{} 统计纯买单数:{} 目标纯买单数:{} 大单数量:{} 目标大单数量:{}", |
| | | compute_start_index, |
| | | buy_nums, |
| | | threshold_num, buy_count, threshold_count, max_buy_num_set_count, big_num_count) |
| | | |
| | | return None, buy_nums, buy_count, None, max_buy_num_set, not_buy_msg |
| | | |
| | | # 返回(买入执行点, 总手, 总笔数, 从新计算起点, 纯买额阈值) |
| | | # 计算快速买入 |
| | |
| | | for d in record_limit_up_datas: |
| | | if kpl_util.filter_block(d[2]) != plate: |
| | | continue |
| | | if not tool.is_can_buy_code(d[3]): |
| | | continue |
| | | # 代码,名称,涨停时间,是否炸板,是否想买,是否已经下过单,涨停时间,自由流通市值,是否在黑名单里面 |
| | | codes_info.append( |
| | | [d[3], d[4], tool.to_time_str(int(d[5])), 1 if d[3] not in now_limit_up_codes else 0, 0, 0, d[12], |
| | |
| | | continue |
| | | if plate not in [kpl_util.filter_block(k) for k in d[6].split("、")]: |
| | | continue |
| | | if not tool.is_can_buy_code(d[3]): |
| | | continue |
| | | # 代码,名称,涨停时间,是否炸板,是否想买,是否已经下过单,涨停时间,自由流通市值,是否在黑名单里面 |
| | | codes_info.append( |
| | | [d[3], d[4], tool.to_time_str(int(d[5])), 1 if d[3] not in now_limit_up_codes else 0, 0, 0, d[12], |
| | |
| | | from third_data.history_k_data_util import JueJinApi |
| | | from trade import trade_manager, l2_trade_util, \ |
| | | trade_data_manager, trade_constant, radical_buy_strategy |
| | | from trade.buy_money_count_setting import BuyMoneyAndCountSetting |
| | | |
| | | from trade.huaxin import huaxin_trade_api as trade_api, huaxin_trade_api, huaxin_trade_data_update, \ |
| | | huaxin_trade_record_manager, huaxin_sell_util |
| | |
| | | # 判断昨日是否涨停过 |
| | | async_log_util.info(logger_l2_radical_buy, f"涨停主动买:{code}-{transaction_datas[-1]}") |
| | | deal_codes = RadicalBuyDealCodesManager().get_deal_codes() |
| | | if len(deal_codes) >= 4: |
| | | async_log_util.info(logger_l2_radical_buy, f"扫入成交代码个数大于4个:{code}-{deal_codes}") |
| | | radical_buy_setting = BuyMoneyAndCountSetting().get_radical_buy_setting() |
| | | 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 |
| | | if code in deal_codes: |
| | | async_log_util.info(logger_l2_radical_buy, f"该代码已经成交:{code}") |
| | |
| | | match_blocks, info = CodeThirdBlocksManager().get_intersection_blocks_info(code, blocks) |
| | | match_blocks -= constant.KPL_INVALID_BLOCKS |
| | | fblocks = match_blocks & RealTimeKplMarketData.get_top_market_jingxuan_blocks() |
| | | if not fblocks: |
| | | fblocks, info = CodeThirdBlocksManager().get_intersection_blocks_info(code, blocks, same_count=3) |
| | | fblocks -= constant.KPL_INVALID_BLOCKS |
| | | return fblocks, match_blocks |
| | | |
| | | @classmethod |
| | |
| | | |
| | | from db.mysql_data_delegate import Mysqldb |
| | | from utils import middle_api_protocol |
| | | from utils.kpl_data_db_util import KPLLimitUpDataUtil |
| | | from utils.ths_industry_util import ThsCodeIndustryManager |
| | | |
| | | SOURCE_TYPE_KPL = 1 # 东方财富 |
| | | SOURCE_TYPE_KPL = 1 # 开盘啦 |
| | | SOURCE_TYPE_TDX = 2 # 通达信 |
| | | SOURCE_TYPE_THS = 3 # 同花顺 |
| | | SOURCE_TYPE_EASTMONEY = 4 # 东方财富 |
| | | SOURCE_TYPE_KPL_RECORD = 5 # 开盘啦历史数据 |
| | | |
| | | |
| | | class CodeThirdBlocksManager: |
| | |
| | | cls.__code_source_blocks_dict_origin[result[0]] = {} |
| | | blocks = set(result[2].split("、")) |
| | | if result[1] == SOURCE_TYPE_THS: |
| | | # 同花顺加入2级分类 |
| | | industry = cls.__ths_industry.get_industry(result[0]) |
| | | if industry: |
| | | blocks.add(industry) |
| | | |
| | | cls.__code_source_blocks_dict_origin[result[0]][result[1]] = blocks |
| | | cls.__code_source_blocks_dict[result[0]][result[1]] = BlockMapManager().filter_blocks(blocks) |
| | | # 加载开盘啦历史涨停原因 |
| | | kpl_results = KPLLimitUpDataUtil.get_latest_block_infos() |
| | | code_blocks = {} |
| | | for r in kpl_results: |
| | | if r[0] not in code_blocks: |
| | | code_blocks[r[0]] = set() |
| | | code_blocks[r[0]].add(r[2]) |
| | | if r[3]: |
| | | code_blocks[r[0]] |= set(r[3].split("、")) |
| | | for code in code_blocks: |
| | | if code not in cls.__code_source_blocks_dict: |
| | | cls.__code_source_blocks_dict[code] = {} |
| | | cls.__code_source_blocks_dict_origin[code] = {} |
| | | blocks = code_blocks[code] |
| | | cls.__code_source_blocks_dict_origin[code][SOURCE_TYPE_KPL_RECORD] = blocks |
| | | cls.__code_source_blocks_dict[code][SOURCE_TYPE_KPL_RECORD] = BlockMapManager().filter_blocks(blocks) |
| | | |
| | | |
| | | def get_source_blocks(self, code): |
| | | """ |
| | |
| | | """ |
| | | return self.__code_source_blocks_dict_origin.get(code) |
| | | |
| | | def get_intersection_blocks_info(self, code, blocks): |
| | | def get_intersection_blocks_info(self, code, blocks, same_count=2): |
| | | # 获取交集 |
| | | bs = [] |
| | | b1 = BlockMapManager().filter_blocks(blocks) |
| | |
| | | for s in sb_dict: |
| | | if sb_dict[s]: |
| | | bs.append(sb_dict[s]) |
| | | if len(bs) < 2: |
| | | if len(bs) < same_count: |
| | | return set(), bs |
| | | s_count = len(bs) |
| | | fblocks = set() |
| | | |
| | | # 求2个平台的交集 |
| | | for ces in combinations(bs, 2): |
| | | for ces in combinations(bs, same_count): |
| | | ic = None |
| | | for c in ces: |
| | | if ic is None: |
| | |
| | | |
| | | import constant |
| | | from db.mysql_data_delegate import Mysqldb |
| | | from l2.l2_data_manager import OrderBeginPosInfo |
| | | |
| | | |
| | | class BuyMoneyAndCountSetting: |
| | | __mysql = Mysqldb() |
| | | __instance = None |
| | | # 常规买 |
| | | __normal_buy = [10, [("15:00:00", constant.BUY_MONEY_PER_CODE)]] # (数量, [("时间", 金额)]) |
| | | __normal_buy = [10, [("15:00:00", constant.BUY_MONEY_PER_CODE, 4)]] # (数量, [("时间", 金额, 买入数量)]) |
| | | # 扫入买 |
| | | __radical_buy = [4, [("15:00:00", constant.BUY_MONEY_PER_CODE)]] # (数量, [("时间", 金额)]) |
| | | __radical_buy = [4, [("15:00:00", constant.BUY_MONEY_PER_CODE, 3)]] # (数量, [("时间", 金额, 买入数量)]) |
| | | |
| | | def __new__(cls, *args, **kwargs): |
| | | if not cls.__instance: |
| | |
| | | |
| | | class BuyMoneyUtil: |
| | | @classmethod |
| | | def get_buy_money(cls, time_str, money_list: list): |
| | | def get_buy_data(cls, time_str, buy_mode, deals, delegates): |
| | | """ |
| | | @param time_str: |
| | | @param money_list:[("09:30:00",20000)] |
| | | @return: |
| | | 获取买入数据 |
| | | @param time_str: 买入时间 |
| | | @param buy_mode: 买入模式 |
| | | @return:是否可买入, 买入金额, 信息 |
| | | """ |
| | | if len(money_list) == 0: |
| | | return constant.BUY_MONEY_PER_CODE |
| | | for money_info in money_list: |
| | | # radical_deals, radical_delegates, normal_deals, normal_delegates |
| | | # if buy_mode == OrderBeginPosInfo.MODE_RADICAL: |
| | | # [(成交代码, 成交时间)] |
| | | # deals = DealAndDelegateWithBuyModeDataManager().get_deal_codes_info(buy_mode) |
| | | if deals is None: |
| | | deals = [] |
| | | # [(委托代码, 委托时间)] |
| | | # delegates = DealAndDelegateWithBuyModeDataManager().get_delegates_codes_info(buy_mode) |
| | | if delegates is None: |
| | | delegates =[] |
| | | # 最大委托数量 |
| | | max_count = 0 |
| | | # 配置数据:[(时间,金额,数量)] |
| | | money_list = [] |
| | | if buy_mode == OrderBeginPosInfo.MODE_RADICAL: |
| | | max_count, money_list = BuyMoneyAndCountSetting().get_radical_buy_setting() |
| | | else: |
| | | max_count, money_list = BuyMoneyAndCountSetting().get_normal_buy_setting() |
| | | |
| | | codes = set([x[0] for x in deals]) |
| | | if len(codes) >= max_count: |
| | | return False, 0, f"成交数量({len(codes)})超过{max_count}个" |
| | | |
| | | # 获取当前时间段允许成交的数量 |
| | | start_time = "09:25:00" |
| | | end_info = None |
| | | for i in range(0, len(money_list)): |
| | | money_info = money_list[i] |
| | | if int(time_str.replace(":", "")) <= int(money_info[0].replace(":", "")): |
| | | return money_info[1] |
| | | return constant.BUY_MONEY_PER_CODE |
| | | |
| | | |
| | | def set_buy_money(deal_codes, delegate_codes): |
| | | """ |
| | | 设置买入金额 |
| | | @param deal_codes: |
| | | @param delegate_codes: |
| | | @return: |
| | | """ |
| | | codes = set() |
| | | if deal_codes: |
| | | codes |= deal_codes |
| | | if delegate_codes: |
| | | codes |= delegate_codes |
| | | if len(codes) < 4: |
| | | constant.BUY_MONEY_PER_CODE = 50000 |
| | | else: |
| | | constant.BUY_MONEY_PER_CODE = 20000 |
| | | end_info = money_info |
| | | if i > 0: |
| | | start_time = money_list[i - 1][0] |
| | | break |
| | | # 获取时间段已经成交/已经挂单的代码数量 |
| | | end_time_int = int(end_info[0].replace(":", "")) |
| | | start_time_int = int(start_time.replace(":", "")) |
| | | codes = set() |
| | | for d in deals: |
| | | if start_time_int < int(d[1].replace(":", "")) <= end_time_int: |
| | | codes.add(d[0]) |
| | | for d in delegates: |
| | | if start_time_int < int(d[1].replace(":", "")) <= end_time_int: |
| | | codes.add(d[0]) |
| | | if len(codes) >= end_info[2]: |
| | | return True, constant.BUY_MONEY_PER_CODE, f"时间段:{start_time}-{end_info[0]} 已成交/委托数量({codes})超过{end_info[2]}个,按照默认金额委托" |
| | | else: |
| | | return True, end_info[ |
| | | 1], f"时间段:{start_time}-{end_info[0]} 已成交/委托数量({codes})没有超过{end_info[2]}个,委托金额为:{end_info[1]}" |
| | | |
| | | |
| | | if __name__ == '__main__': |
| | | set_buy_money({"000333"}, None) |
| | | pass |
| | |
| | | min_volume = int(round(50 * 10000 / limit_up_price)) |
| | | # 传递笼子价 |
| | | add_datas.append( |
| | | # (代码, 最小量, 涨停价,影子订单价格,买量, 特殊价格) |
| | | (d, min_volume, limit_up_price, round(tool.get_shadow_price(limit_up_price), 2), |
| | | tool.get_buy_volume(limit_up_price))) |
| | | tool.get_buy_volume(limit_up_price), constant.AVAILABLE_BUY_MONEYS)) |
| | | huaxin_target_codes_manager.HuaXinL2SubscriptCodesManager.push(add_datas, request_id) |
| | | except Exception as e: |
| | | logging.exception(e) |
| | |
| | | |
| | | from code_attribute import gpcode_manager |
| | | from huaxin_client import constant as huaxin_client_constant |
| | | from l2.l2_data_manager import TradePointManager, OrderBeginPosInfo |
| | | from log_module import async_log_util |
| | | from log_module.log import hx_logger_trade_debug, logger_system, logger_debug |
| | | from trade import trade_manager, trade_data_manager, buy_money_count_setting |
| | | from trade import trade_manager, trade_data_manager, order_statistic |
| | | from trade.huaxin import huaxin_trade_api, huaxin_trade_record_manager |
| | | |
| | | from trade.huaxin.huaxin_trade_order_processor import HuaxinOrderEntity, TradeResultProcessor |
| | |
| | | __process_thread_pool.submit(huaxin_trade_record_manager.DelegateRecordManager.add, data) |
| | | # 是否可以撤单 |
| | | if data: |
| | | codes = [] |
| | | codes_info = [] |
| | | codes = set() |
| | | for d in data: |
| | | code = d["securityID"] |
| | | orderStatus = d["orderStatus"] |
| | |
| | | TradeResultProcessor.process_buy_order(order) |
| | | if huaxin_util.is_can_cancel(orderStatus) and str(direction) == str( |
| | | huaxin_util.TORA_TSTP_D_Buy): |
| | | codes.append(code) |
| | | trade_manager.delegate_codes = set(codes) |
| | | buy_money_count_setting.set_buy_money(trade_manager.deal_codes, |
| | | trade_manager.delegate_codes) |
| | | codes.add(code) |
| | | order_begin_pos = TradePointManager().get_buy_compute_start_data_cache(code) |
| | | mode = OrderBeginPosInfo.MODE_ACTIVE |
| | | if order_begin_pos: |
| | | mode = order_begin_pos.mode |
| | | codes_info.append((code, insertTime, mode)) |
| | | order_statistic.DealAndDelegateWithBuyModeDataManager().set_delegates_info(codes_info) |
| | | if codes: |
| | | try: |
| | | trade_manager.process_trade_delegate_data([{"code": c} for c in codes]) |
| | |
| | | for d in datas: |
| | | if str(d['direction']) == str(huaxin_util.TORA_TSTP_D_Buy): |
| | | buy_deal_codes.add(d['securityID']) |
| | | trade_manager.deal_codes = buy_deal_codes |
| | | buy_money_count_setting.set_buy_money(trade_manager.deal_codes, trade_manager.delegate_codes) |
| | | except Exception as e: |
| | | logger_debug.exception(e) |
| | | huaxin_trade_record_manager.DealRecordManager.add(datas) |
New file |
| | |
| | | import json |
| | | |
| | | from db import redis_manager |
| | | from db.redis_manager_delegate import RedisUtils |
| | | from log_module import async_log_util |
| | | from log_module.log import logger_debug |
| | | from utils import tool |
| | | |
| | | |
| | | class DealAndDelegateWithBuyModeDataManager: |
| | | """ |
| | | 成交与委托买入模式数据管理 |
| | | 成交数据需要持久化 |
| | | """ |
| | | __instance = None |
| | | __db = 2 |
| | | __redisManager = redis_manager.RedisManager(2) |
| | | __deal_codes = set() |
| | | __deal_mode_list_dict = {} |
| | | __delegates_mode_list_dict = {} |
| | | |
| | | def __new__(cls, *args, **kwargs): |
| | | if not cls.__instance: |
| | | cls.__instance = super(DealAndDelegateWithBuyModeDataManager, cls).__new__(cls, *args, **kwargs) |
| | | cls.__load_datas() |
| | | return cls.__instance |
| | | |
| | | @classmethod |
| | | def __get_redis(cls): |
| | | return cls.__redisManager.getRedis() |
| | | |
| | | @classmethod |
| | | def __load_datas(cls): |
| | | keys = RedisUtils.keys(cls.__get_redis(), "deal_delegate_by_mode-*") |
| | | for k in keys: |
| | | mode = int(k.split("-")[1]) |
| | | val = RedisUtils.get(cls.__get_redis(), k) |
| | | cls.__deal_mode_list_dict[mode] = json.loads(val) |
| | | for m in cls.__deal_mode_list_dict: |
| | | cls.__deal_codes |= set([x[0] for x in cls.__deal_mode_list_dict[m]]) |
| | | |
| | | def add_deal_code(self, code, deal_time, mode): |
| | | """ |
| | | 添加成交数据 |
| | | @param code: |
| | | @param deal_time: |
| | | @param mode: 买入模式 |
| | | @return: |
| | | """ |
| | | async_log_util.info(logger_debug, f"下单模式统计成交:{code}-{deal_time}-{mode}") |
| | | # 添加成交数据 |
| | | if code in self.__deal_codes: |
| | | return |
| | | self.__deal_codes.add(code) |
| | | if mode not in self.__deal_mode_list_dict: |
| | | self.__deal_mode_list_dict[mode] = [] |
| | | self.__deal_mode_list_dict[mode].append((code, deal_time)) |
| | | # 将当前数据缓存到数据库 |
| | | RedisUtils.setex_async(self.__db, f"deal_delegate_by_mode-{mode}", tool.get_expire(), |
| | | json.dumps(self.__deal_mode_list_dict[mode])) |
| | | |
| | | def get_deal_codes_info(self, mode): |
| | | """ |
| | | 获取成交代码信息 |
| | | @param mode: |
| | | @return: |
| | | """ |
| | | return self.__deal_mode_list_dict.get(mode) |
| | | |
| | | def set_delegates_info(self, delegates): |
| | | """ |
| | | 设置委托信息 |
| | | @param delegates:[(代码,委托时间, 委托模式)] |
| | | @return: |
| | | """ |
| | | temp_dict = {} |
| | | for d in delegates: |
| | | mode = d[2] |
| | | if mode not in temp_dict: |
| | | temp_dict[mode] = [] |
| | | temp_dict[mode].append((d[0], d[1])) |
| | | self.__delegates_mode_list_dict = temp_dict |
| | | |
| | | def get_delegates_codes_info(self, mode): |
| | | """ |
| | | 获取成交代码信息 |
| | | @param mode: |
| | | @return: |
| | | """ |
| | | return self.__delegates_mode_list_dict.get(mode) |
| | | |
| | |
| | | from l2 import l2_data_manager, l2_data_log |
| | | |
| | | from log_module.log import * |
| | | from trade.buy_money_count_setting import BuyMoneyUtil |
| | | from trade.huaxin.huaxin_trade_record_manager import TradeOrderIdManager |
| | | from trade.order_statistic import DealAndDelegateWithBuyModeDataManager |
| | | from trade.trade_data_manager import AccountMoneyManager, RadicalBuyDealCodesManager |
| | | from utils import import_util, tool, huaxin_util |
| | | |
| | |
| | | guiTrade = None # trade_gui.THSGuiTrade() if trade_gui is not None else None |
| | | |
| | | latest_trade_delegate_data = [] |
| | | |
| | | # 成交的代码 |
| | | deal_codes = set() |
| | | # 委托代码 |
| | | delegate_codes = set() |
| | | |
| | | |
| | | # 关闭购买入口 |
| | |
| | | |
| | | def get_mode_cache(self): |
| | | return self.__auto_cancel_sell_mode |
| | | |
| | | |
| | | # 代码的交易状态管理 |
| | | class CodesTradeStateManager: |
| | |
| | | async_log_util.info(logger_trade, "{} trade_manager.__buy 开始".format(code)) |
| | | try: |
| | | if constant.API_TRADE_ENABLE: |
| | | count = tool.get_buy_volume(price) |
| | | can_buy, money, msg = BuyMoneyUtil.get_buy_data(tool.get_now_time_str(), mode, DealAndDelegateWithBuyModeDataManager().get_deal_codes_info(mode), DealAndDelegateWithBuyModeDataManager().get_delegates_codes_info(mode)) |
| | | if not can_buy: |
| | | raise Exception(msg) |
| | | count = tool.get_buy_volume_by_money(price, money) |
| | | |
| | | # if mode == OrderBeginPosInfo.MODE_RADICAL: |
| | | # # 激进买入金额为1手 |
| | | # count = 100 |
| | |
| | | # 加入黑名单 |
| | | if not l2_trade_util.is_in_forbidden_trade_codes(code): |
| | | l2_trade_util.forbidden_trade(code, "buy success", force=True) |
| | | if TradePointManager().get_latest_place_order_mode(code) == OrderBeginPosInfo.MODE_RADICAL: |
| | | mode = TradePointManager().get_latest_place_order_mode(code) |
| | | if mode is None: |
| | | mode = OrderBeginPosInfo.MODE_NORMAL |
| | | DealAndDelegateWithBuyModeDataManager().add_deal_code(code, tool.get_now_time_str(), mode) |
| | | if mode == OrderBeginPosInfo.MODE_RADICAL: |
| | | RadicalBuyDealCodesManager().add_deal_code(code) |
| | | # 取s消所有的挂单 |
| | | if constant.API_TRADE_ENABLE: |
| | |
| | | |
| | | |
| | | def get_buy_volume(limit_up_price): |
| | | count = (constant.BUY_MONEY_PER_CODE // int(round(float(limit_up_price) * 100))) * 100 |
| | | return get_buy_volume_by_money(limit_up_price, constant.BUY_MONEY_PER_CODE) |
| | | |
| | | |
| | | def get_buy_volume_by_money(limit_up_price, money): |
| | | count = (money // int(round(float(limit_up_price) * 100))) * 100 |
| | | if count < 100: |
| | | count = 100 |
| | | return count |