| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422 |
- /**
- * 统一多账户管理系统演示
- * 展示多平台多账户的管理、对冲和监控功能
- */
- import 'dotenv/config'
- import { UnifiedAccountManager, AccountConfig } from '../src/accounts/UnifiedAccountManager'
- async function main() {
- console.log('🚀 统一多账户管理系统演示')
- try {
- // 1. 创建统一账户管理器
- console.log('\n🏗️ 创建统一账户管理器...')
- const manager = new UnifiedAccountManager({
- maxRetries: 3,
- timeoutMs: 30000,
- atomicTimeout: 5000,
- enableRollback: true,
- slippageTolerance: 0.005,
- positionSizeLimit: 1000,
- })
- // 2. 配置多个账户
- console.log('\n📝 配置账户...')
- // 检查可用的交易所凭证
- const hasAsterCredentials =
- process.env.ASTER_ORDER_USER && process.env.ASTER_API_KEY && process.env.ASTER_API_SECRET
- const hasPacificaCredentials = process.env.PACIFICA_ACCOUNT_PRIVATE_KEY && process.env.PACIFICA_ACCOUNT
- console.log(`✅ Aster 凭证: ${hasAsterCredentials ? '可用' : '不可用'}`)
- console.log(`✅ Pacifica 凭证: ${hasPacificaCredentials ? '可用' : '不可用'}`)
- // 使用优雅的账户配置系统
- const accountGroups = createAccountGroups()
- const accountConfigs = accountGroups.getActiveConfigs()
- if (accountConfigs.length === 0) {
- console.log('⚠️ 没有找到有效的 API 凭证,将以模拟模式运行')
- console.log('设置环境变量以启用真实账户连接:')
- console.log(' ASTER_ORDER_USER, ASTER_API_KEY, ASTER_API_SECRET (Aster DEX)')
- console.log(' PACIFICA_ACCOUNT, PACIFICA_ACCOUNT_PRIVATE_KEY (Pacifica)')
- // 运行模拟演示
- await runSimulationDemo(manager)
- return
- }
- // 3. 批量注册账户
- console.log('\n🔐 注册账户...')
- await manager.registerAccountsFromConfig(accountConfigs)
- // 4. 监听系统事件
- manager.on('account_registered', ({ accountKey, exchange }) => {
- console.log(`✅ 账户注册成功: ${accountKey} (${exchange})`)
- })
- manager.on('account_failed', ({ accountKey, error }) => {
- console.log(`❌ 账户失败: ${accountKey}, 错误: ${error.message}`)
- })
- manager.on('hedge_execution_completed', ({ accountKey, result }) => {
- console.log(`🎯 对冲完成: ${accountKey}, 数量: ${result.executedQuantity}`)
- })
- manager.on('system_stats_updated', stats => {
- console.log(`📊 系统统计更新: 总账户 ${stats.totalAccounts}, 在线 ${stats.onlineAccounts}`)
- })
- // 5. 等待初始化完成
- console.log('\n⏳ 等待账户初始化...')
- await new Promise(resolve => setTimeout(resolve, 3000))
- // 6. 获取聚合余额
- console.log('\n💰 获取聚合余额...')
- try {
- const balances = await manager.getAggregatedBalances()
- console.log('余额统计:')
- console.log(`📋 找到 ${Object.keys(balances).length} 种资产`)
- for (const [asset, balance] of Object.entries(balances)) {
- if (balance.total > 0.001) {
- // 只显示有意义的余额
- console.log(` ${asset}: ${balance.total.toFixed(8)} (${balance.accounts.length} 个账户)`)
- balance.accounts.forEach(account => {
- if (account.amount > 0.001) {
- console.log(` └─ ${account.accountKey}: ${account.amount.toFixed(8)}`)
- }
- })
- }
- }
- if (Object.keys(balances).length === 0) {
- console.log(' 暂无余额数据')
- }
- } catch (error) {
- console.log(`⚠️ 获取余额失败: ${error.message}`)
- }
- // 7. 获取聚合仓位
- console.log('\n📊 获取聚合仓位...')
- try {
- const positions = await manager.getAggregatedPositions()
- console.log('仓位统计:')
- console.log(`📋 找到 ${Object.keys(positions).length} 个交易对仓位`)
- for (const [symbol, position] of Object.entries(positions)) {
- if (Math.abs(position.netSize) > 0.001) {
- console.log(` ${symbol}: ${position.netSize.toFixed(6)} (净仓位, ${position.accounts.length} 个账户)`)
- position.accounts.forEach(account => {
- if (Math.abs(account.size) > 0.001) {
- console.log(` └─ ${account.accountKey}: ${account.size.toFixed(6)} (${account.side})`)
- }
- })
- }
- }
- if (Object.keys(positions).length === 0) {
- console.log(' 暂无仓位数据')
- }
- } catch (error) {
- console.log(`⚠️ 获取仓位失败: ${error.message}`)
- }
- // 8. 模拟智能路由下单
- console.log('\n🎯 模拟智能路由下单...')
- try {
- console.log('⚠️ 演示模式:不会执行真实交易')
- // 这里会选择最优账户进行下单
- console.log('智能路由会根据以下因素选择账户:')
- console.log(' - 账户优先级')
- console.log(' - 仓位限制')
- console.log(' - 日交易量限制')
- console.log(' - 账户健康状态')
- // 在真实环境中,这里会执行:
- // const result = await manager.smartRouteOrder({
- // symbol: 'BTCUSDT',
- // side: 'BUY',
- // type: 'MARKET',
- // quantity: '0.001'
- // });
- } catch (error) {
- console.log(`❌ 智能路由失败: ${error.message}`)
- }
- // 9. 显示系统统计
- console.log('\n📈 系统统计:')
- const stats = manager.getSystemStats()
- console.log(`总账户数: ${stats.accounts?.total || 0}`)
- console.log(`在线账户: ${stats.accounts?.online || 0}`)
- console.log(`离线账户: ${stats.accounts?.offline || 0}`)
- console.log(`错误账户: ${stats.accounts?.error || 0}`)
- console.log(`总权益: $${(stats.equity?.totalUsd || 0).toFixed(2)}`)
- console.log(`今日交易量: $${(stats.volume?.totalDailyUsd || 0).toFixed(2)}`)
- console.log(`对冲组数量: ${stats.hedgingGroups || 0}`)
- console.log(`对冲执行次数: ${stats.hedging?.totalExecutions || 0}`)
- console.log('\n🎯 跨账户对冲演示')
- console.log('系统会自动:')
- console.log(' - 检测仓位偏差')
- console.log(' - 选择最优对冲账户')
- console.log(' - 执行原子配对交易')
- console.log(' - 监控净敞口')
- console.log(' - 提供风险报告')
- // 10. 清理演示
- console.log('\n🧹 清理资源...')
- manager.destroy()
- console.log('\n🎉 演示完成')
- } catch (error) {
- console.error('❌ 演示失败:', error)
- }
- }
- /**
- * 优雅的账户分组配置系统
- * 支持批量配置、分组管理、环境变量自动检测
- */
- interface AccountGroup {
- name: string
- description: string
- accounts: AccountConfig[]
- enabled: boolean
- priority: number
- }
- class AccountGroupManager {
- private groups: Map<string, AccountGroup> = new Map()
- addGroup(name: string, group: Omit<AccountGroup, 'name'>): this {
- this.groups.set(name, { name, ...group })
- return this
- }
- getGroup(name: string): AccountGroup | undefined {
- return this.groups.get(name)
- }
- getActiveConfigs(): AccountConfig[] {
- const configs: AccountConfig[] = []
- // 按优先级排序组
- const sortedGroups = Array.from(this.groups.values())
- .filter(group => group.enabled)
- .sort((a, b) => a.priority - b.priority)
- for (const group of sortedGroups) {
- configs.push(...group.accounts.filter(account => account.enabled))
- }
- return configs
- }
- getGroupSummary(): { [groupName: string]: { total: number; active: number } } {
- const summary: { [groupName: string]: { total: number; active: number } } = {}
- for (const [name, group] of this.groups.entries()) {
- summary[name] = {
- total: group.accounts.length,
- active: group.enabled ? group.accounts.filter(account => account.enabled).length : 0,
- }
- }
- return summary
- }
- }
- /**
- * 创建账户分组配置
- */
- function createAccountGroups(): AccountGroupManager {
- const manager = new AccountGroupManager()
- // 主交易组 - 用于主要的交易和对冲
- const mainTradingAccounts: AccountConfig[] = []
- // Aster DEX 主账户 - 使用环境变量自动检测
- if (process.env.ASTER_ORDER_USER && process.env.ASTER_API_KEY && process.env.ASTER_API_SECRET) {
- mainTradingAccounts.push({
- exchange: 'aster',
- accountId: process.env.ASTER_ORDER_USER,
- alias: 'Aster主账户',
- enabled: true,
- priority: 1,
- tradingEnabled: true,
- hedgingEnabled: true,
- maxPositionUsd: 10000,
- maxDailyVolumeUsd: 100000,
- // 不需要显式 credentials,AdapterFactory 会从环境变量加载
- })
- }
- // Pacifica 主账户 - 使用环境变量自动检测
- if (process.env.PACIFICA_ACCOUNT && process.env.PACIFICA_ACCOUNT_PRIVATE_KEY) {
- mainTradingAccounts.push({
- exchange: 'pacifica',
- accountId: process.env.PACIFICA_ACCOUNT,
- alias: 'Pacifica主账户',
- enabled: true,
- priority: 2,
- tradingEnabled: true,
- hedgingEnabled: true,
- maxPositionUsd: 5000,
- maxDailyVolumeUsd: 50000,
- // 不需要显式 credentials,AdapterFactory 会从环境变量加载
- })
- }
- manager.addGroup('main_trading', {
- description: '主要交易账户组 - 用于核心交易和对冲策略',
- accounts: mainTradingAccounts,
- enabled: true,
- priority: 1,
- })
- // 测试账户组 - 用于测试和开发
- const testAccounts: AccountConfig[] = []
- // 可以在这里添加测试账户配置
- // if (process.env.ASTER_TEST_USER) { ... }
- manager.addGroup('testing', {
- description: '测试账户组 - 用于策略测试和开发',
- accounts: testAccounts,
- enabled: false, // 默认禁用测试账户
- priority: 9,
- })
- // 套利账户组 - 用于跨交易所套利
- const arbitrageAccounts: AccountConfig[] = []
- // 套利账户可以是同一交易所的多个账户,或者专门用于套利的账户
- // 这里可以添加专门的套利账户配置
- manager.addGroup('arbitrage', {
- description: '套利账户组 - 用于跨交易所套利策略',
- accounts: arbitrageAccounts,
- enabled: false, // 默认禁用,需要时手动启用
- priority: 5,
- })
- // 打印账户组信息
- const summary = manager.getGroupSummary()
- console.log('\n📊 账户组配置:')
- for (const [groupName, info] of Object.entries(summary)) {
- const group = manager.getGroup(groupName)!
- console.log(
- ` ${group.enabled ? '✅' : '❌'} ${groupName}: ${info.active}/${info.total} 账户活跃 - ${group.description}`,
- )
- }
- return manager
- }
- /**
- * 模拟演示 - 在没有真实 API 凭证时展示功能
- */
- async function runSimulationDemo(manager: UnifiedAccountManager) {
- console.log('\n🎭 模拟模式演示')
- // 模拟账户数据
- const mockAccounts = [
- {
- key: 'binance::main',
- exchange: 'binance',
- accountId: 'main',
- alias: 'Binance主账户',
- balances: [
- { asset: 'USDT', free: '1000.50', locked: '99.50', total: '1100.00' },
- { asset: 'BTC', free: '0.05234', locked: '0', total: '0.05234' },
- { asset: 'ETH', free: '1.2345', locked: '0.1', total: '1.3345' },
- ],
- positions: [
- { symbol: 'BTCUSDT', size: 0.025, side: 'long', unrealizedPnl: 125.3, entryPrice: 45000 },
- { symbol: 'ETHUSDT', size: -0.5, side: 'short', unrealizedPnl: -23.45, entryPrice: 3200 },
- ],
- equity: 3567.89,
- margin: 234.56,
- },
- {
- key: 'pacifica::demo',
- exchange: 'pacifica',
- accountId: 'demo',
- alias: 'Pacifica演示账户',
- balances: [
- { asset: 'USDT', free: '500.25', locked: '25.75', total: '526.00' },
- { asset: 'BTC', free: '0.01', locked: '0', total: '0.01' },
- ],
- positions: [{ symbol: 'BTCUSDT', size: 0.01, side: 'long', unrealizedPnl: 12.34, entryPrice: 44800 }],
- equity: 986.45,
- margin: 45.67,
- },
- ]
- console.log('\n💰 模拟聚合余额:')
- const aggregatedBalances = {
- USDT: { total: 1626.0, free: 1500.75, locked: 125.25 },
- BTC: { total: 0.06234, free: 0.06234, locked: 0 },
- ETH: { total: 1.3345, free: 1.2345, locked: 0.1 },
- }
- for (const [asset, balance] of Object.entries(aggregatedBalances)) {
- console.log(` ${asset}: ${balance.total.toFixed(8)} (可用: ${balance.free.toFixed(8)})`)
- }
- console.log('\n📊 模拟聚合仓位:')
- const aggregatedPositions = {
- BTCUSDT: { size: 0.035, side: 'long', unrealizedPnl: 137.64 },
- ETHUSDT: { size: -0.5, side: 'short', unrealizedPnl: -23.45 },
- }
- for (const [symbol, position] of Object.entries(aggregatedPositions)) {
- console.log(
- ` ${symbol}: ${position.size.toFixed(6)} (方向: ${position.side}, 未实现盈亏: ${position.unrealizedPnl.toFixed(
- 2,
- )})`,
- )
- }
- console.log('\n🎯 模拟智能路由决策:')
- console.log('场景: 需要在 BTCUSDT 上执行 0.01 BTC 的买单')
- console.log('分析结果:')
- console.log(' - Binance主账户: 优先级 1, 可用保证金充足, 日交易量限制内 ✅')
- console.log(' - Pacifica演示账户: 优先级 2, 可用保证金充足, 日交易量限制内 ✅')
- console.log('选择结果: Binance主账户 (优先级最高)')
- console.log('\n📈 模拟系统统计:')
- console.log(`总账户数: ${mockAccounts.length}`)
- console.log(`在线账户: ${mockAccounts.length}`)
- console.log(`总权益: $${(3567.89 + 986.45).toFixed(2)}`)
- console.log(`今日交易量: $12,345.67`)
- console.log(`活跃对冲会话: 0`)
- console.log('\n🎯 跨账户对冲场景演示:')
- console.log('检测到仓位偏差:')
- console.log(' - Binance: BTCUSDT +0.025 (多头过多)')
- console.log(' - Pacifica: BTCUSDT +0.01 (轻微多头)')
- console.log('对冲建议:')
- console.log(' - 在 Binance 开设 -0.01 BTCUSDT 空头仓位')
- console.log(' - 预期降低整体净敞口')
- console.log(' - 预计执行时间: 2-5秒')
- console.log('\n🔍 风险监控:')
- console.log(' ✅ 所有账户保证金率健康 (>150%)')
- console.log(' ✅ 日交易量限制内')
- console.log(' ⚠️ ETHUSDT 净敞口较大,建议关注')
- console.log(' ✅ 系统延迟正常 (<100ms)')
- console.log('\n🎉 模拟演示完成')
- console.log('\n💡 要使用真实数据,请设置以下环境变量:')
- console.log('export ASTER_ORDER_USER="your_user_address"')
- console.log('export ASTER_API_KEY="your_api_key"')
- console.log('export ASTER_API_SECRET="your_api_secret"')
- console.log('export PACIFICA_ACCOUNT="your_account_id"')
- console.log('export PACIFICA_ACCOUNT_PRIVATE_KEY="your_private_key"')
- }
- // 运行演示
- main().catch(console.error)
|