""" 交易路由 处理订单发送、撤单、查询 """ from fastapi import APIRouter, Depends, HTTPException, status from typing import List import logging from ..models import ( SendOrderRequest, CancelOrderRequest, OrderResponse, AccountResponse, PositionData, AccountData, ApiResponse, TradeData ) from ..deps import get_current_user, get_vn_service logger = logging.getLogger(__name__) router = APIRouter() # ============================================ # 账户和持仓 # ============================================ @router.get("/accounts", response_model=List[AccountData]) async def get_accounts( current_user: dict = Depends(get_current_user), vn_service=Depends(get_vn_service) ): """ 获取账户信息 返回所有账户的资金信息 """ accounts = await vn_service.get_accounts() return [ AccountData( account_id=acc["account_id"], balance=acc["balance"], available=acc["available"], frozen=acc.get("frozen", 0.0), ) for acc in accounts ] @router.get("/positions", response_model=List[PositionData]) async def get_positions( current_user: dict = Depends(get_current_user), vn_service=Depends(get_vn_service) ): """ 获取持仓信息 返回所有持仓数据 """ positions = await vn_service.get_positions() return [ PositionData( symbol=p["symbol"], exchange=p["exchange"], direction=p["direction"], volume=p["volume"], price=p["price"], pnl=p["pnl"], pnl_ratio=p.get("pnl_ratio", 0.0), frozen=p.get("frozen", 0.0), ) for p in positions ] # ============================================ # 订单管理 # ============================================ @router.get("/orders", response_model=List[OrderResponse]) async def get_orders( current_user: dict = Depends(get_current_user), vn_service=Depends(get_vn_service) ): """ 获取所有委托 返回所有订单,包括历史订单和活动订单 """ orders_data = await vn_service.get_orders() return [ OrderResponse( order_id=o["order_id"], symbol=o["symbol"], exchange=o["exchange"], direction=o["direction"], order_type=o["order_type"], volume=o["volume"], price=o.get("price"), traded=o["traded"], status=o["status"], time=o["time"] ) for o in orders_data ] @router.get("/orders/active", response_model=List[OrderResponse]) async def get_active_orders( current_user: dict = Depends(get_current_user), vn_service=Depends(get_vn_service) ): """ 获取活动委托 返回所有未完成的活动订单 """ orders_data = await vn_service.get_active_orders() return [ OrderResponse( order_id=o["order_id"], symbol=o["symbol"], exchange=o["exchange"], direction=o["direction"], order_type=o["order_type"], volume=o["volume"], price=o.get("price"), traded=o["traded"], status=o["status"], time=o["time"] ) for o in orders_data ] @router.post("/orders", response_model=dict) async def send_order( request: SendOrderRequest, current_user: dict = Depends(get_current_user), vn_service=Depends(get_vn_service) ): """ 发送订单 - **symbol**: 品种代码 - **exchange**: 交易所 - **direction**: 方向 (buy/sell) - **order_type**: 类型 (limit/market/stop) - **volume**: 数量 - **price**: 价格(限价单必填) - **reference**: 客户引用(可选) """ order_id = await vn_service.send_order( symbol=request.symbol, exchange=request.exchange, direction=request.direction.value, order_type=request.order_type.value, volume=request.volume, price=request.price, reference=request.reference ) if order_id: return { "success": True, "order_id": order_id, "message": "Order sent successfully" } else: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Failed to send order" ) @router.delete("/orders/{vt_orderid}") async def cancel_order( vt_orderid: str, current_user: dict = Depends(get_current_user), vn_service=Depends(get_vn_service) ): """ 撤销订单 - **vt_orderid**: 订单号(格式:gateway_name.orderid) """ success = await vn_service.cancel_order(vt_orderid) if success: return ApiResponse( success=True, message=f"Order {vt_orderid} cancelled successfully" ) else: raise HTTPException( status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"Failed to cancel order {vt_orderid}" ) # ============================================ # 成交记录 # ============================================ @router.get("/trades") async def get_trades( current_user: dict = Depends(get_current_user), vn_service=Depends(get_vn_service) ): """ 获取成交列表 返回所有成交记录 """ trades = await vn_service.get_trades() return { "trades": trades, "total": len(trades) } # ============================================ # 综合查询 # ============================================ @router.get("/account", response_model=AccountResponse) async def get_account( current_user: dict = Depends(get_current_user), vn_service=Depends(get_vn_service) ): """ 获取账户信息(包括持仓和委托) 返回账户资金、持仓和委托的综合信息 """ accounts = await vn_service.get_accounts() positions_data = await vn_service.get_positions() orders_data = await vn_service.get_orders() # 取第一个账户 account_data = accounts[0] if accounts else None if not account_data: raise HTTPException( status_code=status.HTTP_404_NOT_FOUND, detail="No account found" ) account = AccountData( account_id=account_data["account_id"], balance=account_data["balance"], available=account_data["available"], frozen=account_data.get("frozen", 0.0), ) positions = [ PositionData( symbol=p["symbol"], exchange=p["exchange"], direction=p["direction"], volume=p["volume"], price=p["price"], pnl=p["pnl"], pnl_ratio=p.get("pnl_ratio", 0.0), frozen=p.get("frozen", 0.0), ) for p in positions_data ] orders = [ OrderResponse( order_id=o["order_id"], symbol=o["symbol"], exchange=o["exchange"], direction=o["direction"], order_type=o["order_type"], volume=o["volume"], price=o.get("price"), traded=o["traded"], status=o["status"], time=o["time"] ) for o in orders_data ] return AccountResponse( account=account, positions=positions, orders=orders )