Tonic commited on
Commit
6730937
·
unverified ·
1 Parent(s): 40e1958

fix covariate and model training issues

Browse files
Files changed (1) hide show
  1. app.py +105 -16
app.py CHANGED
@@ -3528,11 +3528,17 @@ def get_enhanced_covariate_data(symbol: str, timeframe: str = "1d", lookback_day
3528
  ))
3529
  if not data.empty:
3530
  market_data[index] = data['Close']
 
 
 
3531
  except Exception as e:
3532
- print(f"Error fetching {index}: {str(e)}")
3533
 
3534
  if market_data:
3535
  covariate_data['market_indices'] = pd.DataFrame(market_data)
 
 
 
3536
 
3537
  # Collect sector data
3538
  print("Collecting sector data...")
@@ -3545,11 +3551,17 @@ def get_enhanced_covariate_data(symbol: str, timeframe: str = "1d", lookback_day
3545
  ))
3546
  if not data.empty:
3547
  sector_data[sector] = data['Close']
 
 
 
3548
  except Exception as e:
3549
- print(f"Error fetching {sector}: {str(e)}")
3550
 
3551
  if sector_data:
3552
  covariate_data['sectors'] = pd.DataFrame(sector_data)
 
 
 
3553
 
3554
  # Collect economic indicators
3555
  print("Collecting economic indicators...")
@@ -3562,11 +3574,17 @@ def get_enhanced_covariate_data(symbol: str, timeframe: str = "1d", lookback_day
3562
  ))
3563
  if not data.empty:
3564
  economic_data[indicator] = data['Close']
 
 
 
3565
  except Exception as e:
3566
- print(f"Error fetching {indicator} ({ticker_symbol}): {str(e)}")
3567
 
3568
  if economic_data:
3569
  covariate_data['economic_indicators'] = pd.DataFrame(economic_data)
 
 
 
3570
 
3571
  return covariate_data
3572
 
@@ -3711,12 +3729,13 @@ def create_enhanced_ensemble_model(df: pd.DataFrame, covariate_data: Dict,
3711
  target = df['Close'].values
3712
 
3713
  # Technical indicators as features
3714
- features.append(df['RSI'].values)
3715
- features.append(df['MACD'].values)
3716
- features.append(df['Volatility'].values)
3717
 
3718
  if 'BB_Upper' in df.columns:
3719
  bb_position = (df['Close'] - df['BB_Lower']) / (df['BB_Upper'] - df['BB_Lower'])
 
3720
  features.append(bb_position.values)
3721
 
3722
  # Add covariate data
@@ -3725,32 +3744,44 @@ def create_enhanced_ensemble_model(df: pd.DataFrame, covariate_data: Dict,
3725
  covariate_series = covariate_data['market_indices'][col]
3726
  # Align covariate data to target length
3727
  if len(covariate_series) == len(target):
3728
- features.append(covariate_series.values)
 
 
3729
  elif len(covariate_series) > len(target):
3730
  # Truncate to target length
3731
- features.append(covariate_series.tail(len(target)).values)
 
 
3732
  else:
3733
  # Pad with last value
3734
  padded_values = np.pad(covariate_series.values,
3735
  (len(target) - len(covariate_series), 0),
3736
  mode='edge')
3737
- features.append(padded_values)
 
 
3738
 
3739
  if 'economic_indicators' in covariate_data:
3740
  for col in covariate_data['economic_indicators'].columns:
3741
  covariate_series = covariate_data['economic_indicators'][col]
3742
  # Align covariate data to target length
3743
  if len(covariate_series) == len(target):
3744
- features.append(covariate_series.values)
 
 
3745
  elif len(covariate_series) > len(target):
3746
  # Truncate to target length
3747
- features.append(covariate_series.tail(len(target)).values)
 
 
3748
  else:
3749
  # Pad with last value
3750
  padded_values = np.pad(covariate_series.values,
3751
  (len(target) - len(covariate_series), 0),
3752
  mode='edge')
3753
- features.append(padded_values)
 
 
3754
 
3755
  # Create feature matrix
3756
  X = np.column_stack(features)
@@ -3770,15 +3801,73 @@ def create_enhanced_ensemble_model(df: pd.DataFrame, covariate_data: Dict,
3770
  print(f"Truncated to minimum length: {min_length}")
3771
 
3772
  # Remove any NaN values
3773
- mask = ~np.isnan(X).any(axis=1) & ~np.isnan(y)
3774
- X = X[mask]
3775
- y = y[mask]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3776
 
3777
  print(f"After NaN removal - X shape: {X.shape}, y shape: {y.shape}")
3778
 
3779
  if len(X) < 50: # Need sufficient data
3780
  print(f"Insufficient data after preprocessing: {len(X)} samples")
3781
- return np.array([]), np.array([])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3782
 
3783
  # Initialize models
3784
  models = {
 
3528
  ))
3529
  if not data.empty:
3530
  market_data[index] = data['Close']
3531
+ print(f" Successfully collected {index}: {len(data)} data points")
3532
+ else:
3533
+ print(f" No data for {index}")
3534
  except Exception as e:
3535
+ print(f" Error fetching {index}: {str(e)}")
3536
 
3537
  if market_data:
3538
  covariate_data['market_indices'] = pd.DataFrame(market_data)
3539
+ print(f"Market indices data shape: {covariate_data['market_indices'].shape}")
3540
+ else:
3541
+ print("No market indices data collected")
3542
 
3543
  # Collect sector data
3544
  print("Collecting sector data...")
 
3551
  ))
