Riy777 commited on
Commit
a18e556
·
verified ·
1 Parent(s): c7e82a1

Update ml_engine/titan_engine.py

Browse files
Files changed (1) hide show
  1. ml_engine/titan_engine.py +25 -22
ml_engine/titan_engine.py CHANGED
@@ -1,10 +1,9 @@
1
  # ==============================================================================
2
- # 🛡️ ml_engine/titan_engine.py (V3.0 - PyTorch ResNet Production Edition)
3
  # ==============================================================================
4
  # GEM-Architect Approved
5
- # - Matches Titan V2 Training Pipeline exactly.
6
- # - Implements cached Scaler loading.
7
- # - Uses PyTorch for inference.
8
  # ==============================================================================
9
 
10
  import os
@@ -156,7 +155,10 @@ class TitanEngine:
156
  Assuming 'df' has at least 100 rows.
157
  """
158
  try:
159
- df = df.copy().sort_values('timestamp')
 
 
 
160
 
161
  # Basic conversions
162
  close = df['close'].values.astype(float)
@@ -229,44 +231,45 @@ class TitanEngine:
229
  def predict(self, ohlcv_data: dict) -> dict:
230
  """
231
  Main Interface used by Processor.
232
- Expected input: {'5m': dataframe, '15m': dataframe ...}
233
- We primarily use '15m' as per the training configuration.
234
  """
235
  if not self.initialized: return {'score': 0.0, 'error': 'Not Initialized'}
236
 
237
  try:
238
- # We use 15m data as the main driver (matching training)
239
  target_tf = '15m'
240
- df = ohlcv_data.get(target_tf)
241
 
242
- if df is None or df.empty:
243
- # Fallback to 5m resampled if needed, but for now error out
244
  return {'score': 0.0, 'error': 'No 15m Data'}
 
 
 
 
 
 
 
 
 
 
 
 
245
 
246
  # Preprocess
247
  X_raw = self.preprocess_live_data(df)
248
  if X_raw is None:
249
  return {'score': 0.0, 'error': 'Not enough data for window'}
250
 
251
- # Scale (CRITICAL: Transform, do not fit)
252
- # Scaler expects (N_samples, N_features). X_raw is (64, 10).
253
- # We need to flatten? No, scaler works on features.
254
- # In training: scaler.transform(chunk_df[FEATURES])
255
- # So we scale the whole window row by row.
256
  X_scaled = self.scaler.transform(X_raw)
257
 
258
- # Prepare Tensor: (Batch, Channels, Length) -> (1, 10, 64)
259
- # Transpose: (64, 10) -> (10, 64)
260
  X_tensor = torch.tensor(X_scaled.T).unsqueeze(0).to(self.device)
261
 
262
  # Inference
263
  with torch.no_grad():
264
  logits = self.model(X_tensor)
265
  probs = torch.softmax(logits, dim=1).cpu().numpy()[0]
266
-
267
- # probs = [Prob(Neutral), Prob(Loss), Prob(Win)]
268
- # Titan Score = Prob(Win)
269
- # We also return raw probs for Oracle
270
 
271
  return {
272
  'score': float(probs[2]), # Win Probability
 
1
  # ==============================================================================
2
+ # 🛡️ ml_engine/titan_engine.py (V3.1 - Fix List vs DataFrame Issue)
3
  # ==============================================================================
4
  # GEM-Architect Approved
5
+ # - Fixes AttributeError: 'list' object has no attribute 'empty'
6
+ # - Auto-converts raw list data to Pandas DataFrame with correct columns.
 
7
  # ==============================================================================
8
 
9
  import os
 
155
  Assuming 'df' has at least 100 rows.
156
  """
157
  try:
158
+ df = df.copy()
159
+ # Ensure sorting if timestamp exists, else assume ordered list
160
+ if 'timestamp' in df.columns:
161
+ df = df.sort_values('timestamp')
162
 
163
  # Basic conversions
164
  close = df['close'].values.astype(float)
 
231
  def predict(self, ohlcv_data: dict) -> dict:
232
  """
233
  Main Interface used by Processor.
234
+ Handles both List and DataFrame inputs robustly.
 
235
  """
236
  if not self.initialized: return {'score': 0.0, 'error': 'Not Initialized'}
237
 
238
  try:
239
+ # We use 15m data as the main driver
240
  target_tf = '15m'
241
+ raw_data = ohlcv_data.get(target_tf)
242
 
243
+ if raw_data is None:
 
244
  return {'score': 0.0, 'error': 'No 15m Data'}
245
+
246
+ # ✅ FIX: Auto-detect List vs DataFrame
247
+ if isinstance(raw_data, list):
248
+ # Standard CCXT OHLCV structure: [timestamp, open, high, low, close, volume]
249
+ df = pd.DataFrame(raw_data, columns=['timestamp', 'open', 'high', 'low', 'close', 'volume'])
250
+ elif isinstance(raw_data, pd.DataFrame):
251
+ df = raw_data
252
+ else:
253
+ return {'score': 0.0, 'error': f'Invalid Data Type: {type(raw_data)}'}
254
+
255
+ if df.empty:
256
+ return {'score': 0.0, 'error': 'Empty Data'}
257
 
258
  # Preprocess
259
  X_raw = self.preprocess_live_data(df)
260
  if X_raw is None:
261
  return {'score': 0.0, 'error': 'Not enough data for window'}
262
 
263
+ # Scale
 
 
 
 
264
  X_scaled = self.scaler.transform(X_raw)
265
 
266
+ # Prepare Tensor
 
267
  X_tensor = torch.tensor(X_scaled.T).unsqueeze(0).to(self.device)
268
 
269
  # Inference
270
  with torch.no_grad():
271
  logits = self.model(X_tensor)
272
  probs = torch.softmax(logits, dim=1).cpu().numpy()[0]
 
 
 
 
273
 
274
  return {
275
  'score': float(probs[2]), # Win Probability