GoshawkVortexAI commited on
Commit
ce9d8fb
·
verified ·
1 Parent(s): 8d2a737

Update risk_engine.py

Browse files
Files changed (1) hide show
  1. risk_engine.py +81 -48
risk_engine.py CHANGED
@@ -1,81 +1,114 @@
1
- import numpy as np
2
  from typing import Dict, Any
 
 
 
3
  from config import (
4
  MAX_RISK_PER_TRADE,
5
- HIGH_VOLATILITY_THRESHOLD,
 
6
  REDUCED_RISK_FACTOR,
 
 
 
7
  )
8
 
9
 
10
- def compute_stop_distance(atr: float, multiplier: float = 2.0) -> float:
11
- return atr * multiplier
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
 
14
  def compute_position_size(
15
  account_equity: float,
16
  entry_price: float,
17
  stop_distance: float,
18
- risk_fraction: float = MAX_RISK_PER_TRADE,
19
  ) -> float:
20
  if stop_distance <= 0 or entry_price <= 0:
21
  return 0.0
22
  dollar_risk = account_equity * risk_fraction
23
  units = dollar_risk / stop_distance
24
- notional = units * entry_price
25
- return notional
26
-
27
-
28
- def compute_risk_fraction(
29
- vol_ratio: float,
30
- regime_score: float,
31
- base_risk: float = MAX_RISK_PER_TRADE,
32
- ) -> float:
33
- risk = base_risk
34
-
35
- if vol_ratio > HIGH_VOLATILITY_THRESHOLD:
36
- risk *= REDUCED_RISK_FACTOR
37
-
38
- if regime_score < 0.4:
39
- risk *= REDUCED_RISK_FACTOR
40
- elif regime_score < 0.6:
41
- risk *= 0.75
42
-
43
- return float(np.clip(risk, 0.001, base_risk))
44
 
45
 
46
  def evaluate_risk(
47
- df_last_close: float,
48
  atr: float,
49
  atr_pct: float,
50
  regime_score: float,
51
  vol_ratio: float,
52
- account_equity: float = 10000.0,
53
- stop_multiplier: float = 2.0,
 
 
54
  ) -> Dict[str, Any]:
55
- stop_distance = compute_stop_distance(atr, stop_multiplier)
56
- risk_fraction = compute_risk_fraction(vol_ratio, regime_score)
 
 
 
 
 
 
57
  position_notional = compute_position_size(
58
- account_equity, df_last_close, stop_distance, risk_fraction
 
 
 
59
  )
60
 
61
- stop_price_long = df_last_close - stop_distance
62
- stop_price_short = df_last_close + stop_distance
63
- risk_reward_target = stop_distance * 2.0
 
 
 
 
64
 
65
- target_long = df_last_close + risk_reward_target
66
- target_short = df_last_close - risk_reward_target
 
 
 
 
 
 
67
 
68
  return {
69
- "entry_price": df_last_close,
70
- "atr": atr,
71
- "atr_pct": atr_pct,
72
- "stop_distance": stop_distance,
73
- "stop_price_long": stop_price_long,
74
- "stop_price_short": stop_price_short,
75
- "target_long": target_long,
76
- "target_short": target_short,
77
- "risk_fraction": risk_fraction,
78
- "position_notional": position_notional,
79
- "vol_ratio": vol_ratio,
80
- "regime_score": regime_score,
 
 
 
 
 
81
  }
 
 
1
  from typing import Dict, Any
2
+
3
+ import numpy as np
4
+
5
  from config import (
6
  MAX_RISK_PER_TRADE,
7
+ HIGH_VOL_THRESHOLD,
8
+ LOW_VOL_THRESHOLD,
9
  REDUCED_RISK_FACTOR,
10
+ ATR_STOP_MULT,
11
+ RR_RATIO,
12
+ DEFAULT_ACCOUNT_EQUITY,
13
  )
14
 
15
 
