#!/usr/bin/env tsx /** * 简洁版Delta中性刷量策略 * 只显示关键信息,日志简洁清晰 */ import { DeltaNeutralVolumeStrategy, DeltaNeutralConfig } from '../src/strategies/DeltaNeutralVolumeStrategy'; import { DeltaNeutralConfigManager } from '../src/strategies/DeltaNeutralConfig'; import { PacificaSigningClient } from '../src/services/PacificaSigningClient'; import { RiskManager, RiskManagerConfig } from '../src/core/RiskManager'; import { MarketDataManager } from '../src/services/MarketDataManager'; import { OrderCleanupService, CleanupOptions } from '../src/services/OrderCleanupService'; import { DynamicPositionManager, PositionAdjustmentConfig } from '../src/services/DynamicPositionManager'; import { Account } from '../src/models/Account'; import { readFileSync, writeFileSync, existsSync } from 'fs'; import { v4 as uuidv4 } from 'uuid'; interface OrderLifecycle { orderId: string; clientOrderId: string; accountId: string; // 记录创建订单的账户ID symbol: string; side: 'bid' | 'ask'; amount: string; price: string; status: 'pending' | 'filled' | 'cancelled' | 'expired'; createdAt: number; lastChecked: number; checkCount: number; maxChecks: number; } interface SimpleStats { totalOrders: number; filledOrders: number; cancelledOrders: number; expiredOrders: number; totalVolume: number; totalPnL: number; startTime: number; lastUpdateTime: number; consecutiveErrors: number; maxConsecutiveErrors: number; apiCallCount: number; lastApiError: number; lastSuccessfulTrade: number; retryCount: number; totalRetries: number; } class SimpleDeltaNeutralStrategy extends DeltaNeutralVolumeStrategy { private orderLifecycle: Map = new Map(); private lastApiCall: number = 0; private apiCallInterval: number = 2000; // 2秒间隔 private orderCheckInterval: NodeJS.Timeout | null = null; private volumeTradingInterval: NodeJS.Timeout | null = null; private deltaMonitoringInterval: NodeJS.Timeout | null = null; private statusDisplayInterval: NodeJS.Timeout | null = null; private statsSaveInterval: NodeJS.Timeout | null = null; private healthCheckInterval: NodeJS.Timeout | null = null; // 账户配对 - Delta中性核心机制 private accountPairs: Array<[Account, Account]> = []; // 多账户客户端映射 - 每个账户一个客户端 private clientMap: Map = new Map(); // 账户列表(保存引用用于动态仓位管理) private strategyAccounts: Account[] = []; // 风险管理器 private riskManager: RiskManager | null = null; private sessionId: string; // 市场数据管理器 - WebSocket实时行情 private marketDataManager: MarketDataManager | null = null; private currentBTCPrice: number = 0; private isPriceReady: boolean = false; // 动态仓位管理器 - 保证金使用率过高时自动减仓 private dynamicPositionManager: DynamicPositionManager | null = null; // 简洁版统计信息 private stats: SimpleStats = { totalOrders: 0, filledOrders: 0, cancelledOrders: 0, expiredOrders: 0, totalVolume: 0, totalPnL: 0, startTime: Date.now(), lastUpdateTime: Date.now(), consecutiveErrors: 0, maxConsecutiveErrors: 3, apiCallCount: 0, lastApiError: 0, lastSuccessfulTrade: 0, retryCount: 0, totalRetries: 0 }; // 配置参数 private readonly STATS_SAVE_INTERVAL = 600000; // 10分钟保存一次统计 private readonly HEALTH_CHECK_INTERVAL = 300000; // 5分钟健康检查 private readonly MAX_RUNTIME = 6 * 60 * 60 * 1000; // 6小时最大运行时间 private readonly ERROR_RECOVERY_DELAY = 60000; // 60秒错误恢复延迟 private readonly STATS_FILE = './data/simple-stats.json'; private readonly TRADING_PAUSE_DURATION = 120000; // 120秒交易暂停 private readonly MAX_RETRY_ATTEMPTS = 2; // 最大重试次数 private readonly RETRY_DELAY = 10000; // 重试延迟 // 状态控制 private isTradingPaused = false; private lastTradingPause = 0; private isInitialized = false; constructor( config: DeltaNeutralConfig, pacificaClient: PacificaSigningClient, accounts: Account[] ) { super(config, pacificaClient, accounts); this.sessionId = `session_${Date.now()}`; this.strategyAccounts = accounts; // 保存账户引用 // 为每个账户创建独立的客户端 accounts.forEach(account => { const client = new PacificaSigningClient(account.getPrivateKey()); this.clientMap.set(account.getId(), client); }); this.loadStats(); this.initializeRiskManager(config); this.initializeMarketDataManager(); this.initializeDynamicPositionManager(); } /** * 初始化风险管理器 */ private initializeRiskManager(config: DeltaNeutralConfig): void { const riskConfig: RiskManagerConfig = { maxTotalVolume: config.maxVolumePositionSize * 10, // 最大总量 maxNetExposure: config.maxDeltaDeviation, // 最大净敞口 maxDailyLoss: config.stopLossThreshold, // 最大每日亏损 positionLimit: config.maxVolumePositionSize, // 仓位限制 stopLossThreshold: config.stopLossThreshold, // 止损阈值 monitoringInterval: 60000 // 60秒监控间隔 }; this.riskManager = new RiskManager(riskConfig); this.riskManager.on('breach_detected', (breach) => { this.log(`风险告警: ${breach.type} - ${breach.severity}`, 'error'); if (breach.severity === 'critical') { this.pauseTrading(); } }); } /** * 初始化市场数据管理器 * 使用WebSocket订阅实时行情,替代REST轮询 */ private initializeMarketDataManager(): void { this.marketDataManager = new MarketDataManager(); // 监听实时价格更新 this.marketDataManager.on('price_update', (priceData) => { if (priceData.symbol === 'BTC') { this.currentBTCPrice = parseFloat(priceData.mark); if (!this.isPriceReady) { this.isPriceReady = true; this.log(`BTC实时价格已就绪: $${this.currentBTCPrice.toFixed(2)}`, 'success'); } } }); // 监听WebSocket连接状态 this.marketDataManager.on('connected', () => { this.log('WebSocket市场数据已连接', 'success'); }); this.marketDataManager.on('disconnected', () => { this.log('WebSocket市场数据断开,切换到REST轮询', 'warning'); this.isPriceReady = false; }); } /** * 初始化动态仓位管理器 * 当保证金使用率过高时自动减仓 */ private initializeDynamicPositionManager(): void { // 从配置文件读取设置 let config: PositionAdjustmentConfig; try { const strategyConfig = JSON.parse(readFileSync('./config/trading-strategy.json', 'utf-8')); const posConfig = strategyConfig.dynamicPositionAdjustment; config = { enabled: posConfig.enabled ?? true, maxMarginUsageThreshold: posConfig.maxMarginUsageThreshold ?? 0.85, targetMarginRelease: posConfig.targetMarginRelease ?? 0.2, minPositionRatio: posConfig.minPositionRatio ?? 0.3, checkInterval: posConfig.checkInterval ?? 10000 }; } catch (error) { // 使用默认配置 config = { enabled: true, maxMarginUsageThreshold: 0.85, targetMarginRelease: 0.2, minPositionRatio: 0.3, checkInterval: 10000 }; } this.dynamicPositionManager = new DynamicPositionManager(config); this.log('动态仓位管理器已初始化', 'success'); } /** * 简洁版日志输出 */ private log(message: string, type: 'info' | 'success' | 'warning' | 'error' = 'info'): void { const icons = { info: '📊', success: '✅', warning: '⚠️', error: '❌' }; // 只显示重要信息,减少时间戳 if (type === 'error' || type === 'success') { console.log(`${icons[type]} ${message}`); } } /** * 加载统计信息 */ private loadStats(): void { try { if (existsSync(this.STATS_FILE)) { const savedStats = JSON.parse(readFileSync(this.STATS_FILE, 'utf-8')); this.stats = { ...this.stats, ...savedStats }; this.log(`加载历史统计: 运行${Math.floor((Date.now() - this.stats.startTime) / 1000 / 60)}分钟`, 'info'); } } catch (error) { // 静默处理加载错误 } } /** * 保存统计信息 */ private saveStats(): void { try { this.stats.lastUpdateTime = Date.now(); writeFileSync(this.STATS_FILE, JSON.stringify(this.stats, null, 2)); } catch (error) { // 静默处理保存错误 } } /** * 带重试的API调用 */ private async callApiWithRetry( apiCall: () => Promise, operation: string, maxRetries: number = this.MAX_RETRY_ATTEMPTS ): Promise { let lastError: Error | null = null; for (let attempt = 1; attempt <= maxRetries; attempt++) { try { await this.waitForApiCallInterval(); const result = await apiCall(); this.stats.apiCallCount++; this.stats.retryCount = 0; return result; } catch (error) { lastError = error as Error; this.stats.retryCount++; this.stats.totalRetries++; if (attempt < maxRetries) { const delay = this.RETRY_DELAY * attempt; await new Promise(resolve => setTimeout(resolve, delay)); } } } throw lastError; } /** * 健康检查 */ private async performHealthCheck(): Promise { try { const runtime = Date.now() - this.stats.startTime; // 检查最大运行时间 if (runtime > this.MAX_RUNTIME) { this.log(`达到最大运行时间,准备停止`, 'warning'); await this.stop(); process.exit(0); } // 检查连续错误 if (this.stats.consecutiveErrors >= this.stats.maxConsecutiveErrors) { this.log(`连续错误过多,暂停交易`, 'error'); await this.pauseTrading(); return; } // 检查API连接 await this.callApiWithRetry( () => this.pacificaClient.getPrices(), '健康检查API连接' ); // 重置连续错误计数 if (this.stats.consecutiveErrors > 0) { this.stats.consecutiveErrors = 0; this.log('API连接恢复', 'success'); } // 检查交易暂停状态 if (this.isTradingPaused && Date.now() - this.lastTradingPause > this.TRADING_PAUSE_DURATION) { this.log('恢复交易', 'info'); this.isTradingPaused = false; } } catch (error) { this.stats.consecutiveErrors++; this.stats.lastApiError = Date.now(); this.log(`健康检查失败`, 'error'); } } /** * 暂停交易 */ private async pauseTrading(): Promise { this.log('暂停交易,等待错误恢复...', 'warning'); this.isTradingPaused = true; this.lastTradingPause = Date.now(); // 暂停交易定时器 if (this.volumeTradingInterval) { clearInterval(this.volumeTradingInterval); this.volumeTradingInterval = null; } // 等待错误恢复 setTimeout(async () => { this.log('尝试恢复交易...', 'info'); await this.resumeTrading(); }, this.ERROR_RECOVERY_DELAY); } /** * 恢复交易 */ private async resumeTrading(): Promise { try { // 重新检查API连接 await this.callApiWithRetry( () => this.pacificaClient.getPrices(), '恢复交易API检查' ); // 恢复交易定时器 this.startVolumeTrading(); this.log('交易恢复成功', 'success'); } catch (error) { this.log(`交易恢复失败`, 'error'); await this.pauseTrading(); } } /** * 重写开始刷量交易方法 */ protected async startVolumeTrading(): Promise { this.log('启动简洁版刷量交易系统', 'info'); // 启动订单生命周期管理 this.startOrderLifecycleManagement(); // 启动状态显示 this.startStatusDisplay(); // 启动统计保存 this.startStatsSaving(); // 启动健康检查 this.startHealthCheck(); // 启动动态仓位管理 await this.startDynamicPositionManager(); // 刷量交易 - 15秒间隔 this.volumeTradingInterval = setInterval(async () => { try { if (!this.isTradingPaused && this.isInitialized) { await this.executeVolumeTradingCycle(); } } catch (error) { this.stats.consecutiveErrors++; this.log(`刷量交易失败`, 'warning'); } }, 15000); // 15秒间隔 // Delta监控 - 120秒间隔 this.deltaMonitoringInterval = setInterval(async () => { try { if (this.isInitialized) { await this.monitorAndRebalance(); } } catch (error) { this.stats.consecutiveErrors++; this.log(`Delta监控失败`, 'warning'); } }, 120000); // 120秒间隔 } /** * 启动订单生命周期管理 */ private startOrderLifecycleManagement(): void { this.orderCheckInterval = setInterval(async () => { try { await this.checkOrderLifecycle(); } catch (error) { this.stats.consecutiveErrors++; this.log(`订单检查失败`, 'warning'); } }, 60000); // 60秒检查一次 } /** * 启动状态显示 */ private startStatusDisplay(): void { this.statusDisplayInterval = setInterval(() => { this.displayStatus(); }, 600000); // 每10分钟显示一次 } /** * 启动统计保存 */ private startStatsSaving(): void { this.statsSaveInterval = setInterval(() => { this.saveStats(); }, this.STATS_SAVE_INTERVAL); } /** * 启动健康检查 */ private startHealthCheck(): void { this.healthCheckInterval = setInterval(async () => { await this.performHealthCheck(); }, this.HEALTH_CHECK_INTERVAL); } /** * 启动动态仓位管理器 */ private async startDynamicPositionManager(): Promise { if (!this.dynamicPositionManager) { console.log('⚠️ 动态仓位管理器未初始化'); return; } // 为每个账户初始化管理器 for (const account of this.strategyAccounts) { const client = this.clientMap.get(account.getId()); if (client) { this.dynamicPositionManager.initializeAccount(account, client); console.log(`✅ 为账户 ${account.getName()} 初始化动态仓位管理`); } } // 启动监控 await this.dynamicPositionManager.startMonitoring(this.strategyAccounts); console.log('✅ 动态仓位管理监控已启动'); this.log('动态仓位管理监控已启动', 'success'); } /** * 显示策略状态 */ private displayStatus(): void { const runtime = Math.floor((Date.now() - this.stats.startTime) / 1000); const runtimeStr = `${Math.floor(runtime / 3600)}时${Math.floor((runtime % 3600) / 60)}分${runtime % 60}秒`; console.log('\n' + '='.repeat(50)); console.log('📈 简洁版策略运行状态'); console.log('='.repeat(50)); console.log(`⏰ 运行时间: ${runtimeStr}`); console.log(`📊 总订单数: ${this.stats.totalOrders}`); console.log(`✅ 已成交: ${this.stats.filledOrders}`); console.log(`❌ 已取消: ${this.stats.cancelledOrders}`); console.log(`📈 总交易量: ${this.stats.totalVolume.toFixed(6)} BTC`); console.log(`💰 总PNL: ${this.stats.totalPnL.toFixed(2)} USDC`); console.log(`🔄 活跃订单: ${this.orderLifecycle.size}`); console.log(`🌐 API调用: ${this.stats.apiCallCount}`); console.log(`⚠️ 连续错误: ${this.stats.consecutiveErrors}`); console.log(`⏸️ 交易状态: ${this.isTradingPaused ? '暂停' : '正常'}`); // 显示WebSocket价格状态 if (this.isPriceReady) { console.log(`💹 BTC价格: $${this.currentBTCPrice.toFixed(2)} (WebSocket实时)`); } else { console.log(`💹 价格源: REST API (WebSocket未就绪)`); } // 显示账户配对信息 console.log(`🔗 账户配对: ${this.accountPairs.length}对`); if (this.stats.totalOrders > 0) { const successRate = ((this.stats.filledOrders / this.stats.totalOrders) * 100).toFixed(1); console.log(`🎯 成交率: ${successRate}%`); } // 显示健康状态 const healthStatus = this.stats.consecutiveErrors === 0 ? '🟢 健康' : '🔴 异常'; console.log(`🏥 健康状态: ${healthStatus}`); console.log('='.repeat(50) + '\n'); } /** * 检查订单生命周期 */ private async checkOrderLifecycle(): Promise { const now = Date.now(); const ordersToRemove: string[] = []; for (const [orderId, order] of this.orderLifecycle) { try { // 检查订单是否超时 const timeSinceCreated = now - order.createdAt; const maxOrderLifetime = 600000; // 600秒最大生命周期 if (timeSinceCreated > maxOrderLifetime) { this.log(`订单超时取消: ${orderId}`, 'warning'); await this.cancelOrderSafely(orderId, order.symbol); this.stats.cancelledOrders++; ordersToRemove.push(orderId); continue; } // 检查订单状态 if (order.status === 'pending' && order.checkCount < order.maxChecks) { await this.checkOrderStatus(order); order.checkCount++; order.lastChecked = now; } // 如果检查次数过多,标记为过期 if (order.checkCount >= order.maxChecks) { this.log(`订单检查超限: ${orderId}`, 'warning'); order.status = 'expired'; this.stats.expiredOrders++; ordersToRemove.push(orderId); } } catch (error) { this.log(`检查订单失败: ${orderId}`, 'error'); ordersToRemove.push(orderId); } } // 清理过期订单 for (const orderId of ordersToRemove) { this.orderLifecycle.delete(orderId); } } /** * 检查单个订单状态 */ private async checkOrderStatus(order: OrderLifecycle): Promise { try { const openOrdersResponse = await this.callApiWithRetry( () => this.pacificaClient.getOpenOrders(), '检查订单状态' ); const openOrders = Array.isArray(openOrdersResponse) ? openOrdersResponse : openOrdersResponse.data || []; const orderExists = openOrders.some((o: any) => o.order_id === parseInt(order.orderId)); if (!orderExists) { order.status = 'filled'; this.stats.filledOrders++; this.stats.totalVolume += parseFloat(order.amount); this.stats.lastSuccessfulTrade = Date.now(); this.log(`订单成交: ${order.side.toUpperCase()} ${order.amount} BTC @ ${order.price}`, 'success'); } } catch (error) { this.log(`检查订单状态失败: ${order.orderId}`, 'error'); } } /** * 安全取消订单 */ private async cancelOrderSafely(orderId: string, symbol: string): Promise { try { await this.callApiWithRetry( () => this.pacificaClient.cancelOrder(orderId, symbol), `取消订单 ${orderId}` ); } catch (error) { this.log(`取消订单失败: ${orderId}`, 'error'); } } /** * API调用间隔控制 */ private async waitForApiCallInterval(): Promise { const now = Date.now(); const timeSinceLastCall = now - this.lastApiCall; if (timeSinceLastCall < this.apiCallInterval) { const waitTime = this.apiCallInterval - timeSinceLastCall; await new Promise(resolve => setTimeout(resolve, waitTime)); } this.lastApiCall = Date.now(); } /** * 重写刷量交易执行 * 优先使用WebSocket实时价格,如果不可用则回退到REST API */ protected async executeVolumeTrades(): Promise { try { // 检查是否应该暂停交易 if (this.isTradingPaused || !this.isInitialized) { return; } let currentPrice: number; // 优先使用WebSocket实时价格 if (this.isPriceReady && this.currentBTCPrice > 0) { currentPrice = this.currentBTCPrice; // 无需API调用,直接使用缓存的实时价格 } else { // 回退到REST API this.log('使用REST API获取价格 (WebSocket未就绪)', 'warning'); const prices = await this.callApiWithRetry( () => this.pacificaClient.getPrices(), '获取价格信息' ); const btcPrice = prices.data.find((p: any) => p.symbol === 'BTC'); currentPrice = parseFloat(btcPrice.mark); } const totalAccountValue = await this.getTotalAccountValue(); const volumePositionSize = Math.min( this.config.maxVolumePositionSize, this.config.volumePositionRatio * totalAccountValue / currentPrice ); // 使用账户配对执行Delta中性刷量 // 每对账户: 一个买入, 一个卖出, 保证净仓位为零 for (const [buyAccount, sellAccount] of this.accountPairs) { await this.executePairedVolumeTrade( buyAccount, sellAccount, volumePositionSize, currentPrice ); } } catch (error) { this.log(`刷量交易失败`, 'warning'); } } /** * 执行配对刷量交易 * 确保买入和卖出同步执行,保持Delta中性 */ private async executePairedVolumeTrade( buyAccount: Account, sellAccount: Account, volumePositionSize: number, currentPrice: number ): Promise { try { // 计算交易数量 - 满足$10最低订单价值要求 const LOT_SIZE = 0.00001; // BTC最小订单大小 (lot size) const MIN_ORDER_VALUE = 10; // $10 USDC最低订单价值 // 计算满足$10最低要求的BTC数量 const minBtcAmount = MIN_ORDER_VALUE / currentPrice; const MIN_ORDER_SIZE = Math.ceil(minBtcAmount / LOT_SIZE) * LOT_SIZE; let tradeSize = Math.max( MIN_ORDER_SIZE, Math.min( volumePositionSize * 0.5, // 每次交易50%的刷量仓位 this.config.maxVolumePositionSize // 最大刷量仓位 ) ); // 确保是lot size的整数倍 tradeSize = Math.floor(tradeSize / LOT_SIZE) * LOT_SIZE; tradeSize = Math.max(tradeSize, MIN_ORDER_SIZE); // 验证订单价值 const orderValue = tradeSize * currentPrice; if (orderValue < MIN_ORDER_VALUE) { this.log(`订单价值过低: $${orderValue.toFixed(2)} < $10, 跳过`, 'warning'); return; } // 余额检查 const buyClient = this.clientMap.get(buyAccount.getId()); const sellClient = this.clientMap.get(sellAccount.getId()); if (!buyClient || !sellClient) { this.log('账户客户端未找到,跳过交易', 'warning'); return; } // 检查买入账户余额 const buyBalance = await this.checkAccountBalance(buyAccount, buyClient, orderValue); if (!buyBalance) { this.log(`买入账户余额不足: ${buyAccount.getId().slice(0,8)}`, 'warning'); this.handleInsufficientBalance(); return; } // 检查卖出账户是否有足够的BTC const sellBalance = await this.checkAccountBalance(sellAccount, sellClient, tradeSize, true); if (!sellBalance) { this.log(`卖出账户BTC不足: ${sellAccount.getId().slice(0,8)}`, 'warning'); this.handleInsufficientBalance(); return; } // 风险检查 - 在执行交易前检查仓位大小 if (this.riskManager) { const buyRiskBreach = await this.riskManager.checkPositionSizeRisk( this.sessionId, buyAccount.getId(), tradeSize ); const sellRiskBreach = await this.riskManager.checkPositionSizeRisk( this.sessionId, sellAccount.getId(), tradeSize ); if (buyRiskBreach || sellRiskBreach) { this.log(`风险检查未通过,跳过本次交易`, 'warning'); return; } } // 同步执行买入和卖出订单 - 这是Delta中性的关键 await Promise.all([ this.executeAccountVolumeTradeWithLifecycle(buyAccount, tradeSize, currentPrice, 'bid'), this.executeAccountVolumeTradeWithLifecycle(sellAccount, tradeSize, currentPrice, 'ask') ]); this.log(`配对交易: ${buyAccount.getId().slice(0,8)}买/${sellAccount.getId().slice(0,8)}卖`, 'success'); } catch (error) { this.log(`配对交易失败: ${buyAccount.getId().slice(0,8)} <-> ${sellAccount.getId().slice(0,8)}`, 'warning'); } } /** * 带生命周期管理的账户刷量交易 * @param side - 'bid' (买入) 或 'ask' (卖出), 由配对机制指定 */ private async executeAccountVolumeTradeWithLifecycle( account: Account, tradeSize: number, currentPrice: number, side: 'bid' | 'ask' ): Promise { try { // 获取账户专属客户端 const client = this.clientMap.get(account.getId()); if (!client) { this.log(`账户客户端未找到: ${account.getId()}`, 'error'); return; } // 智能选择订单类型 if (this.config.preferredOrderType === 'limit') { await this.createLimitOrderWithLifecycle(account, client, side, tradeSize, currentPrice); } else { await this.createVolumeMarketOrder(account, client, side, tradeSize); } } catch (error) { this.log(`账户交易失败: ${account.getId()} (${side})`, 'warning'); } } /** * 创建带生命周期管理的limit订单(优先限价单降低手续费) */ private async createLimitOrderWithLifecycle( account: Account, client: PacificaSigningClient, side: 'bid' | 'ask', amount: number, currentPrice: number ): Promise { try { // 使用更小的价差提高成交率 const spread = this.config.limitOrderSpread; const price = side === 'bid' ? (currentPrice * (1 - spread)).toFixed(0) : (currentPrice * (1 + spread)).toFixed(0); const clientOrderId = uuidv4(); const order = { symbol: 'BTC', amount: amount.toFixed(8), side, price, tif: 'GTC', // Good-Till-Cancel (挂单等待成交) reduce_only: false, client_order_id: clientOrderId }; const result = await this.callApiWithRetry( () => client.createLimitOrder(order), `创建${side}订单 (${account.getId().slice(0,8)})` ); if (result.success && result.data?.order_id) { const orderId = result.data.order_id.toString(); // 创建订单生命周期记录 - 10秒超时 const orderLifecycle: OrderLifecycle = { orderId, clientOrderId, accountId: account.getId(), // 记录账户ID symbol: 'BTC', side, amount: order.amount, price: order.price, status: 'pending', createdAt: Date.now(), lastChecked: Date.now(), checkCount: 0, maxChecks: 1 // 10秒超时(检查1次后转市价单) }; this.orderLifecycle.set(orderId, orderLifecycle); this.stats.totalOrders++; this.log(`限价单: ${side.toUpperCase()} ${amount.toFixed(6)} BTC @ $${price} (${account.getId().slice(0,8)})`, 'info'); // 启动订单监控(如果还未启动) if (!this.orderCheckInterval) { this.startOrderMonitoring(); } } } catch (error) { this.log(`限价单失败: ${side}, 降级为市价单`, 'warning'); // 限价单失败,降级为市价单 await this.createVolumeMarketOrder(account, client, side, amount); } } /** * 启动订单状态监控 */ private startOrderMonitoring(): void { this.orderCheckInterval = setInterval(async () => { await this.checkPendingOrders(); }, 10000); // 每10秒检查一次 this.log('订单监控已启动 (10秒间隔)', 'info'); } /** * 检查待处理订单状态 */ private async checkPendingOrders(): Promise { const now = Date.now(); const ordersToCheck = Array.from(this.orderLifecycle.entries()) .filter(([_, order]) => order.status === 'pending'); for (const [orderId, order] of ordersToCheck) { try { order.checkCount++; order.lastChecked = now; // 检查是否超时 const ageSeconds = (now - order.createdAt) / 1000; if (order.checkCount >= order.maxChecks) { // 超时未成交,撤单并使用市价单重试 this.log(`限价单超时 (${ageSeconds.toFixed(0)}s): ${order.side.toUpperCase()} @ $${order.price}, 转市价单`, 'warning'); await this.cancelAndRetryWithMarket(orderId, order); } } catch (error) { this.log(`检查订单${orderId}失败`, 'warning'); } } } /** * 撤单并使用市价单重试 */ private async cancelAndRetryWithMarket(orderId: string, order: OrderLifecycle): Promise { try { // 使用订单记录中的账户ID找到正确的账户和客户端 const targetAccount = this.accounts.find(acc => acc.getId() === order.accountId); const targetClient = targetAccount ? this.clientMap.get(targetAccount.getId()) : null; if (!targetAccount || !targetClient) { this.log(`找不到订单对应的账户: ${order.accountId.slice(0,8)}`, 'error'); return; } // 尝试撤销订单 try { await targetClient.cancelOrder(orderId, 'BTC'); this.log(`已撤销限价单: ${orderId} (${targetAccount.getId().slice(0,8)})`, 'info'); } catch (error) { // 订单可能已成交或不存在,忽略错误 this.log(`撤单失败(可能已成交): ${orderId}`, 'warning'); } // 标记为已取消 order.status = 'cancelled'; this.stats.cancelledOrders++; // 使用市价单重试相同数量 const amount = parseFloat(order.amount); this.log(`市价单重试: ${order.side.toUpperCase()} ${amount.toFixed(6)} BTC (${targetAccount.getId().slice(0,8)})`, 'info'); await this.createVolumeMarketOrder( targetAccount, targetClient, order.side, amount ); } catch (error) { this.log(`撤单重试失败: ${orderId}`, 'error'); } } /** * 创建市场订单 */ private async createVolumeMarketOrder( account: Account, client: PacificaSigningClient, side: 'bid' | 'ask', amount: number ): Promise { try { const clientOrderId = uuidv4(); const order = { symbol: 'BTC', amount: amount.toFixed(8), side, slippage_percent: '0.5', reduce_only: false, client_order_id: clientOrderId }; const result = await this.callApiWithRetry( () => client.createMarketOrder(order), `创建市场${side}订单 (${account.getId().slice(0,8)})` ); if (result.success && result.data?.order_id) { const orderId = result.data.order_id.toString(); const orderLifecycle: OrderLifecycle = { orderId, clientOrderId, accountId: account.getId(), // 记录账户ID symbol: 'BTC', side, amount: order.amount, price: '0', // market order has no fixed price status: 'pending', createdAt: Date.now(), lastChecked: Date.now(), checkCount: 0, maxChecks: 10 }; this.orderLifecycle.set(orderId, orderLifecycle); this.stats.totalOrders++; this.log(`创建市场订单: ${side.toUpperCase()} ${amount.toFixed(6)} BTC (${account.getId().slice(0,8)})`, 'info'); } } catch (error) { this.log(`创建市场订单失败: ${side}`, 'error'); } } /** * 重写初始化方法 - 完全自定义,不调用父类 */ public async initialize(): Promise { try { this.log('开始初始化简洁版策略...', 'info'); // 初始化账户配对 - Delta中性核心 this.initializeAccountPairs(); // 初始化并启动市场数据管理器 if (this.marketDataManager) { await this.marketDataManager.initialize(); this.log('市场数据管理器已启动 (WebSocket)', 'success'); // 等待初始价格数据 (最多5秒) const priceTimeout = setTimeout(() => { if (!this.isPriceReady) { this.log('WebSocket价格未就绪,将使用REST API后备', 'warning'); } }, 5000); // 等待价格就绪或超时 for (let i = 0; i < 50 && !this.isPriceReady; i++) { await new Promise(resolve => setTimeout(resolve, 100)); } clearTimeout(priceTimeout); } // 初始化并启动风险管理器 if (this.riskManager) { await this.riskManager.initialize(); await this.riskManager.startMonitoring(this.sessionId); this.log('风险管理器已启动', 'success'); } // 启动配对刷量交易循环 this.startPairedVolumeTrading(); // 启动Delta再平衡监控 this.startDeltaRebalancing(); // 启动动态仓位管理器 await this.startDynamicPositionManager(); this.isInitialized = true; this.log('简洁版策略初始化成功', 'success'); } catch (error) { this.log(`策略初始化失败`, 'error'); throw error; } } /** * 启动配对刷量交易 */ private startPairedVolumeTrading(): void { // 启动刷量交易循环 - 每10秒执行一次 this.volumeTradingInterval = setInterval(async () => { if (this.isTradingPaused) { return; } try { await this.executeVolumeTrades(); } catch (error) { this.log('刷量交易周期失败', 'warning'); } }, 10000); this.log('配对刷量交易已启动 (10秒间隔)', 'success'); } /** * 启动Delta再平衡监控 * 定期检查并修正仓位不平衡 */ private startDeltaRebalancing(): void { // 每60秒检查一次Delta平衡 this.deltaMonitoringInterval = setInterval(async () => { if (this.isTradingPaused) { return; } try { await this.checkAndRebalanceDelta(); } catch (error) { this.log('Delta再平衡检查失败', 'warning'); } }, 60000); this.log('Delta再平衡监控已启动 (60秒间隔)', 'success'); } /** * 检查并执行Delta再平衡 */ private async checkAndRebalanceDelta(): Promise { try { // 获取所有账户的实时仓位 const positions = await this.getAllAccountPositions(); if (positions.length === 0) { return; } // 计算总净Delta let totalNetDelta = 0; let totalExposure = 0; for (const pos of positions) { totalNetDelta += pos.netPosition; totalExposure += Math.abs(pos.netPosition); } // 如果没有仓位,无需再平衡 if (totalExposure === 0) { return; } // 计算Delta偏差百分比 const deltaDeviationPercent = Math.abs(totalNetDelta / totalExposure); this.log(`Delta状态: 净Delta=${totalNetDelta.toFixed(8)} BTC, 偏差=${(deltaDeviationPercent * 100).toFixed(2)}%`, 'info'); // 如果偏差超过阈值(例如5%),触发再平衡 const REBALANCE_THRESHOLD = 0.05; // 5%阈值 if (deltaDeviationPercent > REBALANCE_THRESHOLD) { this.log(`⚠️ Delta偏差过大 (${(deltaDeviationPercent * 100).toFixed(2)}%), 开始再平衡...`, 'warning'); await this.executeDeltaRebalance(positions, totalNetDelta); } } catch (error) { this.log('Delta再平衡执行失败', 'error'); } } /** * 获取所有账户的实时仓位 */ private async getAllAccountPositions(): Promise> { const positions = []; for (const account of this.accounts) { const client = this.clientMap.get(account.getId()); if (!client) { continue; } try { const result = await client.getAccountPositions(); if (result.data && Array.isArray(result.data)) { const btcPos = result.data.find((p: any) => p.symbol === 'BTC'); if (btcPos) { // bid = long (正), ask = short (负) const netPosition = btcPos.side === 'bid' ? parseFloat(btcPos.amount) : -parseFloat(btcPos.amount); positions.push({ account, client, netPosition, amount: btcPos.amount, side: btcPos.side }); } } } catch (error) { this.log(`获取账户${account.getId().slice(0,8)}仓位失败`, 'warning'); } } return positions; } /** * 执行Delta再平衡 * 通过调整账户仓位使净Delta接近零 */ private async executeDeltaRebalance( positions: Array<{account: Account, client: PacificaSigningClient, netPosition: number, amount: string, side: string}>, totalNetDelta: number ): Promise { try { // 计算需要平衡的数量(净Delta的一半,分配到两个方向) const rebalanceAmount = Math.abs(totalNetDelta) / 2; // 确保满足最小订单要求 const LOT_SIZE = 0.00001; const MIN_ORDER_VALUE = 10; const currentPrice = this.currentBTCPrice || 113000; const minBtcAmount = MIN_ORDER_VALUE / currentPrice; const MIN_ORDER_SIZE = Math.ceil(minBtcAmount / LOT_SIZE) * LOT_SIZE; let adjustedRebalanceAmount = Math.floor(rebalanceAmount / LOT_SIZE) * LOT_SIZE; if (adjustedRebalanceAmount < MIN_ORDER_SIZE) { this.log(`再平衡数量过小 (${adjustedRebalanceAmount.toFixed(8)} < ${MIN_ORDER_SIZE.toFixed(8)}), 跳过`, 'info'); return; } // 找出净多头和净空头账户 const longPositions = positions.filter(p => p.netPosition > 0); const shortPositions = positions.filter(p => p.netPosition < 0); if (totalNetDelta > 0) { // 净多头过多:减少多头仓位,增加空头仓位 this.log(`执行再平衡: 减少${adjustedRebalanceAmount.toFixed(8)} BTC多头`, 'info'); // 在最大多头账户上减仓 if (longPositions.length > 0) { const maxLongAccount = longPositions.reduce((max, p) => p.netPosition > max.netPosition ? p : max ); await this.executeRebalanceOrder( maxLongAccount.account, maxLongAccount.client, adjustedRebalanceAmount, 'ask' // 平多头 = 卖出 ); } // 在最小空头账户上加仓 if (shortPositions.length > 0) { const minShortAccount = shortPositions.reduce((min, p) => Math.abs(p.netPosition) < Math.abs(min.netPosition) ? p : min ); await this.executeRebalanceOrder( minShortAccount.account, minShortAccount.client, adjustedRebalanceAmount, 'ask' // 增加空头 = 卖出 ); } else { // 如果没有空头账户,在另一个多头账户上开空 if (longPositions.length > 1) { const minLongAccount = longPositions.reduce((min, p) => p.netPosition < min.netPosition ? p : min ); await this.executeRebalanceOrder( minLongAccount.account, minLongAccount.client, adjustedRebalanceAmount, 'ask' ); } } } else { // 净空头过多:减少空头仓位,增加多头仓位 this.log(`执行再平衡: 减少${adjustedRebalanceAmount.toFixed(8)} BTC空头`, 'info'); // 在最大空头账户上减仓 if (shortPositions.length > 0) { const maxShortAccount = shortPositions.reduce((max, p) => Math.abs(p.netPosition) > Math.abs(max.netPosition) ? p : max ); await this.executeRebalanceOrder( maxShortAccount.account, maxShortAccount.client, adjustedRebalanceAmount, 'bid' // 平空头 = 买入 ); } // 在最小多头账户上加仓 if (longPositions.length > 0) { const minLongAccount = longPositions.reduce((min, p) => p.netPosition < min.netPosition ? p : min ); await this.executeRebalanceOrder( minLongAccount.account, minLongAccount.client, adjustedRebalanceAmount, 'bid' // 增加多头 = 买入 ); } else { // 如果没有多头账户,在另一个空头账户上开多 if (shortPositions.length > 1) { const minShortAccount = shortPositions.reduce((min, p) => Math.abs(p.netPosition) < Math.abs(min.netPosition) ? p : min ); await this.executeRebalanceOrder( minShortAccount.account, minShortAccount.client, adjustedRebalanceAmount, 'bid' ); } } } this.log('✅ Delta再平衡完成', 'success'); } catch (error) { this.log('Delta再平衡执行失败', 'error'); } } /** * 执行再平衡订单 */ private async executeRebalanceOrder( account: Account, client: PacificaSigningClient, amount: number, side: 'bid' | 'ask' ): Promise { try { const clientOrderId = uuidv4(); const order = { symbol: 'BTC', amount: amount.toFixed(8), side, slippage_percent: '0.5', reduce_only: false, client_order_id: clientOrderId }; const result = await this.callApiWithRetry( () => client.createMarketOrder(order), `再平衡订单 (${account.getId().slice(0,8)} ${side})` ); if (result.success) { this.log(`✅ 再平衡订单: ${account.getId().slice(0,8)} ${side.toUpperCase()} ${amount.toFixed(8)} BTC`, 'success'); } } catch (error) { this.log(`再平衡订单失败: ${account.getId().slice(0,8)} ${side}`, 'error'); } } /** * 初始化账户配对机制 * 确保Delta中性: 每个买单都有对应的卖单 */ private initializeAccountPairs(): void { if (this.accounts.length < 2) { throw new Error('需要至少2个账户进行Delta中性对冲'); } if (this.accounts.length % 2 !== 0) { this.log(`警告: 账户数量为奇数(${this.accounts.length}), 最后一个账户将不参与配对`, 'warning'); } this.accountPairs = []; for (let i = 0; i < this.accounts.length - 1; i += 2) { this.accountPairs.push([this.accounts[i], this.accounts[i + 1]]); } this.log(`账户配对完成: ${this.accountPairs.length}对账户`, 'success'); this.accountPairs.forEach((pair, index) => { this.log(` 配对${index + 1}: ${pair[0].getId()} (买) <-> ${pair[1].getId()} (卖)`, 'info'); }); } /** * 检查账户余额 * @param account 账户 * @param client 客户端 * @param requiredAmount 需要的金额(USDC或BTC) * @param isBTC 是否检查BTC余额 */ private async checkAccountBalance( account: Account, client: PacificaSigningClient, requiredAmount: number, isBTC: boolean = false ): Promise { try { const accountInfo = await client.getAccountInfo(); if (isBTC) { // 检查BTC持仓 const positions = await client.getAccountPositions(); const btcPositions = Array.isArray(positions.data) ? positions.data.filter((p: any) => p.symbol === 'BTC') : []; const totalBTC = btcPositions.reduce((sum: number, p: any) => { return sum + Math.abs(parseFloat(p.amount)); }, 0); return totalBTC >= requiredAmount; } else { // 检查USDC余额 const availableBalance = parseFloat(accountInfo.data.available_to_spend); const marginBuffer = 1.1; // 10%缓冲 return availableBalance >= requiredAmount * marginBuffer; } } catch (error) { this.log(`检查余额失败: ${account.getId().slice(0,8)}`, 'error'); return false; } } /** * 处理余额不足 */ private handleInsufficientBalance(): void { if (!this.insufficientBalanceCount) { this.insufficientBalanceCount = 0; } this.insufficientBalanceCount++; // 如果连续5次余额不足,暂停交易 if (this.insufficientBalanceCount >= 5) { this.log('⚠️ 连续余额不足,暂停交易60秒', 'warning'); this.isTradingPaused = true; // 60秒后恢复 setTimeout(() => { this.isTradingPaused = false; this.insufficientBalanceCount = 0; this.log('✅ 恢复交易', 'success'); }, 60000); } } private insufficientBalanceCount: number = 0; /** * 重写停止方法 */ public async stop(): Promise { this.log('停止简洁版策略...', 'info'); // 清理定时器 if (this.volumeTradingInterval) { clearInterval(this.volumeTradingInterval); this.volumeTradingInterval = null; } if (this.deltaMonitoringInterval) { clearInterval(this.deltaMonitoringInterval); this.deltaMonitoringInterval = null; } if (this.orderCheckInterval) { clearInterval(this.orderCheckInterval); this.orderCheckInterval = null; } if (this.statusDisplayInterval) { clearInterval(this.statusDisplayInterval); this.statusDisplayInterval = null; } if (this.statsSaveInterval) { clearInterval(this.statsSaveInterval); this.statsSaveInterval = null; } if (this.healthCheckInterval) { clearInterval(this.healthCheckInterval); this.healthCheckInterval = null; } // 停止动态仓位管理器 if (this.dynamicPositionManager) { this.dynamicPositionManager.shutdown(); this.log('动态仓位管理器已停止', 'success'); } // 使用 OrderCleanupService 取消所有开放订单 console.log('\n🧹 正在从 Pacifica API 获取开放订单...'); this.log('清理所有开放订单...', 'info'); try { const cleanupService = new OrderCleanupService(); // 为每个账户初始化清理服务 for (const account of this.accounts) { cleanupService.initializeAccount(account); } // 强制清理所有订单 const cleanupOptions: CleanupOptions = { cleanAll: true, includeReduceOnly: true, // 包括保护性订单 mode: 'force', // 强制模式 dryRun: false }; console.log('从 API 获取订单并取消...'); const results = await cleanupService.cleanupMultipleAccounts( this.accounts, cleanupOptions ); // 汇总清理结果 let totalOrders = 0; let totalCancelled = 0; for (const result of results.values()) { totalOrders += result.totalOrders; totalCancelled += result.cancelledOrders; } console.log(`📊 从 API 获取到 ${totalOrders} 个开放订单`); if (totalCancelled > 0) { console.log(`✅ 已取消 ${totalCancelled} 个开放订单`); this.log(`已取消 ${totalCancelled} 个开放订单`, 'success'); } else { console.log('✅ 没有需要清理的订单'); this.log('没有需要清理的订单', 'info'); } await cleanupService.shutdown(); } catch (error) { this.log('⚠️ 订单清理失败,尝试手动取消', 'warning'); // 降级处理:手动取消内存中的订单 for (const [orderId, order] of this.orderLifecycle) { if (order.status === 'pending') { try { await this.cancelOrderSafely(orderId, order.symbol); } catch (error) { this.log(`取消订单失败: ${orderId}`, 'error'); } } } } // 清理生命周期记录 this.orderLifecycle.clear(); // 停止市场数据管理器 if (this.marketDataManager) { await this.marketDataManager.disconnect(); this.log('市场数据管理器已停止', 'info'); } // 停止风险管理器 if (this.riskManager) { await this.riskManager.stopMonitoring(this.sessionId); await this.riskManager.shutdown(); this.log('风险管理器已停止', 'info'); } // 保存最终统计 this.saveStats(); // 显示最终统计 this.displayFinalStats(); // 调用父类停止方法 await super.stop(); this.log('简洁版策略已停止', 'success'); } /** * 显示最终统计 */ private displayFinalStats(): void { const runtime = Math.floor((Date.now() - this.stats.startTime) / 1000); const runtimeStr = `${Math.floor(runtime / 3600)}时${Math.floor((runtime % 3600) / 60)}分${runtime % 60}秒`; console.log('\n' + '='.repeat(50)); console.log('📊 简洁版策略最终统计'); console.log('='.repeat(50)); console.log(`⏰ 总运行时间: ${runtimeStr}`); console.log(`📊 总订单数: ${this.stats.totalOrders}`); console.log(`✅ 已成交: ${this.stats.filledOrders}`); console.log(`❌ 已取消: ${this.stats.cancelledOrders}`); console.log(`📈 总交易量: ${this.stats.totalVolume.toFixed(6)} BTC`); console.log(`💰 总PNL: ${this.stats.totalPnL.toFixed(2)} USDC`); console.log(`🌐 API调用: ${this.stats.apiCallCount}`); console.log(`🔄 总重试次数: ${this.stats.totalRetries}`); console.log(`⚠️ 最大连续错误: ${this.stats.consecutiveErrors}`); if (this.stats.totalOrders > 0) { const successRate = ((this.stats.filledOrders / this.stats.totalOrders) * 100).toFixed(1); const avgVolume = (this.stats.totalVolume / this.stats.filledOrders).toFixed(6); console.log(`🎯 成交率: ${successRate}%`); console.log(`📊 平均交易量: ${avgVolume} BTC`); } console.log('='.repeat(50) + '\n'); } } async function runSimpleDeltaNeutralStrategy() { console.log('🚀 启动简洁版Delta中性刷量策略...\n'); try { // 1. 加载配置 console.log('📋 加载配置文件...'); const accountsConfig = JSON.parse(readFileSync('./config/accounts.json', 'utf-8')); const strategyConfig = JSON.parse(readFileSync('./config/trading-strategy.json', 'utf-8')); console.log(`✅ 账户配置: ${accountsConfig.length} 个账户`); console.log(`✅ 策略配置: ${strategyConfig.orderStrategy.preferredOrderType}单优先`); // 2. 初始化Pacifica客户端 console.log('\n🔗 初始化Pacifica客户端...'); const privateKey = accountsConfig[0].privateKey; const pacificaClient = new PacificaSigningClient(privateKey); console.log('✅ Pacifica客户端初始化成功'); console.log(`公钥: ${pacificaClient.getPublicKey()}`); // 3. 获取当前市场信息(带重试) console.log('\n📊 获取当前市场信息...'); let prices, marketInfo, accountInfo; let retryCount = 0; const maxRetries = 3; while (retryCount < maxRetries) { try { prices = await pacificaClient.getPrices(); marketInfo = await pacificaClient.getMarketInfo(); accountInfo = await pacificaClient.getAccountInfo(); break; } catch (error) { retryCount++; console.log(`⚠️ 获取市场信息失败 (尝试 ${retryCount}/${maxRetries})`); if (retryCount < maxRetries) { const delay = 10000 * retryCount; console.log(`等待 ${delay/1000} 秒后重试...`); await new Promise(resolve => setTimeout(resolve, delay)); } else { throw error; } } } const btcPrice = prices.data.find((p: any) => p.symbol === 'BTC'); const btcMarket = marketInfo.data.find((m: any) => m.symbol === 'BTC'); const currentPrice = parseFloat(btcPrice.mark); const accountBalance = parseFloat(accountInfo.data.balance); const minOrderSize = parseFloat(btcMarket.min_order_size); const lotSize = parseFloat(btcMarket.lot_size); console.log('✅ 市场信息获取成功'); console.log(`BTC当前价格: ${currentPrice}`); console.log(`账户余额: ${accountBalance} USDC`); console.log(`最小订单大小: ${minOrderSize} USDC`); // 4. 计算仓位大小(基于配置) console.log('\n💰 计算仓位大小...'); const minOrderValue = Math.max(minOrderSize, strategyConfig.positions.minOrderValue); const availableBalance = accountBalance * strategyConfig.positions.balanceUsageRatio; // 基础仓位 const basePositionValue = Math.max( availableBalance * strategyConfig.positions.basePositionRatio, minOrderValue * 1.05 ); const basePositionSize = basePositionValue / currentPrice; const adjustedBaseSize = Math.ceil(basePositionSize / lotSize) * lotSize; // 刷量仓位 const volumePositionValue = Math.max( availableBalance * strategyConfig.positions.volumePositionRatio, minOrderValue ); const volumePositionSize = volumePositionValue / currentPrice; const adjustedVolumeSize = Math.ceil(volumePositionSize / lotSize) * lotSize; console.log(`可用余额: ${availableBalance.toFixed(2)} USDC (${(strategyConfig.positions.balanceUsageRatio * 100).toFixed(0)}%)`); console.log(`基础仓位: ${adjustedBaseSize.toFixed(8)} BTC (${(adjustedBaseSize * currentPrice).toFixed(2)} USDC)`); console.log(`刷量仓位: ${adjustedVolumeSize.toFixed(8)} BTC (${(adjustedVolumeSize * currentPrice).toFixed(2)} USDC)`); // 5. 构建策略配置(从配置文件) console.log('\n⚙️ 构建策略配置...'); const configManager = new DeltaNeutralConfigManager(); const simpleConfig: DeltaNeutralConfig = { // 基础仓位配置 basePositionRatio: strategyConfig.positions.basePositionRatio, basePositionSize: adjustedBaseSize, // 刷量仓位配置 volumePositionRatio: strategyConfig.positions.volumePositionRatio, maxVolumePositionSize: adjustedVolumeSize, // Delta中性配置 maxDeltaDeviation: strategyConfig.deltaRebalancing.maxDeltaDeviation, rebalanceThreshold: strategyConfig.deltaRebalancing.rebalanceThreshold, // 交易配置 - 限价单优先(降低手续费) preferredOrderType: strategyConfig.orderStrategy.preferredOrderType as 'limit' | 'market', limitOrderSpread: strategyConfig.orderStrategy.limitOrderSpread, emergencyMarketThreshold: strategyConfig.orderStrategy.emergencyMarketThreshold, // 风险控制 maxDrawdown: strategyConfig.risk.maxDrawdown, maxPositionSize: adjustedBaseSize * strategyConfig.risk.positionSizeMultiplier, stopLossThreshold: strategyConfig.risk.stopLossThreshold }; configManager.updateConfig(simpleConfig); console.log('✅ 策略配置完成'); console.log(`订单类型: ${simpleConfig.preferredOrderType}单优先`); console.log(`价差: ${(simpleConfig.limitOrderSpread * 100).toFixed(3)}%`); console.log(`Delta偏差限制: ${(simpleConfig.maxDeltaDeviation * 100).toFixed(1)}%`); console.log(`最大回撤: ${(simpleConfig.maxDrawdown * 100).toFixed(1)}%`); // 6. 创建账户对象 const accounts: Account[] = accountsConfig.map((acc: any) => new Account({ id: acc.id, name: acc.name, privateKey: acc.privateKey, apiKey: acc.apiKey || 'not_required', address: acc.address, isActive: acc.isActive !== false, balance: { total: accountBalance, available: availableBalance, used: 0 }, positions: [] })); // 7. 创建简洁版策略实例 console.log('\n🎯 创建简洁版策略实例...'); const strategy = new SimpleDeltaNeutralStrategy( simpleConfig, pacificaClient, accounts ); console.log('✅ 简洁版策略创建成功'); // 8. 清理历史订单(策略启动前) console.log('\n🧹 清理历史开放订单...'); try { const cleanupService = new OrderCleanupService(); // 为每个账户初始化清理服务 for (const account of accounts) { cleanupService.initializeAccount(account); } // 清理选项:清理所有非 reduce_only 订单 const cleanupOptions: CleanupOptions = { cleanAll: true, includeReduceOnly: false, // 保留保护性订单 mode: 'selective', dryRun: false }; console.log('正在从 Pacifica API 获取开放订单...'); const results = await cleanupService.cleanupMultipleAccounts( accounts, cleanupOptions ); // 汇总清理结果 let totalOrders = 0; let totalCancelled = 0; let totalFailed = 0; for (const [accountId, result] of results.entries()) { totalOrders += result.totalOrders; totalCancelled += result.cancelledOrders; totalFailed += result.failedOrders; if (result.totalOrders > 0) { console.log(` 账户 ${accountId.slice(0, 8)}: ${result.totalOrders} 个订单, 已取消 ${result.cancelledOrders}, 失败 ${result.failedOrders}`); } } if (totalOrders > 0) { console.log(`✅ 历史订单清理完成: ${totalCancelled}/${totalOrders} 个订单已取消`); if (totalFailed > 0) { console.log(`⚠️ ${totalFailed} 个订单取消失败`); } } else { console.log('✅ 没有历史开放订单需要清理'); } await cleanupService.shutdown(); } catch (error) { console.log('⚠️ 历史订单清理失败,继续启动策略'); console.log(`错误: ${error instanceof Error ? error.message : '未知错误'}`); } // 9. 显示策略信息 console.log('\n📋 简洁版策略特点:'); console.log('• 超保守参数 - 2%基础仓位 + 5%刷量仓位'); console.log('• 严格风险控制 - 1%最大回撤,0.1%Delta偏差'); console.log('• 智能重试机制 - 自动重试失败的API调用'); console.log('• 智能错误恢复 - 连续错误自动暂停和恢复'); console.log('• 健康检查系统 - 5分钟间隔健康监控'); console.log('• 统计信息持久化 - 10分钟间隔保存统计'); console.log('• 完整的生命周期管理 - 订单自动跟踪和清理'); console.log('• 自动订单清理 - 启动前/停止后自动清理'); console.log('• API频率控制 - 2秒间隔,避免限制'); console.log('• 简洁日志输出 - 只显示关键信息'); console.log('\n🔄 开始执行简洁版策略...'); // 9. 初始化策略 await strategy.initialize(); console.log('✅ 策略初始化完成'); // 10. 启动策略 console.log('\n📊 简洁版策略已启动,开始简洁运行...'); console.log('按 Ctrl+C 停止策略'); // 11. 优雅关闭处理 process.on('SIGINT', async () => { console.log('\n🛑 收到停止信号,正在优雅关闭策略...'); try { await strategy.stop(); console.log('✅ 策略已安全停止'); process.exit(0); } catch (error) { console.error('❌ 停止策略时发生错误:', error); process.exit(1); } }); // 12. 错误处理 process.on('uncaughtException', async (error) => { console.error('❌ 未捕获的异常:', error); try { await strategy.stop(); } catch (stopError) { console.error('❌ 停止策略时发生错误:', stopError); } process.exit(1); }); process.on('unhandledRejection', async (reason) => { console.error('❌ 未处理的Promise拒绝:', reason); try { await strategy.stop(); } catch (stopError) { console.error('❌ 停止策略时发生错误:', stopError); } process.exit(1); }); console.log('\n🎉 简洁版Delta中性刷量策略已启动!'); console.log('策略将持续简洁运行,自动处理API错误和网络问题...'); } catch (error) { console.error('❌ 策略启动失败:', error); process.exit(1); } } // 运行策略 runSimpleDeltaNeutralStrategy().catch(console.error);