riskAssessor.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import { Position } from '../types/core'
  2. export interface RiskSummary {
  3. leverageRatio: number
  4. var: number
  5. maxDrawdown: number
  6. level: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'
  7. score: number
  8. recommendations: string[]
  9. }
  10. export class RiskAssessor {
  11. /**
  12. * 真实的风险评估逻辑实现
  13. */
  14. evaluatePosition(position: Position): RiskSummary {
  15. const leverageRatio = position.leverage || 1
  16. const unrealizedPnL = position.unrealizedPnL || 0
  17. const notional = Math.abs(parseFloat(position.size)) * (position.markPrice || 0)
  18. // 1. 计算Value at Risk (VaR) - 使用简化的历史模拟法
  19. const volatility = this.estimateVolatility(position.symbol)
  20. const confidenceLevel = 0.95 // 95%置信度
  21. const timeHorizon = 1 // 1天
  22. const varValue = notional * volatility * Math.sqrt(timeHorizon) * this.getZScore(confidenceLevel)
  23. // 2. 计算最大回撤
  24. const entryPrice = parseFloat(position.entryPrice || '0')
  25. const currentPrice = position.markPrice || 0
  26. const priceChange = Math.abs(currentPrice - entryPrice) / entryPrice
  27. const maxDrawdown = notional * priceChange
  28. // 3. 综合风险评分 (0-100)
  29. const leverageScore = Math.min(leverageRatio * 10, 50) // 杠杆风险 (最高50分)
  30. const pnlScore = Math.min(Math.abs(unrealizedPnL) / 1000 * 20, 30) // PnL风险 (最高30分)
  31. const concentrationScore = Math.min(notional / 10000 * 20, 20) // 集中度风险 (最高20分)
  32. const totalScore = leverageScore + pnlScore + concentrationScore
  33. // 4. 确定风险等级
  34. let level: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'
  35. if (totalScore < 25) level = 'LOW'
  36. else if (totalScore < 50) level = 'MEDIUM'
  37. else if (totalScore < 75) level = 'HIGH'
  38. else level = 'CRITICAL'
  39. // 5. 生成风险建议
  40. const recommendations = this.generateRecommendations(
  41. leverageRatio,
  42. unrealizedPnL,
  43. notional,
  44. level
  45. )
  46. return {
  47. leverageRatio,
  48. var: varValue,
  49. maxDrawdown,
  50. level,
  51. score: totalScore,
  52. recommendations,
  53. }
  54. }
  55. /**
  56. * 估算波动率 (简化实现)
  57. */
  58. private estimateVolatility(symbol: string): number {
  59. // 基于历史数据的简化波动率估算
  60. const volatilityMap: Record<string, number> = {
  61. 'BTC-USD': 0.04, // 4%日波动率
  62. 'ETH-USD': 0.05, // 5%日波动率
  63. 'SOL-USD': 0.08, // 8%日波动率
  64. }
  65. return volatilityMap[symbol] || 0.06 // 默认6%
  66. }
  67. /**
  68. * 获取置信度对应的Z分数
  69. */
  70. private getZScore(confidenceLevel: number): number {
  71. const zScoreMap: Record<number, number> = {
  72. 0.90: 1.28,
  73. 0.95: 1.645,
  74. 0.99: 2.33,
  75. }
  76. return zScoreMap[confidenceLevel] || 1.645
  77. }
  78. /**
  79. * 生成风险管理建议
  80. */
  81. private generateRecommendations(
  82. leverage: number,
  83. pnl: number,
  84. notional: number,
  85. level: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL'
  86. ): string[] {
  87. const recommendations: string[] = []
  88. // 杠杆相关建议
  89. if (leverage > 10) {
  90. recommendations.push('建议降低杠杆倍数至5倍以下')
  91. } else if (leverage > 5) {
  92. recommendations.push('监控杠杆风险,考虑适当降低')
  93. }
  94. // PnL相关建议
  95. if (pnl < -500) {
  96. recommendations.push('亏损较大,建议设置止损')
  97. } else if (pnl > 1000) {
  98. recommendations.push('盈利较好,建议部分止盈')
  99. }
  100. // 仓位规模建议
  101. if (notional > 50000) {
  102. recommendations.push('仓位规模较大,注意分散风险')
  103. }
  104. // 风险等级相关建议
  105. switch (level) {
  106. case 'CRITICAL':
  107. recommendations.push('风险等级极高,建议立即平仓')
  108. break
  109. case 'HIGH':
  110. recommendations.push('风险等级较高,建议减仓或对冲')
  111. break
  112. case 'MEDIUM':
  113. recommendations.push('风险等级中等,密切监控市场变化')
  114. break
  115. case 'LOW':
  116. recommendations.push('风险等级较低,可维持当前仓位')
  117. break
  118. }
  119. return recommendations
  120. }
  121. }
  122. export const riskAssessor = new RiskAssessor()