Riy777 commited on
Commit
102418b
Β·
verified Β·
1 Parent(s): b39d9b5

Update ml_engine/oracle_engine.py

Browse files
Files changed (1) hide show
  1. ml_engine/oracle_engine.py +50 -43
ml_engine/oracle_engine.py CHANGED
@@ -1,10 +1,9 @@
1
  # ==============================================================================
2
- # 🧠 ml_engine/oracle_engine.py (V4.5 - LightGBM Golden Threshold Edition)
3
  # ==============================================================================
4
  # GEM-Architect Approved
5
- # - Uses the trained LightGBM model.
6
- # - Implements the "Golden Threshold" strategy (0.5% Predicted Return).
7
- # - Integrates CNN probabilities + Market Context properly.
8
  # ==============================================================================
9
 
10
  import os
@@ -23,14 +22,11 @@ class OracleEngine:
23
  self.model = None
24
  self.initialized = False
25
 
26
- # πŸ† THE GOLDEN CONFIGURATION (From Testing)
27
- # Threshold 0.005 (0.5% return) gave 77% Win Rate.
28
  self.CONFIDENCE_THRESHOLD = 0.005
29
 
30
- # Context Features (Must match training)
31
  self.ctx_features = ["ret_var_30", "ret_skew_30", "ret_kurt_30"]
32
- # CNN Features inputs
33
- self.cnn_cols = ["cnn_prob_neutral", "cnn_prob_loss", "cnn_prob_win"]
34
 
35
  async def initialize(self):
36
  """Load LightGBM Model"""
@@ -51,12 +47,33 @@ class OracleEngine:
51
  print(f"❌ [Oracle] Init Error: {e}")
52
  return False
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  def _calc_context_features(self, df):
55
- """Calculate statistical context features from OHLCV"""
56
  try:
57
  if len(df) < 30: return np.zeros(3)
58
 
 
59
  close = df['close'].values.astype(float)
 
60
  prev_close = np.roll(close, 1); prev_close[0] = close[0]
61
  log_ret = np.log(close / np.maximum(prev_close, 1e-9))
62
 
@@ -75,28 +92,27 @@ class OracleEngine:
75
  async def predict(self, symbol_data: dict) -> dict:
76
  """
77
  Decision Core.
78
- Input: symbol_data containing 'ohlcv' and 'titan_probs'.
79
  """
80
  if not self.initialized:
81
- return {'action': 'WAIT', 'reason': 'Oracle Not Init', 'confidence': 0.0}
82
 
83
  try:
84
  # 1. Get Inputs
85
- # Titan Probs: [Neutral, Loss, Win]
86
- titan_probs = symbol_data.get('titan_probs')
87
  if not titan_probs or len(titan_probs) != 3:
88
- return {'action': 'WAIT', 'reason': 'No Titan Input', 'confidence': 0.0}
89
 
90
- # Market Context (From 15m data)
91
- ohlcv_15m = symbol_data.get('ohlcv', {}).get('15m')
92
- if ohlcv_15m is None or ohlcv_15m.empty:
93
- return {'action': 'WAIT', 'reason': 'No Market Data', 'confidence': 0.0}
94
 
95
- # 2. Build Feature Vector
96
- # Order: [cnn_p0, cnn_p1, cnn_p2, ctx_var, ctx_skew, ctx_kurt]
97
- ctx_vals = self._calc_context_features(ohlcv_15m)
98
 
99
- # Handle NaN/Inf
 
100
  ctx_vals = np.nan_to_num(ctx_vals, nan=0.0)
101
 
102
  input_vector = np.concatenate([titan_probs, ctx_vals]).reshape(1, -1)
@@ -104,40 +120,31 @@ class OracleEngine:
104
  # 3. Predict (Net Expected Return)
105
  predicted_pnl = float(self.model.predict(input_vector)[0])
106
 
107
- # 4. Decision Logic (The Golden Rule)
108
- # Titan Win Prob (Raw Confidence)
109
  cnn_win_prob = titan_probs[2]
110
-
111
- # We combine Oracle PnL Prediction AND Titan Win Prob
112
- # Oracle says "How much money?", Titan says "How likely?"
113
-
114
  is_buy = False
115
  reason = ""
116
 
117
  if predicted_pnl > self.CONFIDENCE_THRESHOLD:
118
- # Strong signal
119
  is_buy = True
120
- strength = "HIGH"
121
- reason = f"Golden Setup (Exp. Ret: {predicted_pnl*100:.2f}%)"
122
  elif predicted_pnl > (self.CONFIDENCE_THRESHOLD * 0.5) and cnn_win_prob > 0.7:
123
- # Moderate return but very high certainty
124
  is_buy = True
125
- strength = "MODERATE"
126
- reason = f"High Certainty (Win Prob: {cnn_win_prob:.2f})"
127
  else:
128
- reason = f"Weak Signal (Exp: {predicted_pnl*100:.2f}% < {self.CONFIDENCE_THRESHOLD*100:.1f}%)"
129
 
130
  # 5. Build Result
131
  result = {
132
- 'confidence': float(cnn_win_prob), # For compatibility with old logic
133
- 'oracle_score': float(predicted_pnl), # The real juice
134
  'target_class': "TP2" if predicted_pnl > 0.01 else "TP1",
135
  'action_type': 'BUY',
136
- 'analysis_summary': f"Oracle: {predicted_pnl*100:.2f}% Return | Titan: {cnn_win_prob:.2f} Win"
137
  }
138
 
139
  if is_buy:
140
- result['action'] = 'WATCH' # System will upgrade to BUY after Governance
141
  else:
142
  result['action'] = 'WAIT'
