| | |
| | | 卖票管理器 |
| | | """ |
| | | import concurrent.futures |
| | | import time |
| | | |
| | | from log_module import async_log_util |
| | | from log_module.log import logger_trade, logger_trade_position_api_request |
| | | from trade.huaxin import huaxin_trade_order_processor, huaxin_trade_api |
| | | from utils import huaxin_util, sell_util, tool |
| | | from trade.huaxin.huaxin_trade_record_manager import DealRecordManager, DelegateRecordManager |
| | | |
| | | __cancel_sell_thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=8) |
| | | |
| | | |
| | | # 撤卖单 |
| | | def __cancel_sell_order(code, order_ref): |
| | | for i in range(0, 10): |
| | | time.sleep(0.2) |
| | | order_entity = huaxin_trade_order_processor.TradeResultProcessor.get_huaxin_order_by_order_ref(order_ref) |
| | | if order_entity: |
| | | if order_entity.orderStatus == huaxin_util.TORA_TSTP_OST_AllTraded: |
| | | # 成交的就不需要撤单了 |
| | | return |
| | | try: |
| | | result = huaxin_trade_api.cancel_order(2, code, None, orderRef=order_ref) |
| | | except Exception as e: |
| | | logger_trade.exception(e) |
| | | # 人工卖票管理器 |
| | | class HumanSellManager: |
| | | __code_sell_way_dict = {} |
| | | __DealRecordManager = DealRecordManager() |
| | | |
| | | def set_code_sell_way(self, data): |
| | | fdata = {} |
| | | code = data["code"] |
| | | mode = data["mode"] |
| | | if mode == 1: |
| | | mode1_rate_index = data["mode1_rate_index"] |
| | | fdata["mode1_rate_index"] = mode1_rate_index |
| | | elif mode == 2: |
| | | # 第一笔卖的索引 |
| | | mode2_first_index = data["mode2_first_index"] |
| | | # 剩下几笔卖的索引 |
| | | mode2_left_index = data["mode2_left_index"] |
| | | fdata["mode2_first_index"] = mode2_first_index |
| | | fdata["mode2_left_index"] = mode2_left_index |
| | | fdata["code"] = code |
| | | fdata["mode"] = mode |
| | | self.__code_sell_way_dict[code] = fdata |
| | | # 保存卖的方式 |
| | | async_log_util.info(logger_trade_position_api_request, f"设置卖出方式:{fdata}") |
| | | |
| | | def __get_deal_nums(self, code): |
| | | deal_order_system_id_infos = {} |
| | | # 获取已经卖的单数 |
| | | deal_list = self.__DealRecordManager.list_sell_by_code_cache(code) |
| | | if deal_list: |
| | | for d in deal_list: |
| | | if d["orderSysID"] not in deal_order_system_id_infos: |
| | | deal_order_system_id_infos[d["orderSysID"]] = [d["volume"], d["tradeTime"]] |
| | | else: |
| | | deal_order_system_id_infos[d["orderSysID"]][0] += d["volume"] |
| | | # 获取9:30之前的卖委托 |
| | | current_delegates = DelegateRecordManager().list_current_delegates(code) |
| | | if current_delegates: |
| | | for d in current_delegates: |
| | | if d["orderSysID"] not in deal_order_system_id_infos: |
| | | deal_order_system_id_infos[d["orderSysID"]] = [d["volume"], d["insertTime"]] |
| | | deal_list = [deal_order_system_id_infos[k] for k in deal_order_system_id_infos] |
| | | deal_list.sort(key=lambda x: x[1]) |
| | | sell_order_nums = [k[0] for k in deal_list] |
| | | return sell_order_nums |
| | | |
| | | def distribute_sell_volume(self, code, total_volume): |
| | | def average_volume(_total_volume, count): |
| | | total_volume_100 = _total_volume // 100 |
| | | _base_100 = total_volume_100 // count |
| | | _left_100 = total_volume_100 % count |
| | | temp_list = [] |
| | | for i in range(count): |
| | | if i + 1 <= _left_100: |
| | | temp_list.append((_base_100 + 1) * 100) |
| | | else: |
| | | temp_list.append(_base_100 * 100) |
| | | return temp_list |
| | | |
| | | if code not in self.__code_sell_way_dict: |
| | | raise Exception("还没设置卖出方式") |
| | | |
| | | sell_way = self.__code_sell_way_dict.get(code) |
| | | volumeList = [] |
| | | if sell_way["mode"] == 1: |
| | | # 平均卖 |
| | | mode1_rate_index = sell_way["mode1_rate_index"] |
| | | volumeList = average_volume(total_volume, mode1_rate_index) |
| | | elif sell_way["mode"] == 2: |
| | | # 按百分比卖 |
| | | mode2_first_index = sell_way["mode2_first_index"] |
| | | # 剩下几笔卖的索引 |
| | | mode2_left_index = sell_way["mode2_left_index"] |
| | | first_percent = (mode2_first_index + 1) * 10 |
| | | second_count = mode2_left_index + 1 |
| | | first = first_percent * total_volume // 100 |
| | | if first_percent * total_volume % 100 != 0: |
| | | first += 100 |
| | | volumeList.append(first) |
| | | total_left = total_volume - first |
| | | left_volumes = average_volume(total_left, second_count) |
| | | volumeList.extend(left_volumes) |
| | | return volumeList |
| | | |
| | | # 计算卖出量 |
| | | def compute_sell_volume(self, code, total_volume): |
| | | volumeList = self.distribute_sell_volume(code, total_volume) |
| | | # 获取已卖和已挂单的数据 |
| | | sell_order_nums = self.__get_deal_nums(code) |
| | | if len(sell_order_nums) >= len(volumeList): |
| | | raise Exception(f"挂单已超过设置数量:{sell_order_nums}/{volumeList}") |
| | | return volumeList[len(sell_order_nums)] |
| | | |
| | | |
| | | # 开始撤单 |
| | | def start_sell(code, volume, price_type, limit_up_price, limit_down_price, current_price, blocking=False, |
| | | request_id=None): |
| | | price = sell_util.get_sell_price(price_type, limit_up_price, limit_down_price, current_price) |
| | | if not price: |
| | | raise Exception("价格获取出错") |
| | | async_log_util.info(logger_trade, f"API卖: 单价-{price}") |
| | | order_ref = huaxin_util.create_order_ref() |
| | | result = huaxin_trade_api.order(2, code, volume, price, order_ref=order_ref, |
| | | blocking=blocking, request_id=request_id) |
| | | # 如果是在正常交易时间提交的2s之内还未成交的需要撤单 |
| | | if int("092958") <= int(tool.get_now_time_str().replace(":", "")) <= int("145655"): |
| | | __cancel_sell_thread_pool.submit(lambda: __cancel_sell_order(code, order_ref)) |
| | | return result |
| | | if __name__ == '__main__': |
| | | code = "000333" |
| | | __HumanSellManager = HumanSellManager() |
| | | __HumanSellManager.set_code_sell_way({"code": code, "mode": 1, "mode1_rate_index": 3}) |
| | | # __HumanSellManager.set_code_sell_way({"code": code, "mode": 2, "mode2_first_index": 1, "mode2_left_index": 4}) |
| | | |
| | | |
| | | __code_sell_way_dict = {} |
| | | |
| | | |
| | | def set_code_sell_way(data): |
| | | fdata = {} |
| | | code = data["code"] |
| | | mode = data["mode"] |
| | | if mode == 1: |
| | | mode1_rate_index = data["mode1_rate_index"] |
| | | fdata["mode1_rate_index"] = mode1_rate_index |
| | | elif mode == 2: |
| | | # 第一笔卖的索引 |
| | | mode2_first_index = data["mode2_first_index"] |
| | | # 剩下几笔卖的索引 |
| | | mode2_left_index = data["mode2_left_index"] |
| | | fdata["mode2_first_index"] = mode2_first_index |
| | | fdata["mode2_left_index"] = mode2_left_index |
| | | fdata["code"] = code |
| | | fdata["mode"] = mode |
| | | __code_sell_way_dict[code] = fdata |
| | | # 保存卖的方式 |
| | | async_log_util.info(logger_trade_position_api_request, f"设置卖出方式:{fdata}") |
| | | |
| | | |
| | | # 计算卖出量 |
| | | def compute_sell_volume(code): |
| | | if code not in __code_sell_way_dict: |
| | | raise Exception("还没设置卖出方式") |
| | | sell_way = __code_sell_way_dict.get(code) |
| | | # TODO |
| | | return 100 |
| | | |
| | | f = __HumanSellManager.distribute_sell_volume(code, 2000) |
| | | print(f) |