| | |
| | | print("=================回测状态===============") |
| | | self.__read_backtest_result() |
| | | threading.Thread(target=lambda: async_log_util.run_sync(), daemon=True).start() |
| | | now_day = '2025-08-11' |
| | | now_day = '2025-08-21' |
| | | constant.IS_FOR_BACKTEST = True |
| | | current_datas = self.__init_data(now_day) |
| | | # 从早上09:25:00回测到11:30:00 |
| | |
| | | CLIENT_TYPE_POSITION_LIST = "position_list" |
| | | CLIENT_TYPE_MONEY = "money" |
| | | CLIENT_TYPE_DEAL = "deal" |
| | | CLIENT_TYPE_ORDER_FOUND_DETAIL = "order_found_detail" |
| | | |
| | | CLIENT_TYPE_CMD_L2 = "l2_cmd" |
| | | |
| | |
| | | |
| | | # 获取资金信息 |
| | | def OnMoney(self, client_id, request_id, sk): |
| | | pass |
| | | |
| | | def OnOrderFoundDetail(self, client_id, request_id, sk, data): |
| | | pass |
| | | |
| | | # 测试 |
| | |
| | | cls.action_callback.OnDelegateList(client_id, request_id, sk, can_cancel) |
| | | elif _type == CLIENT_TYPE_POSITION_LIST: |
| | | cls.action_callback.OnPositionList(client_id, request_id, sk) |
| | | elif _type == CLIENT_TYPE_ORDER_FOUND_DETAIL: |
| | | cls.action_callback.OnOrderFoundDetail(client_id, request_id, sk, data) |
| | | elif _type == "test": |
| | | cls.action_callback.OnTest(client_id, request_id, data, sk) |
| | | except Exception as e: |
| | |
| | | # 成交 |
| | | TYPE_DEAL = 6 |
| | | |
| | | # 订单费率 |
| | | TYPE_LIST_ORDER_FOUND = 7 |
| | | |
| | | ENABLE_ORDER = True |
| | | |
| | | |
| | |
| | | |
| | | def queryOrderFoundDetail(self, code, orderSysID): |
| | | """ |
| | | 查询保单资金明细 |
| | | 查询订单单资金明细 |
| | | :param code: |
| | | :param orderSysID: |
| | | :return: |
| | |
| | | self.__temp_order_list_dict = {} |
| | | self.__temp_position_list_dict = {} |
| | | self.__temp_money_account_list_dict = {} |
| | | self.__temp_order_found_list_dict = {} |
| | | self.call_back_thread_pool = concurrent.futures.ThreadPoolExecutor(max_workers=10) |
| | | # 自己的订单号 |
| | | self.own_order_sys_ids = set() |
| | |
| | | pRspInfoField: "CTORATstpRspInfoField", nRequestID: "int", bIsLast: "bool") -> "void": |
| | | logging.info(f"佣金费用响应:{pRspInfoField.ErrorID}-{pRspInfoField.ErrorMsg}-{bIsLast}") |
| | | try: |
| | | data = [pOrderFundDetailField.OrderAmount, pOrderFundDetailField.Turnover, |
| | | pOrderFundDetailField.StampTaxFee, pOrderFundDetailField.HandlingFee, |
| | | pOrderFundDetailField.BrokerageFee, pOrderFundDetailField.TotalFee] |
| | | logging.info(f"佣金费用响应:{data}") |
| | | if nRequestID not in self.__temp_order_found_list_dict: |
| | | self.__temp_order_found_list_dict[nRequestID] = [] |
| | | if bIsLast != 1: |
| | | data = {"orderLocalID": pOrderFundDetailField.OrderLocalID, |
| | | "orderSysID": pOrderFundDetailField.OrderSysID, |
| | | "securityID": pOrderFundDetailField.SecurityID, |
| | | "orderAmount": pOrderFundDetailField.OrderAmount, "turnover": pOrderFundDetailField.Turnover, |
| | | "stampTaxFee": pOrderFundDetailField.StampTaxFee, |
| | | "handlingFee": pOrderFundDetailField.HandlingFee, |
| | | "brokerageFee": pOrderFundDetailField.BrokerageFee, "totalFee": pOrderFundDetailField.TotalFee} |
| | | self.__temp_order_found_list_dict[nRequestID].append(data) |
| | | else: |
| | | results = self.__temp_order_found_list_dict.pop(nRequestID) |
| | | self.call_back_thread_pool.submit(self.__data_callback, TYPE_LIST_ORDER_FOUND, nRequestID, results) |
| | | except: |
| | | pass |
| | | |
| | |
| | | send_response(json.dumps({"code": 1, "msg": str(e)}), "common", client_id, |
| | | request_id) |
| | | |
| | | def OnOrderFoundDetail(self, client_id, request_id, sk, data): |
| | | async_log_util.info(logger_local_huaxin_trade_debug, f"请求订单资金明细:client_id-{client_id} request_id-{request_id}") |
| | | try: |
| | | code, orderSysID = data.get("code"), data.get("orderSysID") |
| | | req_id = self.__tradeSimpleApi.queryOrderFoundDetail(code, orderSysID) |
| | | req_rid_dict[req_id] = (client_id, request_id, sk) |
| | | except Exception as e: |
| | | send_response(json.dumps({"code": 1, "msg": str(e)}), "common", client_id, |
| | | request_id) |
| | | |
| | | |
| | | def OnTest(self, client_id, request_id, data, sk): |
| | | send_response( |
| | | json.dumps({"type": "response", "data": {"code": 0, "data": data}, "client_id": client_id, |
| | |
| | | filter=lambda record: record["extra"].get("name") == "kpl_forbidden_plates", |
| | | rotation="00:00", compression="zip", enqueue=True) |
| | | |
| | | logger.add(self.get_path("virtual_account", "virtual_account_money_records"), |
| | | filter=lambda record: record["extra"].get("name") == "virtual_account_money_records", |
| | | rotation="00:00", compression="zip", enqueue=True) |
| | | |
| | | def get_path(self, dir_name, log_name): |
| | | path_str = "{}/{}/gp/{}/{}".format(constant.get_path_prefix(), constant.LOG_DIR, dir_name, |
| | | log_name) + ".{time:YYYY-MM-DD}.log" |
| | |
| | | |
| | | logger_mysql_debug = __mylogger.get_logger("mysql_debug") |
| | | |
| | | logger_virtual_account_money_records= __mylogger.get_logger("virtual_account_money_records") |
| | | |
| | | # -------------------------------华鑫日志--------------------------------- |
| | | hx_logger_l2_orderdetail = __mylogger.get_logger("hx_l2_orderdetail") |
| | | hx_logger_l2_transaction = __mylogger.get_logger("hx_l2_transaction") |
| | |
| | | else: |
| | | time_str = __get_log_time(line) |
| | | data = line.split(" - ")[1].strip() |
| | | if min_time_str<=time_str<=max_time_str: |
| | | if min_time_str <= time_str <= max_time_str: |
| | | fdatas.append((time_str, eval(data))) |
| | | if time_str > max_time_str: |
| | | break |
| | |
| | | return fdatas |
| | | |
| | | |
| | | def load_virtual_trade_account(date=tool.get_now_date_str()): |
| | | """ |
| | | 加载虚拟交易数据 |
| | | :param date: |
| | | :return: |
| | | """ |
| | | path = f"{constant.get_path_prefix()}/low_suction_log/gp/virtual_account/virtual_account_money_records.{date}.log" |
| | | fdatas = [] |
| | | if os.path.exists(path): |
| | | with open(path, 'r', encoding="utf-8") as f: |
| | | lines = f.readlines() |
| | | if lines: |
| | | for line in lines: |
| | | time_str = __get_async_log_time(line) |
| | | data = line[line.find("]") + 1:].strip() |
| | | fdatas.append((time_str, eval(data))) |
| | | return fdatas |
| | | |
| | | |
| | | if __name__ == '__main__': |
| | | load_k_bars('2025-07-03') |
| | | datas = load_ticks_data("09:50:00") |
| | |
| | | if __name__ == '__main__': |
| | | log.close_print() |
| | | |
| | | def test(): |
| | | time.sleep(10) |
| | | result = huaxin_trade_api.queryOrderFoundDetail("002875", "12101A190001582") |
| | | logger_debug.info("查询资金明细结果:{}", str(result)) |
| | | |
| | | class MyMarketDataCallback(l2_market_client.L2MarketDataCallback): |
| | | |
| | |
| | | target_codes = set(target_codes) | set(position_codes) |
| | | logger_debug.info(f"今日要订阅的代码:{len(target_codes)}-{target_codes}") |
| | | |
| | | # 测试资金明细 |
| | | threading.Thread(target=test, daemon=True).start() |
| | | |
| | | # 订阅L2 market行情 |
| | | l2_market_client.run(target_codes, MyMarketDataCallback()) |
| | |
| | | CLIENT_TYPE_MONEY = "money" |
| | | CLIENT_TYPE_DEAL = "deal" |
| | | CLIENT_TYPE_CMD_L2 = "l2_cmd" |
| | | CLIENT_TYPE_ORDER_FOUND_DETAIL = "order_found_detail" |
| | | socket_client_dict = {} |
| | | socket_client_lock_dict = {} |
| | | active_client_dict = {} |
| | |
| | | return res |
| | | |
| | | |
| | | def queryOrderFoundDetail(code, orderSysID): |
| | | """ |
| | | 查询订单资金明细 |
| | | :param code: |
| | | :param orderSysID: |
| | | :return: |
| | | """ |
| | | request_id = __get_request_id(ClientSocketManager.CLIENT_TYPE_TRADE) |
| | | for i in range(1): |
| | | request_id = __request(ClientSocketManager.CLIENT_TYPE_TRADE, |
| | | {"type": ClientSocketManager.CLIENT_TYPE_ORDER_FOUND_DETAIL, |
| | | "code": code, |
| | | "orderSysID": orderSysID}, |
| | | request_id=request_id, |
| | | is_trade=True) |
| | | try: |
| | | res = __read_response(request_id, True) |
| | | async_log_util.info(hx_logger_trade_debug, f"资金明细结果:{res}") |
| | | return res |
| | | finally: |
| | | pass |
| | | |
| | | |
| | | # money = get_money() |
| | | # print(f"money=={money}") |
| | | |
New file |
| | |
| | | """ |
| | | 虚拟账户管理 |
| | | """ |
| | | from log_module import async_log_util, log_export |
| | | from log_module.log import logger_virtual_account_money_records |
| | | from utils import tool |
| | | |
| | | EVENT_CHARGE = "charge" # 充值 |
| | | |
| | | EVENT_BUY_DEAL = "buy_deal" # 买成交 |
| | | |
| | | EVENT_SELL_DEAL = "sell_deal" # 卖成交 |
| | | |
| | | EVENT_BALANCE_ACCOUNT = "balance_account" # 平账 |
| | | |
| | | EVENT_FEE = "fee" # 手续费 |
| | | |
| | | |
| | | @tool.singleton |
| | | class VirtualAccountMoneyManager: |
| | | """ |
| | | 虚拟账户资金管理 |
| | | """ |
| | | |
| | | def __init__(self): |
| | | self.all_money = 0 |
| | | self.available_money = 0 |
| | | # 冻结金额记录 |
| | | self.frozen_money_record_dict = {} |
| | | self.__load_data() |
| | | |
| | | def __load_data(self): |
| | | """ |
| | | 加载数据,从今天及以前的日志中读取数据 |
| | | :return: |
| | | """ |
| | | all_money = None |
| | | available_money = None |
| | | now_day = tool.get_now_date_str() |
| | | # 加载今日之前的数据 |
| | | for i in range(1, 60): |
| | | day = tool.date_sub(now_day, i) |
| | | results = log_export.load_virtual_trade_account(day) |
| | | if not results: |
| | | continue |
| | | |
| | | for r in results: |
| | | if r[1]["type"] == "资金变化": |
| | | all_money = r[1]["data"]["all_money"] |
| | | available_money = r[1]["data"]["available_money"] |
| | | if all_money: |
| | | if day != now_day: |
| | | # 非今日 |
| | | available_money = all_money |
| | | break |
| | | if all_money is not None: |
| | | self.all_money = all_money |
| | | self.available_money = available_money |
| | | |
| | | # 读取今日日志 |
| | | results = log_export.load_virtual_trade_account(now_day) |
| | | if results: |
| | | for r in results: |
| | | _type = r[1]["type"] |
| | | _data = r[1]["data"] |
| | | if _type == '资金变化': |
| | | self.add_money(_data["amount"], _data["event"], _data["unique_id"], enable_log=False) |
| | | elif _type == '冻结金额': |
| | | self.frozen_money(_data["amount"], _data["unique_id"], enable_log=False) |
| | | elif _type == '解冻金额': |
| | | self.un_frozen_money(_data["amount"], _data["unique_id"], enable_log=False) |
| | | elif _type == '消耗冻结金额': |
| | | self.consume_frozen_money(_data["unique_id"], enable_log=False) |
| | | |
| | | def __format_log(self, type, data): |
| | | fdata = {"type": type, "data": data} |
| | | return f"{fdata}" |
| | | |
| | | def add_money(self, money, event, unique_id, enable_log=True): |
| | | """ |
| | | 添加资金 |
| | | :param enable_log: |
| | | :param unique_id: 唯一ID |
| | | :param money: 金额 |
| | | :param event: 事件 |
| | | :return: |
| | | """ |
| | | self.all_money += money |
| | | self.available_money += money |
| | | if enable_log: |
| | | async_log_util.info(logger_virtual_account_money_records, self.__format_log("资金变化", |
| | | {"event": event, |
| | | 'amount': money, |
| | | 'all_money': self.all_money, |
| | | 'available_money': self.available_money, |
| | | "unique_id": unique_id})) |
| | | |
| | | def frozen_money(self, money, unique_id, enable_log=True): |
| | | """ |
| | | 冻结金额:挂买要冻结 |
| | | :param enable_log: |
| | | :param money: 金额 |
| | | :param unique_id: 唯一索引 |
| | | :return: |
| | | """ |
| | | self.available_money -= money |
| | | self.frozen_money_record_dict[unique_id] = money |
| | | if enable_log: |
| | | async_log_util.info(logger_virtual_account_money_records, self.__format_log("冻结金额", |
| | | {"unique_id": unique_id, |
| | | 'amount': money, |
| | | 'available_money': self.available_money})) |
| | | |
| | | def un_frozen_money(self, money, unique_id, enable_log=True): |
| | | """ |
| | | 解冻金额,买入撤单情况下可解冻 |
| | | :param enable_log: |
| | | :param money: 金额 |
| | | :param unique_id: |
| | | :return: |
| | | """ |
| | | self.available_money += money |
| | | if unique_id in self.frozen_money_record_dict: |
| | | self.frozen_money_record_dict.pop(unique_id) |
| | | if enable_log: |
| | | async_log_util.info(logger_virtual_account_money_records, self.__format_log("解冻金额", |
| | | {"unique_id": unique_id, |
| | | 'amount': money, |
| | | 'available_money': self.available_money})) |
| | | |
| | | def consume_frozen_money(self, unique_id, enable_log=True): |
| | | """ |
| | | 消耗冻结金额:买入成交会消耗 |
| | | :param enable_log: |
| | | :param unique_id: |
| | | :return: |
| | | """ |
| | | if unique_id in self.frozen_money_record_dict: |
| | | self.frozen_money_record_dict.pop(unique_id) |
| | | if enable_log: |
| | | async_log_util.info(logger_virtual_account_money_records, self.__format_log("消耗冻结金额", |
| | | {"unique_id": unique_id, |
| | | 'available_money': self.available_money})) |
| | | |
| | | def get_available_money(self): |
| | | """ |
| | | 获取可用金额 |
| | | :return: |
| | | """ |
| | | return self.available_money |
| | | |
| | | def get_total_money(self): |
| | | """ |
| | | 获取总共金额 |
| | | :return: |
| | | """ |
| | | return self.all_money |
| | | |
| | | |
| | | if __name__ == "__main__": |
| | | VirtualAccountMoneyManager().add_money(20000, EVENT_CHARGE, '') |
| | | print(VirtualAccountMoneyManager().get_total_money(), |
| | | VirtualAccountMoneyManager().get_available_money()) #.add_money(20000, EVENT_CHARGE, '') |
| | | async_log_util.run_sync() |