143
  result['reason'] = reason
@@ -145,6 +152,6 @@ class OracleEngine:
145
  return result
146
 
147
  except Exception as e:
148
- print(f"❌ [Oracle] Inference Error: {e}")
149
- traceback.print_exc()
150
- return {'action': 'WAIT', 'reason': 'Error', 'confidence': 0.0}
 
1
  # ==============================================================================
2
+ # 🧠 ml_engine/oracle_engine.py (V4.6 - Fix List/DataFrame Bug)
3
  # ==============================================================================
4
  # GEM-Architect Approved
5
+ # - Fixes AttributeError: 'list' object has no attribute 'empty'
6
+ # - Auto-converts raw list OHLCV to DataFrame.
 
7
  # ==============================================================================
8
 
9
  import os
 
22
  self.model = None
23
  self.initialized = False
24
 
25
+ # πŸ† THE GOLDEN CONFIGURATION
 
26
  self.CONFIDENCE_THRESHOLD = 0.005
27
 
28
+ # Context Features
29
  self.ctx_features = ["ret_var_30", "ret_skew_30", "ret_kurt_30"]
 
 
30
 
31
  async def initialize(self):
32
  """Load LightGBM Model"""
 
47
  print(f"❌ [Oracle] Init Error: {e}")
48
  return False
49
 
50
+ def _prepare_dataframe(self, data_input):
51
+ """Helper to safely convert List or DF to DataFrame"""
52
+ try:
53
+ if data_input is None: return None
54
+
55
+ # If it's already a DataFrame
56
+ if isinstance(data_input, pd.DataFrame):
57
+ return data_input if not data_input.empty else None
58
+
59
+ # If it's a List (CCXT format: [ts, o, h, l, c, v])
60
+ if isinstance(data_input, list):
61
+ if len(data_input) == 0: return None
62
+ df = pd.DataFrame(data_input, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
63
+ return df
64
+
65
+ return None
66
+ except Exception:
67
+ return None
68
+
69
  def _calc_context_features(self, df):
70
+ """Calculate statistical context features from OHLCV DataFrame"""
71
  try:
72
  if len(df) < 30: return np.zeros(3)
73
 
74
+ # Ensure close is float
75
  close = df['close'].values.astype(float)
76
+
77
  prev_close = np.roll(close, 1); prev_close[0] = close[0]
78
  log_ret = np.log(close / np.maximum(prev_close, 1e-9))
79
 
 
92
  async def predict(self, symbol_data: dict) -> dict:
93
  """
94
  Decision Core.
95
+ Input: symbol_data containing 'ohlcv' (List or DF) and 'pattern_probs'.
96
  """
97
  if not self.initialized:
98
+ return {'action': 'WAIT', 'reason': 'Oracle Not Init', 'oracle_score': 0.0}
99
 
100
  try:
101
  # 1. Get Inputs
102
+ # Support both key names for compatibility
103
+ titan_probs = symbol_data.get('pattern_probs') or symbol_data.get('titan_probs')
104
  if not titan_probs or len(titan_probs) != 3:
105
+ return {'action': 'WAIT', 'reason': 'No Pattern Input', 'oracle_score': 0.0}
106
 
107
+ # Market Context (From 15m data) - βœ… FIXED HERE
108
+ raw_15m = symbol_data.get('ohlcv', {}).get('15m')
109
+ df_15m = self._prepare_dataframe(raw_15m)
 
110
 
111
+ if df_15m is None:
112
+ return {'action': 'WAIT', 'reason': 'No Market Data', 'oracle_score': 0.0}
 
113
 
114
+ # 2. Build Feature Vector
115
+ ctx_vals = self._calc_context_features(df_15m)
116
  ctx_vals = np.nan_to_num(ctx_vals, nan=0.0)
117
 
118
  input_vector = np.concatenate([titan_probs, ctx_vals]).reshape(1, -1)
 
120
  # 3. Predict (Net Expected Return)
121
  predicted_pnl = float(self.model.predict(input_vector)[0])
122
 
123
+ # 4. Decision Logic
 
124
  cnn_win_prob = titan_probs[2]
 
 
 
 
125
  is_buy = False
126
  reason = ""
127
 
128
  if predicted_pnl > self.CONFIDENCE_THRESHOLD:
 
129
  is_buy = True
130
+ reason = f"Golden Setup (Exp: {predicted_pnl*100:.2f}%)"
 
131
  elif predicted_pnl > (self.CONFIDENCE_THRESHOLD * 0.5) and cnn_win_prob > 0.7:
 
132
  is_buy = True
133
+ reason = f"High Certainty (Win: {cnn_win_prob:.2f})"
 
134
  else:
135
+ reason = f"Weak (Exp: {predicted_pnl*100:.2f}%)"
136
 
137
  # 5. Build Result
138
  result = {
139
+ 'confidence': float(cnn_win_prob),
140
+ 'oracle_score': float(predicted_pnl),
141
  'target_class': "TP2" if predicted_pnl > 0.01 else "TP1",
142
  'action_type': 'BUY',
143
+ 'analysis_summary': f"Oracle: {predicted_pnl*100:.2f}% | Pattern: {cnn_win_prob:.2f}"
144
  }
145
 
146
  if is_buy:
147
+ result['action'] = 'WATCH'
148
  else:
149
  result['action'] = 'WAIT'
150
  result['reason'] = reason
 
152
  return result
153
 
154
  except Exception as e:
155
+ # print(f"❌ [Oracle] Inference Error: {e}") # Disabled to reduce log spam
156
+ # traceback.print_exc()
157
+ return {'action': 'WAIT', 'reason': 'Error', 'oracle_score': 0.0}