|
@@ -1,1438 +0,0 @@
|
|
|
-#!/usr/bin/env tsx
|
|
|
-
|
|
|
-/**
|
|
|
- * 完整的多平台加密货币交易系统
|
|
|
- * 集成实时数据、多账户管理、同平台对冲、风险控制
|
|
|
- */
|
|
|
-
|
|
|
-import { EventEmitter } from 'events'
|
|
|
-import { Config, SmartAccountDiscovery } from './config/simpleEnv.js'
|
|
|
-import { PacificaProxyClient } from './exchanges/pacifica/PacificaProxyClient.js'
|
|
|
-import { SamePlatformHedgingManager } from './core/hedging/SamePlatformHedgingManager.js'
|
|
|
-import { StateManager, SystemState } from './utils/StateManager.js'
|
|
|
-import { logger } from './utils/logger.js'
|
|
|
-
|
|
|
-interface SystemStatus {
|
|
|
- accounts: number
|
|
|
- activeConnections: number
|
|
|
- totalTrades: number
|
|
|
- totalVolume: string
|
|
|
- uptime: number
|
|
|
- lastUpdate: number
|
|
|
-}
|
|
|
-
|
|
|
-interface TradingSignal {
|
|
|
- symbol: string
|
|
|
- action: 'buy' | 'sell' | 'hedge' | 'volume_boost' | 'close_position' | 'balance_accounts'
|
|
|
- amount: string
|
|
|
- price?: string
|
|
|
- confidence: number
|
|
|
- reason: string
|
|
|
- reduceOnly?: boolean
|
|
|
- targetAccount?: string
|
|
|
-}
|
|
|
-
|
|
|
-class CompleteTradingSystem extends EventEmitter {
|
|
|
- private startTime: number = Date.now()
|
|
|
- private accounts: any[] = []
|
|
|
- private clients: Map<string, PacificaProxyClient> = new Map()
|
|
|
- private hedgeManager: SamePlatformHedgingManager | null = null
|
|
|
- private stateManager: StateManager
|
|
|
- private isRunning: boolean = false
|
|
|
- private isShuttingDown: boolean = false
|
|
|
- private stats = {
|
|
|
- totalTrades: 0,
|
|
|
- totalVolume: 0,
|
|
|
- successfulTrades: 0,
|
|
|
- failedTrades: 0,
|
|
|
- lastTradeTime: 0
|
|
|
- }
|
|
|
-
|
|
|
- // 账户状态跟踪
|
|
|
- private accountStates = new Map<string, {
|
|
|
- totalTrades: number
|
|
|
- netPosition: number // 净仓位 (正数=多头,负数=空头)
|
|
|
- totalVolume: number
|
|
|
- lastBalance: number
|
|
|
- needsRebalance: boolean
|
|
|
- }>()
|
|
|
-
|
|
|
- // 风险控制参数
|
|
|
- private riskLimits = {
|
|
|
- maxPositionSize: 0.01, // 单个仓位最大0.01 BTC
|
|
|
- maxTotalExposure: 0.05, // 总敞口不超过0.05 BTC
|
|
|
- maxAccountBalance: 10000, // 账户余额上限$10000
|
|
|
- minAccountBalance: 100, // 账户余额下限$100
|
|
|
- maxDailyTrades: 50, // 每日最多50笔交易
|
|
|
- maxSlippage: 0.05, // 最大5%滑点
|
|
|
- emergencyStopLoss: 0.1, // 10%紧急止损
|
|
|
- enabled: true
|
|
|
- }
|
|
|
-
|
|
|
- constructor() {
|
|
|
- super()
|
|
|
- this.stateManager = new StateManager()
|
|
|
- this.setupEventHandlers()
|
|
|
- this.setupGracefulShutdown()
|
|
|
- }
|
|
|
-
|
|
|
- private setupEventHandlers() {
|
|
|
- // 系统事件处理
|
|
|
- this.on('trade_signal', this.handleTradingSignal.bind(this))
|
|
|
- this.on('risk_alert', this.handleRiskAlert.bind(this))
|
|
|
- this.on('system_error', this.handleSystemError.bind(this))
|
|
|
- }
|
|
|
-
|
|
|
- private setupGracefulShutdown() {
|
|
|
- // 优雅关闭处理
|
|
|
- process.on('SIGINT', async () => {
|
|
|
- logger.info('接收到SIGINT信号,准备优雅关闭...')
|
|
|
- await this.gracefulShutdown()
|
|
|
- process.exit(0)
|
|
|
- })
|
|
|
-
|
|
|
- process.on('SIGTERM', async () => {
|
|
|
- logger.info('接收到SIGTERM信号,准备优雅关闭...')
|
|
|
- await this.gracefulShutdown()
|
|
|
- process.exit(0)
|
|
|
- })
|
|
|
-
|
|
|
- // 异常处理
|
|
|
- process.on('uncaughtException', async (error) => {
|
|
|
- logger.error('未捕获异常,准备紧急关闭', { error: error.message })
|
|
|
- await this.emergencyShutdown()
|
|
|
- process.exit(1)
|
|
|
- })
|
|
|
-
|
|
|
- process.on('unhandledRejection', async (reason, promise) => {
|
|
|
- logger.error('未处理的Promise拒绝', { reason, promise })
|
|
|
- await this.emergencyShutdown()
|
|
|
- process.exit(1)
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 启动完整交易系统
|
|
|
- */
|
|
|
- async start(): Promise<void> {
|
|
|
- console.log('🚀 启动完整交易系统')
|
|
|
- console.log('=' .repeat(60))
|
|
|
-
|
|
|
- try {
|
|
|
- // 0. 恢复系统状态
|
|
|
- await this.restoreSystemState()
|
|
|
-
|
|
|
- // 1. 系统初始化
|
|
|
- await this.initialize()
|
|
|
-
|
|
|
- // 2. 启动核心服务
|
|
|
- await this.startCoreServices()
|
|
|
-
|
|
|
- // 3. 开始交易循环
|
|
|
- this.startTradingLoop()
|
|
|
-
|
|
|
- // 4. 启动监控面板
|
|
|
- this.startDashboard()
|
|
|
-
|
|
|
- // 5. 定期保存状态
|
|
|
- this.startStateAutoSave()
|
|
|
-
|
|
|
- this.isRunning = true
|
|
|
- logger.info('✅ 交易系统已完全启动')
|
|
|
-
|
|
|
- } catch (error: any) {
|
|
|
- logger.error('❌ 系统启动失败', { error: error.message })
|
|
|
- throw error
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 系统初始化
|
|
|
- */
|
|
|
- private async initialize(): Promise<void> {
|
|
|
- console.log('\n📋 第一步: 系统初始化')
|
|
|
-
|
|
|
- // 检查代理配置
|
|
|
- const proxyStatus = Config.proxy.isAnyConfigured()
|
|
|
- console.log(`代理状态: ${proxyStatus ? '✅ 启用' : '❌ 禁用'}`)
|
|
|
- logger.info('代理配置检查完成', { enabled: proxyStatus })
|
|
|
-
|
|
|
- // 发现账户
|
|
|
- this.accounts = SmartAccountDiscovery.discoverPacifica()
|
|
|
- console.log(`发现 ${this.accounts.length} 个Pacifica账户`)
|
|
|
-
|
|
|
- if (this.accounts.length === 0) {
|
|
|
- throw new Error('未发现可用账户,请检查环境变量配置')
|
|
|
- }
|
|
|
-
|
|
|
- // 创建客户端连接
|
|
|
- for (let i = 0; i < this.accounts.length; i++) {
|
|
|
- const account = this.accounts[i]
|
|
|
- const clientId = `pacifica-${i + 1}`
|
|
|
-
|
|
|
- const client = new PacificaProxyClient({
|
|
|
- account: account.account,
|
|
|
- privateKey: account.privateKey
|
|
|
- })
|
|
|
-
|
|
|
- this.clients.set(clientId, client)
|
|
|
- console.log(`✅ 创建客户端: ${clientId} (${account.account.substring(0, 8)}...)`)
|
|
|
- }
|
|
|
-
|
|
|
- // 测试连接
|
|
|
- console.log('\n🔌 测试连接...')
|
|
|
- for (const [clientId, client] of this.clients) {
|
|
|
- try {
|
|
|
- const result = await client.testConnection()
|
|
|
- if (result.success) {
|
|
|
- console.log(`✅ ${clientId}: 连接成功 (${result.latency}ms)`)
|
|
|
- } else {
|
|
|
- console.log(`❌ ${clientId}: 连接失败 - ${result.error}`)
|
|
|
- }
|
|
|
- } catch (error: any) {
|
|
|
- console.log(`❌ ${clientId}: 连接异常 - ${error.message}`)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 启动核心服务
|
|
|
- */
|
|
|
- private async startCoreServices(): Promise<void> {
|
|
|
- console.log('\n⚡ 第二步: 启动核心服务')
|
|
|
-
|
|
|
- // 创建对冲管理器
|
|
|
- if (this.accounts.length >= 2) {
|
|
|
- console.log('创建同平台对冲管理器...')
|
|
|
- this.hedgeManager = new SamePlatformHedgingManager('pacifica', this.riskLimits)
|
|
|
-
|
|
|
- // 添加账户
|
|
|
- for (let i = 0; i < Math.min(this.accounts.length, 4); i++) {
|
|
|
- const account = this.accounts[i]
|
|
|
- const accountId = `pacifica-${i + 1}`
|
|
|
-
|
|
|
- this.hedgeManager.addAccount(accountId, {
|
|
|
- account: account.account,
|
|
|
- privateKey: account.privateKey
|
|
|
- })
|
|
|
-
|
|
|
- console.log(`✅ 添加对冲账户: ${accountId}`)
|
|
|
- }
|
|
|
-
|
|
|
- // 创建对冲对
|
|
|
- if (this.accounts.length >= 2) {
|
|
|
- this.hedgeManager.createHedgePair(
|
|
|
- 'btc-usd-hedge',
|
|
|
- 'pacifica-1',
|
|
|
- 'pacifica-2',
|
|
|
- 'BTC-USD',
|
|
|
- 1.0
|
|
|
- )
|
|
|
- console.log('✅ 创建BTC-USD对冲对')
|
|
|
- }
|
|
|
-
|
|
|
- // 获取对冲状态
|
|
|
- const hedgeStatus = this.hedgeManager.getHedgePairStatuses()
|
|
|
- console.log(`✅ 对冲系统就绪,${hedgeStatus.length} 个对冲对激活`)
|
|
|
- } else {
|
|
|
- console.log('⚠️ 账户数量不足,跳过对冲功能 (需要至少2个账户)')
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 开始交易循环
|
|
|
- */
|
|
|
- private startTradingLoop(): void {
|
|
|
- console.log('\n🔄 第三步: 启动交易引擎')
|
|
|
-
|
|
|
- // 刷量交易信号生成器 - 频繁交易增加交易量
|
|
|
- setInterval(() => {
|
|
|
- this.generateTradingSignals()
|
|
|
- }, 15000) // 每15秒执行一次
|
|
|
-
|
|
|
- // 额外的高频刷量
|
|
|
- setInterval(() => {
|
|
|
- this.generateVolumeBoostSignals()
|
|
|
- }, 8000) // 每8秒执行一次小额对冲交易
|
|
|
-
|
|
|
- // 定期健康检查
|
|
|
- setInterval(() => {
|
|
|
- this.performHealthCheck()
|
|
|
- }, 60000) // 每分钟检查一次
|
|
|
-
|
|
|
- // 定期风险检查
|
|
|
- setInterval(() => {
|
|
|
- this.performRiskCheck()
|
|
|
- }, 15000) // 每15秒检查一次
|
|
|
-
|
|
|
- console.log('✅ 交易引擎已启动')
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 启动实时监控面板
|
|
|
- */
|
|
|
- private startDashboard(): void {
|
|
|
- console.log('\n📊 第四步: 启动监控面板')
|
|
|
-
|
|
|
- // 每3秒更新一次状态 - 更频繁的刷新显示实时交易
|
|
|
- setInterval(() => {
|
|
|
- this.displayDashboard()
|
|
|
- }, 3000)
|
|
|
-
|
|
|
- console.log('✅ 监控面板已启动')
|
|
|
-
|
|
|
- // 立即显示一次
|
|
|
- setTimeout(() => this.displayDashboard(), 1000)
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 生成交易信号 - 智能刷量逻辑(开仓+平仓+资金平衡)
|
|
|
- */
|
|
|
- private generateTradingSignals(): void {
|
|
|
- const signals: TradingSignal[] = []
|
|
|
- const randomFactor = Math.random()
|
|
|
-
|
|
|
- // 初始化账户状态
|
|
|
- this.initializeAccountStates()
|
|
|
-
|
|
|
- // 检查是否需要资金平衡
|
|
|
- const needsBalancing = this.checkAccountBalance()
|
|
|
- if (needsBalancing) {
|
|
|
- const balanceSignal = this.generateBalanceSignal()
|
|
|
- if (balanceSignal) {
|
|
|
- signals.push(balanceSignal)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 80%概率生成刷量信号
|
|
|
- if (randomFactor > 0.2) {
|
|
|
- // 决定是开仓还是平仓
|
|
|
- const shouldClosePosition = this.shouldCloseExistingPositions()
|
|
|
-
|
|
|
- if (shouldClosePosition) {
|
|
|
- // 生成平仓信号
|
|
|
- const closeSignal = this.generateCloseSignal()
|
|
|
- if (closeSignal) {
|
|
|
- signals.push(closeSignal)
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 生成开仓信号
|
|
|
- const action = randomFactor > 0.6 ? 'buy' : 'sell'
|
|
|
- const amount = this.calculateTradingAmount()
|
|
|
-
|
|
|
- signals.push({
|
|
|
- symbol: 'BTC-USD',
|
|
|
- action,
|
|
|
- amount,
|
|
|
- confidence: randomFactor,
|
|
|
- reason: `刷量开仓 - ${action === 'buy' ? '买入建仓' : '卖出建仓'}`
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 对冲信号 - 但要考虑是否需要反向操作来平衡
|
|
|
- if (this.hedgeManager && this.accounts.length >= 2 && randomFactor > 0.5) {
|
|
|
- const hedgeSignal = this.generateSmartHedgeSignal()
|
|
|
- if (hedgeSignal) {
|
|
|
- signals.push(hedgeSignal)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 发送信号
|
|
|
- signals.forEach(signal => {
|
|
|
- this.emit('trade_signal', signal)
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 生成额外的刷量信号 - 专门用于增加交易量
|
|
|
- */
|
|
|
- private generateVolumeBoostSignals(): void {
|
|
|
- // 检查是否可以进行高频刷量
|
|
|
- if (!this.shouldTrade()) {
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- const signals: TradingSignal[] = []
|
|
|
-
|
|
|
- // 高频对冲刷量:双向同时开仓再平仓,增加交易量但保持净仓位不变
|
|
|
- if (this.hedgeManager && this.accounts.length >= 2) {
|
|
|
- const boostAmount = '0.0005' // 更小的金额用于高频刷量
|
|
|
-
|
|
|
- // 60%概率执行对冲刷量
|
|
|
- if (Math.random() > 0.4) {
|
|
|
- signals.push({
|
|
|
- symbol: 'BTC-USD',
|
|
|
- action: 'volume_boost',
|
|
|
- amount: boostAmount,
|
|
|
- confidence: 0.9,
|
|
|
- reason: '高频刷量 - 增加交易量'
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 发送信号
|
|
|
- signals.forEach(signal => {
|
|
|
- this.emit('trade_signal', signal)
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 计算交易数量 - 根据风险和流动性动态调整
|
|
|
- */
|
|
|
- private calculateTradingAmount(): string {
|
|
|
- const baseAmount = 0.0003 // 降低基础交易量适配小余额账户
|
|
|
- const randomMultiplier = 0.5 + Math.random() * 1.0 // 0.5x - 1.5x
|
|
|
- const amount = baseAmount * randomMultiplier
|
|
|
- return Math.max(0.0002, Math.min(0.001, amount)).toFixed(4)
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 计算对冲数量
|
|
|
- */
|
|
|
- private calculateHedgeAmount(): string {
|
|
|
- const baseAmount = 0.0003 // 降低对冲基础数量
|
|
|
- const randomMultiplier = 0.8 + Math.random() * 0.4 // 0.8x - 1.2x
|
|
|
- const amount = baseAmount * randomMultiplier
|
|
|
- return Math.max(0.0002, Math.min(0.0008, amount)).toFixed(4)
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理交易信号
|
|
|
- */
|
|
|
- private async handleTradingSignal(signal: TradingSignal): Promise<void> {
|
|
|
- logger.info('收到交易信号', { signal })
|
|
|
-
|
|
|
- // 检查是否在安静时间
|
|
|
- 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' && this.hedgeManager) {
|
|
|
- await this.executeBalanceSignal(signal)
|
|
|
- } else if (signal.action === 'close_position') {
|
|
|
- await this.executeCloseSignal(signal)
|
|
|
- } else {
|
|
|
- await this.executeTradeSignal(signal)
|
|
|
- }
|
|
|
- } catch (error: any) {
|
|
|
- logger.error('交易信号处理失败', { signal, error: error.message })
|
|
|
- this.emit('system_error', { type: 'trade_execution', error, signal })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 初始化账户状态
|
|
|
- */
|
|
|
- private initializeAccountStates(): void {
|
|
|
- this.accounts.forEach((account, index) => {
|
|
|
- const accountId = `pacifica-${index + 1}`
|
|
|
- if (!this.accountStates.has(accountId)) {
|
|
|
- this.accountStates.set(accountId, {
|
|
|
- totalTrades: 0,
|
|
|
- netPosition: 0,
|
|
|
- totalVolume: 0,
|
|
|
- lastBalance: 0,
|
|
|
- needsRebalance: false
|
|
|
- })
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 检查账户是否需要资金平衡
|
|
|
- */
|
|
|
- private checkAccountBalance(): boolean {
|
|
|
- const accounts = Array.from(this.accountStates.values())
|
|
|
- if (accounts.length < 2) return false
|
|
|
-
|
|
|
- // 检查净仓位差异
|
|
|
- const positions = accounts.map(a => Math.abs(a.netPosition))
|
|
|
- const maxPosition = Math.max(...positions)
|
|
|
- const minPosition = Math.min(...positions)
|
|
|
-
|
|
|
- // 如果仓位差异超过阈值,需要平衡
|
|
|
- return (maxPosition - minPosition) > 0.003 // 超过0.003 BTC差异
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 生成资金平衡信号
|
|
|
- */
|
|
|
- private generateBalanceSignal(): TradingSignal | null {
|
|
|
- const accountsArray = Array.from(this.accountStates.entries())
|
|
|
- if (accountsArray.length < 2) return null
|
|
|
-
|
|
|
- // 找到需要平衡的账户对
|
|
|
- const [account1Id, account1State] = accountsArray[0]
|
|
|
- const [account2Id, account2State] = accountsArray[1]
|
|
|
-
|
|
|
- const positionDiff = account1State.netPosition - account2State.netPosition
|
|
|
-
|
|
|
- if (Math.abs(positionDiff) > 0.003) {
|
|
|
- const amount = (Math.abs(positionDiff) / 2).toFixed(4)
|
|
|
-
|
|
|
- return {
|
|
|
- symbol: 'BTC-USD',
|
|
|
- action: 'balance_accounts',
|
|
|
- amount,
|
|
|
- confidence: 0.95,
|
|
|
- reason: `资金平衡 - 调整账户仓位差异`,
|
|
|
- targetAccount: positionDiff > 0 ? account1Id : account2Id,
|
|
|
- reduceOnly: true
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return null
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 判断是否应该平仓
|
|
|
- */
|
|
|
- private shouldCloseExistingPositions(): boolean {
|
|
|
- // 30%概率选择平仓而非开仓
|
|
|
- if (Math.random() > 0.7) {
|
|
|
- // 检查是否有足够的仓位可以平
|
|
|
- const totalNetPosition = Array.from(this.accountStates.values())
|
|
|
- .reduce((sum, account) => sum + Math.abs(account.netPosition), 0)
|
|
|
-
|
|
|
- return totalNetPosition > 0.002 // 有超过0.002 BTC的仓位可以平
|
|
|
- }
|
|
|
-
|
|
|
- return false
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 生成平仓信号
|
|
|
- */
|
|
|
- private generateCloseSignal(): TradingSignal | null {
|
|
|
- // 找到净仓位最大的账户进行部分平仓
|
|
|
- const accountsArray = Array.from(this.accountStates.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.001) {
|
|
|
- const closeAmount = (Math.abs(accountState.netPosition) * 0.3).toFixed(4) // 平掉30%的仓位
|
|
|
- const action = accountState.netPosition > 0 ? 'sell' : 'buy' // 反向操作平仓
|
|
|
-
|
|
|
- return {
|
|
|
- symbol: 'BTC-USD',
|
|
|
- action: action as 'buy' | 'sell',
|
|
|
- amount: closeAmount,
|
|
|
- confidence: 0.9,
|
|
|
- reason: `平仓操作 - 减少${accountState.netPosition > 0 ? '多头' : '空头'}仓位`,
|
|
|
- reduceOnly: true,
|
|
|
- targetAccount: accountId
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return null
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 生成智能对冲信号 - 考虑资金平衡
|
|
|
- */
|
|
|
- private generateSmartHedgeSignal(): TradingSignal | null {
|
|
|
- if (!this.hedgeManager || this.accounts.length < 2) return null
|
|
|
-
|
|
|
- // 检查两个账户的仓位状态
|
|
|
- const accountsArray = Array.from(this.accountStates.entries())
|
|
|
- const account1State = accountsArray[0]?.[1]
|
|
|
- const account2State = accountsArray[1]?.[1]
|
|
|
-
|
|
|
- if (!account1State || !account2State) return null
|
|
|
-
|
|
|
- // 如果两个账户仓位相差太大,执行平衡对冲
|
|
|
- const positionDiff = Math.abs(account1State.netPosition - account2State.netPosition)
|
|
|
-
|
|
|
- if (positionDiff > 0.002) {
|
|
|
- // 执行平衡式对冲:让仓位少的账户开仓,仓位多的账户平仓
|
|
|
- const amount = Math.min(0.002, positionDiff / 2).toFixed(4)
|
|
|
-
|
|
|
- return {
|
|
|
- symbol: 'BTC-USD',
|
|
|
- action: 'hedge',
|
|
|
- amount,
|
|
|
- confidence: 0.85,
|
|
|
- reason: '平衡对冲 - 重新平衡两账户仓位'
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 常规对冲
|
|
|
- return {
|
|
|
- symbol: 'BTC-USD',
|
|
|
- action: 'hedge',
|
|
|
- amount: this.calculateHedgeAmount(),
|
|
|
- confidence: 0.85,
|
|
|
- reason: '常规对冲刷量'
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 执行资金平衡信号
|
|
|
- */
|
|
|
- private async executeBalanceSignal(signal: TradingSignal): Promise<void> {
|
|
|
- if (!this.hedgeManager || !signal.targetAccount) return
|
|
|
-
|
|
|
- console.log(`🔄 执行资金平衡: ${signal.reason}`)
|
|
|
-
|
|
|
- // 执行平衡交易逻辑
|
|
|
- const balanceOrders = this.generateBalanceOrders(signal)
|
|
|
- const results = await this.hedgeManager.executeBatchHedge(balanceOrders)
|
|
|
-
|
|
|
- let successCount = 0
|
|
|
- results.forEach((result, index) => {
|
|
|
- if (result.success) {
|
|
|
- successCount++
|
|
|
- console.log(`✅ 平衡订单${index + 1}成功: ${result.orderId || 'N/A'}`)
|
|
|
- } else {
|
|
|
- console.log(`❌ 平衡订单${index + 1}失败: ${result.error}`)
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- this.stats.totalTrades += results.length
|
|
|
- this.stats.successfulTrades += successCount
|
|
|
- this.stats.failedTrades += (results.length - successCount)
|
|
|
-
|
|
|
- console.log(`⚖️ 资金平衡完成: ${successCount}/${results.length} 成功`)
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 执行平仓信号
|
|
|
- */
|
|
|
- private async executeCloseSignal(signal: TradingSignal): Promise<void> {
|
|
|
- const clientId = signal.targetAccount || 'pacifica-1'
|
|
|
- const client = this.clients.get(clientId)
|
|
|
-
|
|
|
- if (!client) {
|
|
|
- throw new Error(`客户端 ${clientId} 不可用`)
|
|
|
- }
|
|
|
-
|
|
|
- const side = signal.action === 'buy' ? 'bid' : 'ask'
|
|
|
-
|
|
|
- console.log(`📉 执行平仓订单: ${signal.reason}`)
|
|
|
-
|
|
|
- const result = await client.createMarketOrder({
|
|
|
- account: this.accounts[0].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.updateAccountState(clientId, { side, amount: signal.amount, success: true })
|
|
|
- } else {
|
|
|
- this.stats.failedTrades++
|
|
|
- throw new Error(`平仓失败: ${result.error}`)
|
|
|
- }
|
|
|
-
|
|
|
- this.stats.totalTrades++
|
|
|
- this.stats.lastTradeTime = Date.now()
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 生成平衡订单
|
|
|
- */
|
|
|
- private generateBalanceOrders(signal: TradingSignal): any[] {
|
|
|
- const amount = parseFloat(signal.amount) / 2
|
|
|
-
|
|
|
- return [
|
|
|
- {
|
|
|
- accountId: 'pacifica-1',
|
|
|
- symbol: 'BTC-USD',
|
|
|
- amount,
|
|
|
- side: 'bid' as const,
|
|
|
- orderType: 'market' as const,
|
|
|
- reason: '平衡-账户1'
|
|
|
- },
|
|
|
- {
|
|
|
- accountId: 'pacifica-2',
|
|
|
- symbol: 'BTC-USD',
|
|
|
- amount,
|
|
|
- side: 'ask' as const,
|
|
|
- orderType: 'market' as const,
|
|
|
- reason: '平衡-账户2'
|
|
|
- }
|
|
|
- ]
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 更新账户状态
|
|
|
- */
|
|
|
- private updateAccountState(accountId: string, trade: { side: string; amount: string; success: boolean }): void {
|
|
|
- const state = this.accountStates.get(accountId)
|
|
|
- if (!state) return
|
|
|
-
|
|
|
- state.totalTrades++
|
|
|
-
|
|
|
- if (trade.success) {
|
|
|
- const amount = parseFloat(trade.amount)
|
|
|
- state.totalVolume += amount
|
|
|
-
|
|
|
- // 更新净仓位
|
|
|
- if (trade.side === 'bid') {
|
|
|
- state.netPosition += amount // 买入增加多头仓位
|
|
|
- } else if (trade.side === 'ask') {
|
|
|
- state.netPosition -= amount // 卖出增加空头仓位(或减少多头)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- this.accountStates.set(accountId, state)
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 执行对冲信号
|
|
|
- */
|
|
|
- private async executeHedgeSignal(signal: TradingSignal): Promise<void> {
|
|
|
- if (!this.hedgeManager) return
|
|
|
-
|
|
|
- const batchOrders = [
|
|
|
- {
|
|
|
- accountId: 'pacifica-1',
|
|
|
- symbol: 'BTC-USD',
|
|
|
- amount: parseFloat(signal.amount),
|
|
|
- side: 'bid' as const,
|
|
|
- orderType: 'market' as const
|
|
|
- },
|
|
|
- {
|
|
|
- accountId: 'pacifica-2',
|
|
|
- symbol: 'BTC-USD',
|
|
|
- amount: parseFloat(signal.amount),
|
|
|
- side: 'ask' as const,
|
|
|
- orderType: 'market' as const
|
|
|
- }
|
|
|
- ]
|
|
|
-
|
|
|
- logger.info('执行对冲订单', { orders: batchOrders.length })
|
|
|
-
|
|
|
- const results = await this.hedgeManager.executeBatchHedge(batchOrders)
|
|
|
-
|
|
|
- let successCount = 0
|
|
|
- results.forEach((result, index) => {
|
|
|
- if (result.success) {
|
|
|
- successCount++
|
|
|
- this.stats.successfulTrades++
|
|
|
- logger.info(`对冲订单${index + 1}成功`, { orderId: result.orderId })
|
|
|
- } else {
|
|
|
- this.stats.failedTrades++
|
|
|
- logger.error(`对冲订单${index + 1}失败`, { error: result.error })
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- this.stats.totalTrades += results.length
|
|
|
- this.stats.lastTradeTime = Date.now()
|
|
|
-
|
|
|
- console.log(`🔄 对冲执行完成: ${successCount}/${results.length} 成功`)
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 执行刷量信号 - 高频小额对冲交易
|
|
|
- */
|
|
|
- private async executeVolumeBoost(signal: TradingSignal): Promise<void> {
|
|
|
- if (!this.hedgeManager || this.accounts.length < 2) return
|
|
|
-
|
|
|
- // 生成高频刷量序列:快速开仓再平仓,增加交易量但保持净仓位接近零
|
|
|
- const boostSequence = [
|
|
|
- // 第一步:双向开仓
|
|
|
- {
|
|
|
- accountId: 'pacifica-1',
|
|
|
- symbol: 'BTC-USD',
|
|
|
- amount: parseFloat(signal.amount),
|
|
|
- side: 'bid' as const, // 买入
|
|
|
- orderType: 'market' as const,
|
|
|
- reason: '刷量开仓-多头'
|
|
|
- },
|
|
|
- {
|
|
|
- accountId: 'pacifica-2',
|
|
|
- symbol: 'BTC-USD',
|
|
|
- amount: parseFloat(signal.amount),
|
|
|
- side: 'ask' as const, // 卖出
|
|
|
- orderType: 'market' as const,
|
|
|
- reason: '刷量开仓-空头'
|
|
|
- }
|
|
|
- ]
|
|
|
-
|
|
|
- logger.info('执行高频刷量序列', {
|
|
|
- orders: boostSequence.length,
|
|
|
- amount: signal.amount,
|
|
|
- reason: signal.reason
|
|
|
- })
|
|
|
-
|
|
|
- const results = await this.hedgeManager.executeBatchHedge(boostSequence)
|
|
|
-
|
|
|
- let successCount = 0
|
|
|
- results.forEach((result, index) => {
|
|
|
- if (result.success) {
|
|
|
- successCount++
|
|
|
- console.log(`✅ 刷量订单${index + 1}成功: ${result.orderId || 'N/A'}`)
|
|
|
- this.stats.totalVolume += parseFloat(signal.amount)
|
|
|
- } 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(signal.amount) * successCount).toFixed(4)} BTC`)
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 执行单个交易信号
|
|
|
- */
|
|
|
- private async executeTradeSignal(signal: TradingSignal): Promise<void> {
|
|
|
- // 选择最佳客户端
|
|
|
- const clientId = 'pacifica-1' // 简化选择逻辑
|
|
|
- const client = this.clients.get(clientId)
|
|
|
-
|
|
|
- if (!client) {
|
|
|
- throw new Error(`客户端 ${clientId} 不可用`)
|
|
|
- }
|
|
|
-
|
|
|
- const side = signal.action === 'buy' ? 'bid' : 'ask'
|
|
|
-
|
|
|
- logger.info('执行交易订单', {
|
|
|
- clientId,
|
|
|
- symbol: signal.symbol,
|
|
|
- side,
|
|
|
- amount: signal.amount
|
|
|
- })
|
|
|
-
|
|
|
- const result = await client.createMarketOrder({
|
|
|
- account: this.accounts[0].account,
|
|
|
- symbol: 'BTCUSDT',
|
|
|
- amount: signal.amount,
|
|
|
- side: side,
|
|
|
- reduceOnly: signal.action === 'sell', // 卖出时尝试减仓
|
|
|
- slippagePercent: '5.0'
|
|
|
- })
|
|
|
-
|
|
|
- if (result.success) {
|
|
|
- this.stats.successfulTrades++
|
|
|
- this.stats.totalVolume += parseFloat(signal.amount)
|
|
|
- logger.info('交易订单执行成功', { orderId: result.data?.order_id })
|
|
|
- console.log(`✅ ${signal.action.toUpperCase()} 订单成功: ${result.data?.order_id}`)
|
|
|
- } else {
|
|
|
- this.stats.failedTrades++
|
|
|
- throw new Error(`订单失败: ${result.error}`)
|
|
|
- }
|
|
|
-
|
|
|
- this.stats.totalTrades++
|
|
|
- this.stats.lastTradeTime = Date.now()
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 检查是否应该交易
|
|
|
- */
|
|
|
- private shouldTrade(): boolean {
|
|
|
- // 检查风险限制
|
|
|
- if (this.stats.totalTrades >= this.riskLimits.maxDailyTrades) {
|
|
|
- return false
|
|
|
- }
|
|
|
-
|
|
|
- // 检查最近交易时间(刷量交易允许更频繁)
|
|
|
- const timeSinceLastTrade = Date.now() - this.stats.lastTradeTime
|
|
|
- if (timeSinceLastTrade < 5000) { // 改为至少间隔5秒
|
|
|
- return false
|
|
|
- }
|
|
|
-
|
|
|
- return true
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 健康检查
|
|
|
- */
|
|
|
- private async performHealthCheck(): Promise<void> {
|
|
|
- logger.debug('执行健康检查')
|
|
|
-
|
|
|
- for (const [clientId, client] of this.clients) {
|
|
|
- try {
|
|
|
- const result = await client.testConnection()
|
|
|
- if (!result.success) {
|
|
|
- logger.warn(`客户端 ${clientId} 连接异常`, { error: result.error })
|
|
|
- this.emit('system_error', {
|
|
|
- type: 'connection_error',
|
|
|
- clientId,
|
|
|
- error: result.error
|
|
|
- })
|
|
|
- }
|
|
|
- } catch (error: any) {
|
|
|
- logger.error(`客户端 ${clientId} 健康检查失败`, { error: error.message })
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 风险检查
|
|
|
- */
|
|
|
- private async performRiskCheck(): Promise<void> {
|
|
|
- // 检查交易频率
|
|
|
- if (this.stats.totalTrades > this.riskLimits.maxDailyTrades * 0.8) {
|
|
|
- this.emit('risk_alert', {
|
|
|
- type: 'daily_trade_limit_warning',
|
|
|
- current: this.stats.totalTrades,
|
|
|
- limit: this.riskLimits.maxDailyTrades
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- // 检查失败率
|
|
|
- const failureRate = this.stats.totalTrades > 0
|
|
|
- ? this.stats.failedTrades / this.stats.totalTrades
|
|
|
- : 0
|
|
|
-
|
|
|
- if (failureRate > 0.3) { // 失败率超过30%
|
|
|
- this.emit('risk_alert', {
|
|
|
- type: 'high_failure_rate',
|
|
|
- rate: failureRate,
|
|
|
- failed: this.stats.failedTrades,
|
|
|
- total: this.stats.totalTrades
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理风险警报
|
|
|
- */
|
|
|
- private handleRiskAlert(alert: any): void {
|
|
|
- logger.warn('风险警报', alert)
|
|
|
- console.log(`⚠️ 风险警报: ${alert.type}`)
|
|
|
-
|
|
|
- // 可以在这里实现自动暂停交易等逻辑
|
|
|
- if (alert.type === 'high_failure_rate') {
|
|
|
- console.log('❌ 失败率过高,建议暂停交易')
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 处理系统错误
|
|
|
- */
|
|
|
- private handleSystemError(error: any): void {
|
|
|
- logger.error('系统错误', error)
|
|
|
- console.log(`🚨 系统错误: ${error.type} - ${error.error}`)
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 显示实时监控面板
|
|
|
- */
|
|
|
- private displayDashboard(): void {
|
|
|
- const uptime = Date.now() - this.startTime
|
|
|
- const uptimeStr = Math.floor(uptime / 1000 / 60) + 'm'
|
|
|
-
|
|
|
- const status: SystemStatus = {
|
|
|
- accounts: this.accounts.length,
|
|
|
- activeConnections: this.clients.size,
|
|
|
- totalTrades: this.stats.totalTrades,
|
|
|
- totalVolume: this.stats.totalVolume.toFixed(6),
|
|
|
- uptime: uptime,
|
|
|
- lastUpdate: Date.now()
|
|
|
- }
|
|
|
-
|
|
|
- // 清屏并显示面板 - 使用ANSI清屏命令确保实时刷新
|
|
|
- process.stdout.write('\u001B[2J\u001B[0;0f') // 清屏并移动到左上角
|
|
|
-
|
|
|
- console.log('🔥 完整交易系统 - 实时监控面板 [刷量模式]')
|
|
|
- console.log('=' .repeat(80))
|
|
|
- console.log(`📊 系统状态`)
|
|
|
- console.log(` 运行时间: ${uptimeStr}`)
|
|
|
- console.log(` 账户数量: ${status.accounts}`)
|
|
|
- console.log(` 活跃连接: ${status.activeConnections}`)
|
|
|
- console.log(` 代理状态: ${Config.proxy.isAnyConfigured() ? '🟢 启用' : '🔴 禁用'}`)
|
|
|
-
|
|
|
- console.log(`\n💰 交易统计 📈`)
|
|
|
- console.log(` 总交易数: ${status.totalTrades}`)
|
|
|
- console.log(` 成功交易: ${this.stats.successfulTrades}`)
|
|
|
- console.log(` 失败交易: ${this.stats.failedTrades}`)
|
|
|
- console.log(` 总交易量: ${status.totalVolume} BTC`)
|
|
|
- console.log(` 成功率: ${status.totalTrades > 0 ? ((this.stats.successfulTrades / status.totalTrades) * 100).toFixed(1) : 0}%`)
|
|
|
-
|
|
|
- if (this.hedgeManager) {
|
|
|
- const hedgeStatus = this.hedgeManager.getHedgePairStatuses()
|
|
|
- console.log(`\n🔄 对冲状态`)
|
|
|
- hedgeStatus.forEach(hedge => {
|
|
|
- console.log(` ${hedge.pairId}: ${hedge.isActive ? '🟢 激活' : '🔴 停用'} (敞口: ${hedge.netExposure})`)
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- console.log(`\n🔧 风险控制`)
|
|
|
- console.log(` 每日交易限制: ${this.stats.totalTrades}/${this.riskLimits.maxDailyTrades}`)
|
|
|
- console.log(` 最大仓位: ${this.riskLimits.maxPositionSize} BTC`)
|
|
|
- console.log(` 紧急止损: ${this.riskLimits.emergencyStopLoss * 100}%`)
|
|
|
-
|
|
|
- // 显示最近的交易活动
|
|
|
- console.log(`\n⚡ 交易活动状态`)
|
|
|
- const timeSinceLastTrade = this.stats.lastTradeTime > 0
|
|
|
- ? Math.round((Date.now() - this.stats.lastTradeTime) / 1000)
|
|
|
- : 0
|
|
|
- console.log(` 上次交易: ${timeSinceLastTrade > 0 ? `${timeSinceLastTrade}秒前` : '无'}`)
|
|
|
- console.log(` 交易频率: 主信号15s + 刷量8s`)
|
|
|
- console.log(` 刷量状态: ${this.stats.totalTrades > 0 ? '🟢 活跃' : '⏸️ 等待'}`)
|
|
|
-
|
|
|
- console.log(`\n⏰ 最后更新: ${new Date().toLocaleTimeString()}`)
|
|
|
- console.log('=' .repeat(80))
|
|
|
- console.log('💡 按 Ctrl+C 安全退出系统 | 刷量交易进行中...')
|
|
|
-
|
|
|
- // 强制刷新缓冲区
|
|
|
- process.stdout.write('')
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取系统状态
|
|
|
- */
|
|
|
- getSystemStatus(): SystemStatus {
|
|
|
- return {
|
|
|
- accounts: this.accounts.length,
|
|
|
- activeConnections: this.clients.size,
|
|
|
- totalTrades: this.stats.totalTrades,
|
|
|
- totalVolume: this.stats.totalVolume.toFixed(6),
|
|
|
- uptime: Date.now() - this.startTime,
|
|
|
- lastUpdate: Date.now()
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 安全关闭系统
|
|
|
- */
|
|
|
- async shutdown(): Promise<void> {
|
|
|
- if (!this.isRunning) return
|
|
|
-
|
|
|
- console.log('\n🛑 正在安全关闭系统...')
|
|
|
- this.isRunning = false
|
|
|
-
|
|
|
- try {
|
|
|
- // 清理资源
|
|
|
- this.clients.clear()
|
|
|
- this.hedgeManager = null
|
|
|
-
|
|
|
- // 显示最终统计
|
|
|
- console.log('\n📊 最终统计:')
|
|
|
- console.log(` 总交易数: ${this.stats.totalTrades}`)
|
|
|
- console.log(` 成功交易: ${this.stats.successfulTrades}`)
|
|
|
- console.log(` 失败交易: ${this.stats.failedTrades}`)
|
|
|
- console.log(` 总运行时间: ${Math.floor((Date.now() - this.startTime) / 1000 / 60)} 分钟`)
|
|
|
-
|
|
|
- logger.info('交易系统已安全关闭')
|
|
|
- console.log('✅ 系统已安全关闭')
|
|
|
-
|
|
|
- process.exit(0)
|
|
|
- } catch (error: any) {
|
|
|
- logger.error('系统关闭时出错', { error: error.message })
|
|
|
- process.exit(1)
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * 显示使用帮助
|
|
|
- */
|
|
|
-function showHelp() {
|
|
|
- console.log(`
|
|
|
-🔥 完整加密货币交易系统
|
|
|
-
|
|
|
-功能特性:
|
|
|
- 🚀 多平台交易所集成 (Pacifica, Binance, Aster)
|
|
|
- 📊 实时市场数据处理
|
|
|
- 🏦 多账户统一管理
|
|
|
- 🔄 同平台智能对冲
|
|
|
- 🛡️ 完整风险控制系统
|
|
|
- 📈 实时监控面板
|
|
|
- ⚡ 自动交易执行
|
|
|
- 🔐 代理网络支持
|
|
|
-
|
|
|
-使用方法:
|
|
|
- tsx src/main-complete.ts 启动完整系统
|
|
|
- tsx src/main-complete.ts --help 显示此帮助
|
|
|
-
|
|
|
-环境要求:
|
|
|
- 🔧 Node.js >= 18.12
|
|
|
- 🔧 配置有效的交易所账户
|
|
|
- 🔧 足够的账户余额
|
|
|
- 🔧 稳定的网络连接
|
|
|
-
|
|
|
-安全特性:
|
|
|
- 🛡️ 多层风险控制
|
|
|
- 🛡️ 自动止损机制
|
|
|
- 🛡️ 交易频率限制
|
|
|
- 🛡️ 余额保护检查
|
|
|
- 🛡️ 异常自动恢复
|
|
|
-
|
|
|
-监控功能:
|
|
|
- 📊 实时交易统计
|
|
|
- 📈 盈亏分析
|
|
|
- 🔍 系统健康检查
|
|
|
- ⚠️ 风险警报系统
|
|
|
- 📝 详细交易日志
|
|
|
-
|
|
|
-⚠️ 风险提醒:
|
|
|
-加密货币交易存在巨大风险,可能导致本金损失。
|
|
|
-请确保您完全理解相关风险并具备相应的风险承受能力。
|
|
|
-建议先在测试环境中运行,并使用小额资金测试。
|
|
|
-`)
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 恢复系统状态
|
|
|
- */
|
|
|
- private async restoreSystemState(): Promise<void> {
|
|
|
- try {
|
|
|
- console.log('\n📋 第0步: 恢复系统状态')
|
|
|
-
|
|
|
- const savedState = await this.stateManager.loadState()
|
|
|
- if (savedState) {
|
|
|
- // 恢复账户状态
|
|
|
- Object.entries(savedState.accountStates).forEach(([accountId, state]) => {
|
|
|
- this.accountStates.set(accountId, {
|
|
|
- totalTrades: state.totalTrades,
|
|
|
- netPosition: state.netPosition,
|
|
|
- totalVolume: state.totalVolume,
|
|
|
- lastBalance: state.lastBalance,
|
|
|
- needsRebalance: state.needsRebalance
|
|
|
- })
|
|
|
- })
|
|
|
-
|
|
|
- // 恢复全局统计
|
|
|
- this.stats = {
|
|
|
- ...this.stats,
|
|
|
- ...savedState.globalStats
|
|
|
- }
|
|
|
-
|
|
|
- // 检查Delta中性状态
|
|
|
- const deltaReport = this.stateManager.getDeltaNeutralityReport(savedState)
|
|
|
- if (!deltaReport.isDeltaNeutral) {
|
|
|
- logger.warn('⚠️ 上次会话未达到Delta中性状态', deltaReport)
|
|
|
- console.log(`⚠️ 检测到未平衡仓位: ${deltaReport.totalDelta.toFixed(4)} BTC`)
|
|
|
- console.log(`🔄 ${deltaReport.recommendation}`)
|
|
|
- } else {
|
|
|
- console.log('✅ 上次会话保持了Delta中性状态')
|
|
|
- }
|
|
|
-
|
|
|
- logger.info('系统状态恢复成功', {
|
|
|
- accounts: Object.keys(savedState.accountStates).length,
|
|
|
- totalTrades: savedState.globalStats.totalTrades,
|
|
|
- totalDelta: savedState.deltaMetrics.totalDelta
|
|
|
- })
|
|
|
- } else {
|
|
|
- console.log('🆕 首次启动,创建新的系统状态')
|
|
|
- this.initializeAccountStates()
|
|
|
- }
|
|
|
- } catch (error: any) {
|
|
|
- logger.error('恢复系统状态失败', { error: error.message })
|
|
|
- console.log('⚠️ 状态恢复失败,使用默认设置启动')
|
|
|
- this.initializeAccountStates()
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 开始自动保存状态
|
|
|
- */
|
|
|
- private startStateAutoSave(): void {
|
|
|
- // 每30秒自动保存一次状态
|
|
|
- setInterval(async () => {
|
|
|
- if (!this.isShuttingDown) {
|
|
|
- await this.saveCurrentState()
|
|
|
- }
|
|
|
- }, 30000)
|
|
|
-
|
|
|
- logger.info('自动状态保存已启动 (30秒间隔)')
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 保存当前状态
|
|
|
- */
|
|
|
- private async saveCurrentState(): Promise<void> {
|
|
|
- try {
|
|
|
- const currentState: SystemState = {
|
|
|
- timestamp: Date.now(),
|
|
|
- accountStates: {},
|
|
|
- globalStats: {
|
|
|
- totalTrades: this.stats.totalTrades,
|
|
|
- successfulTrades: this.stats.successfulTrades,
|
|
|
- failedTrades: this.stats.failedTrades,
|
|
|
- totalVolume: this.stats.totalVolume,
|
|
|
- sessionStartTime: this.startTime
|
|
|
- },
|
|
|
- deltaMetrics: {
|
|
|
- totalDelta: this.calculateTotalDelta(),
|
|
|
- maxDelta: this.riskLimits.maxTotalExposure,
|
|
|
- lastRebalanceTime: Date.now(),
|
|
|
- rebalanceCount: 0
|
|
|
- },
|
|
|
- riskMetrics: {
|
|
|
- dailyTrades: this.stats.totalTrades,
|
|
|
- lastRiskCheck: Date.now(),
|
|
|
- emergencyStops: 0
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 转换账户状态
|
|
|
- this.accountStates.forEach((state, accountId) => {
|
|
|
- currentState.accountStates[accountId] = {
|
|
|
- ...state,
|
|
|
- lastUpdateTime: Date.now()
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- await this.stateManager.saveState(currentState)
|
|
|
- } catch (error: any) {
|
|
|
- logger.error('保存系统状态失败', { error: error.message })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 计算总Delta敞口
|
|
|
- */
|
|
|
- private calculateTotalDelta(): number {
|
|
|
- let totalDelta = 0
|
|
|
- this.accountStates.forEach(account => {
|
|
|
- totalDelta += account.netPosition
|
|
|
- })
|
|
|
- return totalDelta
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 优雅关闭系统
|
|
|
- */
|
|
|
- private async gracefulShutdown(): Promise<void> {
|
|
|
- if (this.isShuttingDown) {
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- this.isShuttingDown = true
|
|
|
- console.log('\n🛑 正在优雅关闭系统...')
|
|
|
-
|
|
|
- try {
|
|
|
- // 1. 停止新的交易信号
|
|
|
- this.isRunning = false
|
|
|
- logger.info('已停止交易信号生成')
|
|
|
-
|
|
|
- // 2. 等待当前交易完成
|
|
|
- await this.waitForPendingTrades()
|
|
|
-
|
|
|
- // 3. 检查Delta中性状态
|
|
|
- const deltaReport = await this.checkDeltaNeutrality()
|
|
|
-
|
|
|
- if (!deltaReport.isDeltaNeutral) {
|
|
|
- console.log(`⚠️ 警告: 系统未达到Delta中性状态`)
|
|
|
- console.log(`📊 当前总敞口: ${deltaReport.totalDelta.toFixed(4)} BTC`)
|
|
|
- console.log(`💡 建议: ${deltaReport.recommendation}`)
|
|
|
-
|
|
|
- // 询问用户是否强制关闭
|
|
|
- const shouldForceClose = await this.confirmForceClose()
|
|
|
- if (!shouldForceClose) {
|
|
|
- console.log('🔄 尝试自动平衡账户...')
|
|
|
- await this.attemptDeltaRebalancing()
|
|
|
- }
|
|
|
- } else {
|
|
|
- console.log('✅ Delta中性状态确认,可以安全关闭')
|
|
|
- }
|
|
|
-
|
|
|
- // 4. 保存最终状态
|
|
|
- await this.saveCurrentState()
|
|
|
- logger.info('最终状态已保存')
|
|
|
-
|
|
|
- // 5. 关闭连接
|
|
|
- await this.closeConnections()
|
|
|
-
|
|
|
- console.log('🎉 系统已安全关闭')
|
|
|
-
|
|
|
- } catch (error: any) {
|
|
|
- logger.error('优雅关闭过程中出现错误', { error: error.message })
|
|
|
- await this.emergencyShutdown()
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 紧急关闭系统
|
|
|
- */
|
|
|
- private async emergencyShutdown(): Promise<void> {
|
|
|
- logger.warn('执行紧急关闭流程')
|
|
|
-
|
|
|
- try {
|
|
|
- // 紧急保存状态
|
|
|
- const emergencyState: SystemState = this.stateManager.createDefaultState()
|
|
|
- this.stateManager.emergencySave(emergencyState)
|
|
|
-
|
|
|
- // 强制关闭所有连接
|
|
|
- await this.forceCloseConnections()
|
|
|
-
|
|
|
- logger.warn('紧急关闭完成')
|
|
|
- } catch (error: any) {
|
|
|
- logger.error('紧急关闭失败', { error: error.message })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 等待当前交易完成
|
|
|
- */
|
|
|
- private async waitForPendingTrades(maxWait = 30000): Promise<void> {
|
|
|
- console.log('⏳ 等待当前交易完成...')
|
|
|
- const startTime = Date.now()
|
|
|
-
|
|
|
- while (Date.now() - startTime < maxWait) {
|
|
|
- // 这里可以检查是否有未完成的交易
|
|
|
- // 暂时简单等待3秒
|
|
|
- await new Promise(resolve => setTimeout(resolve, 1000))
|
|
|
-
|
|
|
- // 如果没有待处理的交易,提前退出
|
|
|
- break
|
|
|
- }
|
|
|
-
|
|
|
- console.log('✅ 交易等待完成')
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 检查Delta中性状态
|
|
|
- */
|
|
|
- private async checkDeltaNeutrality(): Promise<{
|
|
|
- isDeltaNeutral: boolean
|
|
|
- totalDelta: number
|
|
|
- maxAllowedDelta: number
|
|
|
- recommendation: string
|
|
|
- }> {
|
|
|
- const totalDelta = Math.abs(this.calculateTotalDelta())
|
|
|
- const maxAllowedDelta = 0.01 // 最大允许敞口 0.01 BTC
|
|
|
-
|
|
|
- const isDeltaNeutral = totalDelta <= maxAllowedDelta
|
|
|
-
|
|
|
- let recommendation = ''
|
|
|
- if (!isDeltaNeutral) {
|
|
|
- recommendation = `需要对冲平仓 ${totalDelta.toFixed(4)} BTC 敞口以保持Delta中性`
|
|
|
- } else {
|
|
|
- recommendation = 'Delta中性状态良好,可以安全退出'
|
|
|
- }
|
|
|
-
|
|
|
- return {
|
|
|
- isDeltaNeutral,
|
|
|
- totalDelta,
|
|
|
- maxAllowedDelta,
|
|
|
- recommendation
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 确认是否强制关闭
|
|
|
- */
|
|
|
- private async confirmForceClose(): Promise<boolean> {
|
|
|
- // 在生产环境中,这里可以实现用户交互
|
|
|
- // 当前返回false,不强制关闭
|
|
|
- return false
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 尝试Delta重新平衡
|
|
|
- */
|
|
|
- private async attemptDeltaRebalancing(): Promise<void> {
|
|
|
- try {
|
|
|
- console.log('🔄 正在尝试自动平衡账户...')
|
|
|
-
|
|
|
- // 生成平衡信号
|
|
|
- const balanceSignal: TradingSignal = {
|
|
|
- symbol: 'BTC-USD',
|
|
|
- action: 'balance_accounts',
|
|
|
- amount: Math.abs(this.calculateTotalDelta()).toFixed(4),
|
|
|
- confidence: 1.0,
|
|
|
- reason: 'shutdown_rebalancing'
|
|
|
- }
|
|
|
-
|
|
|
- await this.executeBalanceSignal(balanceSignal)
|
|
|
-
|
|
|
- // 等待执行完成
|
|
|
- await new Promise(resolve => setTimeout(resolve, 5000))
|
|
|
-
|
|
|
- // 重新检查
|
|
|
- const newDelta = Math.abs(this.calculateTotalDelta())
|
|
|
- if (newDelta <= 0.01) {
|
|
|
- console.log('✅ 自动平衡成功')
|
|
|
- } else {
|
|
|
- console.log(`⚠️ 自动平衡后仍有 ${newDelta.toFixed(4)} BTC 敞口`)
|
|
|
- }
|
|
|
-
|
|
|
- } catch (error: any) {
|
|
|
- logger.error('自动平衡失败', { error: error.message })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 关闭连接
|
|
|
- */
|
|
|
- private async closeConnections(): Promise<void> {
|
|
|
- console.log('🔌 关闭所有连接...')
|
|
|
-
|
|
|
- try {
|
|
|
- // 关闭所有客户端连接
|
|
|
- for (const [accountId, client] of this.clients) {
|
|
|
- try {
|
|
|
- // 如果客户端有关闭方法,调用它
|
|
|
- logger.info(`关闭客户端连接: ${accountId}`)
|
|
|
- } catch (error: any) {
|
|
|
- logger.warn(`关闭客户端 ${accountId} 失败`, { error: error.message })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 清理对冲管理器
|
|
|
- if (this.hedgeManager) {
|
|
|
- this.hedgeManager = null
|
|
|
- }
|
|
|
-
|
|
|
- console.log('✅ 所有连接已关闭')
|
|
|
-
|
|
|
- } catch (error: any) {
|
|
|
- logger.error('关闭连接失败', { error: error.message })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 强制关闭连接
|
|
|
- */
|
|
|
- private async forceCloseConnections(): Promise<void> {
|
|
|
- logger.warn('强制关闭所有连接')
|
|
|
-
|
|
|
- this.clients.clear()
|
|
|
- this.hedgeManager = null
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 主程序入口
|
|
|
-async function main() {
|
|
|
- if (process.argv.includes('--help') || process.argv.includes('-h')) {
|
|
|
- showHelp()
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- try {
|
|
|
- const system = new CompleteTradingSystem()
|
|
|
- await system.start()
|
|
|
-
|
|
|
- // 保持程序运行
|
|
|
- process.stdin.resume()
|
|
|
-
|
|
|
- } catch (error: any) {
|
|
|
- logger.error('系统启动失败', { error: error.message, stack: error.stack })
|
|
|
- console.error('❌ 系统启动失败:', error.message)
|
|
|
- process.exit(1)
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 运行主程序
|
|
|
-if (import.meta.url === `file://${process.argv[1]}`) {
|
|
|
- main()
|
|
|
-}
|
|
|
-
|
|
|
-export { CompleteTradingSystem }
|