3552
  if not data.empty:
3553
  sector_data[sector] = data['Close']
3554
+ print(f" Successfully collected {sector}: {len(data)} data points")
3555
+ else:
3556
+ print(f" No data for {sector}")
3557
  except Exception as e:
3558
+ print(f" Error fetching {sector}: {str(e)}")
3559
 
3560
  if sector_data:
3561
  covariate_data['sectors'] = pd.DataFrame(sector_data)
3562
+ print(f"Sector data shape: {covariate_data['sectors'].shape}")
3563
+ else:
3564
+ print("No sector data collected")
3565
 
3566
  # Collect economic indicators
3567
  print("Collecting economic indicators...")
 
3574
  ))
3575
  if not data.empty:
3576
  economic_data[indicator] = data['Close']
3577
+ print(f" Successfully collected {indicator} ({ticker_symbol}): {len(data)} data points")
3578
+ else:
3579
+ print(f" No data for {indicator} ({ticker_symbol})")
3580
  except Exception as e:
3581
+ print(f" Error fetching {indicator} ({ticker_symbol}): {str(e)}")
3582
 
3583
  if economic_data:
3584
  covariate_data['economic_indicators'] = pd.DataFrame(economic_data)
3585
+ print(f"Economic indicators data shape: {covariate_data['economic_indicators'].shape}")
3586
+ else:
3587
+ print("No economic indicators data collected")
3588
 
3589
  return covariate_data
3590
 
 
3729
  target = df['Close'].values
3730
 
3731
  # Technical indicators as features
3732
+ features.append(df['RSI'].fillna(50).values) # Fill NaN with neutral RSI value
3733
+ features.append(df['MACD'].fillna(0).values) # Fill NaN with zero
3734
+ features.append(df['Volatility'].fillna(df['Volatility'].mean()).values) # Fill with mean volatility
3735
 
3736
  if 'BB_Upper' in df.columns:
3737
  bb_position = (df['Close'] - df['BB_Lower']) / (df['BB_Upper'] - df['BB_Lower'])
3738
+ bb_position = bb_position.fillna(0.5) # Fill NaN with neutral position
3739
  features.append(bb_position.values)
3740
 
3741
  # Add covariate data
 
3744
  covariate_series = covariate_data['market_indices'][col]
3745
  # Align covariate data to target length
3746
  if len(covariate_series) == len(target):
3747
+ # Fill NaN values with forward fill, then backward fill
3748
+ filled_series = covariate_series.fillna(method='ffill').fillna(method='bfill')
3749
+ features.append(filled_series.values)
3750
  elif len(covariate_series) > len(target):
3751
  # Truncate to target length
3752
+ truncated_series = covariate_series.tail(len(target))
3753
+ filled_series = truncated_series.fillna(method='ffill').fillna(method='bfill')
3754
+ features.append(filled_series.values)
3755
  else:
3756
  # Pad with last value
3757
  padded_values = np.pad(covariate_series.values,
3758
  (len(target) - len(covariate_series), 0),
3759
  mode='edge')
3760
+ # Fill any remaining NaN values
3761
+ filled_values = pd.Series(padded_values).fillna(method='ffill').fillna(method='bfill').values
3762
+ features.append(filled_values)
3763
 
3764
  if 'economic_indicators' in covariate_data:
3765
  for col in covariate_data['economic_indicators'].columns:
3766
  covariate_series = covariate_data['economic_indicators'][col]
3767
  # Align covariate data to target length
3768
  if len(covariate_series) == len(target):
