ivolatility-backtesting 1.8.0__tar.gz → 1.10.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of ivolatility-backtesting might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ivolatility_backtesting
3
- Version: 1.8.0
3
+ Version: 1.10.0
4
4
  Summary: A universal backtesting framework for financial strategies using the IVolatility API.
5
5
  Author-email: IVolatility <support@ivolatility.com>
6
6
  Project-URL: Homepage, https://ivolatility.com
@@ -2350,7 +2350,7 @@ def preload_options_data(config, progress_widgets=None):
2350
2350
  symbol = config['symbol']
2351
2351
  dte_target = config.get('dte_target', 30)
2352
2352
  lookback_period = config.get('lookback_period', 60)
2353
- chunk_months = config.get('chunk_months', 3)
2353
+ chunk_months = config.get('chunk_months', 1) # Default 1 month (~30 days), not 3
2354
2354
 
2355
2355
  # Calculate date chunks
2356
2356
  data_start = start_date - timedelta(days=lookback_period + 60)
@@ -2358,8 +2358,10 @@ def preload_options_data(config, progress_widgets=None):
2358
2358
  date_chunks = []
2359
2359
  current_chunk_start = data_start
2360
2360
  while current_chunk_start <= end_date:
2361
+ # Use chunk_days_options if available, otherwise chunk_months * 30
2362
+ chunk_days = config.get('chunk_days_options', chunk_months * 30)
2361
2363
  chunk_end = min(
2362
- current_chunk_start + timedelta(days=chunk_months * 31),
2364
+ current_chunk_start + timedelta(days=chunk_days),
2363
2365
  end_date
2364
2366
  )
2365
2367
  date_chunks.append((current_chunk_start, chunk_end))
