| | |
| | | |
| | | |
| | | def alarm(): |
| | | return |
| | | if not tool.is_alert_time() or constant.TEST: |
| | | return |
| | | # TODO 暂时关闭报警 |
| | |
| | | return _volumn |
| | | |
| | | |
| | | # 获取量比(今日量/max(60天最大量,昨日量)) |
| | | def get_volume_rate(code): |
| | | today = get_today_volumn(code) |
| | | max60, yesterday = get_histry_volumn(code) |
| | | if today is None or max60 is None or yesterday is None: |
| | | raise Exception("获取量失败") |
| | | return round(int(today) / max(int(max60), int(yesterday)), 2) |
| | | |
| | | |
| | | # 获取量比索引 |
| | | def get_volume_rate_index(volume_rate): |
| | | rates = [0.2, 0.4, 0.6, 0.8, 1, 1.2, 1.4, 1.6] |
| | | for index in range(0, len(rates)): |
| | | if volume_rate <= rates[index]: |
| | | return index |
| | | return len(rates) - 1 |
| | | |
| | | |
| | | # 保存今日量 |
| | | def save_today_volumn(code, volumn, volumnUnit): |
| | | _volumn = None |
| | |
| | | BIG_MONEY_NUM = 7888 |
| | | |
| | | # S撤比例 |
| | | S_CANCEL_FIRST_RATE = 0.69 |
| | | S_CANCEL_MIN_MONEY = 98 |
| | | S_CANCEL_SECOND_RATE = 0.59 |
| | | S_CANCEL_THIRD_RATE = 0.49 |
| | | # s撤守护时间 |
| | |
| | | |
| | | # H撤比例 |
| | | H_CANCEL_FIRST_RATE = 0.69 |
| | | H_CANCEL_SECOND_RATE = 0.59 |
| | | H_CANCEL_THIRD_RATE = 0.49 |
| | | H_CANCEL_MIN_MONEY = 10000000 |
| | | H_CANCEL_MIN_MONEY = 98 |
| | | H_CANCEL_MIN_COUNT = 40 |
| | | H_CANCEL_MIN_BIG_NUM_COUNT = 3 |
| | | |
| | |
| | | import tool |
| | | import decimal |
| | | |
| | | from ths import l2_listen_pos_health_manager |
| | | |
| | | __redisManager = redis_manager.RedisManager(0) |
| | | |
| | | |
| | |
| | | return val.get(name) |
| | | |
| | | @classmethod |
| | | def add_first_code_name(cls, code,name): |
| | | def add_first_code_name(cls, code, name): |
| | | val = cls.__get_redis().get("gp_list_names_first") |
| | | if not val: |
| | | return None |
| | |
| | | return True |
| | | else: |
| | | return False |
| | | |
| | | |
| | | # 想要买的代码 |
| | | class WantBuyCodesManager: |
| | | redisManager = redis_manager.RedisManager(0) |
| | | __redis_key = "want_buy_codes" |
| | | |
| | | @classmethod |
| | | def __get_redis(cls): |
| | | return cls.redisManager.getRedis() |
| | | |
| | | @classmethod |
| | | def clear(cls): |
| | | cls.__get_redis().delete(cls.__redis_key) |
| | | |
| | | @classmethod |
| | | def add_code(cls, code): |
| | | cls.__get_redis().sadd(cls.__redis_key, code) |
| | | |
| | | @classmethod |
| | | def remove_code(cls, code): |
| | | cls.__get_redis().srem(cls.__redis_key, code) |
| | | |
| | | @classmethod |
| | | def is_in(cls, code): |
| | | return cls.__get_redis().sismember(cls.__redis_key, code) |
| | | |
| | | @classmethod |
| | | def list_code(cls): |
| | | return cls.__get_redis().smembers(cls.__redis_key) |
| | | |
| | | |
| | | def __parse_codes_data(code_datas): |
| | |
| | | client_ids = client_manager.getValidL2Clients() |
| | | else: |
| | | client_ids.append(client_id) |
| | | random.shuffle(client_ids) |
| | | # random.shuffle(client_ids) |
| | | available_positions = [] |
| | | for client_id in client_ids: |
| | | redis_instance = __redisManager.getRedis() |
| | | k = "listen_code-{}-*".format(client_id) |
| | | keys = redis_instance.keys(k) |
| | | random.shuffle(keys) |
| | | # random.shuffle(keys) |
| | | codes = [] |
| | | for key in keys: |
| | | index = key.split("-")[-1] |
| | |
| | | continue |
| | | result = redis_instance.get(key) |
| | | if result is None or len(result) == 0: |
| | | return client_id, int(key.replace("listen_code-{}-".format(client_id), "")) |
| | | available_positions.append((client_id, int(key.replace("listen_code-{}-".format(client_id), "")))) |
| | | else: |
| | | codes.append((key, result)) |
| | | |
| | | # 查询是否有重复的代码 |
| | | codes_set = set() |
| | | count = 0 |
| | |
| | | codes_set.add(code[1]) |
| | | if len(codes_set) < count: |
| | | return client_id, int(code[0].replace("listen_code-{}-".format(client_id), "")) |
| | | |
| | | if available_positions: |
| | | # 获取健康状态 |
| | | available_positions_health_states = l2_listen_pos_health_manager.list_health_state(available_positions) |
| | | available_positions.sort(key=lambda x: available_positions_health_states[x], reverse=True) |
| | | # 取第1个数据 |
| | | return available_positions[0][0], available_positions[0][1] |
| | | |
| | | |
| | | |
| | | return None, None |
| | | |
| | |
| | | |
| | | |
| | | if __name__ == '__main__': |
| | | print(get_free_listen_pos_count()) |
| | | print(get_name_code("华脉科技")) |
| | | print(get_name_codes()) |
| | | print(get_can_listen_pos()) |
| | |
| | | l2_trade_util.init_forbidden_trade_codes() |
| | | # 清空白名单 |
| | | l2_trade_util.WhiteListCodeManager.clear() |
| | | |
| | | # TODO 删除所有首板代码 |
| | | # 清空想要买 |
| | | gpcode_manager.WantBuyCodesManager.clear() |
| | | |
| | | |
| | | # 每日初始化 |
| | |
| | | return f_results |
| | | |
| | | @classmethod |
| | | def get_history_tick_n(cls, code, count): |
| | | def get_history_tick_n(cls, code, count, fields=None): |
| | | account_id, s_id, token = getAccountInfo() |
| | | symbols = gpcode_manager.get_gp_list_with_prefix([code]) |
| | | gmapi.set_token(token) |
| | | results = gmapi.history_n(symbol=symbols[0], frequency="1d", count=count) |
| | | results = gmapi.history_n(symbol=symbols[0], frequency="1d", count=count, fields=fields) |
| | | return results |
| | | |
| | | @classmethod |
| | |
| | | |
| | | |
| | | # 获取近90天的最大量与最近的量 |
| | | # 获取最近一次涨停/涨停下一个交易日的最大值 |
| | | def get_volumn(code) -> object: |
| | | end = datetime.datetime.now() |
| | | account_id, s_id, token = getAccountInfo() |
| | | gmapi.set_token(token) |
| | | gmapi.set_account_id(account_id) |
| | | results = gmapi.history_n(symbol=gpcode_manager.get_gp_list_with_prefix([code])[0], frequency="1d", |
| | | count=60, |
| | | fields="volume", |
| | | end_time=end) |
| | | if not results: |
| | | return None |
| | | yes_volume = results[-1]["volume"] |
| | | max_volume = results[0]["volume"] |
| | | for result in results: |
| | | volumn = int(result["volume"]) |
| | | if volumn > max_volume: |
| | | max_volume = volumn |
| | | return (max_volume, yes_volume) |
| | | datas = JueJinManager.get_history_tick_n(code, 60, "open,high,low,close,volume,pre_close,bob") |
| | | # 计算 |
| | | datas.sort(key=lambda x: x["bob"], reverse=True) |
| | | max_volume = 0 |
| | | for i in range(len(datas)): |
| | | # 查询涨停 |
| | | item = datas[i] |
| | | volume = item["volume"] |
| | | if max_volume < volume: |
| | | max_volume = volume |
| | | # 是否有涨停 |
| | | limit_up_price = float(gpcode_manager.get_limit_up_price_by_preprice(item["pre_close"])) |
| | | if abs(limit_up_price - item["high"]) < 0.01: |
| | | next_volume = 0 |
| | | if i > 0: |
| | | next_volume = datas[i - 1]["volume"] |
| | | return (max(volume, next_volume), max(volume, next_volume)) |
| | | return (max_volume, max_volume) |
| | | |
| | | |
| | | # 根据涨幅高低分配交易窗口 |
| | |
| | | |
| | | |
| | | if __name__ == '__main__': |
| | | free_count = 0 |
| | | if free_count < 2: |
| | | # 空闲位置不足 |
| | | listen_codes = gpcode_manager.get_listen_codes() |
| | | for code in listen_codes: |
| | | if not gpcode_manager.is_in_gp_pool(code): |
| | | client_id, pos = gpcode_manager.get_listen_code_pos(code) |
| | | gpcode_manager.set_listen_code_by_pos(client_id, pos, "") |
| | | free_count += 1 |
| | | if free_count > 2: |
| | | break |
| | | print(get_volumn("002291")) |
| | |
| | | |
| | | class SecondCancelBigNumComputer: |
| | | __redis_manager = redis_manager.RedisManager(0) |
| | | __sCancelParamsManager = l2_trade_factor.SCancelParamsManager |
| | | |
| | | @classmethod |
| | | def __getRedis(cls): |
| | |
| | | |
| | | # 计算净大单 |
| | | @classmethod |
| | | def __compute_left_big_num(cls, code, buy_single_index, start_index, end_index, total_data, place_order_count): |
| | | def __compute_left_big_num(cls, code, buy_single_index, start_index, end_index, total_data, volume_rate_index): |
| | | # 获取大单的最小手数 |
| | | left_big_num = 0 |
| | | # 点火大单数量 |
| | | fire_count = 5 |
| | | if place_order_count <= 4: |
| | | fire_count = 6 - place_order_count |
| | | else: |
| | | fire_count = 2 |
| | | fire_count = cls.__sCancelParamsManager.get_max_exclude_count(volume_rate_index) |
| | | for i in range(start_index, end_index + 1): |
| | | data = total_data[i] |
| | | val = data["val"] |
| | | # 去除非大单 |
| | | if not l2_data_util.is_big_money(val): |
| | | if val["num"] * float(val["price"]) <= constant.S_CANCEL_MIN_MONEY * 100: |
| | | continue |
| | | |
| | | if L2DataUtil.is_limit_up_price_buy(val): |
| | |
| | | |
| | | @classmethod |
| | | def need_cancel(cls, 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 start_index >= 217: |
| | | print("进入调试") |
| | | # 只守护30s |
| | | buy_exec_time = total_data[buy_exec_index]["val"]["time"] |
| | | if tool.trade_time_sub(total_data[start_index]["val"]["time"], |
| | | total_data[buy_exec_index]["val"]["time"]) > constant.S_CANCEL_EXPIRE_TIME: |
| | | buy_exec_time) > constant.S_CANCEL_EXPIRE_TIME: |
| | | return False, None |
| | | l2_log.cancel_debug(code, "S级是否需要撤单,数据范围:{}-{} ", start_index, end_index) |
| | | logger_l2_s_cancel.debug(f"code-{code} S级是否需要撤单,数据范围:{start_index}-{end_index}") |
| | |
| | | # if buy_index is not None and a_start_index <= buy_index <= a_end_index: |
| | | # # 在买入信号之后 |
| | | # cls.__save_cancel_data(code, i) |
| | | |
| | | range_seconds = cls.__sCancelParamsManager.get_buy_time_range(buy_volume_rate_index) |
| | | cancel_rate_threshold = cls.__sCancelParamsManager.get_cancel_rate(volume_rate_index) |
| | | try: |
| | | for i in range(start_index, end_index + 1): |
| | | data = total_data[i] |
| | |
| | | if process_index_old >= i: |
| | | # 已经处理过的数据不需要处理 |
| | | continue |
| | | if not l2_data_util.is_big_money(val): |
| | | if val["num"] * float(val["price"]) <= constant.S_CANCEL_MIN_MONEY * 100: |
| | | continue |
| | | |
| | | if L2DataUtil.is_limit_up_price_buy(val): |
| | | buy_num += data["re"] * int(val["num"]) |
| | | # 如果在囊括时间范围内就可以计算买 |
| | | 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(code, data, |
| | | local_today_num_operate_map.get( |
| | | code)) |
| | | if buy_index is not None and buy_single_index <= buy_index: |
| | | cancel_num += total_data[buy_index]["re"] * int(total_data[buy_index]["val"]["num"]) |
| | | # 买入时间在囊括范围内 |
| | | if 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"], |
| | |
| | | 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(":", "")): |
| | | cancel_num += data["re"] * int(val["num"]) |
| | | # 买入时间在囊括范围内 |
| | | if tool.trade_time_sub(tool.trade_time_add_second(buy_exec_time, range_seconds), |
| | | total_data[buy_index]["val"]["time"]) >= 0: |
| | | cancel_num += data["re"] * int(val["num"]) |
| | | |
| | | # 保存数据 |
| | | |
| | | if need_cancel: |
| | | cancel_rate_threshold = constant.S_CANCEL_FIRST_RATE |
| | | |
| | | if place_order_count <= 1: |
| | | cancel_rate_threshold = constant.S_CANCEL_FIRST_RATE |
| | | elif place_order_count <= 2: |
| | | cancel_rate_threshold = constant.S_CANCEL_SECOND_RATE |
| | | else: |
| | | cancel_rate_threshold = constant.S_CANCEL_THIRD_RATE |
| | | if is_first_code: |
| | | cancel_rate_threshold += 0.1 |
| | | cancel_rate_threshold = round(cancel_rate_threshold, 2) |
| | | if cancel_num / max(buy_num, 1) > 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)) |
| | | 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) |
| | | |
| | | # 保存处理进度与数据 |
| | | cls.__save_compute_data(code, process_index, buy_num, cancel_num) |
| | |
| | | __redis_manager = redis_manager.RedisManager(0) |
| | | __tradeBuyQueue = TradeBuyQueue() |
| | | __buyL2SafeCountManager = BuyL2SafeCountManager() |
| | | __hCancelParamsManager = l2_trade_factor.HCancelParamsManager() |
| | | |
| | | @classmethod |
| | | def __getRedis(cls): |
| | |
| | | |
| | | @classmethod |
| | | def need_cancel(cls, code, buy_exec_index, start_index, end_index, total_data, local_today_num_operate_map, |
| | | buy_volume_index, volume_index, |
| | | is_first_code): |
| | | time_space = tool.trade_time_sub(total_data[start_index]["val"]["time"], |
| | | total_data[buy_exec_index]["val"]["time"]) |
| | | if time_space >= constant.S_CANCEL_EXPIRE_TIME - 1: |
| | | # 开始计算需要监控的单 |
| | | cls.__compute_watch_indexs_after_exec(code, buy_exec_index, total_data, local_today_num_operate_map) |
| | | cls.__compute_watch_indexs_after_exec(code, buy_exec_index, total_data, local_today_num_operate_map, |
| | | buy_volume_index) |
| | | |
| | | # 守护30s以外的数据 |
| | | if time_space <= constant.S_CANCEL_EXPIRE_TIME: |
| | |
| | | l2_log.cancel_debug(code, "H级是否需要撤单,数据范围:{}-{} ", start_index, end_index) |
| | | # 获取下单次数 |
| | | place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(code) |
| | | cancel_rate_threshold = constant.H_CANCEL_FIRST_RATE |
| | | if place_order_count <= 1: |
| | | cancel_rate_threshold = constant.H_CANCEL_FIRST_RATE |
| | | elif place_order_count <= 2: |
| | | cancel_rate_threshold = constant.H_CANCEL_SECOND_RATE |
| | | else: |
| | | cancel_rate_threshold = constant.H_CANCEL_THIRD_RATE |
| | | if is_first_code: |
| | | cancel_rate_threshold += 0.1 |
| | | cancel_rate_threshold = round(cancel_rate_threshold,2) |
| | | cancel_rate_threshold = cls.__hCancelParamsManager.get_cancel_rate(volume_index) |
| | | process_index = start_index |
| | | try: |
| | | for i in range(start_index, end_index + 1): |
| | |
| | | if cancel_num / total_nums > cancel_rate_threshold: |
| | | return True, data |
| | | finally: |
| | | l2_log.cancel_debug(code, "H级撤单计算结果 范围:{}-{} 处理进度:{} 取消计算结果:{}/{}", start_index, end_index, |
| | | l2_log.cancel_debug(code, "H级撤单计算结果 范围:{}-{} 处理进度:{} 取消计算结果:{}/{} 目标撤单比例:{}", start_index, end_index, |
| | | process_index, cancel_num, |
| | | total_nums) |
| | | total_nums,cancel_rate_threshold) |
| | | logger_l2_h_cancel.info( |
| | | f"code-{code} H级撤单计算结果 范围:{start_index}-{end_index} 处理进度:{process_index} 目标比例:{cancel_rate_threshold} 取消计算结果:{cancel_num}/{total_nums}") |
| | | # 保存处理进度与数据 |
| | |
| | | if left_count > 0: |
| | | data = total_data[i] |
| | | val = data["val"] |
| | | if val["num"] * float(val["price"]) <= 9900: |
| | | if val["num"] * float(val["price"]) <= constant.H_CANCEL_MIN_MONEY*100: |
| | | continue |
| | | total_count += left_count |
| | | watch_set.add((i, val["num"], left_count)) |
| | |
| | | |
| | | # 计算执行位置之后的需要监听的数据 |
| | | @classmethod |
| | | def __compute_watch_indexs_after_exec(cls, code, buy_exec_index, total_data, local_today_num_operate_map): |
| | | def __compute_watch_indexs_after_exec(cls, code, buy_exec_index, total_data, local_today_num_operate_map, |
| | | buy_volume_index): |
| | | watch_list, process_index_old, total_count_old, big_num_count_old, finish = cls.__get_watch_index_set_after_exec( |
| | | code) |
| | | if watch_list and finish: |
| | |
| | | big_num_count = big_num_count_old |
| | | total_count = total_count_old |
| | | # H撤单 |
| | | MIN_H_COUNT = l2_trade_factor.L2TradeFactorUtil.get_h_cancel_min_count(code) |
| | | MIN_H_COUNT = cls.__hCancelParamsManager.get_max_watch_count(buy_volume_index) |
| | | |
| | | for i in range(buy_exec_index, total_data[-1]["index"] + 1): |
| | | if i <= process_index_old: |
| | |
| | | if left_count > 0: |
| | | data = total_data[i] |
| | | val = data["val"] |
| | | if val["num"] * float(val["price"]) <= 9900: |
| | | if val["num"] * float(val["price"]) <= constant.H_CANCEL_MIN_MONEY*100: |
| | | continue |
| | | total_count += left_count |
| | | watch_set.add((i, val["num"], left_count)) |
| | |
| | | # 判断是否达到阈值 |
| | | if total_count >= MIN_H_COUNT and big_num_count >= constant.H_CANCEL_MIN_BIG_NUM_COUNT: # and total_num >= threshold_num |
| | | finished = True |
| | | l2_log.cancel_debug(code, "获取到H撤监听数据:{},计算截至位置:{}", json.dumps(list(watch_set)), |
| | | total_data[-1]["index"]) |
| | | l2_log.cancel_debug(code, "获取到H撤监听数据:{},计算截至位置:{},目标计算数量:{}", json.dumps(list(watch_set)), |
| | | total_data[-1]["index"],MIN_H_COUNT) |
| | | break |
| | | |
| | | final_watch_list = list(watch_set) |
New file |
| | |
| | | """ |
| | | 代码价格管理 |
| | | """ |
| | | import json |
| | | |
| | | import tool |
| | | from db import redis_manager |
| | | |
| | | |
| | | class Buy1PriceManager: |
| | | __redisManager = redis_manager.RedisManager(1) |
| | | |
| | | @classmethod |
| | | def __get_redis(cls): |
| | | return cls.__redisManager.getRedis() |
| | | |
| | | # 保存买1价格信息 |
| | | @classmethod |
| | | def __save_buy1_price_info(cls, code, limit_up_time, open_limit_up_time): |
| | | cls.__get_redis().setex(f"buy1_price_limit_up_info-{code}", tool.get_expire(), |
| | | json.dumps((limit_up_time, open_limit_up_time))) |
| | | |
| | | @classmethod |
| | | def __get_buy1_price_info(cls, code): |
| | | data = cls.__get_redis().get(f"buy1_price_limit_up_info-{code}") |
| | | if not data: |
| | | return None, None |
| | | data = json.loads(data) |
| | | return data[0], data[1] |
| | | |
| | | # 处理 |
| | | @classmethod |
| | | def process(cls, code, buy_1_price, time_str, limit_up_price): |
| | | # 买1价格不能小于1块 |
| | | if float(buy_1_price) < 1.0: |
| | | return |
| | | is_limit_up = abs(float(limit_up_price) - float(buy_1_price)) < 0.01 |
| | | old_limit_up_time, old_open_limit_up_time = cls.__get_buy1_price_info(code) |
| | | if old_limit_up_time and old_open_limit_up_time: |
| | | return |
| | | if is_limit_up and old_limit_up_time is None: |
| | | cls.__save_buy1_price_info(code, time_str, None) |
| | | elif old_limit_up_time and not is_limit_up and old_open_limit_up_time is None: |
| | | # 有涨停时间,当前没有涨停,之前没有打开涨停 |
| | | cls.__save_buy1_price_info(code, old_limit_up_time, time_str) |
| | | |
| | | # 是否可以下单 |
| | | @classmethod |
| | | def is_can_buy(cls, code): |
| | | old_limit_up_time, old_open_limit_up_time = cls.__get_buy1_price_info(code) |
| | | if old_limit_up_time and old_open_limit_up_time: |
| | | return True |
| | | return False |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | code = "000333" |
| | | limit_up_price = "54.00" |
| | | Buy1PriceManager.process("000333", "53.00", "09:56:00", limit_up_price) |
| | | print(Buy1PriceManager.is_can_buy(code)) |
| | | Buy1PriceManager.process("000333", "54.00", "09:57:00", limit_up_price) |
| | | print(Buy1PriceManager.is_can_buy(code)) |
| | | Buy1PriceManager.process("000333", "53.00", "09:58:00", limit_up_price) |
| | | print(Buy1PriceManager.is_can_buy(code)) |
| | | Buy1PriceManager.process("000333", "54.00", "09:59:00", limit_up_price) |
| | | print(Buy1PriceManager.is_can_buy(code)) |
| | |
| | | _key = "buy_compute_index_info-{}".format(code) |
| | | _data_json = redis.get(_key) |
| | | if _data_json is None: |
| | | return None, None, None, 0, 0, [] |
| | | return None, None, None, 0, 0, [],0 |
| | | _data = json.loads(_data_json) |
| | | return _data[0], _data[1], _data[2], _data[3], _data[4], _data[5] |
| | | return _data[0], _data[1], _data[2], _data[3], _data[4], _data[5], _data[6] |
| | | |
| | | # 设置买入点的值 |
| | | # buy_single_index 买入信号位 |
| | |
| | | # compute_index 计算位置 |
| | | # nums 累计纯买额 |
| | | @staticmethod |
| | | def set_buy_compute_start_data(code, buy_single_index, buy_exec_index, compute_index, nums, count, max_num_sets): |
| | | def set_buy_compute_start_data(code, buy_single_index, buy_exec_index, compute_index, nums, count, max_num_sets, volume_rate): |
| | | redis = TradePointManager.__get_redis() |
| | | expire = tool.get_expire() |
| | | _key = "buy_compute_index_info-{}".format(code) |
| | | if buy_single_index is not None: |
| | | redis.setex(_key, expire, |
| | | json.dumps((buy_single_index, buy_exec_index, compute_index, nums, count, list(max_num_sets)))) |
| | | json.dumps((buy_single_index, buy_exec_index, compute_index, nums, count, list(max_num_sets),volume_rate))) |
| | | else: |
| | | _buy_single_index, _buy_exec_index, _compute_index, _nums, _count, _max_num_index = TradePointManager.get_buy_compute_start_data(code) |
| | | _buy_single_index, _buy_exec_index, _compute_index, _nums, _count, _max_num_index,_volume_rate = TradePointManager.get_buy_compute_start_data(code) |
| | | redis.setex(_key, expire, |
| | | json.dumps((_buy_single_index, buy_exec_index, compute_index, nums, count, list(max_num_sets)))) |
| | | json.dumps((_buy_single_index, buy_exec_index, compute_index, nums, count, list(max_num_sets),volume_rate))) |
| | | |
| | | # 获取撤买入开始计算的信息 |
| | | # 返回数据的内容为:撤销点索引 撤买纯买额 计算的数据索引 |
| | |
| | | |
| | | import big_money_num_manager |
| | | import code_data_util |
| | | import code_volumn_manager |
| | | import constant |
| | | import global_util |
| | | import gpcode_manager |
| | |
| | | import tool |
| | | from trade import trade_data_manager, trade_manager, trade_queue_manager, l2_trade_factor, l2_trade_util, \ |
| | | trade_result_manager |
| | | from l2 import safe_count_manager, l2_data_manager, l2_data_log, l2_log, l2_data_source_util |
| | | from l2 import safe_count_manager, l2_data_manager, l2_data_log, l2_log, l2_data_source_util, code_price_manager |
| | | from l2.cancel_buy_strategy import SecondCancelBigNumComputer, HourCancelBigNumComputer, L2LimitUpMoneyStatisticUtil, \ |
| | | L2LimitUpSellStatisticUtil |
| | | from l2.l2_data_manager import L2DataException, TradePointManager |
| | |
| | | |
| | | class L2TradeDataProcessor: |
| | | unreal_buy_dict = {} |
| | | volume_rate_info = {} |
| | | l2BigNumForMProcessor = L2BigNumForMProcessor() |
| | | __codeActualPriceProcessor = CodeActualPriceProcessor() |
| | | buy1PriceManager = trade_queue_manager.Buy1PriceManager() |
| | | __ths_l2_trade_queue_manager = trade_queue_manager.thsl2tradequeuemanager() |
| | | __thsBuy1VolumnManager = trade_queue_manager.THSBuy1VolumnManager() |
| | | __buyL2SafeCountManager = safe_count_manager.BuyL2SafeCountManager() |
| | | __l2PlaceOrderParamsManager = l2_trade_factor.L2PlaceOrderParamsManager() |
| | | |
| | | @classmethod |
| | | # 数据处理入口 |
| | |
| | | "l2数据预处理时间") |
| | | |
| | | if len(add_datas) > 0: |
| | | # 计算量 |
| | | volume_rate = code_volumn_manager.get_volume_rate(code) |
| | | volume_rate_index = code_volumn_manager.get_volume_rate_index(volume_rate) |
| | | cls.volume_rate_info[code] = (volume_rate, volume_rate_index) |
| | | # 是否为首板代码 |
| | | is_first_code = gpcode_manager.FirstCodeManager.is_in_first_record(code) |
| | | latest_time = add_datas[len(add_datas) - 1]["val"]["time"] |
| | |
| | | b_need_cancel, b_cancel_data = 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) |
| | | if b_need_cancel: |
| | | return b_cancel_data, "S大单撤销比例触发阈值" |
| | |
| | | b_need_cancel, b_cancel_data = HourCancelBigNumComputer.need_cancel(code, buy_exec_index, start_index, |
| | | end_index, total_data, |
| | | local_today_num_operate_map.get( |
| | | code), is_first_code) |
| | | code), |
| | | code_volumn_manager.get_volume_rate_index( |
| | | buy_volume_rate), |
| | | cls.volume_rate_info[code][1], |
| | | is_first_code) |
| | | if b_need_cancel and b_cancel_data: |
| | | return b_cancel_data, "H撤销比例触发阈值" |
| | | except Exception as e: |
| | |
| | | total_data = local_today_datas.get(code) |
| | | _start_time = tool.get_now_timestamp() |
| | | # 获取买入信号起始点 |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set = cls.__get_order_begin_pos(code) |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos( |
| | | code) |
| | | |
| | | f1 = compute_safe_count() |
| | | f2 = compute_m_big_num() |
| | |
| | | f5 = buy_1_cancel() |
| | | f6 = sell_cancel() |
| | | dask_result = is_need_cancel(f1, f2, f3, f4, f5, f6) |
| | | if is_first_code: |
| | | dask_result = is_need_cancel(f3, f4) |
| | | |
| | | cancel_data, cancel_msg = dask_result.compute() |
| | | |
| | | _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time, |
| | |
| | | if not can: |
| | | l2_log.debug(code, "不可以下单,原因:{}", reason) |
| | | if need_clear_data: |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set = cls.__get_order_begin_pos( |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos( |
| | | code) |
| | | trade_result_manager.real_cancel_success(code, buy_single_index, buy_exec_index, |
| | | local_today_datas.get(code)) |
| | |
| | | __start_time = t.time() |
| | | # 判断是否为首板代码 |
| | | if is_first_code: |
| | | # 首板代码且尚未涨停过的不能下单 |
| | | is_limited_up = gpcode_manager.FirstCodeManager.is_limited_up(code) |
| | | if not is_limited_up: |
| | | if not gpcode_manager.WantBuyCodesManager.is_in(code): |
| | | is_limited_up = gpcode_manager.FirstCodeManager.is_limited_up(code) |
| | | gpcode_manager.FirstCodeManager.add_limited_up_record([code]) |
| | | place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count( |
| | | code) |
| | | if place_order_count == 0: |
| | | trade_data_manager.placeordercountmanager.place_order(code) |
| | | return False, True, "首板代码,且尚未涨停过" |
| | | if not code_price_manager.Buy1PriceManager.is_can_buy(code): |
| | | return False, True, "首板代码,没在想要买名单中且未打开涨停板" |
| | | if not is_limited_up: |
| | | return False, True, "首板代码,没在想要买名单中且未涨停过" |
| | | |
| | | # 之前的代码 |
| | | # 首板代码且尚未涨停过的不能下单 |
| | | # is_limited_up = gpcode_manager.FirstCodeManager.is_limited_up(code) |
| | | # if not is_limited_up: |
| | | # gpcode_manager.FirstCodeManager.add_limited_up_record([code]) |
| | | # place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count( |
| | | # code) |
| | | # if place_order_count == 0: |
| | | # trade_data_manager.placeordercountmanager.place_order(code) |
| | | # return False, True, "首板代码,且尚未涨停过" |
| | | |
| | | try: |
| | | # 买1价格必须为涨停价才能买 |
| | |
| | | if sell1_time is not None and sell1_volumn > 0: |
| | | # 获取执行位信息 |
| | | |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set = cls.__get_order_begin_pos( |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos( |
| | | code) |
| | | buy_nums = num |
| | | for i in range(buy_exec_index + 1, total_datas[-1]["index"] + 1): |
| | |
| | | @classmethod |
| | | def cancel_buy(cls, code, msg=None, source="l2"): |
| | | # 是否是交易队列触发 |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set = cls.__get_order_begin_pos( |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos( |
| | | code) |
| | | total_datas = local_today_datas[code] |
| | | if source == "trade_queue": |
| | |
| | | local_today_num_operate_map.get(code)) |
| | | |
| | | # 获取买入信号计算起始位置 |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set = cls.__get_order_begin_pos( |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set, buy_volume_rate = cls.__get_order_begin_pos( |
| | | code) |
| | | |
| | | # 是否为新获取到的位置 |
| | | new_get_single = False |
| | | if buy_single_index is None: |
| | | place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(code) |
| | | continue_count = 3 |
| | | # 前2次的信号连续笔数为3,后面为2 |
| | | if place_order_count > 2: |
| | | continue_count = 2 |
| | | continue_count = cls.__l2PlaceOrderParamsManager.get_begin_continue_buy_count(cls.volume_rate_info[code][1]) |
| | | # 有买入信号 |
| | | has_single, _index = cls.__compute_order_begin_pos(code, max( |
| | | (compute_start_index - continue_count - 1) if new_add else compute_start_index, 0), continue_count, |
| | |
| | | max_num_set) |
| | | _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time, "纯买额统计时间") |
| | | |
| | | l2_log.debug(code, "m值-{} m值因子-{}", threshold_money, msg) |
| | | l2_log.debug(code, "m值-{} 量比:{}", threshold_money, cls.volume_rate_info[code][0]) |
| | | |
| | | # 买入信号位与计算位置间隔2s及以上了 |
| | | if rebegin_buy_pos is not None: |
| | |
| | | buy_count, total_datas[compute_index]) |
| | | |
| | | f1 = dask.delayed(cls.__save_order_begin_data)(code, buy_single_index, compute_index, compute_index, |
| | | buy_nums, buy_count, max_num_set_new) |
| | | buy_nums, buy_count, max_num_set_new, |
| | | cls.volume_rate_info[code][0]) |
| | | f2 = dask.delayed(limit_up_time_manager.save_limit_up_time)(code, total_datas[compute_index]["val"]["time"]) |
| | | f3 = dask.delayed(cls.__virtual_buy)(code, buy_single_index, compute_index, capture_time) |
| | | f4 = dask.delayed(l2_data_manager.TradePointManager.delete_buy_cancel_point)(code) |
| | |
| | | compute_index, |
| | | buy_single_index, compute_index, |
| | | total_datas, is_first_code, |
| | | cls.volume_rate_info[code][1], |
| | | cls.volume_rate_info[code][1], |
| | | True) |
| | | _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time, |
| | | "S级大单处理耗时", force=True) |
| | |
| | | cls.__buy(code, capture_time, total_datas[compute_index], compute_index, is_first_code) |
| | | else: |
| | | SecondCancelBigNumComputer.need_cancel(code, buy_single_index, compute_index, buy_single_index, |
| | | compute_index, total_datas, is_first_code, False) |
| | | compute_index, total_datas, is_first_code, |
| | | cls.volume_rate_info[code][1], |
| | | cls.volume_rate_info[code][1], False) |
| | | |
| | | _start_time = l2_data_log.l2_time(code, tool.get_now_timestamp() - _start_time, |
| | | "S级大单处理耗时", force=True) |
| | |
| | | # 未达到下单条件,保存纯买额,设置纯买额 |
| | | # 记录买入信号位置 |
| | | cls.__save_order_begin_data(code, buy_single_index, -1, compute_end_index, buy_nums, buy_count, |
| | | max_num_set_new) |
| | | max_num_set_new, None) |
| | | print("保存大单时间", round((t.time() - _start_time) * 1000)) |
| | | _start_time = t.time() |
| | | pass |
| | |
| | | # 获取下单起始信号 |
| | | @classmethod |
| | | def __get_order_begin_pos(cls, code): |
| | | buy_single_index, buy_exec_index, compute_index, num, count, max_num_set = l2_data_manager.TradePointManager.get_buy_compute_start_data( |
| | | buy_single_index, buy_exec_index, compute_index, num, count, max_num_set, volume_rate = l2_data_manager.TradePointManager.get_buy_compute_start_data( |
| | | code) |
| | | return buy_single_index, buy_exec_index, compute_index, num, count, max_num_set |
| | | return buy_single_index, buy_exec_index, compute_index, num, count, max_num_set, volume_rate |
| | | |
| | | # 保存下单起始信号 |
| | | @classmethod |
| | | def __save_order_begin_data(self, code, buy_single_index, buy_exec_index, compute_index, num, count, max_num_set): |
| | | def __save_order_begin_data(self, code, buy_single_index, buy_exec_index, compute_index, num, count, max_num_set, |
| | | volume_rate): |
| | | TradePointManager.set_buy_compute_start_data(code, buy_single_index, buy_exec_index, compute_index, num, count, |
| | | max_num_set) |
| | | max_num_set, volume_rate) |
| | | |
| | | # 计算下单起始信号 |
| | | # compute_data_count 用于计算的l2数据数量 |
| | |
| | | |
| | | @classmethod |
| | | def __get_threshmoney(cls, code): |
| | | return l2_trade_factor.L2TradeFactorUtil.compute_m_value(code) |
| | | return l2_trade_factor.L2TradeFactorUtil.compute_m_value(code, cls.volume_rate_info[code][1]) |
| | | |
| | | # 计算万手哥笔数 |
| | | @classmethod |
| | |
| | | buy_nums = origin_num |
| | | buy_count = origin_count |
| | | limit_up_price = gpcode_manager.get_limit_up_price(code) |
| | | buy1_price = cls.buy1PriceManager.get_price(code) |
| | | if limit_up_price is None: |
| | | raise Exception("涨停价无法获取") |
| | | # 目标手数 |
| | | threshold_num = round(threshold_money / (limit_up_price * 100)) |
| | | |
| | | place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(code) |
| | | # place_order_count = trade_data_manager.placeordercountmanager.get_place_order_count(code) |
| | | # 目标订单数量 |
| | | threshold_count = cls.__buyL2SafeCountManager.get_safe_count(code, is_first_code, place_order_count) |
| | | threshold_count = cls.__buyL2SafeCountManager.get_safe_count(code, is_first_code, |
| | | cls.__l2PlaceOrderParamsManager.get_safe_count_rate( |
| | | cls.volume_rate_info[code][1])) |
| | | |
| | | buy_single_time_seconds = L2DataUtil.get_time_as_second(total_datas[buy_single_index]["val"]["time"]) |
| | | |
| | | # 可以触发买,当有涨停买信号时才会触发买 |
| | | trigger_buy = True |
| | | |
| | | if place_order_count > 3: |
| | | place_order_count = 3 |
| | | # 间隔最大时间依次为:3,9,27,81 |
| | | max_space_time = pow(3, place_order_count + 1) - 1 |
| | | max_space_time = cls.__l2PlaceOrderParamsManager.get_time_range(cls.volume_rate_info[code][1]) |
| | | # 最大买量 |
| | | max_buy_num = 0 |
| | | max_buy_num_set = set(max_num_set) |
| | | |
| | | # 需要的最小大单笔数 |
| | | big_num_count = 2 |
| | | if place_order_count > 1: |
| | | # 第一次下单需要大单最少2笔,以后只需要1笔 |
| | | big_num_count = 1 |
| | | big_num_count = cls.__l2PlaceOrderParamsManager.get_big_num_count(cls.volume_rate_info[code][1]) |
| | | |
| | | # 较大单的手数 |
| | | bigger_num = round(5900 / limit_up_price) |
| | |
| | | return l2_trade_factor.L2TradeFactorUtil.get_safe_buy_count(code, is_first) |
| | | |
| | | # 获取最后的安全笔数 |
| | | def get_safe_count(self, code, is_first_code, place_order_count=None): |
| | | def get_safe_count(self, code, is_first_code, rate): |
| | | rate = self.__get_rate(code) |
| | | # 第4次下单按第一次算 |
| | | if place_order_count and place_order_count >= 3: |
| | | rate = 1 |
| | | print("--------------------------------") |
| | | print("安全笔数比例:", rate) |
| | | print("--------------------------------") |
| | | count, min_count, max_count = self.__get_base_save_count(code, is_first_code) |
| | | count = round(count * rate) |
| | | if count < min_count: |
| | | count = min_count |
| | | if count > max_count: |
| | | count = max_count |
| | | return count |
| | | # 第4次下单按第一次算 |
| | | # if place_order_count and place_order_count >= 3: |
| | | # rate = 1 |
| | | # print("--------------------------------") |
| | | # print("安全笔数比例:", rate) |
| | | # print("--------------------------------") |
| | | # count, min_count, max_count = self.__get_base_save_count(code, is_first_code) |
| | | # count = round(count * rate) |
| | | # if count < min_count: |
| | | # count = min_count |
| | | # if count > max_count: |
| | | # count = max_count |
| | | return int(round(count*(1+rate),0)) |
| | | |
| | | # 计算留下来的比例 |
| | | # last_buy_single_index 上一次下单信号起始位置 |
| | |
| | | # 忽略第一条数据 |
| | | for i in range(1, len(queues)): |
| | | num = queues[i] |
| | | if num > min_num: |
| | | if num > min_num and len(num_list) < 4: |
| | | num_list.append(num) |
| | | # 保存列表 |
| | | self.__save_buy_queue_data(code, num_list) |
| | |
| | | index = None |
| | | if True: |
| | | # 最多5个数据 |
| | | buyQueueBigTemp = buyQueueBig[:5] |
| | | buyQueueBigTemp = buyQueueBig |
| | | last_index, is_default = self.get_traded_index(code) |
| | | c_last_index = 0 |
| | | if not is_default and last_index is not None: |
| | |
| | | return True |
| | | else: |
| | | return False |
| | | # if int(val["num"]) >= constant.BIG_MONEY_NUM: |
| | | # return True |
| | | # if int(val["num"]) * limit_up_price >= constant.BIG_MONEY_AMOUNT: |
| | | # return True |
| | | # return False_ |
| | | |
| | | |
| | | |
| | | |
| | | # if int(val["num"]) >= constant.BIG_MONEY_NUM: |
| | | # return True |
| | | # if int(val["num"]) * limit_up_price >= constant.BIG_MONEY_AMOUNT: |
| | | # return True |
| | | # return False_ |
| | | |
| | | |
| | | def compare_time(time1, time2): |
| | |
| | | json_value = json.loads(value) |
| | | _data = {"key": key, "val": item, "re": json_value["re"], "index": int(json_value["index"])} |
| | | return _data |
| | | |
| | | |
| | | |
| | | |
| | | # 减去时间 |
| | |
| | | decimal.Decimal("0.00")) |
| | | # 获取执行位时间 |
| | | exec_time = None |
| | | buy_single_index, buy_exec_index, compute_index, num, count, max_num_set = l2_data_manager.TradePointManager.get_buy_compute_start_data( |
| | | buy_single_index, buy_exec_index, compute_index, num, count, max_num_set,volume_rate = l2_data_manager.TradePointManager.get_buy_compute_start_data( |
| | | code) |
| | | if buy_exec_index: |
| | | try: |
New file |
| | |
| | | """ |
| | | 同花顺l2监听位置健康度管理 |
| | | """ |
| | | # 不健康 |
| | | import tool |
| | | from db import redis_manager |
| | | |
| | | UN_HEALTHY = 0 |
| | | UN_KNOWN = 1 |
| | | HEALTHY = 2 |
| | | |
| | | __redisManager = redis_manager.RedisManager(0) |
| | | |
| | | |
| | | def __get_redis(): |
| | | return __redisManager.getRedis() |
| | | |
| | | |
| | | def __set_health_state(client_id, pos, state): |
| | | __get_redis().setex(f"l2_pos_health_state-{client_id}-{pos}", tool.get_expire(), state) |
| | | |
| | | |
| | | def __get_health_state(client_id, pos): |
| | | val = __get_redis().get(f"l2_pos_health_state-{client_id}-{pos}") |
| | | if val is None: |
| | | return UN_KNOWN |
| | | return int(val) |
| | | |
| | | |
| | | # 初始化所有的健康度 |
| | | def init_all(clients): |
| | | for client_info in clients: |
| | | init(client_info[0], client_info[1]) |
| | | |
| | | |
| | | # 初始化健康度 |
| | | def init(client_id, pos): |
| | | __set_health_state(client_id, pos, UN_KNOWN) |
| | | |
| | | |
| | | # 设置不健康 |
| | | def set_healthy(client_id, pos): |
| | | __set_health_state(client_id, pos, HEALTHY) |
| | | |
| | | |
| | | # 设置不健康 |
| | | def set_unhealthy(client_id, pos): |
| | | # 如果是未知状态才能设置 |
| | | state = __get_health_state(client_id, pos) |
| | | if state == UN_KNOWN: |
| | | __set_health_state(client_id, pos, UN_HEALTHY) |
| | | |
| | | |
| | | # 查询所有的健康状态 |
| | | def list_health_state(poses): |
| | | dict_ = {} |
| | | for client_info in poses: |
| | | dict_[client_info] = __get_health_state(client_info[0], client_info[1]) |
| | | return dict_ |
| | | |
| | | |
| | | if __name__ == '__main__': |
| | | # init_all([(2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6)]) |
| | | set_healthy(2, 0) |
| | | print(list_health_state([(2, 0), (2, 1), (2, 2), (2, 3), (2, 4), (2, 5), (2, 6)])) |
| | | set_unhealthy(2, 0) |
| | | set_healthy(2, 0) |
| | |
| | | import limit_up_time_manager |
| | | |
| | | |
| | | # 下单参数 |
| | | class L2PlaceOrderParamsManager: |
| | | # 获取信号连续买笔数 |
| | | @staticmethod |
| | | def get_begin_continue_buy_count(volume_rate_index): |
| | | counts = [3, 3, 3, 2, 2, 2, 2] |
| | | if volume_rate_index >= len(counts): |
| | | volume_rate_index = -1 |
| | | return counts[volume_rate_index] |
| | | |
| | | # 获取时间计算范围,返回s |
| | | @staticmethod |
| | | def get_time_range(volume_rate_index): |
| | | ts = [pow(3, 1), pow(3, 1), pow(3, 1), pow(3, 2), pow(3, 2), pow(3, 3), pow(3, 3), pow(3, 3)] |
| | | if volume_rate_index >= len(ts): |
| | | volume_rate_index = -1 |
| | | return ts[volume_rate_index] |
| | | |
| | | # 获取需要的大单个数 |
| | | @staticmethod |
| | | def get_big_num_count(volume_rate_index): |
| | | counts = [4, 3, 2, 1, 1, 1, 1] |
| | | if volume_rate_index >= len(counts): |
| | | volume_rate_index = -1 |
| | | return counts[volume_rate_index] |
| | | |
| | | # 获取安全笔数影响比例 |
| | | @staticmethod |
| | | def get_safe_count_rate(volume_rate_index): |
| | | rates = [0, -0.1, -0.2, -0.4, -0.6, -0.8, -0.8, -0.8] |
| | | if volume_rate_index >= len(rates): |
| | | volume_rate_index = -1 |
| | | return rates[volume_rate_index] |
| | | |
| | | # 获取m值影响比例 |
| | | @staticmethod |
| | | def get_m_val_rate(volume_rate_index): |
| | | rates = [0.0, 0.0, 0.0, -0.3, -0.4, -0.5, -0.6, -0.7] |
| | | if volume_rate_index >= len(rates): |
| | | volume_rate_index = -1 |
| | | return rates[volume_rate_index] |
| | | |
| | | |
| | | # S撤参数 |
| | | class SCancelParamsManager: |
| | | # 剔除前几的点火大单 |
| | | @staticmethod |
| | | def get_max_exclude_count(volume_rate_index): |
| | | counts = [5, 4, 3, 2, 1, 1, 1, 1] |
| | | if volume_rate_index >= len(counts): |
| | | volume_rate_index = -1 |
| | | return counts[volume_rate_index] |
| | | |
| | | # 获取买时间范围(距离执行位),返回s |
| | | @staticmethod |
| | | def get_buy_time_range(volume_rate_index): |
| | | seconds = [pow(2, 1), pow(2, 2), pow(2, 3), pow(2, 4), pow(2, 4), pow(2, 5), pow(2, 6), pow(2, 6)] |
| | | if volume_rate_index >= len(seconds): |
| | | volume_rate_index = -1 |
| | | return seconds[volume_rate_index] |
| | | |
| | | # 获取撤销比例 |
| | | @staticmethod |
| | | def get_cancel_rate(volume_rate_index): |
| | | rates = [0.39, 0.49, 0.59, 0.69, 0.69, 0.79, 0.79, 0.79] |
| | | if volume_rate_index >= len(rates): |
| | | volume_rate_index = -1 |
| | | return rates[volume_rate_index] |
| | | |
| | | |
| | | # H撤参数 |
| | | class HCancelParamsManager: |
| | | |
| | | # 获取最大的观察笔数 |
| | | @staticmethod |
| | | def get_max_watch_count(volume_rate_index): |
| | | counts = [40, 36, 32, 28, 24, 20, 16, 12] |
| | | if volume_rate_index >= len(counts): |
| | | volume_rate_index = -1 |
| | | return counts[volume_rate_index] |
| | | |
| | | # 获取撤销比例 |
| | | @staticmethod |
| | | def get_cancel_rate(volume_rate_index): |
| | | rates = [0.39, 0.49, 0.59, 0.69, 0.69, 0.79, 0.79, 0.79] |
| | | if volume_rate_index >= len(rates): |
| | | volume_rate_index = -1 |
| | | return rates[volume_rate_index] |
| | | |
| | | |
| | | class L2TradeFactorUtil: |
| | | # 获取基础m值,返回单位为元 |
| | | @classmethod |
| | |
| | | if yi < 1: |
| | | yi = 1 |
| | | m = 5000000 + (yi - 1) * 500000 |
| | | return round(m * 0.7) |
| | | return round(m) |
| | | |
| | | # 获取行业影响比例 |
| | | # total_limit_percent为统计的比例之和乘以100 |
| | |
| | | return zyltgb |
| | | |
| | | @classmethod |
| | | def compute_m_value(cls, code): |
| | | def compute_m_value(cls, code,volume_rate): |
| | | zyltgb = global_util.zyltgb_map.get(code) |
| | | if zyltgb is None: |
| | | global_data_loader.load_zyltgb() |
| | |
| | | print("没有获取到自由流通市值") |
| | | return 10000000, "" |
| | | zyltgb = cls.get_base_safe_val(zyltgb) |
| | | rate, msg = cls.compute_rate_by_code(code) |
| | | # 暂时注释 |
| | | # rate, msg = cls.compute_rate_by_code(code) |
| | | # print("m值获取:", code, round(zyltgb * rate)) |
| | | return round(zyltgb * rate), msg |
| | | rate = L2PlaceOrderParamsManager.get_m_val_rate(volume_rate) |
| | | |
| | | @classmethod |
| | | def get_h_cancel_min_count(cls, code): |
| | | volumn_day60_max, volumn_yest, volumn_today = cls.__get_volumns(code) |
| | | if volumn_day60_max is None or volumn_yest is None or volumn_today is None: |
| | | return constant.H_CANCEL_MIN_COUNT |
| | | rate = round(int(volumn_today) / max(int(volumn_day60_max), int(volumn_yest)), 2) |
| | | counts = [40, 36, 32, 28, 24, 20, 16] |
| | | rates = [0.3, 0.55, 0.8, 1.05, 1.3, 1.55, 10] |
| | | for index in range(0,len(rates)): |
| | | if rate < rates[index]: |
| | | return counts[index] |
| | | return counts[0] |
| | | return round(zyltgb * (1+rate)), "" |
| | | |
| | | # 获取安全笔数 |
| | | @classmethod |
| | |
| | | # print(L2TradeFactorUtil.get_safe_buy_count("003005")) |
| | | # print(L2TradeFactorUtil.get_rate_factors("003004")) |
| | | # print(L2TradeFactorUtil.factors_to_string("003004")) |
| | | print(L2TradeFactorUtil.get_safe_buy_count_by_gp(100000000 * 4)) |
| | | print(L2TradeFactorUtil.get_safe_buy_count_by_gp(100000000 * 7)) |
| | | print(L2TradeFactorUtil.get_safe_buy_count_by_gp(100000000 * 10)) |
| | | print(L2TradeFactorUtil.get_safe_buy_count_by_gp(100000000 * 16)) |
| | | print(L2TradeFactorUtil.get_safe_buy_count_by_gp(100000000 * 22)) |
| | | print(L2TradeFactorUtil.get_safe_buy_count_by_gp(100000000 * 31)) |
| | | for i in range(2, 151): |
| | | print(i, L2TradeFactorUtil.get_base_safe_val(100000000 * i)) |
| | | # print(L2TradeFactorUtil.get_limit_up_time_rate("11:30:00")) |
| | | # print(L2TradeFactorUtil.get_limit_up_time_rate("13:00:00")) |
| | | # print(L2TradeFactorUtil.get_limit_up_time_rate("13:48:00")) |
| | |
| | | TRADE_STATE_BUY_PLACE_ORDER = 10 |
| | | # 已委托买 |
| | | TRADE_STATE_BUY_DELEGATED = 11 |
| | | # 委托进行中 |
| | | # 委托取消进行中 |
| | | TRADE_STATE_BUY_CANCEL_ING = 13 |
| | | # 撤销成功 |
| | | TRADE_STATE_BUY_CANCEL_SUCCESS = 14 |
| | |
| | | return time_str, volumn |
| | | |
| | | |
| | | # 买1实时价格管理器 |
| | | class Buy1PriceManager: |
| | | __redisManager = redis_manager.RedisManager(0) |
| | | |
| | | def __init__(self): |
| | | self.latest_prices = {} |
| | | |
| | | def __get_redis(self): |
| | | return self.__redisManager.getRedis() |
| | | |
| | | def __save_recod(self, code, price): |
| | | # 保存每一次的 |
| | | key = "buy1_price-{}".format(code) |
| | | self.__get_redis().setex(key, tool.get_expire(), price) |
| | | |
| | | def __get_record(self, code): |
| | | key = "buy1_price-{}".format(code) |
| | | val = self.__get_redis().get(key) |
| | | return val |
| | | |
| | | # 保存数据 |
| | | def save(self, code, price): |
| | | if self.latest_prices.get(code) == price: |
| | | return |
| | | self.latest_prices[code] = price |
| | | self.__save_recod(code, price) |
| | | |
| | | def get_price(self, code): |
| | | return self.__get_record(code) |
| | | |
| | | |
| | | class thsl2tradequeuemanager: |
| | |
| | | logging.exception(e) |
| | | logger_l2_error.exception(e) |
| | | |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set = l2_data_manager.TradePointManager.get_buy_compute_start_data( |
| | | buy_single_index, buy_exec_index, buy_compute_index, num, count, max_num_set,volume_rate = l2_data_manager.TradePointManager.get_buy_compute_start_data( |
| | | code) |
| | | |
| | | f1 = clear_max_buy1_volume(code) |