16
+ def compute_dynamic_risk_fraction(
17
+ vol_ratio: float,
18
+ regime_score: float,
19
+ volume_score: float,
20
+ base_risk: float = MAX_RISK_PER_TRADE,
21
+ ) -> float:
22
+ risk = base_risk
23
+
24
+ if vol_ratio > HIGH_VOL_THRESHOLD:
25
+ risk *= REDUCED_RISK_FACTOR
26
+ elif vol_ratio > HIGH_VOL_THRESHOLD * 0.75:
27
+ risk *= 0.75
28
+
29
+ if regime_score < 0.3:
30
+ risk *= REDUCED_RISK_FACTOR
31
+ elif regime_score < 0.5:
32
+ risk *= 0.7
33
+
34
+ if volume_score < 0.3:
35
+ risk *= 0.8
36
+
37
+ return float(np.clip(risk, 0.002, base_risk))
38
 
39
 
40
  def compute_position_size(
41
  account_equity: float,
42
  entry_price: float,
43
  stop_distance: float,
44
+ risk_fraction: float,
45
  ) -> float:
46
  if stop_distance <= 0 or entry_price <= 0:
47
  return 0.0
48
  dollar_risk = account_equity * risk_fraction
49
  units = dollar_risk / stop_distance
50
+ return units * entry_price
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
 
53
  def evaluate_risk(
54
+ close: float,
55
  atr: float,
56
  atr_pct: float,
57
  regime_score: float,
58
  vol_ratio: float,
59
+ volume_score: float = 0.5,
60
+ account_equity: float = DEFAULT_ACCOUNT_EQUITY,
61
+ stop_mult: float = ATR_STOP_MULT,
62
+ rr_ratio: float = RR_RATIO,
63
  ) -> Dict[str, Any]:
64
+ stop_distance = atr * stop_mult
65
+
66
+ risk_fraction = compute_dynamic_risk_fraction(
67
+ vol_ratio=vol_ratio,
68
+ regime_score=regime_score,
69
+ volume_score=volume_score,
70
+ )
71
+
72
  position_notional = compute_position_size(
73
+ account_equity=account_equity,
74
+ entry_price=close,
75
+ stop_distance=stop_distance,
76
+ risk_fraction=risk_fraction,
77
  )
78
 
79
+ dollar_at_risk = account_equity * risk_fraction
80
+ reward_distance = stop_distance * rr_ratio
81
+
82
+ stop_long = close - stop_distance
83
+ stop_short = close + stop_distance
84
+ target_long = close + reward_distance
85
+ target_short = close - reward_distance
86
 
87
+ leverage_implied = position_notional / account_equity if account_equity > 0 else 1.0
88
+
89
+ quality_deduction = 0.0
90
+ if vol_ratio > HIGH_VOL_THRESHOLD:
91
+ quality_deduction += 0.2
92
+ if regime_score < 0.4:
93
+ quality_deduction += 0.15
94
+ risk_quality = float(np.clip(1.0 - quality_deduction, 0.0, 1.0))
95
 
96
  return {
97
+ "entry_price": close,
98
+ "atr": round(atr, 8),
99
+ "atr_pct": round(atr_pct * 100, 3),
100
+ "stop_distance": round(stop_distance, 8),
101
+ "stop_long": round(stop_long, 8),
102
+ "stop_short": round(stop_short, 8),
103
+ "target_long": round(target_long, 8),
104
+ "target_short": round(target_short, 8),
105
+ "reward_distance": round(reward_distance, 8),
106
+ "rr_ratio": rr_ratio,
107
+ "risk_fraction": round(risk_fraction * 100, 3),
108
+ "dollar_at_risk": round(dollar_at_risk, 2),
109
+ "position_notional": round(position_notional, 2),
110
+ "leverage_implied": round(leverage_implied, 2),
111
+ "vol_ratio": round(vol_ratio, 3),
112
+ "regime_score": round(regime_score, 4),
113
+ "risk_quality": round(risk_quality, 3),
114
  }