@@ -3019,23 +3021,40 @@ def optimize_parameters(base_config, param_grid, strategy_function,
3019
3021
  print("Running optimization (no progress bar)...")
3020
3022
 
3021
3023
  # ═══════════════════════════════════════════════════════════════════════════
3022
- # PRELOAD DATA ONCE (FOR ALL OPTIMIZATION ITERATIONS)
3024
+ # DEPRECATED: optimize_parameters should NOT preload data internally!
3025
+ # Data should be preloaded BEFORE calling optimize_parameters using preload_data_universal()
3023
3026
  # ═══════════════════════════════════════════════════════════════════════════
3024
- print("\n" + "="*80)
3025
- print("📥 PRELOADING OPTIONS DATA (loads ONCE, reused for all combinations)")
3026
- print("="*80)
3027
+ # Check if data is already preloaded
3028
+ preloaded_keys = [k for k in base_config.keys() if k.startswith('_preloaded_')]
3027
3029
 
3028
- preloaded_lean_df, preloaded_options_df = preload_options_data(
3029
- base_config,
3030
- progress_widgets=shared_progress['progress_widgets'] if shared_progress else None
3031
- )
3030
+ # Initialize these variables for backward compatibility
3031
+ preloaded_lean_df = None
3032
+ preloaded_options_df = None
3033
+ use_legacy_preload = False
3032
3034
 
3033
- if preloaded_lean_df.empty:
3034
- print("\n❌ ERROR: Failed to preload data. Cannot proceed with optimization.")
3035
- return pd.DataFrame(), None
3036
-
3037
- print(f"✓ Preloading complete! Data will be reused for all {total_combinations} combinations")
3038
- print("="*80 + "\n")
3035
+ if not preloaded_keys:
3036
+ # Fallback: use old preload_options_data (for backward compatibility)
3037
+ print("\n" + "="*80)
3038
+ print("📥 PRELOADING OPTIONS DATA (loads ONCE, reused for all combinations)")
3039
+ print("="*80)
3040
+ print("⚠️ WARNING: Data not preloaded! Using deprecated preload_options_data()")
3041
+ print("⚠️ Recommendation: Use preload_data_universal() before calling optimize_parameters()")
3042
+ print("="*80)
3043
+
3044
+ preloaded_lean_df, preloaded_options_df = preload_options_data(
3045
+ base_config,
3046
+ progress_widgets=shared_progress['progress_widgets'] if shared_progress else None
3047
+ )
3048
+
3049
+ if preloaded_lean_df.empty:
3050
+ print("\n❌ ERROR: Failed to preload data. Cannot proceed with optimization.")
3051
+ return pd.DataFrame(), None
3052
+
3053
+ use_legacy_preload = True
3054
+ print(f"✓ Preloading complete! Data will be reused for all {total_combinations} combinations")
3055
+ print("="*80 + "\n")
3056
+ else:
3057
+ print("\n✓ Using preloaded data from preload_data_universal() (recommended method)\n")
3039
3058
 
3040
3059
  # ═══════════════════════════════════════════════════════════════════════════
3041
3060
  # RESET PROGRESS BAR FOR OPTIMIZATION LOOP
@@ -3062,8 +3081,11 @@ def optimize_parameters(base_config, param_grid, strategy_function,
3062
3081
  test_config['strategy_name'] = f"{base_config.get('strategy_name', 'Strategy')} [{param_str}]"
3063
3082
 
3064
3083
  # ═══ ADD PRELOADED DATA TO CONFIG ═══
3065
- test_config['_preloaded_lean_df'] = preloaded_lean_df
3066
- test_config['_preloaded_options_cache'] = preloaded_options_df
3084
+ # Only add legacy preloaded data if it was loaded by preload_options_data
3085
+ if use_legacy_preload:
3086
+ test_config['_preloaded_lean_df'] = preloaded_lean_df
3087
+ test_config['_preloaded_options_cache'] = preloaded_options_df
3088
+ # Otherwise, data is already in base_config from preload_data_universal
3067
3089
 
3068
3090
  # Update progress
3069
3091
  if has_widgets:
@@ -3387,8 +3409,9 @@ def optimize_parameters(base_config, param_grid, strategy_function,
3387
3409
  # Create config for best combination
3388
3410
  best_config = base_config.copy()
3389
3411
  best_config.update(best_params)
3390
- best_config['_preloaded_lean_df'] = preloaded_lean_df
3391
- best_config['_preloaded_options_cache'] = preloaded_options_df
3412
+ if use_legacy_preload:
3413
+ best_config['_preloaded_lean_df'] = preloaded_lean_df
3414
+ best_config['_preloaded_options_cache'] = preloaded_options_df
3392
3415
 
3393
3416
  # Create folder for best combination
3394
3417
  best_combo_folder = os.path.join(results_folder, 'best_combination')
@@ -4059,7 +4082,9 @@ def apply_optimization_preset(config, preset='default'):
4059
4082
  # Update only specific fields from preset
4060
4083
  preset_data = presets[preset]
4061
4084
 
4062
- # Save user-defined param_grid if it exists (user override has priority)
4085
+ # CRITICAL LOGIC:
4086
+ # - If preset == 'default' → use param_grid from config (if exists)
4087
+ # - If preset != 'default' → use param_grid from preset (override config)
4063
4088
  user_param_grid = config.get('param_grid')
4064
4089
 
4065
4090
  fields_to_update = [
@@ -4071,19 +4096,22 @@ def apply_optimization_preset(config, preset='default'):
4071
4096
 
4072
4097
  for field in fields_to_update:
4073
4098
  if field in preset_data:
4074
- # Special handling for param_grid: preserve user's param_grid if provided
4075
- if field == 'param_grid' and user_param_grid is not None:
4076
- # User defined param_grid - don't override with preset
4077
- continue
4078
- config[field] = preset_data[field]
4079
-
4080
- # Restore user's param_grid if it was saved (preserve user override)
4081
- if user_param_grid is not None:
4082
- config['param_grid'] = user_param_grid
4099
+ # Special handling for param_grid based on preset type
4100
+ if field == 'param_grid':
4101
+ if preset == 'default' and user_param_grid is not None:
4102
+ # 'default' preset → preserve user's param_grid
4103
+ continue
4104
+ else:
4105
+ # Non-default preset (quick_test, aggressive, etc.) use preset's param_grid
4106
+ config[field] = preset_data[field]
4107
+ else:
4108
+ config[field] = preset_data[field]
4083
4109
 
4084
4110
  print(f"✓ Applied preset: {preset}")
4085
- if user_param_grid is not None:
4086
- print(f" (Preserved user-defined param_grid)")
4111
+ if preset == 'default' and user_param_grid is not None:
4112
+ print(f" (Using user-defined param_grid from config)")
4113
+ elif preset != 'default':
4114
+ print(f" (Using param_grid from preset, ignoring config)")
4087
4115
 
4088
4116
  return config
4089
4117
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ivolatility_backtesting
3
- Version: 1.8.0
3
+ Version: 1.10.0
4
4
  Summary: A universal backtesting framework for financial strategies using the IVolatility API.
5
5
  Author-email: IVolatility <support@ivolatility.com>
6
6
  Project-URL: Homepage, https://ivolatility.com
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "ivolatility_backtesting"
7
- version = "1.8.0"
7
+ version = "1.10.0"
8
8
  description = "A universal backtesting framework for financial strategies using the IVolatility API."
9
9
  readme = "README.md"
10
10
  authors = [