real_trading_test.ts 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. #!/usr/bin/env tsx
  2. /**
  3. * 实际交易和对冲功能测试
  4. * ⚠️ 警告:这将执行真实的交易订单!
  5. * 请确保在测试环境中运行,或使用极小的金额
  6. */
  7. import { Config, SmartAccountDiscovery } from '../src/config/simpleEnv.js'
  8. import { PacificaProxyClient } from '../src/exchanges/pacifica/PacificaProxyClient.js'
  9. import { SamePlatformHedgingManager } from '../src/core/hedging/SamePlatformHedgingManager.js'
  10. import { logger } from '../src/utils/logger.js'
  11. async function realTradingTest() {
  12. console.log('🚨 实际交易和对冲功能测试')
  13. console.log('⚠️ 警告:这将执行真实的交易订单!')
  14. console.log('='.repeat(60))
  15. // 安全检查
  16. if (process.argv.includes('--dry-run')) {
  17. console.log('🔒 DRY RUN 模式 - 不会执行实际交易')
  18. } else {
  19. console.log('💰 实际交易模式 - 将执行真实订单')
  20. console.log('如果您不想执行实际交易,请添加 --dry-run 参数')
  21. console.log('按 Ctrl+C 取消,或等待5秒继续...')
  22. if (!process.argv.includes('--force')) {
  23. await new Promise(resolve => setTimeout(resolve, 5000))
  24. }
  25. }
  26. const isDryRun = process.argv.includes('--dry-run')
  27. try {
  28. // 1. 检查配置和账户
  29. console.log('\n📋 第一步: 检查配置和账户...')
  30. console.log(`代理状态: ${Config.proxy.isAnyConfigured() ? '✅ 启用' : '❌ 禁用'}`)
  31. const accounts = SmartAccountDiscovery.discoverPacifica()
  32. console.log(`发现 ${accounts.length} 个Pacifica账户`)
  33. if (accounts.length < 2) {
  34. console.log('❌ 需要至少2个账户进行对冲测试')
  35. return
  36. }
  37. // 2. 创建增强的对冲管理器(带风险控制)
  38. console.log('\n🛡️ 第二步: 创建带风险控制的对冲管理器...')
  39. const riskLimits = {
  40. maxPositionSize: 0.01, // 最大0.01个币的仓位
  41. maxTotalExposure: 0.02, // 总敞口不超过0.02
  42. maxAccountBalance: 1000, // 账户余额上限
  43. minAccountBalance: 10, // 账户余额下限
  44. maxDailyTrades: 20, // 每日最多20笔交易
  45. maxSlippage: 0.01, // 最大1%滑点
  46. emergencyStopLoss: 0.03, // 3%紧急止损
  47. enabled: true, // 启用风险控制
  48. }
  49. const hedgeManager = new SamePlatformHedgingManager('pacifica', riskLimits)
  50. // 3. 添加账户到对冲管理器
  51. console.log('\n🏦 第三步: 添加账户到对冲管理器...')
  52. const account1 = accounts[0]
  53. const account2 = accounts[1]
  54. hedgeManager.addAccount('pacifica-main', {
  55. account: account1.account,
  56. privateKey: account1.privateKey,
  57. })
  58. hedgeManager.addAccount('pacifica-hedge', {
  59. account: account2.account,
  60. privateKey: account2.privateKey,
  61. })
  62. console.log(`✅ 添加主账户: ${account1.account.substring(0, 8)}...`)
  63. console.log(`✅ 添加对冲账户: ${account2.account.substring(0, 8)}...`)
  64. // 4. 创建对冲对
  65. console.log('\n🔗 第四步: 创建BTC-USD对冲对...')
  66. hedgeManager.createHedgePair('btc-usd-hedge', 'pacifica-main', 'pacifica-hedge', 'BTC-USD', 1.0)
  67. console.log('✅ BTC-USD对冲对创建成功')
  68. // 5. 测试单笔小额交易
  69. console.log('\n💸 第五步: 测试小额交易...')
  70. const testAmount = 0.001 // 0.001 BTC
  71. const testSymbol = 'BTC-USD'
  72. console.log(`测试交易参数:`)
  73. console.log(` 交易对: ${testSymbol}`)
  74. console.log(` 数量: ${testAmount}`)
  75. console.log(` 账户: ${account1.account.substring(0, 8)}...`)
  76. console.log(` 实际执行: ${isDryRun ? '否 (DRY RUN)' : '是'}`)
  77. if (!isDryRun) {
  78. try {
  79. // 创建交易客户端
  80. const client1 = new PacificaProxyClient({
  81. account: account1.account,
  82. privateKey: account1.privateKey,
  83. })
  84. // 跳过余额和持仓检查,直接测试下单
  85. console.log('跳过余额和持仓检查,直接测试下单...')
  86. // 执行小额买单测试
  87. console.log('执行小额买单测试...')
  88. const buyOrderResult = await client1.createMarketOrder({
  89. account: account1.account,
  90. symbol: testSymbol,
  91. amount: testAmount.toString(),
  92. side: 'bid',
  93. reduceOnly: false,
  94. slippagePercent: '0.5',
  95. })
  96. console.log('✅ 买单执行成功:')
  97. console.log(JSON.stringify(buyOrderResult, null, 2))
  98. // 等待一秒后执行对冲卖单
  99. console.log('等待1秒后执行对冲...')
  100. await new Promise(resolve => setTimeout(resolve, 1000))
  101. const client2 = new PacificaProxyClient({
  102. account: account2.account,
  103. privateKey: account2.privateKey,
  104. })
  105. const sellOrderResult = await client2.createMarketOrder({
  106. account: account2.account,
  107. symbol: testSymbol,
  108. amount: testAmount.toString(),
  109. side: 'ask',
  110. reduceOnly: false,
  111. slippagePercent: '0.5',
  112. })
  113. console.log('✅ 对冲卖单执行成功:')
  114. console.log(JSON.stringify(sellOrderResult, null, 2))
  115. } catch (error: any) {
  116. console.log('❌ 交易执行失败:', error.message)
  117. logger.error('实际交易测试失败', { error: error.message })
  118. }
  119. } else {
  120. console.log('🔒 DRY RUN 模式 - 跳过实际交易')
  121. }
  122. // 6. 测试批量对冲功能
  123. console.log('\n🔄 第六步: 测试批量对冲功能...')
  124. const batchOrders = [
  125. {
  126. accountId: 'pacifica-main',
  127. symbol: 'BTC-USD',
  128. amount: 0.001,
  129. side: 'bid' as const,
  130. orderType: 'market' as const,
  131. },
  132. {
  133. accountId: 'pacifica-hedge',
  134. symbol: 'BTC-USD',
  135. amount: 0.001,
  136. side: 'ask' as const,
  137. orderType: 'market' as const,
  138. },
  139. ]
  140. console.log(`批量订单数量: ${batchOrders.length}`)
  141. console.log(`实际执行: ${isDryRun ? '否 (DRY RUN)' : '是'}`)
  142. if (!isDryRun) {
  143. const batchResults = await hedgeManager.executeBatchHedge(batchOrders)
  144. console.log('✅ 批量对冲执行完成:')
  145. batchResults.forEach((result, index) => {
  146. console.log(` 订单${index + 1}: ${result.success ? '成功' : '失败'}`)
  147. if (result.success) {
  148. console.log(` 订单ID: ${result.orderId}`)
  149. } else {
  150. console.log(` 错误: ${result.error}`)
  151. }
  152. })
  153. } else {
  154. console.log('🔒 DRY RUN 模式 - 跳过批量对冲执行')
  155. }
  156. // 7. 检查对冲状态
  157. console.log('\n📊 第七步: 检查对冲状态...')
  158. const hedgeStatuses = hedgeManager.getHedgePairStatuses()
  159. hedgeStatuses.forEach(status => {
  160. console.log(`对冲对: ${status.pairId}`)
  161. console.log(` 交易对: ${status.symbol}`)
  162. console.log(` 多头账户: ${status.longAccount}`)
  163. console.log(` 空头账户: ${status.shortAccount}`)
  164. console.log(` 净敞口: ${status.netExposure}`)
  165. console.log(` 状态: ${status.isActive ? '激活' : '停用'}`)
  166. })
  167. console.log('\n🎉 实际交易和对冲功能测试完成!')
  168. console.log('\n📋 测试总结:')
  169. console.log(` ✅ 发现账户: ${accounts.length} 个`)
  170. console.log(` ✅ 风险控制: 已启用`)
  171. console.log(` ✅ 代理配置: ${Config.proxy.isAnyConfigured() ? '已启用' : '未启用'}`)
  172. console.log(` ✅ 交易执行: ${isDryRun ? 'DRY RUN 模式' : '实际执行'}`)
  173. console.log(` ✅ 对冲功能: 已测试`)
  174. if (isDryRun) {
  175. console.log('\n💡 要执行实际交易,请运行:')
  176. console.log('tsx examples/real_trading_test.ts --force')
  177. } else {
  178. console.log('\n⚠️ 提醒: 已执行实际交易,请检查账户状态!')
  179. }
  180. } catch (error: any) {
  181. console.error('❌ 实际交易测试失败:', error)
  182. logger.error('实际交易测试失败', { error: error.message, stack: error.stack })
  183. }
  184. }
  185. /**
  186. * 显示使用帮助
  187. */
  188. function showTradingHelp() {
  189. console.log('\n💡 实际交易测试使用说明:')
  190. console.log(`
  191. # 使用方式:
  192. ## 安全测试 (推荐)
  193. tsx examples/real_trading_test.ts --dry-run
  194. ## 实际交易 (谨慎使用)
  195. tsx examples/real_trading_test.ts --force
  196. # 参数说明:
  197. --dry-run : 模拟模式,不执行实际交易
  198. --force : 强制执行实际交易
  199. --help : 显示此帮助信息
  200. # 风险提醒:
  201. ⚠️ 实际交易模式将执行真实订单并消耗资金
  202. ⚠️ 建议先在测试环境或极小金额下测试
  203. ⚠️ 确保账户有足够余额并了解交易风险
  204. ⚠️ 系统已内置风险控制,但仍需谨慎操作
  205. # 功能特性:
  206. ✅ 完整的风险控制系统
  207. ✅ 紧急止损机制
  208. ✅ 多账户代理隔离
  209. ✅ 批量对冲执行
  210. ✅ 实时仓位监控
  211. ✅ 详细交易日志
  212. `)
  213. }
  214. // 运行测试
  215. if (import.meta.url === `file://${process.argv[1]}`) {
  216. if (process.argv.includes('--help') || process.argv.includes('-h')) {
  217. showTradingHelp()
  218. } else {
  219. realTradingTest()
  220. }
  221. }