[docs]classConfigLoader:""" Utility class to load backtest configurations from a JSON file. """
[docs]@staticmethoddefload_backtest_config_from_json(filepath:str)->BacktestingOptions:""" Loads backtest configuration from a JSON file. Args: filepath (str): The path to the JSON configuration file. Returns: BacktestConfig: An instance of BacktestConfig populated from the file. Raises: FileNotFoundError: If the specified file does not exist. json.JSONDecodeError: If the file content is not valid JSON. ValueError: If the JSON content is missing required fields or has invalid types. """try:withopen(filepath,'r')asf:config_data=json.load(f)exceptFileNotFoundError:raiseFileNotFoundError(f"Configuration file not found: {filepath}")exceptjson.JSONDecodeErrorase:raisejson.JSONDecodeError(f"Invalid JSON format in {filepath}: {e}",e.doc,e.pos)returnConfigLoader._parse_backtest_config_data(config_data)
@staticmethoddef_parse_backtest_config_data(data:Dict[str,Any])->BacktestingOptions:""" Parses a dictionary into a BacktestConfig object, handling type conversions. """try:symbols=data["symbols"]start_date_str=data["start_date"]end_date_str=data["end_date"]start_date=datetime.strptime(start_date_str,"%Y-%m-%d").date()ifstart_date_strelseNoneend_date=datetime.strptime(end_date_str,"%Y-%m-%d").date()ifend_date_strelseNoneinterval_str=data["interval"]ifinterval_strisnotNone:try:interval=Interval[interval_str.upper()]exceptKeyError:raiseValueError(f"Invalid interval: '{interval_str}'. Must be one of: {[e.nameforeinInterval]}")initial_cash=float(data["initial_cash"])initial_cash=float(data["initial_cash"])transaction_cost_percent=float(data.get("transaction_cost_percent"))ifdata.get("transaction_cost_percent")isnotNoneelseNoneslippage_percent=float(data.get("slippage_percent"))ifdata.get("slippage_percent")isnotNoneelseNonereturnBacktestingOptions(symbols=symbols,start_date=start_date,end_date=end_date,interval=interval,initial_cash=initial_cash,transaction_cost_percent=transaction_cost_percent,slippage_percent=slippage_percent)except(ValueError,TypeError)ase:raiseValueError(f"Error parsing backtest config data: {e}")