import { logger } from '../../utils/logger.js' import { globalPriceManager } from '../price/PriceManager.js' /** * 交易引擎 - 负责信号生成和交易执行 */ export class TradingEngine { constructor(accountManager, riskManager, stopLossService, hedgeManager = null) { this.accountManager = accountManager this.riskManager = riskManager this.stopLossService = stopLossService this.hedgeManager = hedgeManager this.isRunning = false this.tradingIntervals = [] this.stats = { totalTrades: 0, successfulTrades: 0, failedTrades: 0, totalVolume: 0, lastTradeTime: 0, sessionStartTime: Date.now(), } this.riskLimits = { maxPositionSize: 0.01, maxTotalExposure: 0.05, maxAccountBalance: 10000, minAccountBalance: 100, maxDailyTrades: 50, maxSlippage: 0.05, emergencyStopLoss: 0.1, enabled: true, } this.priceCache = {} this.orderbookPriceCache = {} } async initialize() { logger.info('TradingEngine初始化') } async start() { logger.info('TradingEngine启动') this.isRunning = true // 启动时预热orderbook价格缓存 this.preloadOrderbookPrices() this.startTradingLoop() } async stop() { logger.info('TradingEngine停止') this.isRunning = false this.tradingIntervals.forEach(interval => clearInterval(interval)) this.tradingIntervals = [] } getStatus() { return { name: 'TradingEngine', status: this.isRunning ? 'running' : 'stopped', lastUpdate: Date.now(), details: { stats: this.stats, activeIntervals: this.tradingIntervals.length, }, } } /** * 启动交易循环 */ startTradingLoop() { console.log('🔄 启动交易引擎') // 主交易信号生成器 const mainInterval = setInterval(async () => { if (this.isRunning) { await this.generateTradingSignals() } }, 15000) this.tradingIntervals.push(mainInterval) // 高频刷量信号 const volumeInterval = setInterval(async () => { if (this.isRunning) { await this.generateVolumeBoostSignals() } }, 8000) this.tradingIntervals.push(volumeInterval) console.log('✅ 交易引擎已启动') } /** * 生成交易信号 */ async generateTradingSignals() { const signals = [] const randomFactor = Math.random() // 初始化账户状态 this.accountManager.getAllAccountStates() // 检查是否需要资金平衡 const needsBalancing = this.checkAccountBalance() if (needsBalancing) { const balanceSignal = this.generateBalanceSignal() if (balanceSignal) { signals.push(balanceSignal) // 高使用率时,执行降低使用率策略 const accounts = Array.from(this.accountManager.getAllAccountStates().values()) let maxUtilizationRate = 0 let highUtilizationAccount = null accounts.forEach(account => { if (account.lastBalance > 0) { const utilizationRate = Math.abs(account.lastBalance - account.availableBalance) / account.lastBalance if (utilizationRate > maxUtilizationRate) { maxUtilizationRate = utilizationRate highUtilizationAccount = account } } }) // 动态使用率平衡机制 await this.executeUtilizationBalancing(accounts, maxUtilizationRate) if (maxUtilizationRate >= 0.9) { console.log(`🚨 [高使用率警报] 使用率${(maxUtilizationRate * 100).toFixed(1)}% >= 90%,启动紧急降低机制`) // 执行敞口平衡 for (const signal of signals) { await this.handleTradingSignal(signal) } // 主动降低使用率:减少仓位 await this.executeUtilizationReduction(highUtilizationAccount, maxUtilizationRate) return } } } // 根据使用率动态调整刷量策略 const avgUtilizationRate = this.calculateAverageUtilizationRate() let shouldGenerateSignal = false if (avgUtilizationRate < 0.7) { // 使用率过低,积极刷量 shouldGenerateSignal = randomFactor > 0.1 // 90%概率 } else if (avgUtilizationRate <= 0.8) { // 在目标范围内,正常刷量 shouldGenerateSignal = randomFactor > 0.3 // 70%概率 } else if (avgUtilizationRate <= 0.9) { // 超出目标,减少刷量 shouldGenerateSignal = randomFactor > 0.7 // 30%概率 } else { // 使用率过高,基本不刷量 shouldGenerateSignal = randomFactor > 0.9 // 10%概率 } if (shouldGenerateSignal) { const shouldClosePosition = this.shouldCloseExistingPositions(avgUtilizationRate) if (shouldClosePosition) { const closeSignal = await this.generateCloseSignal() if (closeSignal && parseFloat(closeSignal.amount) > 0) { signals.push(closeSignal) } } else { const action = randomFactor > 0.6 ? 'buy' : 'sell' const amount = await this.calculateTradingAmount() // 只有当金额大于0时才添加信号 if (parseFloat(amount) > 0) { signals.push({ symbol: 'BTC-USD', action, amount, confidence: randomFactor, reason: `智能刷量(使用率${(avgUtilizationRate * 100).toFixed(1)}%) - ${ action === 'buy' ? '买入建仓' : '卖出建仓' }`, }) } } } // 对冲信号 if (this.hedgeManager && randomFactor > 0.5) { const hedgeSignal = await this.generateSmartHedgeSignal() if (hedgeSignal && parseFloat(hedgeSignal.amount) > 0) { signals.push(hedgeSignal) } } // 发送信号 for (const signal of signals) { await this.handleTradingSignal(signal) } } /** * 生成刷量信号 */ async generateVolumeBoostSignals() { if (!this.shouldTrade()) { return } const signals = [] if (this.hedgeManager && Math.random() > 0.4) { const primaryAccountId = 'pacifica-1' const boostAmount = await this.calculateSmartTradeAmount(primaryAccountId, 'open') signals.push({ symbol: 'BTC-USD', action: 'volume_boost', amount: boostAmount, confidence: 0.9, reason: `智能刷量 - 金额: ${boostAmount} BTC`, }) } signals.forEach(signal => { this.handleTradingSignal(signal) }) } /** * 处理交易信号 */ async handleTradingSignal(signal) { logger.info('收到交易信号', { signal }) // 对于减仓信号,跳过常规交易检查(允许在高使用率时执行) const isReduceOnlySignal = signal.reduceOnly || (signal.reason && (signal.reason.includes('使用率控制') || signal.reason.includes('降低使用率') || signal.reason.includes('双向减仓'))) if (isReduceOnlySignal) { console.log(`🔄 [强制执行] 减仓信号,跳过常规交易检查: ${signal.reason || 'reduceOnly'}`) } else if (!this.shouldTrade()) { logger.info('当前不适合交易,忽略信号') return } try { if (signal.action === 'hedge' && this.hedgeManager) { await this.executeHedgeSignal(signal) } else if (signal.action === 'volume_boost' && this.hedgeManager) { await this.executeVolumeBoost(signal) } else if (signal.action === 'balance_accounts') { await this.executeBalanceSignal(signal) } else if (signal.action === 'balance') { // 使用率控制平仓 await this.executeUtilizationControlSignal(signal) } else if (signal.action === 'close_position') { await this.executeCloseSignal(signal) } else { await this.executeTradeSignal(signal) } } catch (error) { logger.error('交易信号处理失败', { signal, error: error.message }) this.stats.failedTrades++ } } /** * 执行使用率控制信号(强制平仓) */ async executeUtilizationControlSignal(signal) { const clientId = signal.targetAccount || 'pacifica-1' const client = this.accountManager.getClient(clientId) if (!client) { throw new Error(`客户端 ${clientId} 不可用`) } console.log(`🔄 [使用率控制] 执行强制平仓: ${signal.amount} BTC, side=${signal.side}`) // 确保 side 映射正确 const side = signal.side === 'buy' ? 'bid' : 'ask' // 获取账户信息以获取正确的账户地址 const accountIndex = parseInt(clientId.split('-')[1]) - 1 const accounts = this.accountManager.getAccounts() const account = accounts[accountIndex] if (!account) { throw new Error(`找不到账户 ${clientId} 的配置信息`) } const result = await client.marketOrder({ account: account.account, symbol: 'BTCUSDT', amount: signal.amount, side: side, reduceOnly: true, slippagePercent: '5.0', }) if (result.success) { this.stats.successfulTrades++ this.stats.totalVolume += parseFloat(signal.amount) console.log(`✅ [使用率控制] 强制平仓成功: ${result.data?.order_id}`) this.accountManager.updateTradeState(clientId, { side: signal.side, amount: signal.amount, success: true, }) } else { this.stats.failedTrades++ throw new Error(`使用率控制平仓失败: ${result.error}`) } this.stats.totalTrades++ this.stats.lastTradeTime = Date.now() } /** * 执行交易信号 */ async executeTradeSignal(signal) { const clientId = signal.targetAccount || 'pacifica-1' const client = this.accountManager.getClient(clientId) if (!client) { throw new Error(`客户端 ${clientId} 不可用`) } const side = signal.action === 'buy' ? 'bid' : 'ask' const accountStates = this.accountManager.getAllAccountStates() const firstAccountId = Array.from(accountStates.keys())[0] // 获取当前价格用于止盈止损 const currentPrice = await this.getCurrentPrice(signal.symbol) // 执行订单 const result = await client.createMarketOrder({ account: firstAccountId, symbol: 'BTCUSDT', amount: signal.amount, side: side, reduceOnly: signal.reduceOnly || signal.action === 'sell', slippagePercent: '5.0', }) if (result.success) { this.stats.successfulTrades++ this.stats.totalVolume += parseFloat(signal.amount) this.stats.lastTradeTime = Date.now() logger.info('交易订单执行成功', { orderId: result.data?.order_id }) console.log(`✅ ${signal.action.toUpperCase()} 订单成功: ${result.data?.order_id}`) // 更新账户状态 this.accountManager.updateTradeState(clientId, { side, amount: signal.amount, success: true }) // 设置止盈止损 if (!signal.reduceOnly && result.data?.order_id) { await this.stopLossService.setupStopLossAndTakeProfit({ parentOrderId: result.data.order_id, symbol: signal.symbol, amount: signal.amount, side: signal.action, currentPrice, clientId, stopLoss: signal.stopLoss, takeProfit: signal.takeProfit, enableTrailing: signal.enableTrailing, }) } } else { this.stats.failedTrades++ throw new Error(`订单失败: ${result.error}`) } this.stats.totalTrades++ } /** * 执行对冲信号 */ async executeHedgeSignal(signal) { if (!this.hedgeManager) return const amount = parseFloat(signal.amount) if (!amount || amount <= 0 || !isFinite(amount)) { console.log(`❌ [订单跳过] 无效金额: ${signal.amount} → ${amount}`) return } const batchOrders = [ { accountId: 'pacifica-1', symbol: 'BTC-USD', amount: amount, side: 'bid', orderType: 'market', }, { accountId: 'pacifica-2', symbol: 'BTC-USD', amount: amount, side: 'ask', orderType: 'market', }, ] const results = await this.hedgeManager.executeBatchHedge(batchOrders) this.processHedgeResults(results, batchOrders) } /** * 执行刷量信号 */ async executeVolumeBoost(signal) { if (!this.hedgeManager) return const boostSequence = [ { accountId: 'pacifica-1', symbol: 'BTC-USD', amount: parseFloat(signal.amount), side: 'bid', orderType: 'market', reason: '刷量开仓-多头', }, { accountId: 'pacifica-2', symbol: 'BTC-USD', amount: parseFloat(signal.amount), side: 'ask', orderType: 'market', reason: '刷量开仓-空头', }, ] const results = await this.hedgeManager.executeBatchHedge(boostSequence) this.processVolumeBoostResults(results, boostSequence, signal.amount) } /** * 执行平衡信号 */ async executeBalanceSignal(signal) { if (!this.hedgeManager || !signal.targetAccount) return const balanceOrders = this.generateBalanceOrders(signal) const results = await this.hedgeManager.executeBatchHedge(balanceOrders) let successCount = 0 results.forEach((result, index) => { if (result.success) { successCount++ } }) this.stats.totalTrades += results.length this.stats.successfulTrades += successCount this.stats.failedTrades += results.length - successCount const successRate = results.length > 0 ? ((successCount / results.length) * 100).toFixed(1) : '0.0' console.log(`⚖️ [平衡完成] 成功率: ${successRate}% (${successCount}/${results.length})`) } /** * 执行平仓信号 */ async executeCloseSignal(signal) { const clientId = signal.targetAccount || 'pacifica-1' const client = this.accountManager.getClient(clientId) if (!client) { throw new Error(`客户端 ${clientId} 不可用`) } const side = signal.action === 'buy' ? 'bid' : 'ask' const accountStates = this.accountManager.getAllAccountStates() const firstAccountId = Array.from(accountStates.keys())[0] const result = await client.createMarketOrder({ account: firstAccountId, symbol: 'BTCUSDT', amount: signal.amount, side: side, reduceOnly: true, slippagePercent: '5.0', }) if (result.success) { this.stats.successfulTrades++ this.stats.totalVolume += parseFloat(signal.amount) console.log(`✅ 平仓成功: ${result.data?.order_id}`) this.accountManager.updateTradeState(clientId, { side, amount: signal.amount, success: true }) } else { this.stats.failedTrades++ throw new Error(`平仓失败: ${result.error}`) } this.stats.totalTrades++ this.stats.lastTradeTime = Date.now() } // Helper methods checkAccountBalance() { const accounts = Array.from(this.accountManager.getAllAccountStates().values()) if (accounts.length < 2) return false const totalNetExposure = accounts.reduce((sum, account) => sum + account.netPosition, 0) const exposureThreshold = this.riskManager.calculateDynamicExposureThreshold() return Math.abs(totalNetExposure) > exposureThreshold } generateBalanceSignal() { const accountsArray = Array.from(this.accountManager.getAllAccountStates().entries()) if (accountsArray.length < 2) return null const totalNetExposure = accountsArray.reduce((sum, [_, state]) => sum + state.netPosition, 0) const dynamicThreshold = this.riskManager.calculateDynamicExposureThreshold() if (Math.abs(totalNetExposure) > dynamicThreshold) { const sortedAccounts = accountsArray.sort((a, b) => Math.abs(b[1].netPosition) - Math.abs(a[1].netPosition)) const [targetAccountId] = sortedAccounts[0] const adjustmentAmount = Math.min(Math.abs(totalNetExposure) * 0.5, 0.001) const action = totalNetExposure > 0 ? 'sell' : 'buy' return { symbol: 'BTC-USD', action: 'balance_accounts', side: action, amount: adjustmentAmount.toFixed(4), confidence: 0.95, reason: `敞口平衡 - 总净敞口${totalNetExposure.toFixed(4)} BTC`, targetAccount: targetAccountId, reduceOnly: false, } } return null } /** * 计算平均使用率 */ calculateAverageUtilizationRate() { const accounts = Array.from(this.accountManager.getAllAccountStates().values()) if (accounts.length === 0) return 0 let totalUtilization = 0 let validAccounts = 0 accounts.forEach(account => { if (account.lastBalance > 0) { const utilizationRate = Math.abs(account.lastBalance - account.availableBalance) / account.lastBalance totalUtilization += utilizationRate validAccounts++ } }) return validAccounts > 0 ? totalUtilization / validAccounts : 0 } shouldCloseExistingPositions(avgUtilizationRate) { const utilizationRate = avgUtilizationRate || this.calculateAverageUtilizationRate() // 根据使用率调整平仓概率 if (utilizationRate >= 0.85) { return Math.random() < 0.6 // 高使用率时,60%概率平仓 } else if (utilizationRate >= 0.75) { return Math.random() < 0.4 // 中高使用率时,40%概率平仓 } else if (utilizationRate >= 0.65) { return Math.random() < 0.2 // 正常使用率时,20%概率平仓 } else { return Math.random() < 0.1 // 低使用率时,10%概率平仓 } } async generateCloseSignal() { const accountsArray = Array.from(this.accountManager.getAllAccountStates().entries()) const accountWithMaxPosition = accountsArray.reduce((max, current) => { return Math.abs(current[1].netPosition) > Math.abs(max[1].netPosition) ? current : max }) const [accountId, accountState] = accountWithMaxPosition if (Math.abs(accountState.netPosition) > 0.0001) { const smartCloseAmount = await this.calculateSmartTradeAmount(accountId, 'close') const action = accountState.netPosition > 0 ? 'sell' : 'buy' return { symbol: 'BTC-USD', action: action, amount: smartCloseAmount, confidence: 0.9, reason: `智能平仓 - 减少${accountState.netPosition > 0 ? '多头' : '空头'}仓位`, reduceOnly: true, targetAccount: accountId, } } return null } async generateSmartHedgeSignal() { if (!this.hedgeManager) return null const hedgeAmount = await this.calculateHedgeAmount() return { symbol: 'BTC-USD', action: 'hedge', amount: hedgeAmount, confidence: 0.85, reason: '常规对冲刷量', } } async calculateTradingAmount() { return await this.calculateSmartTradeAmount('pacifica-1', 'open') } async calculateSmartTradeAmount(accountId, action) { const state = this.accountManager.getAccountState(accountId) // 获取实时余额(与calculateHedgeAmount保持一致) const freshBalance = await this.accountManager.getAccountBalance(accountId) // Pacifica最小订单要求: 10 USDT const minOrderAmountUsd = 10 const currentBtcPrice = this.getCurrentPriceSync('BTC-USD') // 获取实时BTC价格 // 边界检查:确保价格有效 if (!currentBtcPrice || currentBtcPrice <= 0 || !isFinite(currentBtcPrice)) { console.log(`⚠️ [价格异常] BTC价格无效: ${currentBtcPrice}, 跳过此次交易`) return '0' // 返回0表示跳过交易 } const minOrderAmountBtc = minOrderAmountUsd / currentBtcPrice // 边界检查:确保最小订单金额有效 if (!isFinite(minOrderAmountBtc) || minOrderAmountBtc <= 0 || minOrderAmountBtc > 1) { console.log(`⚠️ [金额异常] 计算的最小BTC金额异常: ${minOrderAmountBtc}, 跳过此次交易`) return '0' // 返回0表示跳过交易 } const minAmountStr = minOrderAmountBtc.toFixed(6) // 使用实时余额进行判断 const availableBalance = freshBalance || 0 const utilizationRate = state?.lastBalance && state.lastBalance > 0 ? Math.abs(state.lastBalance - availableBalance) / state.lastBalance : 0 // 如果账户余额不足以支持最小订单,跳过交易 if (availableBalance < minOrderAmountUsd) { console.log( `⚠️ [交易跳过] 账户${accountId}可用余额$${availableBalance.toFixed(2)} < 最小订单要求$${minOrderAmountUsd}`, ) return '0' } if (!state) { return minAmountStr } if (action === 'open') { // 根据使用率智能调整开仓大小 let targetAmount if (utilizationRate >= 0.8) { // 使用率已在目标上限,使用最小金额 targetAmount = minOrderAmountBtc } else if (utilizationRate >= 0.7) { // 在目标范围内,保持适中 targetAmount = Math.max((availableBalance * 0.05) / currentBtcPrice, minOrderAmountBtc) targetAmount = Math.min(targetAmount, 0.0003) } else if (utilizationRate >= 0.5) { // 低于目标,适度增加 targetAmount = Math.max((availableBalance * 0.08) / currentBtcPrice, minOrderAmountBtc) targetAmount = Math.min(targetAmount, 0.0005) } else { // 使用率过低,积极开仓 targetAmount = Math.max((availableBalance * 0.1) / currentBtcPrice, minOrderAmountBtc) targetAmount = Math.min(targetAmount, 0.001) } // 最终边界检查 let finalAmount = Math.max(targetAmount, minOrderAmountBtc) // Pacifica lot size精度调整: 必须是0.00001的倍数 const lotSize = 0.00001 finalAmount = Math.round(finalAmount / lotSize) * lotSize // 确保调整后仍满足最小要求 if (finalAmount < minOrderAmountBtc) { finalAmount = Math.ceil(minOrderAmountBtc / lotSize) * lotSize } const result = finalAmount.toFixed(5) // 5位小数精度匹配lot size console.log( `📊 [开仓金额] ${accountId}: $${availableBalance.toFixed(2)} 可用 → ${result} BTC (${( finalAmount * currentBtcPrice ).toFixed(2)} USDT) [lot调整]`, ) return result } else { // 平仓策略:根据使用率和仓位大小决定 const positionSize = Math.abs(state.netPosition) if (positionSize === 0) return minAmountStr let closeRatio = 0.3 // 默认平仓30% if (utilizationRate >= 0.85) { closeRatio = 0.5 // 高使用率时加大平仓比例 } else if (utilizationRate <= 0.65) { closeRatio = 0.2 // 低使用率时减少平仓比例 } const closeAmount = Math.min(positionSize * closeRatio, 0.002) let finalAmount = Math.max(closeAmount, minOrderAmountBtc) // Pacifica lot size精度调整: 必须是0.00001的倍数 const lotSize = 0.00001 finalAmount = Math.round(finalAmount / lotSize) * lotSize // 确保调整后仍满足最小要求 if (finalAmount < minOrderAmountBtc) { finalAmount = Math.ceil(minOrderAmountBtc / lotSize) * lotSize } const result = finalAmount.toFixed(5) // 5位小数精度匹配lot size console.log( `📊 [平仓金额] ${accountId}: ${positionSize.toFixed(4)} BTC 仓位 → ${result} BTC (${( finalAmount * currentBtcPrice ).toFixed(2)} USDT) [lot调整]`, ) return result } } async calculateHedgeAmount() { try { const account1Balance = await this.accountManager.getAccountBalance('pacifica-1') const account2Balance = await this.accountManager.getAccountBalance('pacifica-2') const minBalance = Math.min(account1Balance || 0, account2Balance || 0) // Pacifica最小订单要求: 10 USDT const minOrderAmountUsd = 10 const currentBTCPrice = this.getCurrentPriceSync('BTC-USD') // 边界检查:确保价格有效 if (!currentBTCPrice || currentBTCPrice <= 0 || !isFinite(currentBTCPrice)) { console.log(`⚠️ [对冲价格异常] BTC价格无效: ${currentBTCPrice}, 跳过对冲交易`) return '0' // 返回0表示跳过交易 } const minOrderAmountBtc = minOrderAmountUsd / currentBTCPrice // 边界检查:确保最小订单金额有效 if (!isFinite(minOrderAmountBtc) || minOrderAmountBtc <= 0 || minOrderAmountBtc > 1) { console.log(`⚠️ [对冲金额异常] 计算的最小BTC金额异常: ${minOrderAmountBtc}, 跳过对冲交易`) return '0' } if (minBalance < minOrderAmountUsd) { console.log(`⚠️ [对冲跳过] 最小账户余额$${minBalance.toFixed(2)} < 最小订单要求$${minOrderAmountUsd}`) return '0' } const baseAmount = (minBalance * 0.01) / currentBTCPrice const amount = baseAmount * (0.8 + Math.random() * 0.4) // 确保不低于最小订单金额 let finalAmount = Math.max(minOrderAmountBtc, Math.min(0.001, amount)) // Pacifica lot size精度调整: 必须是0.00001的倍数 const lotSize = 0.00001 finalAmount = Math.round(finalAmount / lotSize) * lotSize // 确保调整后仍满足最小要求 if (finalAmount < minOrderAmountBtc) { finalAmount = Math.ceil(minOrderAmountBtc / lotSize) * lotSize } const result = finalAmount.toFixed(5) // 5位小数精度匹配lot size console.log( `📊 [对冲金额] 最小余额: $${minBalance.toFixed(2)} → ${result} BTC (${(finalAmount * currentBTCPrice).toFixed( 2, )} USDT) [lot调整]`, ) return result } catch (error) { logger.error('计算对冲数量时出错', { error: error.message }) // 安全的错误处理 console.log(`⚠️ [对冲计算错误] 跳过此次对冲交易`) return '0' // 错误时跳过交易 } } shouldTrade() { if (this.stats.totalTrades >= this.riskLimits.maxDailyTrades) { return false } const timeSinceLastTrade = Date.now() - this.stats.lastTradeTime if (timeSinceLastTrade < 5000) { return false } // 检查使用率是否过高 if (this.shouldSkipTradeForUtilization()) { return false } return true } async getCurrentPrice(symbol) { return this.getCurrentPriceSync(symbol) } getCurrentPriceSync(symbol) { try { // 直接从全局价格管理器获取实时价格 const price = globalPriceManager.getPrice(symbol) if (price > 0) { logger.debug(`📊 [实时价格] ${symbol}: $${price.toFixed(2)}`) return price } // 如果没有价格数据,使用fallback价格确保利用率控制能正常工作 const fallbackPrice = this.getFallbackPrice(symbol) if (fallbackPrice > 0) { logger.warn(`⚠️ [价格回退] ${symbol}使用回退价格: $${fallbackPrice.toFixed(2)}`, { priceManagerStatus: globalPriceManager.getStatus(), availableSymbols: Array.from(globalPriceManager.getAllPrices().keys()).slice(0, 5), }) return fallbackPrice } return 0 } catch (error) { logger.error('获取价格失败', { symbol, error: error.message }) return this.getFallbackPrice(symbol) } } /** * 获取回退价格,确保使用率控制机制能正常工作 */ getFallbackPrice(symbol) { const symbolUpper = symbol.toUpperCase() // 基于当前市场的合理回退价格 if (symbolUpper.includes('BTC')) { return 95000 // BTC 回退价格 } if (symbolUpper.includes('ETH')) { return 3800 // ETH 回退价格 } if (symbolUpper.includes('SOL')) { return 220 // SOL 回退价格 } if (symbolUpper.includes('USD') || symbolUpper.includes('USDT') || symbolUpper.includes('USDC')) { return 1 // 稳定币回退价格 } // 默认回退价格(对于未知交易对) return 100 } fetchRealTimePriceSync(symbol) { try { // 尝试从最近的orderbook数据获取价格 const midPrice = this.getLastKnownPrice(symbol) if (midPrice > 0) { return midPrice } // 尝试从外部API获取实时价格 const externalPrice = this.getExternalPrice(symbol) if (externalPrice > 0) { console.log(`📊 [外部价格] ${symbol}: $${externalPrice}`) return externalPrice } // 最后的Fallback: 从现有的orderbook缓存中获取历史价格 const historicalPrice = this.getHistoricalPrice(symbol) if (historicalPrice > 0) { console.log(`📊 [历史价格] ${symbol}: $${historicalPrice}`) return historicalPrice } // 如果都失败,使用fallback if (symbol.includes('BTC')) { console.log(`🔄 [最终fallback] ${symbol}: $65000 (所有尝试失败)`) return 65000 } throw new Error(`无法获取${symbol}的有效价格`) } catch (error) { logger.warn('获取实时价格失败', { symbol, error }) // 提供最终的fallback而不是抛出错误 if (symbol.includes('BTC')) { console.log(`🔄 [catch fallback] ${symbol}: $65000 (异常处理)`) return 65000 } throw error } } /** * 从外部API获取实时价格(使用Pacifica prices API) */ getExternalPrice(symbol) { try { const client = this.accountManager.getFirstAvailableClient() if (client && client.getPrices) { // 首先检查是否已有orderbook缓存数据 const cached = this.orderbookPriceCache[symbol] if (cached && Date.now() - cached.timestamp < 180 * 1000) { // 3分钟有效期 const midPrice = (cached.bid + cached.ask) / 2 console.log( `📊 [缓存价格] ${symbol}: $${midPrice.toFixed(2)} (bid=${cached.bid.toFixed(2)}, ask=${cached.ask.toFixed( 2, )})`, ) return midPrice } // 异步获取价格数据 this.updatePricesAsync(symbol) // 同时触发orderbook更新 this.updateOrderbookPriceAsync(symbol) } return 0 // 异步获取,这次返回0 } catch (error) { return 0 } } /** * 异步更新价格数据 */ async updatePricesAsync(symbol) { try { const client = this.accountManager.getFirstAvailableClient() if (!client || !client.getPrices) { return } const pricesData = await client.getPrices() if (pricesData && pricesData.data) { // 查找对应symbol的价格 const symbolPrice = pricesData.data.find( item => item.symbol === symbol || item.symbol === symbol.replace('-', '') || item.symbol === symbol.replace('USD', 'USDT'), ) if (symbolPrice && symbolPrice.price) { const price = parseFloat(symbolPrice.price) if (!isNaN(price) && price > 0) { // 更新价格缓存 const cacheKey = `price_${symbol}` this.priceCache[cacheKey] = { price: price, timestamp: Date.now(), } console.log(`📊 [价格API] ${symbol}: $${price.toFixed(2)}`) } } } } catch (error) { logger.debug('更新价格API数据失败', { symbol, error: error.message }) } } /** * 从历史orderbook缓存获取价格 */ getHistoricalPrice(symbol) { try { // 检查所有缓存的orderbook数据,即使过期的也可以作为最后的参考 const cacheKey = symbol const cached = this.orderbookPriceCache[cacheKey] if (cached && cached.bid > 0 && cached.ask > 0) { const midPrice = (cached.bid + cached.ask) / 2 const ageMinutes = (Date.now() - cached.timestamp) / 1000 / 60 console.log(`📊 [历史缓存] ${symbol}: $${midPrice.toFixed(2)} (${ageMinutes.toFixed(1)}分钟前)`) return midPrice } return 0 } catch (error) { return 0 } } getLastKnownPrice(symbol) { try { // 检查是否有缓存的orderbook价格 const cacheKey = symbol const cached = this.orderbookPriceCache[cacheKey] if (cached && Date.now() - cached.timestamp < 120 * 1000) { // 延长到2分钟有效期 const midPrice = (cached.bid + cached.ask) / 2 return midPrice } // 如果没有缓存,触发异步获取 this.updateOrderbookPriceAsync(symbol) // 返回BTC的保守估算价格,避免订单金额为0 if (symbol.includes('BTC')) { console.log(`🔄 [估算价格] ${symbol}: $65000 (缓存过期)`) return 65000 } return 0 } catch (error) { // 错误时也返回估算价格 if (symbol.includes('BTC')) { console.log(`⚠️ [错误价格] ${symbol}: $65000 (获取失败)`) return 65000 } return 0 } } async updateOrderbookPriceAsync(symbol) { console.log(`🔄 [价格获取] 开始获取 ${symbol} orderbook数据`) try { const client = this.accountManager.getFirstAvailableClient() console.log(`🔄 [价格获取] 获取到客户端:`, !!client, '有getOrderBook方法:', !!client?.getOrderBook) if (!client || !client.getOrderBook) { console.log( `⚠️ [价格获取] 客户端或getOrderBook方法不可用 - client: ${!!client}, getOrderBook: ${!!client?.getOrderBook}`, ) return } // 调用正确的方法名 const response = await client.getOrderBook(symbol, 5) if (!response) { console.log(`⚠️ [价格获取] orderbook响应为空`) return } // 原始orderbook数据已获取 // 解析Pacifica API的orderbook格式 const orderbook = this.parseOrderbookData(response) if ( !orderbook || !orderbook.bids || !orderbook.asks || orderbook.bids.length === 0 || orderbook.asks.length === 0 ) { console.log(`⚠️ [价格获取] orderbook数据解析后无效:`, orderbook) return } const bestBid = parseFloat(orderbook.bids[0].price) const bestAsk = parseFloat(orderbook.asks[0].price) if (!isNaN(bestBid) && !isNaN(bestAsk) && bestBid > 0 && bestAsk > 0) { this.orderbookPriceCache[symbol] = { bid: bestBid, ask: bestAsk, timestamp: Date.now(), } const midPrice = (bestBid + bestAsk) / 2 console.log(`📊 [价格] ${symbol}: $${midPrice.toFixed(2)}`) } } catch (error) { logger.debug('更新orderbook价格失败', { symbol, error: error.message }) } } /** * 预热orderbook价格缓存 */ async preloadOrderbookPrices() { const symbols = ['BTC-USD', 'BTCUSDT'] for (const symbol of symbols) { try { await this.updateOrderbookPriceAsync(symbol) // 避免请求过快 await new Promise(resolve => setTimeout(resolve, 200)) } catch (error) { logger.debug('预热价格缓存失败', { symbol }) } } console.log('📊 [价格缓存] orderbook价格缓存已预热') } /** * 解析Pacifica API的orderbook数据格式 */ parseOrderbookData(response) { try { const payload = response?.data ?? response // 格式1: payload.l = [bids[], asks[]] - 每个元素是 {p: price, a: amount, n: numOrders} if (Array.isArray(payload?.l) && payload.l.length >= 2) { const rawBids = Array.isArray(payload.l[0]) ? payload.l[0] : [] const rawAsks = Array.isArray(payload.l[1]) ? payload.l[1] : [] const bids = rawBids .map(lvl => ({ price: String(lvl?.p ?? lvl?.price ?? ''), qty: String(lvl?.a ?? lvl?.amount ?? ''), })) .filter(x => x.price && x.qty && parseFloat(x.price) > 0) const asks = rawAsks .map(lvl => ({ price: String(lvl?.p ?? lvl?.price ?? ''), qty: String(lvl?.a ?? lvl?.amount ?? ''), })) .filter(x => x.price && x.qty && parseFloat(x.price) > 0) if (bids.length > 0 && asks.length > 0) { return { bids, asks } } } // 格式2: Fallback - bids/asks 作为 [price, qty] 数组 if (payload?.bids || payload?.asks) { const bids = (payload?.bids ?? []) .map(x => ({ price: String(x[0] ?? ''), qty: String(x[1] ?? '') })) .filter(x => x.price && x.qty && parseFloat(x.price) > 0) const asks = (payload?.asks ?? []) .map(x => ({ price: String(x[0] ?? ''), qty: String(x[1] ?? '') })) .filter(x => x.price && x.qty && parseFloat(x.price) > 0) if (bids.length > 0 && asks.length > 0) { return { bids, asks } } } // 格式3: 直接的bids/asks对象数组格式 if (Array.isArray(payload?.bids) && Array.isArray(payload?.asks)) { const bids = payload.bids .map(x => ({ price: String(x?.price ?? x?.p ?? ''), qty: String(x?.qty ?? x?.q ?? x?.amount ?? x?.a ?? ''), })) .filter(x => x.price && x.qty && parseFloat(x.price) > 0) const asks = payload.asks .map(x => ({ price: String(x?.price ?? x?.p ?? ''), qty: String(x?.qty ?? x?.q ?? x?.amount ?? x?.a ?? ''), })) .filter(x => x.price && x.qty && parseFloat(x.price) > 0) if (bids.length > 0 && asks.length > 0) { return { bids, asks } } } console.log(`⚠️ [价格解析] 无法识别的orderbook格式:`, JSON.stringify(payload, null, 2)) return null } catch (error) { console.log(`❌ [价格解析] orderbook解析出错:`, error.message) return null } } generateBalanceOrders(signal) { if (!signal.targetAccount) return [] const amount = parseFloat(signal.amount) const side = signal.side === 'buy' ? 'bid' : 'ask' return [ { accountId: signal.targetAccount, symbol: 'BTC-USD', amount, side: side, orderType: 'market', reason: `敞口平衡-${signal.side}-${amount}`, }, ] } processHedgeResults(results, orders) { let successCount = 0 results.forEach((result, index) => { if (result.success) { successCount++ this.stats.successfulTrades++ const order = orders[index] this.accountManager.updateTradeState(order.accountId, { side: order.side, amount: order.amount.toString(), success: true, }) } else { this.stats.failedTrades++ } }) this.stats.totalTrades += results.length this.stats.lastTradeTime = Date.now() console.log(`🔄 对冲执行完成: ${successCount}/${results.length} 成功`) } processVolumeBoostResults(results, orders, amount) { let successCount = 0 results.forEach((result, index) => { if (result.success) { successCount++ console.log(`✅ 刷量订单${index + 1}成功: ${result.orderId || result.order_id || 'N/A'}`) this.stats.totalVolume += parseFloat(amount) const order = orders[index] this.accountManager.updateTradeState(order.accountId, { side: order.side, amount: order.amount.toString(), success: true, }) } else { console.log(`❌ 刷量订单${index + 1}失败: ${result.error}`) } }) this.stats.totalTrades += results.length this.stats.successfulTrades += successCount this.stats.failedTrades += results.length - successCount this.stats.lastTradeTime = Date.now() console.log( `⚡ 刷量执行完成: ${successCount}/${results.length} 成功 - 增加交易量: ${( parseFloat(amount) * successCount ).toFixed(4)} BTC`, ) } /** * 动态使用率平衡机制 - 保持70-80%目标使用率 */ async executeUtilizationBalancing(accounts, maxUtilizationRate) { const targetMinUtilization = 0.7 const targetMaxUtilization = 0.8 try { // 检查是否需要动态平衡 if (maxUtilizationRate >= targetMinUtilization && maxUtilizationRate <= targetMaxUtilization) { console.log(`🎯 [动态平衡] 使用率${(maxUtilizationRate * 100).toFixed(1)}%在目标范围(70-80%)内,保持当前状态`) return } if (maxUtilizationRate > targetMaxUtilization && maxUtilizationRate < 0.9) { // 超出目标上限但未达到危险级别:适度减仓 console.log(`📉 [动态平衡] 使用率${(maxUtilizationRate * 100).toFixed(1)}%超出目标上限,执行适度减仓`) await this.executeModerateReduction(accounts, maxUtilizationRate) } else if (maxUtilizationRate < targetMinUtilization) { // 低于目标下限:适度增仓 console.log(`📈 [动态平衡] 使用率${(maxUtilizationRate * 100).toFixed(1)}%低于目标下限,执行适度增仓`) await this.executeModerateIncrease(accounts, maxUtilizationRate) } } catch (error) { logger.error('动态使用率平衡失败', { error: error.message, maxUtilizationRate }) } } /** * 执行双向同步减仓 */ async executeModerateReduction(accounts, utilizationRate) { if (!this.hedgeManager) return console.log(`🔄 [双向减仓] 开始执行双向同步减仓,当前使用率: ${(utilizationRate * 100).toFixed(1)}%`) // 获取两个主要账户状态 const account1State = this.accountManager.getAccountState('pacifica-1') const account2State = this.accountManager.getAccountState('pacifica-2') if (!account1State || !account2State) { console.log('⚠️ [双向减仓] 账户状态不可用,跳过减仓') return } // 检查两个账户是否都有仓位 const pos1 = Math.abs(account1State.netPosition) const pos2 = Math.abs(account2State.netPosition) if (pos1 < 0.0001 && pos2 < 0.0001) { console.log('ℹ️ [双向减仓] 当前无仓位,无需减仓') return } // 计算减仓数量 - 根据使用率动态调整 let reductionRatio = 0.15 // 基础减仓比例15% if (utilizationRate >= 0.95) { reductionRatio = 0.3 // 高使用率时加大减仓比例 } else if (utilizationRate >= 0.9) { reductionRatio = 0.2 } const reduceAmount = Math.min(Math.max(pos1, pos2) * reductionRatio, 0.002) if (reduceAmount < 0.0001) { console.log('⚠️ [双向减仓] 计算的减仓数量过小,跳过') return } console.log(`📊 [双向减仓] 减仓数量: ${reduceAmount.toFixed(4)} BTC (比例: ${(reductionRatio * 100).toFixed(1)}%)`) // 同步双向减仓 const reductionOrders = [] // 账户1减仓 if (pos1 > 0.0001) { const side1 = account1State.netPosition > 0 ? 'ask' : 'bid' // 平多仓用ask,平空仓用bid reductionOrders.push({ accountId: 'pacifica-1', symbol: 'BTC-USD', amount: reduceAmount, side: side1, orderType: 'market', reason: `双向减仓-降低使用率`, }) } // 账户2减仓 if (pos2 > 0.0001) { const side2 = account2State.netPosition > 0 ? 'ask' : 'bid' // 平多仓用ask,平空仓用bid reductionOrders.push({ accountId: 'pacifica-2', symbol: 'BTC-USD', amount: reduceAmount, side: side2, orderType: 'market', reason: `双向减仓-降低使用率`, }) } if (reductionOrders.length > 0) { const results = await this.hedgeManager.executeBatchHedge(reductionOrders) console.log(`📉 [适度减仓] 执行${results.length}笔减仓订单,目标:降低使用率至70-80%`) } } /** * 执行适度增仓 */ async executeModerateIncrease(accounts, utilizationRate) { if (!this.hedgeManager) return // 找到有可用余额的账户进行增仓 const availableAccounts = accounts .filter(account => account.availableBalance > 5) // 至少有5美元可用余额 .sort((a, b) => b.availableBalance - a.availableBalance) .slice(0, 2) // 取前两个最有资金的账户 const increaseOrders = [] for (const account of availableAccounts) { const maxIncrease = Math.min((account.availableBalance * 0.1) / 65000, 0.0008) // 使用10%可用余额,最多0.0008 BTC if (maxIncrease >= 0.0001) { const increaseAction = Math.random() > 0.5 ? 'bid' : 'ask' increaseOrders.push({ accountId: account.id || 'pacifica-1', symbol: 'BTC-USD', amount: maxIncrease, side: increaseAction, orderType: 'market', reason: `适度增仓-提升使用率至目标范围`, }) } } if (increaseOrders.length > 0) { const results = await this.hedgeManager.executeBatchHedge(increaseOrders) console.log(`📈 [适度增仓] 执行${results.length}笔增仓订单,目标:提升使用率至70-80%`) } } /** * 紧急双向减仓 */ async executeEmergencyReduction(accounts, utilizationRate) { if (!this.hedgeManager) return console.log(`🚨 [紧急减仓] 执行大幅双向减仓,使用率: ${(utilizationRate * 100).toFixed(1)}%`) // 获取两个主要账户状态 const account1State = this.accountManager.getAccountState('pacifica-1') const account2State = this.accountManager.getAccountState('pacifica-2') if (!account1State || !account2State) { console.log('⚠️ [紧急减仓] 账户状态不可用,跳过减仓') return } const pos1 = Math.abs(account1State.netPosition) const pos2 = Math.abs(account2State.netPosition) if (pos1 < 0.0001 && pos2 < 0.0001) { console.log('ℹ️ [紧急减仓] 当前无仓位,无需减仓') return } // 紧急减仓:减少50%仓位 const reductionRatio = 0.5 const reduceAmount = Math.min(Math.max(pos1, pos2) * reductionRatio, 0.003) if (reduceAmount < 0.0001) { console.log('⚠️ [紧急减仓] 计算的减仓数量过小,跳过') return } console.log( `🚨 [紧急减仓] 大幅减仓数量: ${reduceAmount.toFixed(4)} BTC (比例: ${(reductionRatio * 100).toFixed(1)}%)`, ) // 同步双向减仓 const emergencyOrders = [] // 账户1减仓 if (pos1 > 0.0001) { const side1 = account1State.netPosition > 0 ? 'ask' : 'bid' emergencyOrders.push({ accountId: 'pacifica-1', symbol: 'BTC-USD', amount: reduceAmount, side: side1, orderType: 'market', reason: `紧急双向减仓-降低高使用率`, }) } // 账户2减仓 if (pos2 > 0.0001) { const side2 = account2State.netPosition > 0 ? 'ask' : 'bid' emergencyOrders.push({ accountId: 'pacifica-2', symbol: 'BTC-USD', amount: reduceAmount, side: side2, orderType: 'market', reason: `紧急双向减仓-降低高使用率`, }) } if (emergencyOrders.length > 0) { try { const results = await this.hedgeManager.executeBatchHedge(emergencyOrders) console.log(`🚨 [紧急减仓] 执行${results.length}笔紧急减仓订单`) } catch (error) { logger.error('紧急减仓执行失败', { error: error.message }) } } } /** * 执行降低使用率策略 */ async executeUtilizationReduction(account, utilizationRate) { if (!account || !this.hedgeManager) return try { console.log(`📉 [紧急降低使用率] 开始处理账户使用率: ${(utilizationRate * 100).toFixed(1)}%`) // 紧急情况下执行大幅双向减仓 const accounts = Array.from(this.accountManager.getAllAccountStates().values()) await this.executeEmergencyReduction(accounts, utilizationRate) // 策略2: 暂时降低交易频率 if (utilizationRate >= 0.95) { console.log(`⏸️ [使用率控制] 极高使用率(${(utilizationRate * 100).toFixed(1)}%),暂停10秒交易`) await new Promise(resolve => setTimeout(resolve, 10000)) } else if (utilizationRate >= 0.9) { console.log(`⏸️ [使用率控制] 高使用率(${(utilizationRate * 100).toFixed(1)}%),暂停5秒交易`) await new Promise(resolve => setTimeout(resolve, 5000)) } // 策略3: 动态调整交易规模 await this.adjustTradingSizeForUtilization(utilizationRate) } catch (error) { logger.error('执行降低使用率策略失败', { error: error.message, utilizationRate }) } } /** * 根据使用率动态调整交易规模和策略 */ async adjustTradingSizeForUtilization(utilizationRate) { // 目标使用率范围:70-80% const targetMinUtilization = 0.7 const targetMaxUtilization = 0.8 if (utilizationRate >= 0.9) { // 过高使用率:强制减仓 this.riskLimits.maxPositionSize = 0.002 console.log(`📊 [使用率控制] 过高使用率${(utilizationRate * 100).toFixed(1)}%,执行强制减仓`) await this.executeUtilizationRebalance('reduce', utilizationRate) } else if (utilizationRate > targetMaxUtilization) { // 超出目标上限:适度减仓 this.riskLimits.maxPositionSize = 0.005 console.log(`📊 [使用率控制] 超出目标上限${(utilizationRate * 100).toFixed(1)}%,执行适度减仓`) await this.executeUtilizationRebalance('reduce', utilizationRate) } else if (utilizationRate >= targetMinUtilization && utilizationRate <= targetMaxUtilization) { // 目标范围内:保持平衡 this.riskLimits.maxPositionSize = 0.007 console.log(`🎯 [动态平衡] 使用率${(utilizationRate * 100).toFixed(1)}%在目标范围(70-80%)内`) } else if (utilizationRate >= 0.5) { // 低于目标:适度增仓 this.riskLimits.maxPositionSize = 0.008 console.log(`📈 [使用率控制] 使用率${(utilizationRate * 100).toFixed(1)}%偏低,执行适度增仓`) await this.executeUtilizationRebalance('increase', utilizationRate) } else { // 使用率过低:积极增仓 this.riskLimits.maxPositionSize = 0.01 console.log(`🚀 [使用率控制] 使用率${(utilizationRate * 100).toFixed(1)}%过低,执行积极增仓`) await this.executeUtilizationRebalance('increase', utilizationRate) } } /** * 执行使用率再平衡操作 */ async executeUtilizationRebalance(action, currentUtilization) { try { const accounts = await this.accountManager.getAllAccountStates() const targetUtilization = 0.75 // 目标使用率75% for (const [accountId, state] of Object.entries(accounts)) { if (state.lastBalance <= 0) continue const utilizationRate = Math.abs(state.lastBalance - state.availableBalance) / state.lastBalance if (action === 'reduce' && utilizationRate > 0.8) { // 减仓:通过平仓部分仓位来降低使用率 const targetReduction = (utilizationRate - targetUtilization) * state.lastBalance const positionToClose = Math.min( targetReduction / (await this.getCurrentPriceSync('BTC-USD')), Math.abs(state.netPosition) * 0.3, ) if (positionToClose > 0.00001) { // 至少0.00001 BTC才值得平仓 console.log( `📉 [减仓操作] ${accountId}: 当前使用率${(utilizationRate * 100).toFixed( 1, )}% → 目标75%, 平仓${positionToClose.toFixed(5)} BTC`, ) const signal = await this.generateTradeSignal({ accountId, symbol: 'BTC-USD', action: 'close', amount: positionToClose.toFixed(5), side: state.netPosition > 0 ? 'ask' : 'bid', reason: `使用率控制平仓 - 当前${(utilizationRate * 100).toFixed(1)}%`, }) if (signal) { await this.executeHedgeSignal(signal) } } } else if (action === 'increase' && utilizationRate < 0.7) { // 增仓:通过开仓来提高使用率 const targetIncrease = (targetUtilization - utilizationRate) * state.lastBalance const positionToOpen = targetIncrease / (await this.getCurrentPriceSync('BTC-USD')) if (positionToOpen > 0.00001 && state.availableBalance > 15) { // 确保有足够余额 console.log( `📈 [增仓操作] ${accountId}: 当前使用率${(utilizationRate * 100).toFixed( 1, )}% → 目标75%, 开仓${positionToOpen.toFixed(5)} BTC`, ) const signal = await this.generateTradeSignal({ accountId, symbol: 'BTC-USD', action: 'open', amount: positionToOpen.toFixed(5), side: Math.random() > 0.5 ? 'bid' : 'ask', reason: `使用率控制开仓 - 当前${(utilizationRate * 100).toFixed(1)}%`, }) if (signal) { await this.executeHedgeSignal(signal) } } } } } catch (error) { logger.error('执行使用率再平衡失败', { action, currentUtilization, error: error.message }) } } /** * 检查是否因使用率过高需要跳过交易 */ shouldSkipTradeForUtilization() { const accounts = Array.from(this.accountManager.getAllAccountStates().values()) let maxUtilizationRate = 0 let highUtilizationAccount = null accounts.forEach(account => { if (account.lastBalance > 0) { const utilizationRate = Math.abs(account.lastBalance - account.availableBalance) / account.lastBalance if (utilizationRate > maxUtilizationRate) { maxUtilizationRate = utilizationRate highUtilizationAccount = account } } }) if (maxUtilizationRate >= 0.95) { console.log(`🚨 [使用率控制] 使用率${(maxUtilizationRate * 100).toFixed(1)}%过高,启动主动降低机制`) // 主动执行降低使用率操作,而不是仅仅跳过交易 this.executeEmergencyUtilizationReduction(highUtilizationAccount, maxUtilizationRate).catch(error => { logger.error('紧急降低使用率失败', { error: error.message }) }) return true // 仍然跳过常规交易,但已触发降低机制 } return false } /** * 紧急降低使用率机制 - 当使用率>=95%时触发 */ async executeEmergencyUtilizationReduction(account, utilizationRate) { console.log(`🚨 [紧急使用率控制] 启动主动降低机制,当前使用率: ${(utilizationRate * 100).toFixed(1)}%`) // 直接调用现有的强力降低使用率方法 await this.executeUtilizationReduction(account, utilizationRate) console.log(`✅ [紧急使用率控制] 主动降低机制执行完成`) } getStats() { return { ...this.stats } } }