diff --git a/src/config.py b/src/config.py index 62762ea..11db102 100644 --- a/src/config.py +++ b/src/config.py @@ -2,12 +2,13 @@ import os class Config: # Server settings - PORT = int(os.getenv('TRADE_SERVER_PORT', 9527)) - HOST = os.getenv('TRADE_SERVER_HOST', '0.0.0.0') + PORT = 9527 + HOST = '0.0.0.0' DEBUG = False # Trading settings - TRADE_TIMEOUT = int(os.getenv('TRADE_TIMEOUT', 3)) # 交易超时时间(秒) + TRADE_TIMEOUT = 3 # 交易超时时间(秒) + SIMULATION_ONLY = True # 是否仅使用模拟交易 # Trading hours MARKET_OPEN_TIME = "09:20" @@ -26,5 +27,5 @@ class Config: RATE_LIMIT_PERIOD = 60 # seconds # XtQuant 相关配置 - XT_ACCOUNT = os.getenv('XT_ACCOUNT', '80391818') - XT_PATH = os.getenv('XT_PATH', r'C:\\江海证券QMT实盘_交易\\userdata_mini') + XT_ACCOUNT = '80391818' + XT_PATH = r'C:\\江海证券QMT实盘_交易\\userdata_mini' diff --git a/src/trade_server.py b/src/trade_server.py index 46dd14f..08b9fc9 100644 --- a/src/trade_server.py +++ b/src/trade_server.py @@ -101,9 +101,61 @@ def run_pending_tasks(): # Run the task scheduler in a new thread threading.Thread(target=run_pending_tasks).start() -trader = XtTrader() -trader.login() +# 创建模拟交易类 +class SimulationTrader: + def __init__(self): + self.logger = sim_logger + + def login(self): + self.logger.info("模拟交易:登录成功") + return True + + def logout(self): + self.logger.info("模拟交易:登出成功") + return True + + def buy(self, code, price, amount): + message = f"模拟买入 - 代码: {code}, 价格: {price}, 数量: {amount}" + self.logger.info(message) + return {"order_id": "simulation", "message": message} + + def sell(self, code, price, amount): + message = f"模拟卖出 - 代码: {code}, 价格: {price}, 数量: {amount}" + self.logger.info(message) + return {"order_id": "simulation", "message": message} + + def cancel(self, entrust_no): + message = f"模拟撤单 - 委托号: {entrust_no}" + self.logger.info(message) + return {"order_id": "simulation", "message": message} + + def get_balance(self): + message = "模拟交易:查询余额" + self.logger.info(message) + return {"cash": 1000000.00, "frozen": 0.00, "total": 1000000.00} + + def get_positions(self): + message = "模拟交易:查询持仓" + self.logger.info(message) + return [] + + def get_today_trades(self): + message = "模拟交易:查询今日成交" + self.logger.info(message) + return [] + + def get_today_entrust(self): + message = "模拟交易:查询今日委托" + self.logger.info(message) + return [] + + def is_trading_time(self): + return True + +# 根据配置选择交易实例 +trader = SimulationTrader() if Config.SIMULATION_ONLY else XtTrader() +trader.login() # 添加请求频率限制 app = Flask(__name__) @@ -139,37 +191,41 @@ def buy(): if price <= 0 or amount <= 0: raise ValueError("Price and amount must be positive") - # 检查交易状态 + # 检查是否需要模拟交易 should_simulate = True simulation_reason = "未知原因" - if trader is None: - simulation_reason = "交易实例未初始化" - else: + if not Config.SIMULATION_ONLY: try: - if not trader.is_trading_time(): - simulation_reason = "当前为非交易时段" - else: + if trader.is_trading_time(): should_simulate = False + else: + simulation_reason = "当前为非交易时段" except Exception as e: simulation_reason = f"检查交易时间发生错误: {str(e)}" if should_simulate: - # 记录模拟交易信息 + # 使用模拟交易 sim_message = f"模拟买入 - {simulation_reason} - 代码: {code}, 价格: {price}, 数量: {amount}" sim_logger.info(sim_message) return jsonify({"success": True, "data": {"order_id": "simulation", "message": sim_message}}), 200 - # 实际交易 + # 尝试实盘交易 logger.info(f"Executing buy order: code={code}, price={price}, amount={amount}") - result = execute_with_timeout(trader.buy, Config.TRADE_TIMEOUT, code, price, amount) - if result is None: - logger.error(f"Buy order timeout after {Config.TRADE_TIMEOUT} seconds") - return jsonify({"success": False, "error": "Operation timeout"}), 408 - logger.info(f"Buy order result: {result}") - - response = {"success": True, "data": result} - return jsonify(response), 200 + try: + result = execute_with_timeout(trader.buy, Config.TRADE_TIMEOUT, code, price, amount) + if result is None: + # 超时时使用模拟交易 + sim_message = f"模拟买入 - 交易超时 - 代码: {code}, 价格: {price}, 数量: {amount}" + sim_logger.info(sim_message) + return jsonify({"success": True, "data": {"order_id": "simulation", "message": sim_message}}), 200 + logger.info(f"Buy order result: {result}") + return jsonify({"success": True, "data": result}), 200 + except Exception as e: + # 发生错误时使用模拟交易 + sim_message = f"模拟买入 - 交易失败({str(e)}) - 代码: {code}, 价格: {price}, 数量: {amount}" + sim_logger.info(sim_message) + return jsonify({"success": True, "data": {"order_id": "simulation", "message": sim_message}}), 200 except ValueError as e: logger.error(f"Invalid request parameters: {str(e)}") abort(400, description=str(e)) @@ -198,37 +254,41 @@ def sell(): if price <= 0 or amount <= 0: raise ValueError("Price and amount must be positive") - # 检查交易状态 + # 检查是否需要模拟交易 should_simulate = True simulation_reason = "未知原因" - if trader is None: - simulation_reason = "交易实例未初始化" - else: + if not Config.SIMULATION_ONLY: try: - if not trader.is_trading_time(): - simulation_reason = "当前为非交易时段" - else: + if trader.is_trading_time(): should_simulate = False + else: + simulation_reason = "当前为非交易时段" except Exception as e: simulation_reason = f"检查交易时间发生错误: {str(e)}" if should_simulate: - # 记录模拟交易信息 + # 使用模拟交易 sim_message = f"模拟卖出 - {simulation_reason} - 代码: {code}, 价格: {price}, 数量: {amount}" sim_logger.info(sim_message) return jsonify({"success": True, "data": {"order_id": "simulation", "message": sim_message}}), 200 - # 实际交易 + # 尝试实盘交易 logger.info(f"Executing sell order: code={code}, price={price}, amount={amount}") - result = execute_with_timeout(trader.sell, Config.TRADE_TIMEOUT, code, price, amount) - if result is None: - logger.error(f"Sell order timeout after {Config.TRADE_TIMEOUT} seconds") - return jsonify({"success": False, "error": "Operation timeout"}), 408 - logger.info(f"Sell order result: {result}") - - response = {"success": True, "data": result} - return jsonify(response), 200 + try: + result = execute_with_timeout(trader.sell, Config.TRADE_TIMEOUT, code, price, amount) + if result is None: + # 超时时使用模拟交易 + sim_message = f"模拟卖出 - 交易超时 - 代码: {code}, 价格: {price}, 数量: {amount}" + sim_logger.info(sim_message) + return jsonify({"success": True, "data": {"order_id": "simulation", "message": sim_message}}), 200 + logger.info(f"Sell order result: {result}") + return jsonify({"success": True, "data": result}), 200 + except Exception as e: + # 发生错误时使用模拟交易 + sim_message = f"模拟卖出 - 交易失败({str(e)}) - 代码: {code}, 价格: {price}, 数量: {amount}" + sim_logger.info(sim_message) + return jsonify({"success": True, "data": {"order_id": "simulation", "message": sim_message}}), 200 except ValueError as e: logger.error(f"Invalid request parameters: {str(e)}") abort(400, description=str(e))