建立扫入代码不算身位机制/优化代码/提供设置影子单的量
| | |
| | | def __cancel_not_deal_order(self, code, order_ref, timeout=3): |
| | | time.sleep(timeout) |
| | | # 撤买单 |
| | | huaxin_trade_api.cancel_order(1, code, "", orderRef=order_ref) |
| | | huaxin_trade_api.cancel_order(huaxin_trade_api.TRADE_DIRECTION_BUY, code, "", orderRef=order_ref) |
| | | |
| | | # 交易 |
| | | def OnTrade(self, client_id, request_id, data): |
| | |
| | | "pay_attention": need_pay_attention, |
| | | "trade_progress_percent": round( |
| | | total_left_num * float(limit_up_price) * 100 * 100 / buy1_money, 2), # 成交进度比例 |
| | | "limit_up_price": float(gpcode_manager.get_limit_up_price(code)), |
| | | "limit_up_price": gpcode_manager.get_limit_up_price_as_num(code), |
| | | "is_near_big_order": is_near_big_order, |
| | | "block": '', |
| | | "trade_queue": [] |
| | |
| | | # 计算的上截至位距离下截至位纯买额要小于2.5倍m值 |
| | | # thresh_hold_money = l2_trade_factor.L2PlaceOrderParamsManager.get_base_m_val(code) |
| | | # thresh_hold_money = int(thresh_hold_money * 2.5) |
| | | min_num = int(5000 / (float(gpcode_manager.get_limit_up_price(code)))) |
| | | min_num = int(5000 / gpcode_manager.get_limit_up_price_as_num(code)) |
| | | # 统计净涨停买的数量 |
| | | not_cancel_indexes_with_num = [] |
| | | re_start_index = start_index |
| | |
| | | # 下单位置之后数10笔卖单 |
| | | watch_indexes = set() |
| | | total_datas = local_today_datas.get(code) |
| | | MIN_NUM = int(5000 / (float(gpcode_manager.get_limit_up_price(code)))) |
| | | MIN_NUM = int(5000 / gpcode_manager.get_limit_up_price_as_num(code)) |
| | | MAX_COUNT = 10 |
| | | for i in range(real_place_order_index + 1, end_index): |
| | | data = total_datas[i] |
| | |
| | | is_ge_code = tool.is_ge_code(code) |
| | | try: |
| | | # 真实下单位置后面的数据就只看大单 |
| | | MIN_NUM = int(5000 / (float(gpcode_manager.get_limit_up_price(code)))) |
| | | MIN_NUM = int(5000 / gpcode_manager.get_limit_up_price_as_num(code)) |
| | | real_place_order_info = self.__real_place_order_index_dict.get(code) |
| | | if real_place_order_info and not real_place_order_info[1]: |
| | | # 从真实下单位往后找 |
| | |
| | | is_ge_code = tool.is_ge_code(code) |
| | | if real_place_order_info and real_place_order_info[0] > index: |
| | | total_datas = local_today_datas.get(code) |
| | | min_num = int(5000 / (float(gpcode_manager.get_limit_up_price(code)))) |
| | | min_num = int(5000 / gpcode_manager.get_limit_up_price_as_num(code)) |
| | | for j in range(real_place_order_info[0] - 1, index, -1): |
| | | data = total_datas[j] |
| | | val = data['val'] |
| | |
| | | thresh_hold_money = l2_trade_factor.L2PlaceOrderParamsManager.get_base_m_val(code) |
| | | thresh_hold_money = thresh_hold_money * 3 |
| | | # 阈值为2倍m值 |
| | | thresh_hold_num = thresh_hold_money // (float(gpcode_manager.get_limit_up_price(code)) * 100) |
| | | thresh_hold_num = thresh_hold_money // (gpcode_manager.get_limit_up_price_as_num(code) * 100) |
| | | for i in range(trade_progress_index + 1, real_place_order_index_info[0]): |
| | | data = total_data[i] |
| | | val = data['val'] |
| | |
| | | return |
| | | try: |
| | | # 计算触发位置 |
| | | min_num = int(5000 / (float(gpcode_manager.get_limit_up_price(code)))) |
| | | min_num = int(5000 / (gpcode_manager.get_limit_up_price_as_num(code))) |
| | | # 统计净涨停买的数量 |
| | | not_cancel_indexes = [] |
| | | total_datas = local_today_datas.get(code) |
| | |
| | | from code_attribute import gpcode_manager |
| | | |
| | | # 代码股性记录管理 |
| | | from db import redis_manager |
| | | from db import redis_manager_delegate as redis_manager |
| | | from utils import tool |
| | | from db.redis_manager_delegate import RedisUtils |
| | | from utils.tool import CodeDataCacheUtil |
| | |
| | | cls.__front_id = front_id |
| | | |
| | | # sinfo |
| | | def buy(self, code, count, price, sinfo, order_ref, shadow_price=None, cancel_shadow_order=True): |
| | | def buy(self, code, count, price, sinfo, order_ref, shadow_price=None, cancel_shadow_order=True, |
| | | shadow_volume=constant.SHADOW_ORDER_VOLUME): |
| | | """ |
| | | 下单 |
| | | @param shadow_volume: 影子单的量 |
| | | @param code: |
| | | @param count: |
| | | @param price: |
| | |
| | | req_field.LimitPrice = shadow_price |
| | | req_field.SInfo = shadow_sinfo |
| | | req_field.OrderRef = shadow_order_ref |
| | | req_field.VolumeTotalOriginal = constant.SHADOW_ORDER_VOLUME |
| | | req_field.VolumeTotalOriginal = shadow_volume |
| | | self.req_id += 1 |
| | | ret = api.ReqOrderInsert(req_field, self.req_id) |
| | | if ret != 0: |
| | |
| | | sinfo = data["sinfo"] |
| | | order_ref = data.get("order_ref") |
| | | shadow_price = data.get("shadow_price") |
| | | shadow_volume = data.get("shadow_volume") |
| | | blocking = data.get("blocking") |
| | | cancel_shadow = data.get("cancel_shadow") |
| | | if cancel_shadow is None: |
| | |
| | | # |
| | | # while True: |
| | | # time.sleep(1) |
| | | |
| | | |
| | | input() |
| | |
| | | total_datas = local_today_datas.get(code) |
| | | if tool.trade_time_sub(total_datas[-1]['val']['time'], total_datas[real_order_index]['val']['time']) > 60: |
| | | return False, "超过守护时间" |
| | | limit_up_price = round(float(gpcode_manager.get_limit_up_price(code)), 2) |
| | | limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) |
| | | end_index = L2DataComputeUtil.compute_end_index(code, real_order_index + 1, total_datas[-1]["index"], |
| | | limit_up_price, 10) |
| | | # 从成交进度位到截至位置计算大单 |
| | |
| | | if not outoftime: |
| | | # 上次计算还未超时 |
| | | return |
| | | limit_up_price = round(float(gpcode_manager.get_limit_up_price(code)), 2) |
| | | limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) |
| | | |
| | | if cancel_single_info and outoftime: |
| | | # 更新需要计算信号 |
| | |
| | | return False, None, "超过生效时间" |
| | | |
| | | buyno_map = local_today_buyno_map.get(code) |
| | | limit_up_price = round(float(gpcode_manager.get_limit_up_price(code)), 2) |
| | | limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) |
| | | min_volume = 50 * 10000 // int(limit_up_price * 100) |
| | | # 计算纯买额 |
| | | for i in range(start_index, end_index + 1): |
| | |
| | | return False, "没有找到真实下单位" |
| | | real_place_order_index = real_place_order_index_info[0] |
| | | |
| | | limit_up_price = round(float(gpcode_manager.get_limit_up_price(code)), 2) |
| | | limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) |
| | | if limit_up_price < 3: |
| | | return False, "股价小于3块" |
| | | |
| | |
| | | |
| | | |
| | | # 下单 |
| | | def place_order(code, price, volume, exec_index, latest_data, order_ref, shadow_price): |
| | | def place_order(code, price, volume, exec_index, latest_data, order_ref, shadow_price, |
| | | shadow_volume=huaxin_client_constant.SHADOW_ORDER_VOLUME): |
| | | async_log_util.info(logger_real_place_order_position, |
| | | f"下单:code-{code} price-{price} shadow_price-{shadow_price} volume-{volume} exec-index-{exec_index} order_ref-{order_ref}") |
| | | _place_order_info_dict[code] = (price, volume, latest_data, time.time(), order_ref, shadow_price, exec_index) |
| | | f"下单:code-{code} price-{price} shadow_price-{shadow_price} volume-{volume} exec-index-{exec_index} order_ref-{order_ref} shadow_volume-{shadow_volume}") |
| | | _place_order_info_dict[code] = ( |
| | | price, volume, latest_data, time.time(), order_ref, shadow_price, exec_index, shadow_volume) |
| | | |
| | | |
| | | # 获取下单信息 |
| | |
| | | |
| | | |
| | | # 计算预估下单位 |
| | | def __compute_estimate_order_position(code, exec_buy_index, shadow_price): |
| | | def __compute_estimate_order_position(code, exec_buy_index, shadow_price, shadow_volume): |
| | | total_datas = l2_data_util.local_today_datas.get(code) |
| | | try: |
| | | if tool.is_sh_code(code): |
| | |
| | | d = total_datas[i] |
| | | val = d['val'] |
| | | # 判断影子订单位置 |
| | | if val["num"] != huaxin_client_constant.SHADOW_ORDER_VOLUME // 100: |
| | | if val["num"] != shadow_volume // 100: |
| | | continue |
| | | if abs(shadow_price - float(val["price"])) >= 0.001: |
| | | continue |
| | |
| | | order_time = order_info[3] # 下单时间 |
| | | order_ref = order_info[4] |
| | | shadow_price = order_info[5] |
| | | shadow_volume = order_info[7] |
| | | shadow_place_order_index = None |
| | | # 查找影子挂单 |
| | | for d in datas: |
| | | val = d['val'] |
| | | # 判断影子订单位置 |
| | | if val["num"] != huaxin_client_constant.SHADOW_ORDER_VOLUME // 100: |
| | | if val["num"] != shadow_volume // 100: |
| | | continue |
| | | if abs(shadow_price - float(val["price"])) >= 0.001: |
| | | continue |
| | |
| | | if not L2DataUtil.is_limit_up_price_buy(d["val"]): |
| | | continue |
| | | try: |
| | | if tool.is_sh_code(code) and tool.trade_time_sub_with_ms(L2DataUtil.get_time_with_ms(d["val"]), exec_time_with_ms) <= 30: |
| | | if tool.is_sh_code(code) and tool.trade_time_sub_with_ms(L2DataUtil.get_time_with_ms(d["val"]), |
| | | exec_time_with_ms) <= 30: |
| | | # 上证真实下单位置与执行位置要相差30ms以上才行 |
| | | continue |
| | | except: |
| | |
| | | real_place_index_info = shadow_place_order_index, RELIABILITY_TYPE_VIRTUAL |
| | | else: |
| | | real_place_index_info = real_place_index, RELIABILITY_TYPE_REAL |
| | | elif tool.trade_time_sub(datas[-1]['val']['time'], exec_data['val']['time']) >= estimate_time_space and time.time() - order_time >5: |
| | | elif tool.trade_time_sub(datas[-1]['val']['time'], |
| | | exec_data['val']['time']) >= estimate_time_space and time.time() - order_time > 5: |
| | | # 下单超过2s且绝对时间超过5S以上才会估算真实下单位置 |
| | | estimate_index = __compute_estimate_order_position(code, exec_data["index"], shadow_price) |
| | | estimate_index = __compute_estimate_order_position(code, exec_data["index"], shadow_price, shadow_volume) |
| | | if estimate_index: |
| | | real_place_index_info = estimate_index, RELIABILITY_TYPE_ESTIMATE |
| | | if real_place_index_info: |
| | | # 获取到了下单位置 |
| | | async_log_util.info(hx_logger_trade_debug, f"真实下单位置:{code}-{real_place_index_info}") |
| | | async_log_util.info(logger_real_place_order_position, f"真实下单位置:{code}-{real_place_index_info}-{shadow_place_order_index}") |
| | | async_log_util.info(logger_real_place_order_position, |
| | | f"真实下单位置:{code}-{real_place_index_info}-{shadow_place_order_index}") |
| | | if code in _place_order_info_dict: |
| | | _place_order_info_dict.pop(code) |
| | | __place_order_position[code] = real_place_index_info[0] |
| | |
| | | order_time = order_info[3] # 下单时间 |
| | | order_ref = order_info[4] |
| | | shadow_price = order_info[5] |
| | | shadow_volume = order_info[7] |
| | | # 在重新计算真实下单位置,在2s后计算 |
| | | for t in range(0, 10): |
| | | time.sleep(1) |
| | |
| | | continue |
| | | if not L2DataUtil.is_buy(val): |
| | | continue |
| | | if val["num"] != huaxin_client_constant.SHADOW_ORDER_VOLUME // 100: |
| | | if val["num"] != shadow_volume // 100: |
| | | continue |
| | | if abs(shadow_price - float(val["price"])) >= 0.001: |
| | | continue |
| | |
| | | now_time_int = int(tool.get_now_time_str().replace(":", "")) |
| | | if now_time_int >= 145700: |
| | | return False, True, f"14:57后不能交易", True |
| | | |
| | | if now_time_int < 93200: |
| | | return False, True, f"09:32之前不能交易", True |
| | | # 二板以上的票不买 |
| | | yesterday_codes = kpl_data_manager.get_yesterday_limit_up_codes() |
| | | if yesterday_codes and code in yesterday_codes: |
| | |
| | | trade_index, is_default = cls.__TradeBuyQueue.get_traded_index(code) |
| | | if trade_index is None: |
| | | trade_index = 0 |
| | | limit_up_price = round(float(gpcode_manager.get_limit_up_price(code)), 2) |
| | | limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) |
| | | # 从成交进度位到截至位置计算大单 |
| | | min_money = l2_data_util.get_big_money_val(limit_up_price, tool.is_ge_code(code)) |
| | | left_count, left_money = cancel_buy_strategy.L2DataComputeUtil.compute_left_buy_order(code, |
| | |
| | | import json |
| | | |
| | | import l2_data_util |
| | | from db import redis_manager |
| | | from db import redis_manager_delegate as redis_manager |
| | | from db.redis_manager_delegate import RedisUtils |
| | | from l2 import l2_log |
| | | from l2.huaxin import l2_huaxin_util |
| | |
| | | # 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]] |
| | | # 数据格式[订单号,总股数,成交金额,成交开始时间,成交结束时间, 最近的成交价格] |
| | | cls.__dealing_order_info_dict[code] = [data[6], data[2], data[2] * data[1], data[3], data[3], data[1]] |
| | | else: |
| | | if cls.__dealing_order_info_dict[code][0] == data[6]: |
| | | # 成交同一个订单号 |
| | | cls.__dealing_order_info_dict[code][1] += data[2] |
| | | 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] |
| | | else: |
| | | # 保存上一条数据 |
| | | async_log_util.info(hx_logger_l2_transaction_desc, f"{code}#{cls.__dealing_order_info_dict[code]}") |
| | |
| | | cls.__latest_deal_order_info_dict[code] = deal_info |
| | | # 是否为大买单 |
| | | if deal_info[2] >= threshold_big_money: |
| | | big_buy_datas.append(deal_info) |
| | | # 如果最后一笔成交价格不是涨停价就不算 |
| | | if abs(deal_info[5] - limit_up_price) < 0.0001: |
| | | big_buy_datas.append(deal_info) |
| | | if deal_info[2] >= 500000: |
| | | normal_buy_datas.append(deal_info) |
| | | |
| | | # 初始化本条数据 |
| | | cls.__dealing_order_info_dict[code] = [data[6], data[2], data[2] * data[1], data[3], data[3]] |
| | | cls.__dealing_order_info_dict[code] = [data[6], data[2], data[2] * data[1], data[3], data[3], |
| | | data[1]] |
| | | # 统计主动买(买单号大于卖单号) |
| | | try: |
| | | if data[6] > data[7]: |
| | |
| | | @param datas: |
| | | @return: |
| | | """ |
| | | limit_up_price = round(float(gpcode_manager.get_limit_up_price(code)), 2) |
| | | limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) |
| | | 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) |
| | |
| | | TargetCodePlateKeyManager |
| | | 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, radical_buy_data_manager |
| | | trade_data_manager, trade_constant, radical_buy_strategy, radical_buy_data_manager, buy_open_limit_up_strategy |
| | | from trade.buy_money_count_setting import BuyMoneyAndCountSetting, BuyMoneyUtil |
| | | |
| | | from trade.huaxin import huaxin_trade_api as trade_api, huaxin_trade_api, huaxin_trade_data_update, \ |
| | |
| | | current_delegates = DelegateRecordManager().list_current_delegates(code) |
| | | if current_delegates: |
| | | for c in current_delegates: |
| | | huaxin_trade_api.cancel_order(1, code, c["orderSysID"]) |
| | | huaxin_trade_api.cancel_order(huaxin_trade_api.TRADE_DIRECTION_BUY, code, |
| | | c["orderSysID"]) |
| | | |
| | | # 获取L1现价 |
| | | @classmethod |
| | |
| | | result_by_volume = radical_buy_strategy.process_limit_up_active_buy_deal(code, transaction_datas) |
| | | async_log_util.info(logger_l2_radical_buy, f"量买入结果判断:{code}, 结果:{result_by_volume} 板块:{buy_blocks}") |
| | | if result_by_volume[0] != radical_buy_strategy.BUY_MODE_NONE: |
| | | if tool.get_now_time_as_int() < 93200: |
| | | radical_buy_data_manager.ExcludeIndexComputeCodesManager.add_code(code) |
| | | async_log_util.info(logger_l2_radical_buy, |
| | | f"09:32之前不交易:{code}") |
| | | return |
| | | # 判断是否开得太高 |
| | | 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 |
| | | radical_buy_data_manager.ExcludeIndexComputeCodesManager.remove_code(code) |
| | | |
| | | |
| | | if result_by_volume[0] == radical_buy_strategy.BUY_MODE_DIRECT: |
| | | refer_sell_data = L2MarketSellManager().get_refer_sell_data(code, |
| | |
| | | return |
| | | try: |
| | | volume = tool.get_buy_volume_by_money(limit_up_price, constant.AVAILABLE_BUY_MONEYS[0]) |
| | | result = huaxin_trade_api.order(1, code, volume, limit_up_price, blocking=True, |
| | | shadow_price=shadow_price) |
| | | result = huaxin_trade_api.order(huaxin_trade_api.TRADE_DIRECTION_BUY, code, volume, limit_up_price, |
| | | blocking=True, |
| | | shadow_price=shadow_price, shadow_volume=volume) |
| | | async_log_util.info(logger_trade, f"{code}下单结束:{result}") |
| | | buy_open_limit_up_strategy.BuyOpenLimitupDataManager().set_place_order_info(code, volume, volume) |
| | | except Exception as e: |
| | | pass |
| | | |
| | |
| | | |
| | | from log_module.log import logger_kpl_block_can_buy, logger_debug, logger_kpl_jx_out |
| | | from third_data.kpl_util import KPLPlatManager |
| | | from trade import trade_manager, l2_trade_util, trade_constant |
| | | from trade import trade_manager, l2_trade_util, trade_constant, radical_buy_data_manager |
| | | |
| | | # 代码精选板块管理 |
| | | from utils.kpl_data_db_util import KPLLimitUpDataUtil |
| | |
| | | if history_index == 1: |
| | | # 当前代码为老2,要判断老大是否可买 |
| | | if RadicalBuyDataManager.is_code_can_buy(history_before_codes_info[0][0], |
| | | DealAndDelegateWithBuyModeDataManager().get_deal_codes())[0]: |
| | | DealAndDelegateWithBuyModeDataManager().get_deal_codes(), is_refered=True)[0]: |
| | | return False, f"开1数量:{count},前排代码可买:{history_before_codes_info[0]}" |
| | | return True, f"开1数量:{count},前排代码不可买:{history_before_codes_info[0]},历史前排-{history_before_codes_info},开1代码-{open_limit_up_block_codes}" |
| | | return True, f"开1数量:{count},历史-{history_index + 1} 实时-{current_index + 1}, 前排代码-{current_before_codes_info}, 开1代码-{open_limit_up_block_codes}" |
| | |
| | | @classmethod |
| | | def __filter_before_codes(cls, block, index, before_codes_info, yesterday_codes): |
| | | """ |
| | | 过滤前排涨停原因不正的代码 |
| | | 过滤前排涨停原因不正/不算身位的代码 |
| | | @param code: |
| | | @param block:板块 |
| | | @param index: 目标代码位置 |
| | |
| | | temp_before_codes_info = [] |
| | | for b in before_codes_info: |
| | | # 当作目标票获取扫入板块 |
| | | blocks = LimitUpCodesBlockRecordManager().get_radical_buy_blocks(b[0]) |
| | | code_ = b[0] |
| | | blocks = LimitUpCodesBlockRecordManager().get_radical_buy_blocks(code_) |
| | | blocks = BlockMapManager().filter_blocks(blocks) |
| | | need_delete = False |
| | | # 判断原因不正 |
| | | if block not in blocks and b[0] not in yesterday_codes: |
| | | # 首板涨停原因不正 |
| | | need_delete = True |
| | | # 判断是否是不计算身位 |
| | | if not need_delete: |
| | | if radical_buy_data_manager.ExcludeIndexComputeCodesManager.is_in_cache(code_): |
| | | need_delete = True |
| | | if need_delete: |
| | | temp_index -= 1 |
| | | else: |
| | | temp_before_codes_info.append(b) |
| | | |
| | | return temp_index, temp_before_codes_info |
| | | except Exception as e: |
| | | async_log_util.error(logger_debug, f"扫入板块过滤出错:{str(e)}") |
| | |
| | | pre_code = history_before_codes_info[0][0] |
| | | # pre_code不能买,才能买 |
| | | if RadicalBuyDataManager.is_code_can_buy(pre_code, |
| | | DealAndDelegateWithBuyModeDataManager().get_deal_codes())[0]: |
| | | DealAndDelegateWithBuyModeDataManager().get_deal_codes(), is_refered=True)[0]: |
| | | return False, f"前排代码可买:{pre_code}" |
| | | # 前面一个代码不能买,前一个代码必须与前前个代码涨停时间相差15分钟内 |
| | | for i in range(len(all_history_before_codes_info) - 1, -1, -1): |
| | |
| | | import json |
| | | |
| | | import constant |
| | | from db import redis_manager |
| | | from db import redis_manager_delegate as redis_manager |
| | | from db.mysql_data_delegate import Mysqldb |
| | | from db.redis_manager_delegate import RedisUtils |
| | | from l2.l2_data_manager import OrderBeginPosInfo |
New file |
| | |
| | | """ |
| | | 排1策略 |
| | | """ |
| | | import json |
| | | |
| | | from db import redis_manager_delegate as redis_manager |
| | | from db.redis_manager_delegate import RedisUtils |
| | | from utils import tool |
| | | |
| | | |
| | | class BuyOpenLimitupDataManager: |
| | | """ |
| | | 排1代码数据管理 |
| | | """ |
| | | # 下单信息 |
| | | __place_order_info_dict = {} |
| | | |
| | | __db = 2 |
| | | __redisManager = redis_manager.RedisManager(2) |
| | | __instance = None |
| | | |
| | | def __new__(cls, *args, **kwargs): |
| | | if not cls.__instance: |
| | | cls.__instance = super(BuyOpenLimitupDataManager, cls).__new__(cls, *args, **kwargs) |
| | | cls.__load_data() |
| | | return cls.__instance |
| | | |
| | | @classmethod |
| | | def __get_redis(cls): |
| | | return cls.__redisManager.getRedis() |
| | | |
| | | @classmethod |
| | | def __load_data(cls): |
| | | keys = RedisUtils.get(cls.__get_redis(), "buy_open_limit_up_placing_orderinfo-*") |
| | | if keys: |
| | | for k in keys: |
| | | code = k.split("-")[1] |
| | | val = RedisUtils.get(cls.__get_redis(), k) |
| | | val = json.loads(val) |
| | | cls.__place_order_info_dict[code] = val |
| | | |
| | | def set_place_order_info(self, code, volume, shadow_volume): |
| | | """ |
| | | @param code: |
| | | @param volume: |
| | | @param shadow_volume: |
| | | @return: |
| | | """ |
| | | self.__place_order_info_dict[code] = (volume, shadow_volume) |
| | | RedisUtils.set_async(self.__db, f"buy_open_limit_up_placing_orderinfo-{code}", tool.get_expire(), |
| | | json.dumps(self.__place_order_info_dict[code])) |
| | | |
| | | def get_place_order_info(self, code): |
| | | """ |
| | | 获取下单信息 |
| | | @param code: |
| | | @return:(下单量, 影子单量) |
| | | """ |
| | | return self.__place_order_info_dict.get(code) |
| | |
| | | # 如果当前清单处于委托状态就不能移除 |
| | | if trade_state == trade_constant.TRADE_STATE_BUY_PLACE_ORDER or trade_state == trade_constant.TRADE_STATE_BUY_DELEGATED: |
| | | is_want_buy = True |
| | | |
| | | if gpcode_manager.BuyOpenLimitUpCodeManager().is_in_cache(code): |
| | | is_want_buy = True |
| | | |
| | | rate = round((price - pricePre) * 100 / pricePre, 2) |
| | | if tool.is_ge_code(code): |
| | | # 创业板的涨幅需要打折 |
| | |
| | | # 成交的就不需要撤单了 |
| | | return |
| | | try: |
| | | result = huaxin_trade_api.cancel_order(2, code, None, orderRef=order_ref) |
| | | result = huaxin_trade_api.cancel_order(huaxin_trade_api.TRADE_DIRECTION_SELL, code, None, orderRef=order_ref) |
| | | except Exception as e: |
| | | logger_trade.exception(e) |
| | | |
| | |
| | | order_: HuaxinOrderEntity = TradeResultProcessor.get_huaxin_order_by_order_ref(order_ref) |
| | | if order_ is not None: |
| | | if huaxin_util.is_can_cancel(order_.orderStatus): |
| | | cancel_order(2, code, order_.orderSysID) |
| | | cancel_order(TRADE_DIRECTION_SELL, code, order_.orderSysID) |
| | | |
| | | def __process_order(data): |
| | | # 更新委托队列 |
| | |
| | | need_cancel = TradeResultProcessor.process_buy_order(order) |
| | | if need_cancel: |
| | | # 需要撤买单 |
| | | threading.Thread(target=lambda: cancel_order(2, order.code, order.orderSysID), daemon=True).start() |
| | | threading.Thread(target=lambda: cancel_order(TRADE_DIRECTION_SELL, order.code, order.orderSysID), daemon=True).start() |
| | | need_watch_cancel = TradeResultProcessor.process_sell_order(order) |
| | | if need_watch_cancel: |
| | | # 需要撤卖单 |
| | |
| | | |
| | | |
| | | def order(direction, code, volume, price, price_type=2, blocking=False, sinfo=None, request_id=None, |
| | | order_ref=None, shadow_price=None): |
| | | order_ref=None, shadow_price=None, shadow_volume=100): |
| | | """ |
| | | 下单委托 |
| | | @param shadow_volume: 影子单的量 |
| | | @param direction: 1-买 2-卖 |
| | | @param code: |
| | | @param volume:交易量 |
| | |
| | | "price_type": price_type, |
| | | "price": price, |
| | | "shadow_price": shadow_price, |
| | | "shadow_volume": shadow_volume, |
| | | "sinfo": sinfo, |
| | | "blocking": blocking, |
| | | "cancel_shadow": cancel_shadow}, |
| | |
| | | import json |
| | | |
| | | from db import redis_manager |
| | | from db import redis_manager_delegate as redis_manager |
| | | from db.redis_manager_delegate import RedisUtils |
| | | from log_module import async_log_util |
| | | from log_module.log import logger_debug |
| | |
| | | 激进买数据管理 |
| | | """ |
| | | import constant |
| | | import l2_data_util |
| | | from code_attribute import code_nature_analyse, code_volumn_manager, gpcode_manager |
| | | from code_attribute.code_l1_data_manager import L1DataManager |
| | | from l2.l2_sell_manager import L2MarketSellManager |
| | | from l2.l2_transaction_data_manager import BigOrderDealManager |
| | | 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 |
| | | from third_data import kpl_data_manager |
| | |
| | | from utils import tool, global_util |
| | | |
| | | |
| | | class RadicalBuyDataManager(): |
| | | class RadicalBuyDataManager: |
| | | @classmethod |
| | | def is_code_can_buy(cls, code, deal_codes=None): |
| | | def is_code_can_buy(cls, code, deal_codes=None, is_refered=False): |
| | | """ |
| | | 代码是否可以买(根据代码本身属性) |
| | | @param deal_codes: 已经成交的代码 |
| | | @param is_refered: 是否是参考票 |
| | | @param code: 代码 |
| | | @param total_sell_volume: 总卖量 |
| | | @return: 是否可以买, 原因 |
| | |
| | | else: |
| | | # 拉黑且不是已经买入性质的拉黑 |
| | | return False, "已拉黑" |
| | | |
| | | if is_refered: |
| | | # 参考票没有大单 |
| | | volume_rate = code_volumn_manager.CodeVolumeManager().get_volume_rate(code, with_info=False) |
| | | if volume_rate is None: |
| | | volume_rate = 0.5 |
| | | big_order_deal_enough = is_big_order_deal_enough(code, volume_rate) |
| | | if not big_order_deal_enough[0] and big_order_deal_enough[2]: |
| | | return False, "交易前两分钟大单不足" |
| | | |
| | | return True, "" |
| | | |
| | | @classmethod |
| | |
| | | @classmethod |
| | | def place_order_success(cls, code): |
| | | # 如果有大单成交就加红 |
| | | deal_big_order_count = BigOrderDealManager().get_total_buy_count(code) |
| | | if deal_big_order_count > 0: |
| | | volume_rate = code_volumn_manager.CodeVolumeManager().get_volume_rate(code, with_info=False) |
| | | if volume_rate is None: |
| | | volume_rate = 0.5 |
| | | big_order_deal_enough = is_big_order_deal_enough(code, |
| | | volume_rate) # BigOrderDealManager().get_total_buy_count(code) |
| | | if big_order_deal_enough[0]: |
| | | gpcode_manager.MustBuyCodesManager().add_code(code) |
| | | |
| | | |
| | | class ExcludeIndexComputeCodesManager: |
| | | """ |
| | | 排除身位计算管理器 |
| | | """ |
| | | __codes_cache = set() |
| | | |
| | | @classmethod |
| | | def add_code(cls, code): |
| | | cls.__codes_cache.add(code) |
| | | |
| | | @classmethod |
| | | def remove_code(cls, code): |
| | | cls.__codes_cache.discard(code) |
| | | |
| | | @classmethod |
| | | def get_all_codes(cls): |
| | | return cls.__codes_cache |
| | | |
| | | @classmethod |
| | | def is_in_cache(cls, code): |
| | | return code in cls.__codes_cache |
| | | |
| | | |
| | | def is_big_order_deal_enough(code, volume_rate): |
| | | """ |
| | | 大单成交是否足够 |
| | | @param code: |
| | | @param volume_rate: |
| | | @return: 大单是否足够, 原因, 是否是短时生效 |
| | | """ |
| | | limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) |
| | | refer_volume = code_volumn_manager.CodeVolumeManager().get_max_volume_in_5days(code) |
| | | if refer_volume is None: |
| | | refer_volume = 0 |
| | | |
| | | money_y = int(refer_volume * limit_up_price / 1e8) |
| | | money_y = min(money_y, 50) |
| | | money_y = max(money_y, 5) |
| | | before_time = tool.get_now_time_as_int() < 93200 |
| | | # 计算大单参考数量 |
| | | threshold_count = 1 # int(round(0.4 * money_y)) |
| | | if before_time: |
| | | threshold_count = int(round(0.4 * money_y * 1.5)) |
| | | threshold_money = threshold_count * 299 * 10000 |
| | | |
| | | if volume_rate >= 0.5 or True: |
| | | # 按量大于50%算 |
| | | # 当换手量>50%时,则,不需要每次扫入时需要≥2笔大单,而是累计需要≥2笔大单即可 |
| | | deal_big_order_money = BigOrderDealManager().get_total_buy_money(code) |
| | | try: |
| | | # 获取正在成交的订单 |
| | | dealing_order_info = HuaXinBuyOrderManager().get_dealing_order_info(code) |
| | | threshold_big_money = l2_data_util.get_big_money_val(limit_up_price, tool.is_ge_code(code)) |
| | | if dealing_order_info and dealing_order_info[2] >= threshold_big_money: |
| | | # 正在成交的订单是大单 |
| | | deal_big_order_money += dealing_order_info[2] |
| | | except Exception as e: |
| | | async_log_util.info(logger_l2_radical_buy, f"计算正在成交大单出错:{str(e)}") |
| | | |
| | | if deal_big_order_money >= threshold_money: |
| | | return True, f"量比-{volume_rate}, 总大单成交金额({deal_big_order_money})>={threshold_money}", before_time |
| | | else: |
| | | return False, f"量比-{volume_rate}, 总大单成交金额({deal_big_order_money})<{threshold_money}", before_time |
| | | else: |
| | | current_big_order_deal_count = EveryLimitupBigDealOrderManager.get_big_buy_deal_order_count(code) |
| | | if current_big_order_deal_count >= threshold_count: |
| | | return True, f"量比-{volume_rate}, 本次大单成交数量({current_big_order_deal_count})>={threshold_count}", before_time |
| | | else: |
| | | return False, f"量比-{volume_rate}, 本次大单成交数量({current_big_order_deal_count})<{threshold_count}", before_time |
| | | |
| | | |
| | | class EveryLimitupBigDealOrderManager: |
| | | """ |
| | | 每次上板的大单管理 |
| | |
| | | THRESHOLD_RATE = radical_buy_data_manager.get_volume_rate_threshold(code, volume_rate) |
| | | if rate >= THRESHOLD_RATE: |
| | | # 根据大单判断是否可以扫 |
| | | big_order_deal_result = __is_big_order_deal_enough(code, volume_rate) |
| | | big_order_deal_result = radical_buy_data_manager.is_big_order_deal_enough(code, volume_rate) |
| | | 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: |
| | |
| | | if volume_rate is None: |
| | | volume_rate = 0.5 |
| | | # 根据大单判断是否可以扫 |
| | | big_order_deal_result = __is_big_order_deal_enough(code, volume_rate) |
| | | big_order_deal_result = radical_buy_data_manager.is_big_order_deal_enough(code, volume_rate) |
| | | result = __get_deal_rate_by(code, huaxin_timestamp) |
| | | if result[0] == BUY_MODE_DIRECT: |
| | | if big_order_deal_result[0]: |
| | |
| | | return result |
| | | |
| | | |
| | | def __is_big_order_deal_enough(code, volume_rate): |
| | | """ |
| | | 大单成交是否足够 |
| | | @param code: |
| | | @param volume_rate: |
| | | @return: |
| | | """ |
| | | limit_up_price = gpcode_manager.get_limit_up_price_as_num(code) |
| | | refer_volume = code_volumn_manager.CodeVolumeManager().get_max_volume_in_5days(code) |
| | | if refer_volume is None: |
| | | refer_volume = 0 |
| | | |
| | | money_y = int(refer_volume * limit_up_price / 1e8) |
| | | money_y = min(money_y, 50) |
| | | money_y = max(money_y, 5) |
| | | # 计算大单参考数量 |
| | | threshold_count = 1 # int(round(0.4 * money_y)) |
| | | threshold_money = threshold_count * 299 * 10000 |
| | | |
| | | if volume_rate >= 0.5 or True: |
| | | # 按量大于50%算 |
| | | # 当换手量>50%时,则,不需要每次扫入时需要≥2笔大单,而是累计需要≥2笔大单即可 |
| | | deal_big_order_money = BigOrderDealManager().get_total_buy_money(code) |
| | | try: |
| | | # 获取正在成交的订单 |
| | | dealing_order_info = HuaXinBuyOrderManager().get_dealing_order_info(code) |
| | | |
| | | threshold_big_money = l2_data_util.get_big_money_val(limit_up_price, tool.is_ge_code(code)) |
| | | if dealing_order_info and dealing_order_info[2] >= threshold_big_money: |
| | | # 正在成交的订单是大单 |
| | | deal_big_order_money += dealing_order_info[2] |
| | | except Exception as e: |
| | | async_log_util.info(logger_l2_radical_buy, f"计算正在成交大单出错:{str(e)}") |
| | | |
| | | if deal_big_order_money >= threshold_money: |
| | | return True, f"量比-{volume_rate}, 总大单成交金额({deal_big_order_money})>={threshold_money}" |
| | | else: |
| | | return False, f"量比-{volume_rate}, 总大单成交金额({deal_big_order_money})<{threshold_money}" |
| | | else: |
| | | current_big_order_deal_count = EveryLimitupBigDealOrderManager.get_big_buy_deal_order_count(code) |
| | | if current_big_order_deal_count >= threshold_count: |
| | | return True, f"量比-{volume_rate}, 本次大单成交数量({current_big_order_deal_count})>={threshold_count}" |
| | | else: |
| | | return False, f"量比-{volume_rate}, 本次大单成交数量({current_big_order_deal_count})<{threshold_count}" |
| | | |
| | | |
| | | def is_can_buy_with_open_price(code, open_price): |
| | | """ |
| | | 根据开盘价判断是否可买 |
| | |
| | | @param open_price: |
| | | @return: |
| | | """ |
| | | if tool.get_now_time_as_int() < int("093100"): |
| | | if tool.get_now_time_as_int() < int("093500"): |
| | | async_log_util.info(logger_l2_radical_buy, f"开盘价:{code}-{open_price}") |
| | | pre_price = gpcode_manager.CodePrePriceManager.get_price_pre_cache(code) |
| | | if pre_price: |
| | | rate = round((open_price - pre_price) / pre_price, 4) |
| | | async_log_util.info(logger_l2_radical_buy, f"开盘价涨幅:{code}-{rate}") |
| | | if tool.get_limit_up_rate(code) > 1.1: |
| | | return rate < 0.189 |
| | | return rate < 0.149 |
| | | else: |
| | | return rate < 0.089 |
| | | return rate < 0.049 |
| | | return True |
| | |
| | | |
| | | |
| | | # 通过量下单,返回(代码,账号ID,订单号) |
| | | def order_volume(code, price, count, last_data, order_ref=None, exec_index=None): |
| | | def order_volume(code, price, count, last_data, order_ref=None, exec_index=None, shadow_volume=None): |
| | | if not shadow_volume: |
| | | shadow_volume = 100 |
| | | async_log_util.info(logger_trade, f"{code} trade_huaxin.order_volume 开始") |
| | | try: |
| | | price = round(float(price), 2) |
| | |
| | | # 保存下单信息 |
| | | shadow_price = tool.get_shadow_price(price) |
| | | huaxin.huaxin_delegate_postion_manager.place_order(code, price, count, exec_index, last_data, order_ref, |
| | | shadow_price=shadow_price) |
| | | shadow_price=shadow_price, shadow_volume=shadow_volume) |
| | | if not constant.TRADE_ENABLE: |
| | | return |
| | | result = None |
| | |
| | | try: |
| | | async_log_util.info(logger_trade, f"{code}下单开始") |
| | | result = huaxin_trade_api.order(1, code, count, price, blocking=blocking, order_ref=order_ref, |
| | | shadow_price=shadow_price) |
| | | shadow_price=shadow_price, shadow_volume=shadow_volume) |
| | | async_log_util.info(logger_trade, f"{code}下单结束") |
| | | except Exception as e: |
| | | if str(e).find("超时") >= 0: |
| | |
| | | if orders: |
| | | async_log_util.info(logger_trade, f"{code}:华鑫开始执行撤单 {msg}") |
| | | for order in orders: |
| | | huaxin_trade_api.cancel_order(1, code, order["orderSysID"]) |
| | | huaxin_trade_api.cancel_order(huaxin_trade_api.TRADE_DIRECTION_BUY, code, order["orderSysID"]) |
| | | __TradeOrderIdManager.remove_order_id(code, order["accountId"], order["orderSysID"]) |
| | | async_log_util.info(logger_trade, f"{code}:华鑫撤单结束,撤单数量:{len(orders)}") |
| | | |
| | |
| | | order_refs_info = copy.deepcopy(order_refs_info) |
| | | for order_ref in order_refs_info: |
| | | async_log_util.info(logger_trade, f"{code}:华鑫开始执行撤单 {msg}") |
| | | huaxin_trade_api.cancel_order(1, code, '', orderRef=order_ref) |
| | | huaxin_trade_api.cancel_order(huaxin_trade_api.TRADE_DIRECTION_BUY, code, '', orderRef=order_ref) |
| | | __TradeOrderIdManager.remove_order_ref(code, order_ref) |
| | | async_log_util.info(logger_trade, f"{code}:华鑫执行撤单结束") |
| | | |