{"record":{"id":"3dfd427cc200b3a4","repo":"StockSharp/StockSharp","slug":"parameters-3dfd42","errorCode":null,"errorMessage":"parameters","messagePattern":"parameters","errorType":"validation","errorClass":"ArgumentOutOfRangeException","httpStatus":null,"severity":"error","filePath":"Algo.Gpu/Indicators/GpuFractalAdaptiveMovingAverageCalculator.cs","lineNumber":65,"sourceCode":"\t/// <param name=\"accelerator\">ILGPU accelerator.</param>\n\tpublic GpuFractalAdaptiveMovingAverageCalculator(Context context, Accelerator accelerator)\n\t\t: base(context, accelerator)\n\t{\n\t\t_kernel = Accelerator.LoadAutoGroupedStreamKernel\n\t\t\t<Index2D, ArrayView<GpuCandle>, ArrayView<GpuIndicatorResult>, ArrayView<int>, ArrayView<int>, ArrayView<GpuFramaParams>>(FramaParamsSeriesKernel);\n\t}\n\n\t/// <inheritdoc />\n\tpublic override GpuIndicatorResult[][][] Calculate(GpuCandle[][] candlesSeries, GpuFramaParams[] parameters)\n\t{\n\t\tArgumentNullException.ThrowIfNull(candlesSeries);\n\t\tArgumentNullException.ThrowIfNull(parameters);\n\n\t\tif (candlesSeries.Length == 0)\n\t\t\tthrow new ArgumentOutOfRangeException(nameof(candlesSeries));\n\n\t\tif (parameters.Length == 0)\n\t\t\tthrow new ArgumentOutOfRangeException(nameof(parameters));\n\n\t\tvar seriesCount = candlesSeries.Length;\n\n\t\t// Flatten input\n\t\tvar totalSize = 0;\n\t\tvar seriesOffsets = new int[seriesCount];\n\t\tvar seriesLengths = new int[seriesCount];\n\n\t\tfor (var s = 0; s < seriesCount; s++)\n\t\t{\n\t\t\tseriesOffsets[s] = totalSize;\n\t\t\tvar len = candlesSeries[s]?.Length ?? 0;\n\t\t\tseriesLengths[s] = len;\n\t\t\ttotalSize += len;\n\t\t}\n\n\t\tvar flatCandles = new GpuCandle[totalSize];\n\t\tvar offset = 0;","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/StockSharp/StockSharp/blob/601a191de678bff83da28b14828f8885214ca71c/Algo.Gpu/Indicators/GpuFractalAdaptiveMovingAverageCalculator.cs#L47-L83","documentation":"The Fractal Adaptive Moving Average (FRAMA) calculator computes an adaptive moving average whose smoothing constant responds to the fractal dimension of recent price action across one or more GpuFramaParams parameter sets. Calculate parameterizes its 2DD kernel grid over both the candle-series count and the parameter-set count (series x parameters), so a zero-length parameters array collapses one grid axis and leaves nothing to dispatch. ArgumentOutOfRangeException(nameof(parameters)) fires at the top of Calculate before the flattening loop, ensuring a fast failure rather than a meaningless GPU kernel launch.","triggerScenarios":"Calling Calculate with a GpuFramaParams[] whose Length is 0 (e.g., calculator.Calculate(candlesSeries, Array.Empty<GpuFramaParams>())). Also occurs when a parameter sweep or configuration loader produces zero entries and the empty array is passed through without a count guard.","commonSituations":"A parameter grid-search where validation rules filtered out all candidates; a configuration file with no parameter section for this indicator; a default-parameter factory with an off-by-one or early-return bug; a user-facing settings UI that saved zero parameter sets; JSON deserialization where the GpuFramaParams array key was absent and defaulted to empty.","solutions":["Guard the call site: check parameters.Length > 0 before invoking Calculate.","Verify the parameter generation or sweep logic produces at least one entry; add a sensible default parameter set as fallback.","Validate configuration at startup: if the indicator parameter section is missing or empty, fail fast with a clear message naming the indicator.","For user-driven parameter UI, enforce a minimum of one GpuFramaParams before enabling the calculate action."],"exampleFix":"// before -- throws ArgumentOutOfRangeException (ParamName: parameters)\nvar results = calculator.Calculate(candlesSeries, parameters);\n\n// after -- guard before calling\nif (parameters is null || parameters.Length == 0)\n    throw new ArgumentException(\n        $\"At least one GpuFramaParams set is required.\", nameof(parameters));\nvar results = calculator.Calculate(candlesSeries, parameters);","handlingStrategy":"validation","validationCode":"// Pre-call validation for GpuFractalAdaptiveMovingAverageCalculator.Calculate\nif (parameters is null || parameters.Length == 0)\n    throw new ArgumentException(\n        $\"At least one GpuFramaParams set is required.\", nameof(parameters));","typeGuard":"static bool HasParameterSets(GpuFramaParams[]? parameters) =>\n    parameters is { Length: > 0 };","tryCatchPattern":"GpuIndicatorResult[][][] results;\ntry\n{\n    results = calculator.Calculate(candlesSeries, parameters);\n}\ncatch (ArgumentOutOfRangeException ex) when (ex.ParamName == \"parameters\")\n{\n    logger.LogWarning(\"GpuFractalAdaptiveMovingAverageCalculator: parameters array was empty, returning empty results\");\n    results = Array.Empty<GpuIndicatorResult[][][]>();\n}","preventionTips":["Validate parameter arrays at configuration load time, not just at calculation time.","Enforce a minimum of one parameter set in parameter builder and factory methods.","Add a startup health check verifying each configured indicator has non-empty parameters.","Use a shared guard helper (e.g., RequireNonEmpty) and call it consistently across all indicator calculators."],"tags":["gpu","argument-validation","indicator-params","ilgpu","frama"],"backgroundTag":null,"analyzedSha":"601a191de678bff83da28b14828f8885214ca71c","analyzedAt":"2026-08-13T20:43:24.460Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}