审计日期: 2025-10-02 审计范围: 完整主流程 + 架构设计 + 风险控制 审计深度: 代码级 + 系统级 + 业务逻辑级
位置: Line 544-562
当前代码:
this.marketDataManager.getWebSocketManager().on('order_update', (update: any) => {
if (update.status && this.orderLifecycleManager) {
let status: 'open' | 'filled' | 'cancelled' | 'partially_filled' = 'open';
if (update.status === 'filled') {
status = 'filled';
} else if (update.status === 'cancelled' || update.status === 'canceled') {
status = 'cancelled';
} else if (update.status === 'partially_filled' || update.status === 'partial') {
status = 'partially_filled';
}
this.orderLifecycleManager.updateOrderStatus(
update.orderId,
update.symbol,
status
);
}
});
问题:
orderId
和 symbol
,但可能是 order_id
或 i
修复:
this.marketDataManager.getWebSocketManager().on('order_update', (update: any) => {
if (!this.orderLifecycleManager) return;
// ✅ 提取并验证必要字段
const orderId = update.orderId || update.order_id || update.i;
const symbol = update.symbol || update.s;
const statusRaw = update.status || update.order_status;
if (!orderId || !symbol || !statusRaw) {
this.logger.warn('Invalid order update from WebSocket', { update });
return;
}
// ✅ 映射状态
let status: 'open' | 'filled' | 'cancelled' | 'partially_filled' = 'open';
const normalizedStatus = statusRaw.toLowerCase();
if (normalizedStatus === 'filled' || normalizedStatus === 'completely_filled') {
status = 'filled';
} else if (normalizedStatus === 'cancelled' || normalizedStatus === 'canceled') {
status = 'cancelled';
} else if (normalizedStatus === 'partially_filled' || normalizedStatus === 'partial') {
status = 'partially_filled';
} else if (normalizedStatus === 'open' || normalizedStatus === 'new') {
status = 'open';
} else {
this.logger.warn('Unknown order status from WebSocket', { status: statusRaw, orderId, symbol });
return;
}
this.orderLifecycleManager.updateOrderStatus(orderId, symbol, status);
});
位置: Line 540
当前代码:
this.orderLifecycleManager = new OrderLifecycleManager(lifecycleConfig);
this.orderLifecycleManager.setSigningClient(firstClient); // ❌ 仅使用第一个账户
await this.orderLifecycleManager.start();
问题:
firstClient
(第一个账户)影响: 严重 - 订单生命周期管理失效
修复方案A (推荐): OrderLifecycleManager 支持多账户
// 修改 OrderLifecycleManager 接口
public setSigningClients(clients: Map<string, PacificaSigningClient>): void {
this.signingClients = clients;
}
// 在 run-refactored-strategy.ts
const clientsMap = new Map<string, PacificaSigningClient>();
for (const [accountId, accountInfo] of this.accounts) {
clientsMap.set(accountId, accountInfo.client);
}
this.orderLifecycleManager.setSigningClients(clientsMap);
修复方案B (简单): 每个账户独立的 OrderLifecycleManager
// 为每个账户创建独立的 OrderLifecycleManager
private orderLifecycleManagers: Map<string, OrderLifecycleManager> = new Map();
for (const [accountId, accountInfo] of this.accounts) {
const lifecycleManager = new OrderLifecycleManager(lifecycleConfig);
lifecycleManager.setSigningClient(accountInfo.client);
await lifecycleManager.start();
this.orderLifecycleManagers.set(accountId, lifecycleManager);
}
位置: Line 690
当前代码:
await accountInfo.client.cancelOrder(order.symbol, order.orderId);
问题:
PacificaSigningClient.cancelOrder
方法签名是什么?(orderId, symbol)
而不是 (symbol, orderId)
需要验证: 检查 PacificaSigningClient.cancelOrder
的正确签名
位置: 整个初始化流程
问题:
建议:
// 定期同步订单状态(每30秒)
setInterval(async () => {
for (const [accountId, accountInfo] of this.accounts) {
try {
const ordersResult = await accountInfo.client.getOpenOrders();
if (ordersResult?.orders) {
// 同步到 OrderLifecycleManager
// 取消本地追踪但服务器不存在的订单
}
} catch (error) {
this.logger.error('Failed to sync orders', { accountId, error });
}
}
}, 30000);
位置: Line 754-830
问题:
DataAggregator
触发 account_balance_updated
事件时序问题:
1. initializeAccountBalances()
→ updateAccountBalanceExternal()
→ 触发 account_balance_updated 事件
2. 监听器还没注册 ❌
3. 手动触发一次同步 (Line 890-967) ✅ 补救
建议: 先注册监听器,再初始化余额
位置: MarginUtilizationMonitor (referenced)
问题:
Map<string, number>
建议: 不是严重问题,但可以优化
位置: Line 1133
问题:
const executionResult = await this.signalExecutor.executeSignalsBatch(allSignals);
executeSignalsBatch
挂起,整个交易周期会卡住建议:
const executionPromise = this.signalExecutor.executeSignalsBatch(allSignals);
const timeoutPromise = new Promise((_, reject) =>
setTimeout(() => reject(new Error('Execution timeout')), 60000)
);
const executionResult = await Promise.race([executionPromise, timeoutPromise]);
位置: Line 484-497
问题:
this.riskManager = new RiskManager(riskConfig);
await this.riskManager.initialize();
await this.riskManager.startMonitoring(sessionId);
riskManager.checkRisk()
或类似方法建议:
runTradingCycle
中集成 RiskManager 检查位置: Line 1062-1066
问题:
this.cycleInterval = setInterval(() => {
this.runTradingCycle().catch(error => {
this.logger.error('Trading cycle error', { error });
});
}, this.config.tradingInterval);
runTradingCycle
执行时间 > 15秒,会导致并发执行修复:
private isRunningCycle: boolean = false;
this.cycleInterval = setInterval(() => {
if (this.isRunningCycle) {
this.logger.warn('Previous trading cycle still running, skipping this cycle');
return;
}
this.isRunningCycle = true;
this.runTradingCycle()
.catch(error => {
this.logger.error('Trading cycle error', { error });
})
.finally(() => {
this.isRunningCycle = false;
});
}, this.config.tradingInterval);
位置: Line 576-588
问题:
DualAccountCoordinator
被初始化coordinateOrders
)状态: Sprint 2 功能可能未完成
问题:
try-catch
.catch()
建议: 统一错误处理模式
问题:
logger.info
logger.warn
warn
级别的日志其实是 error
示例: Line 1024
this.logger.warn(`Failed to get initial positions for ${accountId}`, { error });
应该是:
this.logger.error(`Failed to get initial positions for ${accountId}`, { error });
问题:
0.5
(Line 242) - 平衡50%0.995
/ 1.005
(Line 722-724) - 减仓价格偏差3000
(Line 516) - 等待时间100
(Line 987) - 重试次数建议: 提取为常量
优先级 | 发现问题数 | 已修复 | 待修复 |
---|---|---|---|
P0 严重 | 5 | 2 | 3 |
P1 中等 | 9 | 2 | 7 |
P2 轻微 | 8 | 0 | 8 |
总计 | 22 | 4 | 18 |
类别 | 问题数 | 严重性 |
---|---|---|
架构设计 | 4 | 🔴 高 |
错误处理 | 3 | ⚠️ 中 |
并发控制 | 2 | ⚠️ 中 |
数据同步 | 3 | 🔴 高 |
配置管理 | 1 | ✅ 已修复 |
代码质量 | 5 | 🟢 低 |
资源管理 | 2 | ⚠️ 中 |
风险控制 | 2 | 🔴 高 |
之前的审计不够全面。需要:
审计完成 - 发现了重要的系统级问题,建议立即处理