convergenceAlgorithm.ts 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  1. import { logger } from '../../utils/logger.js'
  2. /**
  3. * 智能价格收敛算法 - 实现两个账户开仓价格逐步接近的策略
  4. */
  5. export class ConvergenceAlgorithm {
  6. private config: ConvergenceAlgorithmConfig
  7. constructor(config?: Partial<ConvergenceAlgorithmConfig>) {
  8. this.config = {
  9. targetDeviation: config?.targetDeviation || 0.001, // 0.1% 目标偏差
  10. maxDeviation: config?.maxDeviation || 0.01, // 1% 最大允许偏差
  11. convergenceSpeed: config?.convergenceSpeed || 0.3, // 收敛速度 (0-1)
  12. minAdjustmentPercent: config?.minAdjustmentPercent || 0.0005, // 0.05% 最小调整
  13. maxAdjustmentPercent: config?.maxAdjustmentPercent || 0.005, // 0.5% 最大调整
  14. aggressiveThreshold: config?.aggressiveThreshold || 0.005, // 0.5% 激进调整阈值
  15. dampingFactor: config?.dampingFactor || 0.8, // 阻尼系数,防止过度调整
  16. volatilityWeight: config?.volatilityWeight || 0.2, // 波动率权重
  17. trendWeight: config?.trendWeight || 0.3, // 趋势权重
  18. enableAdaptiveSpeed: config?.enableAdaptiveSpeed || true, // 启用自适应速度
  19. enableVolatilityAdjustment: config?.enableVolatilityAdjustment || true, // 启用波动率调整
  20. }
  21. }
  22. /**
  23. * 计算收敛策略
  24. */
  25. calculateConvergenceStrategy(
  26. account1Position: PositionInfo,
  27. account2Position: PositionInfo,
  28. marketData: MarketData,
  29. ): ConvergenceStrategy {
  30. // 计算当前价格偏差
  31. const priceDeviation = this.calculatePriceDeviation(account1Position, account2Position)
  32. // 如果偏差在目标范围内,不需要调整
  33. if (Math.abs(priceDeviation) <= this.config.targetDeviation) {
  34. return {
  35. needsAdjustment: false,
  36. priceDeviation,
  37. strategy: 'hold',
  38. account1Action: null,
  39. account2Action: null,
  40. confidence: 1.0,
  41. reasoning: '价格偏差在目标范围内',
  42. }
  43. }
  44. // 分析市场环境
  45. const marketAnalysis = this.analyzeMarketConditions(marketData)
  46. // 计算调整策略
  47. const adjustmentStrategy = this.calculateAdjustmentStrategy(
  48. account1Position,
  49. account2Position,
  50. priceDeviation,
  51. marketAnalysis,
  52. )
  53. // 生成具体的交易动作
  54. const actions = this.generateTradeActions(adjustmentStrategy, account1Position, account2Position, marketData)
  55. return {
  56. needsAdjustment: true,
  57. priceDeviation,
  58. strategy: adjustmentStrategy.type,
  59. account1Action: actions.account1Action,
  60. account2Action: actions.account2Action,
  61. confidence: adjustmentStrategy.confidence,
  62. reasoning: adjustmentStrategy.reasoning,
  63. marketAnalysis,
  64. urgency: this.calculateUrgency(priceDeviation, marketAnalysis),
  65. }
  66. }
  67. /**
  68. * 计算价格偏差
  69. */
  70. private calculatePriceDeviation(pos1: PositionInfo, pos2: PositionInfo): number {
  71. if (!pos1.averagePrice || !pos2.averagePrice) return 0
  72. const avgPrice = (pos1.averagePrice + pos2.averagePrice) / 2
  73. return (pos1.averagePrice - pos2.averagePrice) / avgPrice
  74. }
  75. /**
  76. * 分析市场条件
  77. */
  78. private analyzeMarketConditions(marketData: MarketData): MarketAnalysis {
  79. const { price, volume, volatility, trend, momentum } = marketData
  80. // 波动率分析
  81. let volatilityLevel: 'low' | 'medium' | 'high'
  82. if (volatility < 0.02) {
  83. volatilityLevel = 'low'
  84. } else if (volatility < 0.05) {
  85. volatilityLevel = 'medium'
  86. } else {
  87. volatilityLevel = 'high'
  88. }
  89. // 趋势强度分析
  90. const trendStrength = Math.abs(momentum || 0)
  91. let trendLevel: 'weak' | 'moderate' | 'strong'
  92. if (trendStrength < 0.01) {
  93. trendLevel = 'weak'
  94. } else if (trendStrength < 0.03) {
  95. trendLevel = 'moderate'
  96. } else {
  97. trendLevel = 'strong'
  98. }
  99. // 流动性分析
  100. const avgVolume =
  101. marketData.historicalVolume?.reduce((sum, v) => sum + v, 0) / (marketData.historicalVolume?.length || 1)
  102. const volumeRatio = volume / avgVolume
  103. let liquidityLevel: 'low' | 'medium' | 'high'
  104. if (volumeRatio < 0.5) {
  105. liquidityLevel = 'low'
  106. } else if (volumeRatio < 1.5) {
  107. liquidityLevel = 'medium'
  108. } else {
  109. liquidityLevel = 'high'
  110. }
  111. return {
  112. volatilityLevel,
  113. trendLevel,
  114. liquidityLevel,
  115. trendDirection: trend || 'sideways',
  116. momentum: momentum || 0,
  117. volumeRatio,
  118. riskScore: this.calculateMarketRiskScore(volatilityLevel, trendLevel, liquidityLevel),
  119. }
  120. }
  121. /**
  122. * 计算市场风险评分
  123. */
  124. private calculateMarketRiskScore(
  125. volatility: 'low' | 'medium' | 'high',
  126. trend: 'weak' | 'moderate' | 'strong',
  127. liquidity: 'low' | 'medium' | 'high',
  128. ): number {
  129. let score = 0
  130. // 波动率风险
  131. switch (volatility) {
  132. case 'low':
  133. score += 0.1
  134. break
  135. case 'medium':
  136. score += 0.3
  137. break
  138. case 'high':
  139. score += 0.6
  140. break
  141. }
  142. // 趋势风险
  143. switch (trend) {
  144. case 'weak':
  145. score += 0.1
  146. break
  147. case 'moderate':
  148. score += 0.2
  149. break
  150. case 'strong':
  151. score += 0.4
  152. break
  153. }
  154. // 流动性风险
  155. switch (liquidity) {
  156. case 'high':
  157. score += 0.1
  158. break
  159. case 'medium':
  160. score += 0.2
  161. break
  162. case 'low':
  163. score += 0.4
  164. break
  165. }
  166. return Math.min(1.0, score)
  167. }
  168. /**
  169. * 计算调整策略
  170. */
  171. private calculateAdjustmentStrategy(
  172. pos1: PositionInfo,
  173. pos2: PositionInfo,
  174. deviation: number,
  175. marketAnalysis: MarketAnalysis,
  176. ): AdjustmentStrategy {
  177. const absDeviation = Math.abs(deviation)
  178. // 确定策略类型
  179. let strategyType: ConvergenceStrategyType
  180. let baseAdjustmentPercent: number
  181. if (absDeviation <= this.config.targetDeviation) {
  182. strategyType = 'hold'
  183. baseAdjustmentPercent = 0
  184. } else if (absDeviation <= this.config.aggressiveThreshold) {
  185. strategyType = 'gradual_convergence'
  186. baseAdjustmentPercent = this.config.minAdjustmentPercent
  187. } else if (absDeviation <= this.config.maxDeviation) {
  188. strategyType = 'aggressive_convergence'
  189. baseAdjustmentPercent = this.config.maxAdjustmentPercent
  190. } else {
  191. strategyType = 'emergency_rebalance'
  192. baseAdjustmentPercent = this.config.maxAdjustmentPercent * 2
  193. }
  194. // 根据市场条件调整
  195. const marketAdjustment = this.calculateMarketAdjustment(marketAnalysis, baseAdjustmentPercent)
  196. const finalAdjustmentPercent = Math.min(this.config.maxAdjustmentPercent, baseAdjustmentPercent * marketAdjustment)
  197. // 计算置信度
  198. const confidence = this.calculateStrategyConfidence(deviation, marketAnalysis, strategyType)
  199. // 生成推理说明
  200. const reasoning = this.generateStrategyReasoning(deviation, marketAnalysis, strategyType)
  201. return {
  202. type: strategyType,
  203. adjustmentPercent: finalAdjustmentPercent,
  204. confidence,
  205. reasoning,
  206. targetDeviation: this.config.targetDeviation,
  207. marketRiskAdjustment: marketAdjustment,
  208. }
  209. }
  210. /**
  211. * 计算市场调整系数
  212. */
  213. private calculateMarketAdjustment(marketAnalysis: MarketAnalysis, basePercent: number): number {
  214. let adjustment = 1.0
  215. // 波动率调整
  216. if (this.config.enableVolatilityAdjustment) {
  217. switch (marketAnalysis.volatilityLevel) {
  218. case 'low':
  219. adjustment *= 1.2 // 低波动时可以更激进
  220. break
  221. case 'medium':
  222. adjustment *= 1.0 // 正常
  223. break
  224. case 'high':
  225. adjustment *= 0.7 // 高波动时更保守
  226. break
  227. }
  228. }
  229. // 流动性调整
  230. switch (marketAnalysis.liquidityLevel) {
  231. case 'high':
  232. adjustment *= 1.1
  233. break
  234. case 'medium':
  235. adjustment *= 1.0
  236. break
  237. case 'low':
  238. adjustment *= 0.8 // 低流动性时更保守
  239. break
  240. }
  241. // 趋势调整
  242. if (marketAnalysis.trendLevel === 'strong') {
  243. adjustment *= 0.9 // 强趋势时略微保守
  244. }
  245. // 应用阻尼系数
  246. adjustment *= this.config.dampingFactor
  247. return adjustment
  248. }
  249. /**
  250. * 计算策略置信度
  251. */
  252. private calculateStrategyConfidence(
  253. deviation: number,
  254. marketAnalysis: MarketAnalysis,
  255. strategyType: ConvergenceStrategyType,
  256. ): number {
  257. let confidence = 0.8 // 基础置信度
  258. // 偏差越大,紧急性越高,置信度相应调整
  259. const absDeviation = Math.abs(deviation)
  260. if (absDeviation > this.config.maxDeviation) {
  261. confidence += 0.15 // 需要紧急调整
  262. } else if (absDeviation > this.config.aggressiveThreshold) {
  263. confidence += 0.1
  264. }
  265. // 市场条件调整
  266. if (marketAnalysis.volatilityLevel === 'high') {
  267. confidence -= 0.2 // 高波动降低置信度
  268. }
  269. if (marketAnalysis.liquidityLevel === 'low') {
  270. confidence -= 0.15 // 低流动性降低置信度
  271. }
  272. if (marketAnalysis.trendLevel === 'strong') {
  273. confidence -= 0.1 // 强趋势可能干扰收敛
  274. }
  275. // 策略类型调整
  276. switch (strategyType) {
  277. case 'hold':
  278. confidence = 0.95
  279. break
  280. case 'gradual_convergence':
  281. confidence += 0.1
  282. break
  283. case 'emergency_rebalance':
  284. confidence += 0.05 // 紧急情况下虽然必要但风险较高
  285. break
  286. }
  287. return Math.max(0.1, Math.min(1.0, confidence))
  288. }
  289. /**
  290. * 生成策略推理说明
  291. */
  292. private generateStrategyReasoning(
  293. deviation: number,
  294. marketAnalysis: MarketAnalysis,
  295. strategyType: ConvergenceStrategyType,
  296. ): string {
  297. const absDeviation = Math.abs(deviation)
  298. const deviationPercent = (absDeviation * 100).toFixed(2)
  299. let reasoning = `价格偏差${deviationPercent}%`
  300. switch (strategyType) {
  301. case 'hold':
  302. reasoning += ',在目标范围内,保持现状'
  303. break
  304. case 'gradual_convergence':
  305. reasoning += ',适中偏差,采用渐进收敛策略'
  306. break
  307. case 'aggressive_convergence':
  308. reasoning += ',偏差较大,采用激进收敛策略'
  309. break
  310. case 'emergency_rebalance':
  311. reasoning += ',偏差过大,需要紧急再平衡'
  312. break
  313. }
  314. // 添加市场条件说明
  315. reasoning += `。市场条件:波动率${marketAnalysis.volatilityLevel},流动性${marketAnalysis.liquidityLevel}`
  316. if (marketAnalysis.volatilityLevel === 'high') {
  317. reasoning += ',高波动环境下调整更加谨慎'
  318. }
  319. if (marketAnalysis.liquidityLevel === 'low') {
  320. reasoning += ',低流动性环境下减少调整幅度'
  321. }
  322. return reasoning
  323. }
  324. /**
  325. * 生成具体交易动作
  326. */
  327. private generateTradeActions(
  328. strategy: AdjustmentStrategy,
  329. pos1: PositionInfo,
  330. pos2: PositionInfo,
  331. marketData: MarketData,
  332. ): { account1Action: TradeAction | null; account2Action: TradeAction | null } {
  333. if (strategy.type === 'hold') {
  334. return { account1Action: null, account2Action: null }
  335. }
  336. const deviation = this.calculatePriceDeviation(pos1, pos2)
  337. const adjustmentSize = this.calculateAdjustmentSize(pos1, pos2, strategy.adjustmentPercent)
  338. // 决定调整方向:价格高的账户减仓或降低均价,价格低的账户加仓或提高均价
  339. if (deviation > 0) {
  340. // pos1 价格高于 pos2,需要降低 pos1 均价或提高 pos2 均价
  341. return {
  342. account1Action: this.createReduceAverageAction(pos1, adjustmentSize, marketData.price),
  343. account2Action: this.createIncreaseAverageAction(pos2, adjustmentSize, marketData.price),
  344. }
  345. } else {
  346. // pos2 价格高于 pos1,需要降低 pos2 均价或提高 pos1 均价
  347. return {
  348. account1Action: this.createIncreaseAverageAction(pos1, adjustmentSize, marketData.price),
  349. account2Action: this.createReduceAverageAction(pos2, adjustmentSize, marketData.price),
  350. }
  351. }
  352. }
  353. /**
  354. * 计算调整大小
  355. */
  356. private calculateAdjustmentSize(pos1: PositionInfo, pos2: PositionInfo, adjustmentPercent: number): number {
  357. const totalSize = Math.abs(pos1.size) + Math.abs(pos2.size)
  358. const baseSize = totalSize * adjustmentPercent
  359. // 考虑最小和最大调整限制
  360. const minSize = Math.max(pos1.minOrderSize || 0.001, pos2.minOrderSize || 0.001)
  361. const maxSize = Math.min(
  362. Math.abs(pos1.size) * 0.3, // 最多调整30%的仓位
  363. Math.abs(pos2.size) * 0.3,
  364. )
  365. return Math.max(minSize, Math.min(maxSize, baseSize))
  366. }
  367. /**
  368. * 创建降低均价动作
  369. */
  370. private createReduceAverageAction(position: PositionInfo, size: number, currentPrice: number): TradeAction {
  371. const isLong = position.size > 0
  372. if (isLong) {
  373. // 多头仓位:如果当前价格低于均价,加仓降低均价;否则减仓
  374. if (currentPrice < position.averagePrice) {
  375. return {
  376. type: 'increase_position',
  377. size,
  378. side: 'buy',
  379. expectedPrice: currentPrice,
  380. purpose: 'reduce_average_price',
  381. }
  382. } else {
  383. return {
  384. type: 'reduce_position',
  385. size: Math.min(size, Math.abs(position.size) * 0.5),
  386. side: 'sell',
  387. expectedPrice: currentPrice,
  388. purpose: 'reduce_average_price',
  389. }
  390. }
  391. } else {
  392. // 空头仓位:如果当前价格高于均价,加仓降低均价;否则减仓
  393. if (currentPrice > position.averagePrice) {
  394. return {
  395. type: 'increase_position',
  396. size,
  397. side: 'sell',
  398. expectedPrice: currentPrice,
  399. purpose: 'reduce_average_price',
  400. }
  401. } else {
  402. return {
  403. type: 'reduce_position',
  404. size: Math.min(size, Math.abs(position.size) * 0.5),
  405. side: 'buy',
  406. expectedPrice: currentPrice,
  407. purpose: 'reduce_average_price',
  408. }
  409. }
  410. }
  411. }
  412. /**
  413. * 创建提高均价动作
  414. */
  415. private createIncreaseAverageAction(position: PositionInfo, size: number, currentPrice: number): TradeAction {
  416. const isLong = position.size > 0
  417. if (isLong) {
  418. // 多头仓位:如果当前价格高于均价,加仓提高均价
  419. if (currentPrice > position.averagePrice) {
  420. return {
  421. type: 'increase_position',
  422. size,
  423. side: 'buy',
  424. expectedPrice: currentPrice,
  425. purpose: 'increase_average_price',
  426. }
  427. } else {
  428. // 否则等待更好的价格或小幅减仓
  429. return {
  430. type: 'wait_better_price',
  431. size: 0,
  432. side: 'buy',
  433. expectedPrice: position.averagePrice * 1.001, // 稍高于当前均价
  434. purpose: 'increase_average_price',
  435. }
  436. }
  437. } else {
  438. // 空头仓位:如果当前价格低于均价,加仓提高均价
  439. if (currentPrice < position.averagePrice) {
  440. return {
  441. type: 'increase_position',
  442. size,
  443. side: 'sell',
  444. expectedPrice: currentPrice,
  445. purpose: 'increase_average_price',
  446. }
  447. } else {
  448. return {
  449. type: 'wait_better_price',
  450. size: 0,
  451. side: 'sell',
  452. expectedPrice: position.averagePrice * 0.999, // 稍低于当前均价
  453. purpose: 'increase_average_price',
  454. }
  455. }
  456. }
  457. }
  458. /**
  459. * 计算紧急程度
  460. */
  461. private calculateUrgency(deviation: number, marketAnalysis: MarketAnalysis): 'low' | 'medium' | 'high' {
  462. const absDeviation = Math.abs(deviation)
  463. if (absDeviation > this.config.maxDeviation) {
  464. return 'high'
  465. }
  466. if (absDeviation > this.config.aggressiveThreshold) {
  467. // 考虑市场条件
  468. if (marketAnalysis.volatilityLevel === 'high' || marketAnalysis.liquidityLevel === 'low') {
  469. return 'high'
  470. }
  471. return 'medium'
  472. }
  473. return 'low'
  474. }
  475. /**
  476. * 更新算法配置
  477. */
  478. updateConfig(newConfig: Partial<ConvergenceAlgorithmConfig>): void {
  479. this.config = { ...this.config, ...newConfig }
  480. logger.info('收敛算法配置已更新', newConfig)
  481. }
  482. /**
  483. * 获取当前配置
  484. */
  485. getConfig(): ConvergenceAlgorithmConfig {
  486. return { ...this.config }
  487. }
  488. }
  489. // 类型定义
  490. export interface PositionInfo {
  491. symbol: string
  492. size: number // 正数为多头,负数为空头
  493. averagePrice: number
  494. currentPrice: number
  495. unrealizedPnl: number
  496. minOrderSize?: number
  497. }
  498. export interface MarketData {
  499. symbol: string
  500. price: number
  501. volume: number
  502. volatility: number // 波动率
  503. trend?: 'up' | 'down' | 'sideways'
  504. momentum?: number // 动量指标
  505. historicalVolume?: number[] // 历史成交量
  506. priceHistory?: number[] // 历史价格
  507. }
  508. export interface MarketAnalysis {
  509. volatilityLevel: 'low' | 'medium' | 'high'
  510. trendLevel: 'weak' | 'moderate' | 'strong'
  511. liquidityLevel: 'low' | 'medium' | 'high'
  512. trendDirection: 'up' | 'down' | 'sideways'
  513. momentum: number
  514. volumeRatio: number
  515. riskScore: number // 0-1,越高风险越大
  516. }
  517. export interface AdjustmentStrategy {
  518. type: ConvergenceStrategyType
  519. adjustmentPercent: number
  520. confidence: number
  521. reasoning: string
  522. targetDeviation: number
  523. marketRiskAdjustment: number
  524. }
  525. export type ConvergenceStrategyType = 'hold' | 'gradual_convergence' | 'aggressive_convergence' | 'emergency_rebalance'
  526. export interface TradeAction {
  527. type: 'increase_position' | 'reduce_position' | 'wait_better_price'
  528. size: number
  529. side: 'buy' | 'sell'
  530. expectedPrice: number
  531. purpose: 'reduce_average_price' | 'increase_average_price'
  532. }
  533. export interface ConvergenceStrategy {
  534. needsAdjustment: boolean
  535. priceDeviation: number
  536. strategy: ConvergenceStrategyType
  537. account1Action: TradeAction | null
  538. account2Action: TradeAction | null
  539. confidence: number
  540. reasoning: string
  541. marketAnalysis?: MarketAnalysis
  542. urgency?: 'low' | 'medium' | 'high'
  543. }
  544. export interface ConvergenceAlgorithmConfig {
  545. targetDeviation: number // 目标价格偏差
  546. maxDeviation: number // 最大允许偏差
  547. convergenceSpeed: number // 收敛速度 (0-1)
  548. minAdjustmentPercent: number // 最小调整百分比
  549. maxAdjustmentPercent: number // 最大调整百分比
  550. aggressiveThreshold: number // 激进调整阈值
  551. dampingFactor: number // 阻尼系数
  552. volatilityWeight: number // 波动率权重
  553. trendWeight: number // 趋势权重
  554. enableAdaptiveSpeed: boolean // 启用自适应速度
  555. enableVolatilityAdjustment: boolean // 启用波动率调整
  556. }
  557. export const convergenceAlgorithm = new ConvergenceAlgorithm()