3769
+ # Fill NaN values with forward fill, then backward fill
3770
+ filled_series = covariate_series.fillna(method='ffill').fillna(method='bfill')
3771
+ features.append(filled_series.values)
3772
  elif len(covariate_series) > len(target):
3773
  # Truncate to target length
3774
+ truncated_series = covariate_series.tail(len(target))
3775
+ filled_series = truncated_series.fillna(method='ffill').fillna(method='bfill')
3776
+ features.append(filled_series.values)
3777
  else:
3778
  # Pad with last value
3779
  padded_values = np.pad(covariate_series.values,
3780
  (len(target) - len(covariate_series), 0),
3781
  mode='edge')
3782
+ # Fill any remaining NaN values
3783
+ filled_values = pd.Series(padded_values).fillna(method='ffill').fillna(method='bfill').values
3784
+ features.append(filled_values)
3785
 
3786
  # Create feature matrix
3787
  X = np.column_stack(features)
 
3801
  print(f"Truncated to minimum length: {min_length}")
3802
 
3803
  # Remove any NaN values
3804
+ print(f"Checking for NaN values in feature matrix...")
3805
+ nan_rows = np.isnan(X).any(axis=1)
3806
+ nan_count = nan_rows.sum()
3807
+ print(f"Found {nan_count} rows with NaN values out of {len(X)} total rows")
3808
+
3809
+ if nan_count > 0:
3810
+ # Check which features have NaN values
3811
+ for i, feature_name in enumerate(['RSI', 'MACD', 'Volatility', 'BB_Position'] +
3812
+ [f'Market_{j}' for j in range(len(features)-4)]):
3813
+ if i < X.shape[1]:
3814
+ nan_count_feature = np.isnan(X[:, i]).sum()
3815
+ if nan_count_feature > 0:
3816
+ print(f" Feature {feature_name}: {nan_count_feature} NaN values")
3817
+
3818
+ # Only remove rows if there are still NaN values after filling
3819
+ if nan_count > 0:
3820
+ mask = ~np.isnan(X).any(axis=1) & ~np.isnan(y)
3821
+ X = X[mask]
3822
+ y = y[mask]
3823
+ print(f"Removed {nan_count} rows with NaN values")
3824
+ else:
3825
+ print("No NaN values found in feature matrix")
3826
 
3827
  print(f"After NaN removal - X shape: {X.shape}, y shape: {y.shape}")
3828
 
3829
  if len(X) < 50: # Need sufficient data
3830
  print(f"Insufficient data after preprocessing: {len(X)} samples")
3831
+ print("This might be due to:")
3832
+ print("1. Too many NaN values in covariate data")
3833
+ print("2. Insufficient historical data")
3834
+ print("3. Data alignment issues")
3835
+ print("Trying fallback with technical indicators only...")
3836
+
3837
+ # Fallback: Use only technical indicators
3838
+ try:
3839
+ fallback_features = []
3840
+ fallback_features.append(df['RSI'].fillna(50).values)
3841
+ fallback_features.append(df['MACD'].fillna(0).values)
3842
+ fallback_features.append(df['Volatility'].fillna(df['Volatility'].mean()).values)
3843
+
3844
+ if 'BB_Upper' in df.columns:
3845
+ bb_position = (df['Close'] - df['BB_Lower']) / (df['BB_Upper'] - df['BB_Lower'])
3846
+ bb_position = bb_position.fillna(0.5)
3847
+ fallback_features.append(bb_position.values)
3848
+
3849
+ X_fallback = np.column_stack(fallback_features)
3850
+ y_fallback = df['Close'].values
3851
+
3852
+ # Remove any remaining NaN values
3853
+ mask = ~np.isnan(X_fallback).any(axis=1) & ~np.isnan(y_fallback)
3854
+ X_fallback = X_fallback[mask]
3855
+ y_fallback = y_fallback[mask]
3856
+
3857
+ print(f"Fallback feature matrix shape: {X_fallback.shape}")
3858
+
3859
+ if len(X_fallback) >= 50:
3860
+ print("Using fallback ensemble with technical indicators only")
3861
+ # Use the fallback data for the rest of the function
3862
+ X = X_fallback
3863
+ y = y_fallback
3864
+ else:
3865
+ print("Fallback also failed, returning empty arrays")
3866
+ return np.array([]), np.array([])
3867
+
3868
+ except Exception as fallback_error:
3869
+ print(f"Fallback failed: {str(fallback_error)}")
3870
+ return np.array([]), np.array([])
3871
 
3872
  # Initialize models
3873
  models = {