position_sizing.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. """
  2. 反脆弱仓位管理器
  3. 基于改进凯利公式计算最优仓位:
  4. f* = (p×b - q) / b + γ×Convexity + δ×Regime_Adapt
  5. """
  6. from dataclasses import dataclass
  7. from typing import Dict, Optional, Any
  8. import numpy as np
  9. from core.ecosystem import MacroRegime, UnifiedEcosystem
  10. @dataclass
  11. class PositionSize:
  12. """仓位计算结果"""
  13. base_size: float # 基础仓位
  14. adjusted_size: float # 调整后的仓位
  15. kelly_fraction: float # 凯利比例
  16. convexity_adjustment: float
  17. regime_adjustment: float
  18. max_position: float
  19. reasoning: str
  20. class AntifragilePositionSizer:
  21. """
  22. 反脆弱仓位管理器
  23. 核心算法:
  24. 1. 基础凯利公式计算
  25. 2. 凸性调节(正凸性加分,负凸性减分)
  26. 3. 生态适应系数调节
  27. """
  28. def __init__(
  29. self,
  30. kelly_fraction: float = 0.7, # 激进凯利: 70%
  31. gamma_convexity: float = 0.15,
  32. max_position: float = 1.0, # 允许满仓
  33. min_position: float = 0.0
  34. ):
  35. self.kelly_fraction = kelly_fraction
  36. self.gamma_convexity = gamma_convexity
  37. self.max_position = max_position
  38. self.min_position = min_position
  39. # 生态适应系数 - 激进配置
  40. self.regime_multipliers = {
  41. MacroRegime.SPRING: 0.9,
  42. MacroRegime.SUMMER: 1.2, # 夏季超配120%
  43. MacroRegime.AUTUMN: 0.3,
  44. MacroRegime.WINTER: 0.0,
  45. MacroRegime.UNKNOWN: 0.0
  46. }
  47. def calculate_position(
  48. self,
  49. win_probability: float,
  50. win_loss_ratio: float,
  51. ecosystem: Optional[UnifiedEcosystem] = None,
  52. convexity: float = 0.0
  53. ) -> PositionSize:
  54. """
  55. 计算建议仓位
  56. Args:
  57. win_probability: 胜率 (0-1)
  58. win_loss_ratio: 盈亏比
  59. ecosystem: 市场生态
  60. convexity: 凸性特征(正凸性策略为正,负凸性为负)
  61. Returns:
  62. PositionSize: 仓位计算结果
  63. """
  64. # 基础凯利公式
  65. q = 1 - win_probability
  66. if win_loss_ratio <= 0:
  67. kelly_f = 0.0
  68. else:
  69. kelly_f = (win_probability * win_loss_ratio - q) / win_loss_ratio
  70. kelly_f = max(0, min(1, kelly_f))
  71. # 应用半凯利
  72. base_size = kelly_f * self.kelly_fraction
  73. # 凸性调节
  74. convexity_adj = self.gamma_convexity * convexity
  75. # 生态适应调节
  76. regime_adj = 0.0
  77. if ecosystem and hasattr(ecosystem, 'macro'):
  78. regime = ecosystem.macro.regime
  79. regime_multiplier = self.regime_multipliers.get(regime, 1.0)
  80. regime_adj = (regime_multiplier - 1.0) * base_size
  81. # 计算最终仓位
  82. adjusted_size = base_size + convexity_adj + regime_adj
  83. adjusted_size = max(self.min_position, min(self.max_position, adjusted_size))
  84. return PositionSize(
  85. base_size=base_size,
  86. adjusted_size=adjusted_size,
  87. kelly_fraction=kelly_f,
  88. convexity_adjustment=convexity_adj,
  89. regime_adjustment=regime_adj,
  90. max_position=self.max_position,
  91. reasoning=f"Kelly={kelly_f:.2f}, Convexity={convexity_adj:+.2f}, Regime={regime_adj:+.2f}"
  92. )