]> Piment Noir Git Repositories - freqai-strategies.git/commitdiff
refactor(quickadapter): replace duplicated domain string literals with canonical...
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Thu, 17 Sep 2026 20:23:14 +0000 (22:23 +0200)
committerJérôme Benoit <jerome.benoit@piment-noir.org>
Thu, 17 Sep 2026 20:23:14 +0000 (22:23 +0200)
quickadapter/.basedpyright/diagnostics.json
quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py
quickadapter/user_data/strategies/LabelTransformer.py
quickadapter/user_data/strategies/QuickAdapterV3.py
quickadapter/user_data/strategies/Utils.py

index 01badd32925e8e2b3f92958f93e963a1e5177653..7b4a437f7bdf900f6cfb115a332f2539d96677ea 100644 (file)
   "diagnostics": [
     {
       "endCharacter": 46,
-      "endLine": 1301,
+      "endLine": 1307,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"str | None\" cannot be assigned to parameter \"default\" of type \"str\" in function \"_validate_label_selection_metric\"\n  Type \"str | None\" is not assignable to type \"str\"\n    \"None\" is not assignable to \"str\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 24,
-      "startLine": 1301
+      "startLine": 1307
     },
     {
       "endCharacter": 79,
-      "endLine": 2083,
+      "endLine": 2089,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n  Attribute \"index\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 74,
-      "startLine": 2083
+      "startLine": 2089
     },
     {
       "endCharacter": 72,
-      "endLine": 2085,
+      "endLine": 2091,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n  Attribute \"index\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 67,
-      "startLine": 2085
+      "startLine": 2091
     },
     {
       "endCharacter": 90,
-      "endLine": 2094,
+      "endLine": 2100,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n  Attribute \"index\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 85,
-      "startLine": 2094
+      "startLine": 2100
     },
     {
       "endCharacter": 34,
-      "endLine": 2107,
+      "endLine": 2113,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"train_features\" of type \"DataFrame\" in function \"_filter_train_by_mask\"\n  Type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n    \"list[Unknown]\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 20,
-      "startLine": 2107
+      "startLine": 2113
     },
     {
       "endCharacter": 32,
-      "endLine": 2108,
+      "endLine": 2114,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"train_labels\" of type \"DataFrame\" in function \"_filter_train_by_mask\"\n  Type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n    \"list[Unknown]\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 20,
-      "startLine": 2108
+      "startLine": 2114
     },
     {
       "endCharacter": 38,
-      "endLine": 2109,
+      "endLine": 2115,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"train_weights\" of type \"NDArray[floating[Any]]\" in function \"_filter_train_by_mask\"\n  Type \"Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"NDArray[floating[Any]]\"\n    \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 20,
-      "startLine": 2109
+      "startLine": 2115
     },
     {
       "endCharacter": 59,
-      "endLine": 2112,
+      "endLine": 2118,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" cannot be assigned to parameter \"train_label_weights\" of type \"NDArray[floating[Any]] | None\" in function \"_filter_train_by_mask\"\n  Type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" is not assignable to type \"NDArray[floating[Any]] | None\"\n    Type \"list[Unknown]\" is not assignable to type \"NDArray[floating[Any]] | None\"\n      \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"\n      \"list[Unknown]\" is not assignable to \"None\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 40,
-      "startLine": 2112
+      "startLine": 2118
     },
     {
       "endCharacter": 34,
-      "endLine": 2146,
+      "endLine": 2152,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"features\" of type \"DataFrame\" in function \"_shuffle_split_rows\"\n  Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n    \"list[Unknown]\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 20,
-      "startLine": 2146
+      "startLine": 2152
     },
     {
       "endCharacter": 32,
-      "endLine": 2147,
+      "endLine": 2153,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"labels\" of type \"DataFrame\" in function \"_shuffle_split_rows\"\n  Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n    \"list[Unknown]\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 20,
-      "startLine": 2147
+      "startLine": 2153
     },
     {
       "endCharacter": 38,
-      "endLine": 2148,
+      "endLine": 2154,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"base_weights\" of type \"NDArray[floating[Any]]\" in function \"_shuffle_split_rows\"\n  Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"NDArray[floating[Any]]\"\n    \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 20,
-      "startLine": 2148
+      "startLine": 2154
     },
     {
       "endCharacter": 39,
-      "endLine": 2149,
+      "endLine": 2155,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" cannot be assigned to parameter \"label_weights\" of type \"NDArray[floating[Any]] | None\" in function \"_shuffle_split_rows\"\n  Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" is not assignable to type \"NDArray[floating[Any]] | None\"\n    Type \"list[Unknown]\" is not assignable to type \"NDArray[floating[Any]] | None\"\n      \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"\n      \"list[Unknown]\" is not assignable to \"None\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 20,
-      "startLine": 2149
+      "startLine": 2155
     },
     {
       "endCharacter": 37,
-      "endLine": 2156,
+      "endLine": 2162,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | DataFrame\" cannot be assigned to parameter \"features\" of type \"DataFrame\" in function \"_shuffle_split_rows\"\n  Type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | DataFrame\" is not assignable to type \"DataFrame\"\n    \"list[Unknown]\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 24,
-      "startLine": 2156
+      "startLine": 2162
     },
     {
       "endCharacter": 35,
-      "endLine": 2157,
+      "endLine": 2163,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | DataFrame\" cannot be assigned to parameter \"labels\" of type \"DataFrame\" in function \"_shuffle_split_rows\"\n  Type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | DataFrame\" is not assignable to type \"DataFrame\"\n    \"list[Unknown]\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 24,
-      "startLine": 2157
+      "startLine": 2163
     },
     {
       "endCharacter": 41,
-      "endLine": 2158,
+      "endLine": 2164,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | ndarray[_AnyShape, dtype[floating[Any]]]\" cannot be assigned to parameter \"base_weights\" of type \"NDArray[floating[Any]]\" in function \"_shuffle_split_rows\"\n  Type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | ndarray[_AnyShape, dtype[floating[Any]]]\" is not assignable to type \"NDArray[floating[Any]]\"\n    \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 24,
-      "startLine": 2158
+      "startLine": 2164
     },
     {
       "endCharacter": 42,
-      "endLine": 2159,
+      "endLine": 2165,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | ndarray[_AnyShape, dtype[floating[Any]]] | None\" cannot be assigned to parameter \"label_weights\" of type \"NDArray[floating[Any]] | None\" in function \"_shuffle_split_rows\"\n  Type \"Unknown | NDArray[Unknown] | Any | list[Unknown] | ndarray[_AnyShape, dtype[floating[Any]]] | None\" is not assignable to type \"NDArray[floating[Any]] | None\"\n    Type \"list[Unknown]\" is not assignable to type \"NDArray[floating[Any]] | None\"\n      \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"\n      \"list[Unknown]\" is not assignable to \"None\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 24,
-      "startLine": 2159
+      "startLine": 2165
     },
     {
       "endCharacter": 30,
-      "endLine": 2177,
+      "endLine": 2183,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"base_weights\" of type \"NDArray[floating[Any]]\" in function \"_compose_train_weights_with_support\"\n  Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"NDArray[floating[Any]]\"\n    \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 12,
-      "startLine": 2177
+      "startLine": 2183
     },
     {
       "endCharacter": 31,
-      "endLine": 2178,
+      "endLine": 2184,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" cannot be assigned to parameter \"label_weights\" of type \"NDArray[floating[Any]] | None\" in function \"_compose_train_weights_with_support\"\n  Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" is not assignable to type \"NDArray[floating[Any]] | None\"\n    Type \"list[Unknown]\" is not assignable to type \"NDArray[floating[Any]] | None\"\n      \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"\n      \"list[Unknown]\" is not assignable to \"None\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 12,
-      "startLine": 2178
+      "startLine": 2184
     },
     {
       "endCharacter": 33,
-      "endLine": 2184,
+      "endLine": 2190,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"base_weights\" of type \"NDArray[floating[Any]]\" in function \"_compose_eval_weights\"\n  Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"NDArray[floating[Any]]\"\n    \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 16,
-      "startLine": 2184
+      "startLine": 2190
     },
     {
       "endCharacter": 34,
-      "endLine": 2185,
+      "endLine": 2191,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" cannot be assigned to parameter \"label_weights\" of type \"NDArray[floating[Any]] | None\" in function \"_compose_eval_weights\"\n  Type \"NDArray[floating[Any]] | Unknown | NDArray[Unknown] | Any | list[Unknown] | None\" is not assignable to type \"NDArray[floating[Any]] | None\"\n    Type \"list[Unknown]\" is not assignable to type \"NDArray[floating[Any]] | None\"\n      \"list[Unknown]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"\n      \"list[Unknown]\" is not assignable to \"None\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 16,
-      "startLine": 2185
+      "startLine": 2191
     },
     {
       "endCharacter": 26,
-      "endLine": 2192,
+      "endLine": 2198,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"train_df\" of type \"DataFrame\" in function \"build_data_dictionary\"\n  Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n    \"list[Unknown]\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 12,
-      "startLine": 2192
+      "startLine": 2198
     },
     {
       "endCharacter": 25,
-      "endLine": 2193,
+      "endLine": 2199,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"test_df\" of type \"DataFrame\" in function \"build_data_dictionary\"\n  Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n    \"list[Unknown]\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 12,
-      "startLine": 2193
+      "startLine": 2199
     },
     {
       "endCharacter": 24,
-      "endLine": 2194,
+      "endLine": 2200,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"train_labels\" of type \"DataFrame\" in function \"build_data_dictionary\"\n  Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n    \"list[Unknown]\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 12,
-      "startLine": 2194
+      "startLine": 2200
     },
     {
       "endCharacter": 23,
-      "endLine": 2195,
+      "endLine": 2201,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" cannot be assigned to parameter \"test_labels\" of type \"DataFrame\" in function \"build_data_dictionary\"\n  Type \"DataFrame | Unknown | NDArray[Unknown] | Any | list[Unknown]\" is not assignable to type \"DataFrame\"\n    \"list[Unknown]\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 12,
-      "startLine": 2195
+      "startLine": 2201
     },
     {
       "endCharacter": 87,
-      "endLine": 2409,
+      "endLine": 2415,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n  Attribute \"index\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 82,
-      "startLine": 2409
+      "startLine": 2415
     },
     {
       "endCharacter": 68,
-      "endLine": 2410,
+      "endLine": 2416,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n  Attribute \"index\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 63,
-      "startLine": 2410
+      "startLine": 2416
     },
     {
       "endCharacter": 63,
-      "endLine": 2421,
+      "endLine": 2427,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n  Attribute \"index\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 58,
-      "startLine": 2421
+      "startLine": 2427
     },
     {
       "endCharacter": 47,
-      "endLine": 2423,
+      "endLine": 2429,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"loc\" for class \"NDArray[Unknown]\"\n  Attribute \"loc\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 44,
-      "startLine": 2423
+      "startLine": 2429
     },
     {
       "endCharacter": 47,
-      "endLine": 2423,
+      "endLine": 2429,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"loc\" for class \"list[Unknown]\"\n  Attribute \"loc\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 44,
-      "startLine": 2423
+      "startLine": 2429
     },
     {
       "endCharacter": 43,
-      "endLine": 2424,
+      "endLine": 2430,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"loc\" for class \"NDArray[Unknown]\"\n  Attribute \"loc\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 40,
-      "startLine": 2424
+      "startLine": 2430
     },
     {
       "endCharacter": 43,
-      "endLine": 2424,
+      "endLine": 2430,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"loc\" for class \"list[Unknown]\"\n  Attribute \"loc\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 40,
-      "startLine": 2424
+      "startLine": 2430
     },
     {
       "endCharacter": 31,
-      "endLine": 2445,
+      "endLine": 2451,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"empty\" for class \"NDArray[Unknown]\"\n  Attribute \"empty\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 26,
-      "startLine": 2445
+      "startLine": 2451
     },
     {
       "endCharacter": 31,
-      "endLine": 2445,
+      "endLine": 2451,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"empty\" for class \"list[Unknown]\"\n  Attribute \"empty\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 26,
-      "startLine": 2445
+      "startLine": 2451
     },
     {
       "endCharacter": 60,
-      "endLine": 2445,
+      "endLine": 2451,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"empty\" for class \"NDArray[Unknown]\"\n  Attribute \"empty\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 55,
-      "startLine": 2445
+      "startLine": 2451
     },
     {
       "endCharacter": 60,
-      "endLine": 2445,
+      "endLine": 2451,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"empty\" for class \"list[Unknown]\"\n  Attribute \"empty\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 55,
-      "startLine": 2445
+      "startLine": 2451
     },
     {
       "endCharacter": 73,
-      "endLine": 2457,
+      "endLine": 2463,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Unknown | Any | ((value: Unknown, start: SupportsIndex = 0, stop: SupportsIndex = sys.maxsize, /) -> int)\" cannot be assigned to parameter \"target\" of type \"Index[Any]\" in function \"get_indexer\"\n  Type \"Unknown | Any | ((value: Unknown, start: SupportsIndex = 0, stop: SupportsIndex = sys.maxsize, /) -> int)\" is not assignable to type \"Index[Any]\"\n    \"MethodType\" is not assignable to \"Index[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 53,
-      "startLine": 2457
+      "startLine": 2463
     },
     {
       "endCharacter": 73,
-      "endLine": 2457,
+      "endLine": 2463,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n  Attribute \"index\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 68,
-      "startLine": 2457
+      "startLine": 2463
     },
     {
       "endCharacter": 83,
-      "endLine": 2458,
+      "endLine": 2464,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Unknown | Any | ((value: Unknown, start: SupportsIndex = 0, stop: SupportsIndex = sys.maxsize, /) -> int)\" cannot be assigned to parameter \"target\" of type \"Index[Any]\" in function \"get_indexer\"\n  Type \"Unknown | Any | ((value: Unknown, start: SupportsIndex = 0, stop: SupportsIndex = sys.maxsize, /) -> int)\" is not assignable to type \"Index[Any]\"\n    \"MethodType\" is not assignable to \"Index[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 58,
-      "startLine": 2458
+      "startLine": 2464
     },
     {
       "endCharacter": 83,
-      "endLine": 2458,
+      "endLine": 2464,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"index\" for class \"NDArray[Unknown]\"\n  Attribute \"index\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 78,
-      "startLine": 2458
+      "startLine": 2464
     },
     {
       "endCharacter": 9,
-      "endLine": 2606,
+      "endLine": 2612,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Type \"ArrayLike\" is not assignable to declared type \"DataFrame\"\n  Type \"ArrayLike\" is not assignable to type \"DataFrame\"\n    \"Buffer\" is not assignable to \"DataFrame\"",
       "rule": "reportAssignmentType",
       "severity": "error",
       "startCharacter": 45,
-      "startLine": 2604
+      "startLine": 2610
     },
     {
       "endCharacter": 9,
-      "endLine": 2606,
+      "endLine": 2612,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Type \"ArrayLike\" is not assignable to declared type \"NDArray[floating[Any]]\"\n  Type \"ArrayLike\" is not assignable to type \"NDArray[floating[Any]]\"\n    \"Buffer\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
       "rule": "reportAssignmentType",
       "severity": "error",
       "startCharacter": 45,
-      "startLine": 2604
+      "startLine": 2610
     },
     {
       "endCharacter": 60,
-      "endLine": 2616,
+      "endLine": 2622,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"pop\" for class \"Buffer\"\n  Attribute \"pop\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 57,
-      "startLine": 2616
+      "startLine": 2622
     },
     {
       "endCharacter": 60,
-      "endLine": 2616,
+      "endLine": 2622,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"pop\" for class \"_NestedSequence[_SupportsArray[dtype[Any]]]\"\n  Attribute \"pop\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 57,
-      "startLine": 2616
+      "startLine": 2622
     },
     {
       "endCharacter": 60,
-      "endLine": 2616,
+      "endLine": 2622,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"pop\" for class \"_NestedSequence[complex | bytes | str]\"\n  Attribute \"pop\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 57,
-      "startLine": 2616
+      "startLine": 2622
     },
     {
       "endCharacter": 60,
-      "endLine": 2616,
+      "endLine": 2622,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"pop\" for class \"_SupportsArray[dtype[Any]]\"\n  Attribute \"pop\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 57,
-      "startLine": 2616
+      "startLine": 2622
     },
     {
       "endCharacter": 60,
-      "endLine": 2616,
+      "endLine": 2622,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"pop\" for class \"bytes\"\n  Attribute \"pop\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 57,
-      "startLine": 2616
+      "startLine": 2622
     },
     {
       "endCharacter": 60,
-      "endLine": 2616,
+      "endLine": 2622,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"pop\" for class \"complex\"\n  Attribute \"pop\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 57,
-      "startLine": 2616
+      "startLine": 2622
     },
     {
       "endCharacter": 60,
-      "endLine": 2616,
+      "endLine": 2622,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"pop\" for class \"str\"\n  Attribute \"pop\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 57,
-      "startLine": 2616
+      "startLine": 2622
     },
     {
       "endCharacter": 79,
-      "endLine": 2616,
+      "endLine": 2622,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "\"base_weight_column\" is possibly unbound",
       "rule": "reportPossiblyUnboundVariable",
       "severity": "error",
       "startCharacter": 61,
-      "startLine": 2616
+      "startLine": 2622
     },
     {
       "endCharacter": 61,
-      "endLine": 2619,
+      "endLine": 2625,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"pop\" for class \"Buffer\"\n  Attribute \"pop\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 58,
-      "startLine": 2619
+      "startLine": 2625
     },
     {
       "endCharacter": 61,
-      "endLine": 2619,
+      "endLine": 2625,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"pop\" for class \"_NestedSequence[_SupportsArray[dtype[Any]]]\"\n  Attribute \"pop\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 58,
-      "startLine": 2619
+      "startLine": 2625
     },
     {
       "endCharacter": 61,
-      "endLine": 2619,
+      "endLine": 2625,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"pop\" for class \"_NestedSequence[complex | bytes | str]\"\n  Attribute \"pop\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 58,
-      "startLine": 2619
+      "startLine": 2625
     },
     {
       "endCharacter": 61,
-      "endLine": 2619,
+      "endLine": 2625,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"pop\" for class \"_SupportsArray[dtype[Any]]\"\n  Attribute \"pop\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 58,
-      "startLine": 2619
+      "startLine": 2625
     },
     {
       "endCharacter": 61,
-      "endLine": 2619,
+      "endLine": 2625,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"pop\" for class \"bytes\"\n  Attribute \"pop\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 58,
-      "startLine": 2619
+      "startLine": 2625
     },
     {
       "endCharacter": 61,
-      "endLine": 2619,
+      "endLine": 2625,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"pop\" for class \"complex\"\n  Attribute \"pop\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 58,
-      "startLine": 2619
+      "startLine": 2625
     },
     {
       "endCharacter": 61,
-      "endLine": 2619,
+      "endLine": 2625,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"pop\" for class \"str\"\n  Attribute \"pop\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 58,
-      "startLine": 2619
+      "startLine": 2625
     },
     {
       "endCharacter": 81,
-      "endLine": 2619,
+      "endLine": 2625,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "\"label_weight_column\" is possibly unbound",
       "rule": "reportPossiblyUnboundVariable",
       "severity": "error",
       "startCharacter": 62,
-      "startLine": 2619
+      "startLine": 2625
     },
     {
       "endCharacter": 68,
-      "endLine": 2625,
+      "endLine": 2631,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"columns\" for class \"Buffer\"\n  Attribute \"columns\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 61,
-      "startLine": 2625
+      "startLine": 2631
     },
     {
       "endCharacter": 68,
-      "endLine": 2625,
+      "endLine": 2631,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"columns\" for class \"_NestedSequence[_SupportsArray[dtype[Any]]]\"\n  Attribute \"columns\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 61,
-      "startLine": 2625
+      "startLine": 2631
     },
     {
       "endCharacter": 68,
-      "endLine": 2625,
+      "endLine": 2631,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"columns\" for class \"_NestedSequence[complex | bytes | str]\"\n  Attribute \"columns\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 61,
-      "startLine": 2625
+      "startLine": 2631
     },
     {
       "endCharacter": 68,
-      "endLine": 2625,
+      "endLine": 2631,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"columns\" for class \"_SupportsArray[dtype[Any]]\"\n  Attribute \"columns\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 61,
-      "startLine": 2625
+      "startLine": 2631
     },
     {
       "endCharacter": 68,
-      "endLine": 2625,
+      "endLine": 2631,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"columns\" for class \"bytes\"\n  Attribute \"columns\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 61,
-      "startLine": 2625
+      "startLine": 2631
     },
     {
       "endCharacter": 68,
-      "endLine": 2625,
+      "endLine": 2631,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"columns\" for class \"complex\"\n  Attribute \"columns\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 61,
-      "startLine": 2625
+      "startLine": 2631
     },
     {
       "endCharacter": 68,
-      "endLine": 2625,
+      "endLine": 2631,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"columns\" for class \"str\"\n  Attribute \"columns\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 61,
-      "startLine": 2625
+      "startLine": 2631
     },
     {
       "endCharacter": 32,
-      "endLine": 2633,
+      "endLine": 2639,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Type \"ArrayLike\" is not assignable to declared type \"DataFrame\"\n  Type \"ArrayLike\" is not assignable to type \"DataFrame\"\n    \"Buffer\" is not assignable to \"DataFrame\"",
       "rule": "reportAssignmentType",
       "severity": "error",
       "startCharacter": 17,
-      "startLine": 2633
+      "startLine": 2639
     },
     {
       "endCharacter": 62,
-      "endLine": 2634,
+      "endLine": 2640,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Type \"ArrayLike\" is not assignable to declared type \"DataFrame\"\n  Type \"ArrayLike\" is not assignable to type \"DataFrame\"\n    \"Buffer\" is not assignable to \"DataFrame\"",
       "rule": "reportAssignmentType",
       "severity": "error",
       "startCharacter": 23,
-      "startLine": 2634
+      "startLine": 2640
     },
     {
       "endCharacter": 46,
-      "endLine": 2667,
+      "endLine": 2673,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"empty\" for class \"Buffer\"\n  Attribute \"empty\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 41,
-      "startLine": 2667
+      "startLine": 2673
     },
     {
       "endCharacter": 46,
-      "endLine": 2667,
+      "endLine": 2673,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"empty\" for class \"_NestedSequence[_SupportsArray[dtype[Any]]]\"\n  Attribute \"empty\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 41,
-      "startLine": 2667
+      "startLine": 2673
     },
     {
       "endCharacter": 46,
-      "endLine": 2667,
+      "endLine": 2673,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"empty\" for class \"_NestedSequence[complex | bytes | str]\"\n  Attribute \"empty\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 41,
-      "startLine": 2667
+      "startLine": 2673
     },
     {
       "endCharacter": 46,
-      "endLine": 2667,
+      "endLine": 2673,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"empty\" for class \"_SupportsArray[dtype[Any]]\"\n  Attribute \"empty\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 41,
-      "startLine": 2667
+      "startLine": 2673
     },
     {
       "endCharacter": 46,
-      "endLine": 2667,
+      "endLine": 2673,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"empty\" for class \"bytes\"\n  Attribute \"empty\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 41,
-      "startLine": 2667
+      "startLine": 2673
     },
     {
       "endCharacter": 46,
-      "endLine": 2667,
+      "endLine": 2673,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"empty\" for class \"complex\"\n  Attribute \"empty\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 41,
-      "startLine": 2667
+      "startLine": 2673
     },
     {
       "endCharacter": 46,
-      "endLine": 2667,
+      "endLine": 2673,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Cannot access attribute \"empty\" for class \"str\"\n  Attribute \"empty\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 41,
-      "startLine": 2667
+      "startLine": 2673
     },
     {
       "endCharacter": 41,
-      "endLine": 2674,
+      "endLine": 2680,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"ArrayLike\" cannot be assigned to parameter \"features\" of type \"DataFrame\" in function \"_sanitize_pipeline_weights\"\n  Type \"ArrayLike\" is not assignable to type \"DataFrame\"\n    \"Buffer\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 16,
-      "startLine": 2674
+      "startLine": 2680
     },
     {
       "endCharacter": 39,
-      "endLine": 2723,
+      "endLine": 2729,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"ArrayLike\" cannot be assigned to parameter \"features\" of type \"DataFrame\" in function \"_sanitize_pipeline_weights\"\n  Type \"ArrayLike\" is not assignable to type \"DataFrame\"\n    \"Buffer\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 20,
-      "startLine": 2723
+      "startLine": 2729
     },
     {
       "endCharacter": 19,
-      "endLine": 2833,
+      "endLine": 2839,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"int | Any | None\" cannot be assigned to parameter \"gap\" of type \"int\" in function \"__init__\"\n  Type \"int | Any | None\" is not assignable to type \"int\"\n    \"None\" is not assignable to \"int\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 16,
-      "startLine": 2833
+      "startLine": 2839
     },
     {
       "endCharacter": 21,
-      "endLine": 2944,
+      "endLine": 2950,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"X\" of type \"DataFrame\" in function \"hp_objective\"\n  Type \"Any | None\" is not assignable to type \"DataFrame\"\n    \"None\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 20,
-      "startLine": 2944
+      "startLine": 2950
     },
     {
       "endCharacter": 21,
-      "endLine": 2945,
+      "endLine": 2951,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"y\" of type \"DataFrame\" in function \"hp_objective\"\n  Type \"Any | None\" is not assignable to type \"DataFrame\"\n    \"None\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 20,
-      "startLine": 2945
+      "startLine": 2951
     },
     {
       "endCharacter": 33,
-      "endLine": 2946,
+      "endLine": 2952,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"train_weights\" of type \"NDArray[floating[Any]]\" in function \"hp_objective\"\n  Type \"Any | None\" is not assignable to type \"NDArray[floating[Any]]\"\n    \"None\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 20,
-      "startLine": 2946
+      "startLine": 2952
     },
     {
       "endCharacter": 32,
-      "endLine": 2947,
+      "endLine": 2953,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"X_validation\" of type \"DataFrame\" in function \"hp_objective\"\n  Type \"Any | None\" is not assignable to type \"DataFrame\"\n    \"None\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 20,
-      "startLine": 2947
+      "startLine": 2953
     },
     {
       "endCharacter": 32,
-      "endLine": 2948,
+      "endLine": 2954,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"y_validation\" of type \"DataFrame\" in function \"hp_objective\"\n  Type \"Any | None\" is not assignable to type \"DataFrame\"\n    \"None\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 20,
-      "startLine": 2948
+      "startLine": 2954
     },
     {
       "endCharacter": 38,
-      "endLine": 2949,
+      "endLine": 2955,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"validation_weights\" of type \"NDArray[floating[Any]]\" in function \"hp_objective\"\n  Type \"Any | None\" is not assignable to type \"NDArray[floating[Any]]\"\n    \"None\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 20,
-      "startLine": 2949
+      "startLine": 2955
     },
     {
       "endCharacter": 24,
-      "endLine": 2970,
+      "endLine": 2976,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"X_test\" of type \"DataFrame\" in function \"make_test_set_and_weights\"\n  Type \"Any | None\" is not assignable to type \"DataFrame\"\n    \"None\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 12,
-      "startLine": 2970
+      "startLine": 2976
     },
     {
       "endCharacter": 24,
-      "endLine": 2971,
+      "endLine": 2977,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"y_test\" of type \"DataFrame\" in function \"make_test_set_and_weights\"\n  Type \"Any | None\" is not assignable to type \"DataFrame\"\n    \"None\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 12,
-      "startLine": 2971
+      "startLine": 2977
     },
     {
       "endCharacter": 30,
-      "endLine": 2972,
+      "endLine": 2978,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"test_weights\" of type \"NDArray[floating[Any]]\" in function \"make_test_set_and_weights\"\n  Type \"Any | None\" is not assignable to type \"NDArray[floating[Any]]\"\n    \"None\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 12,
-      "startLine": 2972
+      "startLine": 2978
     },
     {
       "endCharacter": 15,
-      "endLine": 2978,
+      "endLine": 2984,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"X\" of type \"DataFrame\" in function \"fit_regressor\"\n  Type \"Any | None\" is not assignable to type \"DataFrame\"\n    \"None\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 14,
-      "startLine": 2978
+      "startLine": 2984
     },
     {
       "endCharacter": 15,
-      "endLine": 2979,
+      "endLine": 2985,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"y\" of type \"DataFrame\" in function \"fit_regressor\"\n  Type \"Any | None\" is not assignable to type \"DataFrame\"\n    \"None\" is not assignable to \"DataFrame\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 14,
-      "startLine": 2979
+      "startLine": 2985
     },
     {
       "endCharacter": 39,
-      "endLine": 2980,
+      "endLine": 2986,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"train_weights\" of type \"NDArray[floating[Any]]\" in function \"fit_regressor\"\n  Type \"Any | None\" is not assignable to type \"NDArray[floating[Any]]\"\n    \"None\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 26,
-      "startLine": 2980
+      "startLine": 2986
     },
     {
       "endCharacter": 38,
-      "endLine": 2990,
+      "endLine": 2996,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "\"columns\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 31,
-      "startLine": 2990
+      "startLine": 2996
     },
     {
       "endCharacter": 34,
-      "endLine": 2991,
+      "endLine": 2997,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "\"index\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 29,
-      "startLine": 2991
+      "startLine": 2997
     },
     {
       "endCharacter": 82,
-      "endLine": 2993,
+      "endLine": 2999,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "\"copy\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 78,
-      "startLine": 2993
+      "startLine": 2999
     },
     {
       "endCharacter": 62,
-      "endLine": 3276,
+      "endLine": 3282,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "\"get_pair_dataframe\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 44,
-      "startLine": 3276
+      "startLine": 3282
     },
     {
       "endCharacter": 68,
-      "endLine": 3651,
+      "endLine": 3657,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Type \"floating[Any] | NDArray[float64]\" is not assignable to return type \"NDArray[floating[Any]]\"\n  Type \"floating[Any] | NDArray[float64]\" is not assignable to type \"NDArray[floating[Any]]\"\n    \"floating[Any]\" is not assignable to \"ndarray[_AnyShape, dtype[floating[Any]]]\"",
       "rule": "reportReturnType",
       "severity": "error",
       "startCharacter": 15,
-      "startLine": 3647
+      "startLine": 3653
     },
     {
       "endCharacter": 13,
-      "endLine": 3680,
+      "endLine": 3686,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "No overloads for \"cdist\" match the provided arguments",
       "rule": "reportCallIssue",
       "severity": "error",
       "startCharacter": 19,
-      "startLine": 3675
+      "startLine": 3681
     },
     {
       "endCharacter": 38,
-      "endLine": 3678,
+      "endLine": 3684,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"str\" cannot be assigned to parameter \"metric\" of type \"_MetricFunc\" in function \"cdist\"\n  Type \"str\" is not assignable to type \"_MetricFunc\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 23,
-      "startLine": 3678
+      "startLine": 3684
     },
     {
       "endCharacter": 9,
-      "endLine": 3783,
+      "endLine": 3789,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "No overloads for \"pdist\" match the provided arguments",
       "rule": "reportCallIssue",
       "severity": "error",
       "startCharacter": 36,
-      "startLine": 3781
+      "startLine": 3787
     },
     {
       "endCharacter": 42,
-      "endLine": 3782,
+      "endLine": 3788,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"str\" cannot be assigned to parameter \"metric\" of type \"_MetricFunc\" in function \"pdist\"\n  Type \"str\" is not assignable to type \"_MetricFunc\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 27,
-      "startLine": 3782
+      "startLine": 3788
     },
     {
       "endCharacter": 9,
-      "endLine": 3860,
+      "endLine": 3866,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "No overloads for \"cdist\" match the provided arguments",
       "rule": "reportCallIssue",
       "severity": "error",
       "startCharacter": 15,
-      "startLine": 3855
+      "startLine": 3861
     },
     {
       "endCharacter": 34,
-      "endLine": 3858,
+      "endLine": 3864,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"str\" cannot be assigned to parameter \"metric\" of type \"_MetricFunc\" in function \"cdist\"\n  Type \"str\" is not assignable to type \"_MetricFunc\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 19,
-      "startLine": 3858
+      "startLine": 3864
     },
     {
       "endCharacter": 99,
-      "endLine": 4049,
+      "endLine": 4055,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "No overloads for \"pdist\" match the provided arguments",
       "rule": "reportCallIssue",
       "severity": "error",
       "startCharacter": 12,
-      "startLine": 4049
+      "startLine": 4055
     },
     {
       "endCharacter": 79,
-      "endLine": 4049,
+      "endLine": 4055,
       "file": "quickadapter/user_data/freqaimodels/QuickAdapterRegressorV3.py",
       "message": "Argument of type \"str\" cannot be assigned to parameter \"metric\" of type \"_MetricFunc\" in function \"pdist\"\n  Type \"str\" is not assignable to type \"_MetricFunc\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 64,
-      "startLine": 4049
+      "startLine": 4055
     },
     {
       "endCharacter": 55,
-      "endLine": 219,
+      "endLine": 221,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Type \"int\" is not assignable to declared type \"cached_property[int]\"\n  \"int\" is not assignable to \"cached_property[int]\"",
       "rule": "reportAssignmentType",
       "severity": "error",
       "startCharacter": 24,
-      "startLine": 219
+      "startLine": 221
     },
     {
       "endCharacter": 15,
-      "endLine": 255,
+      "endLine": 257,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Class variable \"minimal_roi\" overrides instance variable of same name in class \"IStrategy\"",
       "rule": "reportIncompatibleVariableOverride",
       "severity": "error",
       "startCharacter": 4,
-      "startLine": 255
+      "startLine": 257
     },
     {
       "endCharacter": 72,
-      "endLine": 255,
+      "endLine": 257,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Operator \"*\" not supported for types \"cached_property[int]\" and \"Literal[864]\"",
       "rule": "reportOperatorIssue",
       "severity": "error",
       "startCharacter": 49,
-      "startLine": 255
+      "startLine": 257
     },
     {
       "endCharacter": 64,
-      "endLine": 268,
+      "endLine": 270,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"timeframe\" of type \"str\" in function \"timeframe_to_minutes\"\n  Type \"Any | None\" is not assignable to type \"str\"\n    \"None\" is not assignable to \"str\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 36,
-      "startLine": 268
+      "startLine": 270
     },
     {
       "endCharacter": 17,
-      "endLine": 277,
+      "endLine": 279,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "\"can_short\" overrides symbol of same name in class \"IStrategy\"\n  \"property\" is not assignable to \"bool\"",
       "rule": "reportIncompatibleVariableOverride",
       "severity": "error",
       "startCharacter": 8,
-      "startLine": 277
+      "startLine": 279
     },
     {
       "endCharacter": 19,
-      "endLine": 281,
+      "endLine": 283,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "\"plot_config\" overrides symbol of same name in class \"IStrategy\"\n  \"cached_property[dict[str, Any]]\" is not assignable to \"dict[Unknown, Unknown]\"",
       "rule": "reportIncompatibleVariableOverride",
       "severity": "error",
       "startCharacter": 8,
-      "startLine": 281
+      "startLine": 283
     },
     {
       "endCharacter": 19,
-      "endLine": 325,
+      "endLine": 327,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "\"protections\" overrides symbol of same name in class \"IStrategy\"\n  \"cached_property[list[dict[str, Any]]]\" is not assignable to \"list[Unknown]\"",
       "rule": "reportIncompatibleVariableOverride",
       "severity": "error",
       "startCharacter": 8,
-      "startLine": 325
+      "startLine": 327
     },
     {
       "endCharacter": 28,
-      "endLine": 398,
+      "endLine": 400,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "\"startup_candle_count\" overrides symbol of same name in class \"IStrategy\"\n  \"property\" is not assignable to \"int\"",
       "rule": "reportIncompatibleVariableOverride",
       "severity": "error",
       "startCharacter": 8,
-      "startLine": 398
+      "startLine": 400
     },
     {
       "endCharacter": 44,
-      "endLine": 457,
+      "endLine": 459,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Operator \"/\" not supported for \"None\"",
       "rule": "reportOptionalOperand",
       "severity": "error",
       "startCharacter": 12,
-      "startLine": 457
+      "startLine": 459
     },
     {
       "endCharacter": 38,
-      "endLine": 710,
+      "endLine": 712,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "\"to_numpy\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 30,
-      "startLine": 710
+      "startLine": 712
     },
     {
       "endCharacter": 44,
-      "endLine": 743,
+      "endLine": 745,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Operator \"-\" not supported for \"None\"",
       "rule": "reportOptionalOperand",
       "severity": "error",
       "startCharacter": 38,
-      "startLine": 743
+      "startLine": 745
     },
     {
       "endCharacter": 38,
-      "endLine": 751,
+      "endLine": 753,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Object of type \"None\" is not subscriptable",
       "rule": "reportOptionalSubscript",
       "severity": "error",
       "startCharacter": 36,
-      "startLine": 751
+      "startLine": 753
     },
     {
       "endCharacter": 39,
-      "endLine": 752,
+      "endLine": 754,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Object of type \"None\" is not subscriptable",
       "rule": "reportOptionalSubscript",
       "severity": "error",
       "startCharacter": 37,
-      "startLine": 752
+      "startLine": 754
     },
     {
       "endCharacter": 38,
-      "endLine": 753,
+      "endLine": 755,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Object of type \"None\" is not subscriptable",
       "rule": "reportOptionalSubscript",
       "severity": "error",
       "startCharacter": 36,
-      "startLine": 753
+      "startLine": 755
     },
     {
       "endCharacter": 44,
-      "endLine": 776,
+      "endLine": 778,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Operator \"-\" not supported for types \"Series[Any] | None\" and \"Series[Any] | None\"\n  Operator \"-\" not supported for types \"Series[Any]\" and \"None\"\n  Operator \"-\" not supported for types \"None\" and \"Series[Any]\"\n  Operator \"-\" not supported for types \"None\" and \"None\"",
       "rule": "reportOperatorIssue",
       "severity": "error",
       "startCharacter": 29,
-      "startLine": 776
+      "startLine": 778
     },
     {
       "endCharacter": 66,
-      "endLine": 776,
+      "endLine": 778,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"s1\" of type \"Series[Any]\" in function \"non_zero_diff\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 61,
-      "startLine": 776
+      "startLine": 778
     },
     {
       "endCharacter": 72,
-      "endLine": 776,
+      "endLine": 778,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"s2\" of type \"Series[Any]\" in function \"non_zero_diff\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 68,
-      "startLine": 776
+      "startLine": 778
     },
     {
       "endCharacter": 56,
-      "endLine": 780,
+      "endLine": 782,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 50,
-      "startLine": 780
+      "startLine": 782
     },
     {
       "endCharacter": 58,
-      "endLine": 781,
+      "endLine": 783,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 52,
-      "startLine": 781
+      "startLine": 783
     },
     {
       "endCharacter": 57,
-      "endLine": 782,
+      "endLine": 784,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 51,
-      "startLine": 782
+      "startLine": 784
     },
     {
       "endCharacter": 44,
-      "endLine": 785,
+      "endLine": 787,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"series\" of type \"Series[Any]\" in function \"zlema\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 38,
-      "startLine": 785
+      "startLine": 787
     },
     {
       "endCharacter": 44,
-      "endLine": 786,
+      "endLine": 788,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"series\" of type \"Series[Any]\" in function \"zlema\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 38,
-      "startLine": 786
+      "startLine": 788
     },
     {
       "endCharacter": 44,
-      "endLine": 787,
+      "endLine": 789,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"series\" of type \"Series[Any]\" in function \"zlema\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 38,
-      "startLine": 787
+      "startLine": 789
     },
     {
       "endCharacter": 61,
-      "endLine": 788,
+      "endLine": 790,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 55,
-      "startLine": 788
+      "startLine": 790
     },
     {
       "endCharacter": 61,
-      "endLine": 789,
+      "endLine": 791,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 55,
-      "startLine": 789
+      "startLine": 791
     },
     {
       "endCharacter": 61,
-      "endLine": 790,
+      "endLine": 792,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 55,
-      "startLine": 790
+      "startLine": 792
     },
     {
       "endCharacter": 81,
-      "endLine": 798,
+      "endLine": 800,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any]\" cannot be assigned to parameter \"p2\" of type \"T@get_distance\" in function \"get_distance\"\n  \"Series[Any]\" is not assignable to \"float\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 58,
-      "startLine": 798
+      "startLine": 800
     },
     {
       "endCharacter": 67,
-      "endLine": 811,
+      "endLine": 813,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 61,
-      "startLine": 811
+      "startLine": 813
     },
     {
       "endCharacter": 68,
-      "endLine": 812,
+      "endLine": 814,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 62,
-      "startLine": 812
+      "startLine": 814
     },
     {
       "endCharacter": 67,
-      "endLine": 813,
+      "endLine": 815,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 61,
-      "startLine": 813
+      "startLine": 815
     },
     {
       "endCharacter": 44,
-      "endLine": 814,
+      "endLine": 816,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Operator \"-\" not supported for types \"Series[Any] | None\" and \"Series[Any] | None\"\n  Operator \"-\" not supported for types \"Series[Any]\" and \"None\" when expected type is \"_SetItemValueNotDataFrame\"\n  Operator \"-\" not supported for types \"None\" and \"Series[Any]\" when expected type is \"_SetItemValueNotDataFrame\"\n  Operator \"-\" not supported for types \"None\" and \"None\" when expected type is \"_SetItemValueNotDataFrame\"",
       "rule": "reportOperatorIssue",
       "severity": "error",
       "startCharacter": 30,
-      "startLine": 814
+      "startLine": 816
     },
     {
       "endCharacter": 56,
-      "endLine": 815,
+      "endLine": 817,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "No overloads for \"__call__\" match the provided arguments",
       "rule": "reportCallIssue",
       "severity": "error",
       "startCharacter": 31,
-      "startLine": 815
+      "startLine": 817
     },
     {
       "endCharacter": 47,
-      "endLine": 815,
+      "endLine": 817,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"x1\" of type \"ArrayLike\" in function \"__call__\"\n  Type \"Series[Any] | None\" is not assignable to type \"ArrayLike\"\n    Type \"None\" is not assignable to type \"ArrayLike\"\n      \"None\" is incompatible with protocol \"Buffer\"\n        \"__buffer__\" is not present\n      \"None\" is incompatible with protocol \"_SupportsArray[dtype[Any]]\"\n        \"__array__\" is not present\n      \"None\" is incompatible with protocol \"_NestedSequence[_SupportsArray[dtype[Any]]]\"\n        \"__len__\" is not present\n  ...",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 42,
-      "startLine": 815
+      "startLine": 817
     },
     {
       "endCharacter": 55,
-      "endLine": 815,
+      "endLine": 817,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"x2\" of type \"ArrayLike\" in function \"__call__\"\n  Type \"Series[Any] | None\" is not assignable to type \"ArrayLike\"\n    Type \"None\" is not assignable to type \"ArrayLike\"\n      \"None\" is incompatible with protocol \"Buffer\"\n        \"__buffer__\" is not present\n      \"None\" is incompatible with protocol \"_SupportsArray[dtype[Any]]\"\n        \"__array__\" is not present\n      \"None\" is incompatible with protocol \"_NestedSequence[_SupportsArray[dtype[Any]]]\"\n        \"__len__\" is not present\n  ...",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 49,
-      "startLine": 815
+      "startLine": 817
     },
     {
       "endCharacter": 64,
-      "endLine": 816,
+      "endLine": 818,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "No overloads for \"__call__\" match the provided arguments",
       "rule": "reportCallIssue",
       "severity": "error",
       "startCharacter": 39,
-      "startLine": 816
+      "startLine": 818
     },
     {
       "endCharacter": 55,
-      "endLine": 816,
+      "endLine": 818,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"x1\" of type \"ArrayLike\" in function \"__call__\"\n  Type \"Series[Any] | None\" is not assignable to type \"ArrayLike\"\n    Type \"None\" is not assignable to type \"ArrayLike\"\n      \"None\" is incompatible with protocol \"Buffer\"\n        \"__buffer__\" is not present\n      \"None\" is incompatible with protocol \"_SupportsArray[dtype[Any]]\"\n        \"__array__\" is not present\n      \"None\" is incompatible with protocol \"_NestedSequence[_SupportsArray[dtype[Any]]]\"\n        \"__len__\" is not present\n  ...",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 50,
-      "startLine": 816
+      "startLine": 818
     },
     {
       "endCharacter": 63,
-      "endLine": 816,
+      "endLine": 818,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"x2\" of type \"ArrayLike\" in function \"__call__\"\n  Type \"Series[Any] | None\" is not assignable to type \"ArrayLike\"\n    Type \"None\" is not assignable to type \"ArrayLike\"\n      \"None\" is incompatible with protocol \"Buffer\"\n        \"__buffer__\" is not present\n      \"None\" is incompatible with protocol \"_SupportsArray[dtype[Any]]\"\n        \"__array__\" is not present\n      \"None\" is incompatible with protocol \"_NestedSequence[_SupportsArray[dtype[Any]]]\"\n        \"__len__\" is not present\n  ...",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 57,
-      "startLine": 816
+      "startLine": 818
     },
     {
       "endCharacter": 55,
-      "endLine": 824,
+      "endLine": 826,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 49,
-      "startLine": 824
+      "startLine": 826
     },
     {
       "endCharacter": 55,
-      "endLine": 825,
+      "endLine": 827,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 49,
-      "startLine": 825
+      "startLine": 827
     },
     {
       "endCharacter": 55,
-      "endLine": 826,
+      "endLine": 828,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 49,
-      "startLine": 826
+      "startLine": 828
     },
     {
       "endCharacter": 55,
-      "endLine": 827,
+      "endLine": 829,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 49,
-      "startLine": 827
+      "startLine": 829
     },
     {
       "endCharacter": 55,
-      "endLine": 828,
+      "endLine": 830,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 49,
-      "startLine": 828
+      "startLine": 830
     },
     {
       "endCharacter": 55,
-      "endLine": 829,
+      "endLine": 831,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"p1\" of type \"T@get_distance\" in function \"get_distance\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 49,
-      "startLine": 829
+      "startLine": 831
     },
     {
       "endCharacter": 50,
-      "endLine": 858,
+      "endLine": 860,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToInt\" in function \"__new__\"\n  Type \"Any | None\" is not assignable to type \"ConvertibleToInt\"\n    Type \"None\" is not assignable to type \"ConvertibleToInt\"\n      \"None\" is not assignable to \"str\"\n      \"None\" is incompatible with protocol \"Buffer\"\n        \"__buffer__\" is not present\n      \"None\" is incompatible with protocol \"SupportsInt\"\n        \"__int__\" is not present\n      \"None\" is incompatible with protocol \"SupportsIndex\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 44,
-      "startLine": 858
+      "startLine": 860
     },
     {
       "endCharacter": 50,
-      "endLine": 858,
+      "endLine": 860,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToInt\" in function \"__new__\"\n  Type \"Any | None\" is not assignable to type \"ConvertibleToInt\"\n    Type \"None\" is not assignable to type \"ConvertibleToInt\"\n      \"None\" is not assignable to \"str\"\n      \"None\" is incompatible with protocol \"Buffer\"\n        \"__buffer__\" is not present\n      \"None\" is incompatible with protocol \"SupportsInt\"\n        \"__int__\" is not present\n      \"None\" is incompatible with protocol \"SupportsIndex\"\n  ...",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 44,
-      "startLine": 858
+      "startLine": 860
     },
     {
       "endCharacter": 29,
-      "endLine": 859,
+      "endLine": 861,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToInt\" in function \"__new__\"\n  Type \"Any | None\" is not assignable to type \"ConvertibleToInt\"\n    Type \"None\" is not assignable to type \"ConvertibleToInt\"\n      \"None\" is not assignable to \"str\"\n      \"None\" is incompatible with protocol \"Buffer\"\n        \"__buffer__\" is not present\n      \"None\" is incompatible with protocol \"SupportsInt\"\n        \"__int__\" is not present\n      \"None\" is incompatible with protocol \"SupportsIndex\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 23,
-      "startLine": 859
+      "startLine": 861
     },
     {
       "endCharacter": 29,
-      "endLine": 859,
+      "endLine": 861,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToInt\" in function \"__new__\"\n  Type \"Any | None\" is not assignable to type \"ConvertibleToInt\"\n    Type \"None\" is not assignable to type \"ConvertibleToInt\"\n      \"None\" is not assignable to \"str\"\n      \"None\" is incompatible with protocol \"Buffer\"\n        \"__buffer__\" is not present\n      \"None\" is incompatible with protocol \"SupportsInt\"\n        \"__int__\" is not present\n      \"None\" is incompatible with protocol \"SupportsIndex\"\n  ...",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 23,
-      "startLine": 859
+      "startLine": 861
     },
     {
       "endCharacter": 60,
-      "endLine": 896,
+      "endLine": 898,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n  Type \"Any | None\" is not assignable to type \"ConvertibleToFloat\"\n    Type \"None\" is not assignable to type \"ConvertibleToFloat\"\n      \"None\" is not assignable to \"str\"\n      \"None\" is incompatible with protocol \"Buffer\"\n        \"__buffer__\" is not present\n      \"None\" is incompatible with protocol \"SupportsFloat\"\n        \"__float__\" is not present\n      \"None\" is incompatible with protocol \"SupportsIndex\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 50,
-      "startLine": 896
+      "startLine": 898
     },
     {
       "endCharacter": 60,
-      "endLine": 896,
+      "endLine": 898,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n  Type \"Any | None\" is not assignable to type \"ConvertibleToFloat\"\n    Type \"None\" is not assignable to type \"ConvertibleToFloat\"\n      \"None\" is not assignable to \"str\"\n      \"None\" is incompatible with protocol \"Buffer\"\n        \"__buffer__\" is not present\n      \"None\" is incompatible with protocol \"SupportsFloat\"\n        \"__float__\" is not present\n      \"None\" is incompatible with protocol \"SupportsIndex\"\n  ...",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 50,
-      "startLine": 896
+      "startLine": 898
     },
     {
       "endCharacter": 35,
-      "endLine": 897,
+      "endLine": 899,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n  Type \"Any | None\" is not assignable to type \"ConvertibleToFloat\"\n    Type \"None\" is not assignable to type \"ConvertibleToFloat\"\n      \"None\" is not assignable to \"str\"\n      \"None\" is incompatible with protocol \"Buffer\"\n        \"__buffer__\" is not present\n      \"None\" is incompatible with protocol \"SupportsFloat\"\n        \"__float__\" is not present\n      \"None\" is incompatible with protocol \"SupportsIndex\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 25,
-      "startLine": 897
+      "startLine": 899
     },
     {
       "endCharacter": 35,
-      "endLine": 897,
+      "endLine": 899,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n  Type \"Any | None\" is not assignable to type \"ConvertibleToFloat\"\n    Type \"None\" is not assignable to type \"ConvertibleToFloat\"\n      \"None\" is not assignable to \"str\"\n      \"None\" is incompatible with protocol \"Buffer\"\n        \"__buffer__\" is not present\n      \"None\" is incompatible with protocol \"SupportsFloat\"\n        \"__float__\" is not present\n      \"None\" is incompatible with protocol \"SupportsIndex\"\n  ...",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 25,
-      "startLine": 897
+      "startLine": 899
     },
     {
       "endCharacter": 41,
-      "endLine": 1122,
+      "endLine": 1124,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Operator \"<\" not supported for \"None\"",
       "rule": "reportOptionalOperand",
       "severity": "error",
       "startCharacter": 12,
-      "startLine": 1122
+      "startLine": 1124
     },
     {
       "endCharacter": 41,
-      "endLine": 1132,
+      "endLine": 1134,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Operator \">\" not supported for \"None\"",
       "rule": "reportOptionalOperand",
       "severity": "error",
       "startCharacter": 12,
-      "startLine": 1132
+      "startLine": 1134
     },
     {
       "endCharacter": 66,
-      "endLine": 1145,
+      "endLine": 1147,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"timeframe\" of type \"str\" in function \"timeframe_to_prev_date\"\n  Type \"Any | None\" is not assignable to type \"str\"\n    \"None\" is not assignable to \"str\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 38,
-      "startLine": 1145
+      "startLine": 1147
     },
     {
       "endCharacter": 73,
-      "endLine": 1276,
+      "endLine": 1278,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Expected 1 more positional argument",
       "rule": "reportCallIssue",
       "severity": "error",
       "startCharacter": 51,
-      "startLine": 1276
+      "startLine": 1278
     },
     {
       "endCharacter": 74,
-      "endLine": 1340,
+      "endLine": 1342,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"int | None\" cannot be assigned to parameter \"trade_duration_candles\" of type \"int\" in function \"get_trade_natr\"\n  Type \"int | None\" is not assignable to type \"int\"\n    \"None\" is not assignable to \"int\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 52,
-      "startLine": 1340
+      "startLine": 1342
     },
     {
       "endCharacter": 74,
-      "endLine": 1367,
+      "endLine": 1369,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"int | None\" cannot be assigned to parameter \"trade_duration_candles\" of type \"int\" in function \"get_trade_natr\"\n  Type \"int | None\" is not assignable to type \"int\"\n    \"None\" is not assignable to \"int\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 52,
-      "startLine": 1367
+      "startLine": 1369
     },
     {
       "endCharacter": 96,
-      "endLine": 1415,
+      "endLine": 1417,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"timeframe\" of type \"str\" in function \"get_analyzed_dataframe\"\n  Type \"Any | None\" is not assignable to type \"str\"\n    \"None\" is not assignable to \"str\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 68,
-      "startLine": 1415
+      "startLine": 1417
     },
     {
       "endCharacter": 77,
-      "endLine": 1449,
+      "endLine": 1451,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Operator \"<=\" not supported for \"None\"",
       "rule": "reportOptionalOperand",
       "severity": "error",
       "startCharacter": 57,
-      "startLine": 1449
+      "startLine": 1451
     },
     {
       "endCharacter": 9,
-      "endLine": 1454,
+      "endLine": 1456,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Operator \"+\" not supported for types \"float\" and \"float | None\"\n  Operator \"+\" not supported for types \"float\" and \"None\"",
       "rule": "reportOperatorIssue",
       "severity": "error",
       "startCharacter": 28,
-      "startLine": 1452
+      "startLine": 1454
     },
     {
       "endCharacter": 33,
-      "endLine": 1453,
+      "endLine": 1455,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Operator \"-\" not supported for \"None\"",
       "rule": "reportOptionalOperand",
       "severity": "error",
       "startCharacter": 13,
-      "startLine": 1453
+      "startLine": 1455
     },
     {
       "endCharacter": 67,
-      "endLine": 1459,
+      "endLine": 1461,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"float | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n  Type \"float | None\" is not assignable to type \"ConvertibleToFloat\"\n    Type \"None\" is not assignable to type \"ConvertibleToFloat\"\n      \"None\" is not assignable to \"str\"\n      \"None\" is incompatible with protocol \"Buffer\"\n        \"__buffer__\" is not present\n      \"None\" is incompatible with protocol \"SupportsFloat\"\n        \"__float__\" is not present\n      \"None\" is incompatible with protocol \"SupportsIndex\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 47,
-      "startLine": 1459
+      "startLine": 1461
     },
     {
       "endCharacter": 67,
-      "endLine": 1459,
+      "endLine": 1461,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"float | None\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n  Type \"float | None\" is not assignable to type \"ConvertibleToFloat\"\n    Type \"None\" is not assignable to type \"ConvertibleToFloat\"\n      \"None\" is not assignable to \"str\"\n      \"None\" is incompatible with protocol \"Buffer\"\n        \"__buffer__\" is not present\n      \"None\" is incompatible with protocol \"SupportsFloat\"\n        \"__float__\" is not present\n      \"None\" is incompatible with protocol \"SupportsIndex\"\n  ...",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 47,
-      "startLine": 1459
+      "startLine": 1461
     },
     {
       "endCharacter": 64,
-      "endLine": 1613,
+      "endLine": 1615,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "\"isoformat\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 55,
-      "startLine": 1613
+      "startLine": 1615
     },
     {
       "endCharacter": 37,
-      "endLine": 1664,
+      "endLine": 1666,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Operator \"<=\" not supported for \"None\"",
       "rule": "reportOptionalOperand",
       "severity": "error",
       "startCharacter": 15,
-      "startLine": 1664
+      "startLine": 1666
     },
     {
       "endCharacter": 48,
-      "endLine": 1666,
+      "endLine": 1668,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Operator \"<=\" not supported for \"None\"",
       "rule": "reportOptionalOperand",
       "severity": "error",
       "startCharacter": 15,
-      "startLine": 1666
+      "startLine": 1668
     },
     {
       "endCharacter": 96,
-      "endLine": 1846,
+      "endLine": 1848,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"timeframe\" of type \"str\" in function \"get_analyzed_dataframe\"\n  Type \"Any | None\" is not assignable to type \"str\"\n    \"None\" is not assignable to \"str\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 68,
-      "startLine": 1846
+      "startLine": 1848
     },
     {
       "endCharacter": 39,
-      "endLine": 1923,
+      "endLine": 1925,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Operator \"+\" not supported for \"None\"",
       "rule": "reportOptionalOperand",
       "severity": "error",
       "startCharacter": 21,
-      "startLine": 1923
+      "startLine": 1925
     },
     {
       "endCharacter": 90,
-      "endLine": 1923,
+      "endLine": 1925,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Operator \"*\" not supported for types \"float\" and \"Any | None\"\n  Operator \"*\" not supported for types \"float\" and \"None\"",
       "rule": "reportOperatorIssue",
       "severity": "error",
       "startCharacter": 62,
-      "startLine": 1923
+      "startLine": 1925
     },
     {
       "endCharacter": 96,
-      "endLine": 2227,
+      "endLine": 2229,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"timeframe\" of type \"str\" in function \"get_analyzed_dataframe\"\n  Type \"Any | None\" is not assignable to type \"str\"\n    \"None\" is not assignable to \"str\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 68,
-      "startLine": 2227
+      "startLine": 2229
     },
     {
       "endCharacter": 85,
-      "endLine": 2252,
+      "endLine": 2254,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "\"isoformat\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 76,
-      "startLine": 2252
+      "startLine": 2254
     },
     {
       "endCharacter": 47,
-      "endLine": 2258,
+      "endLine": 2260,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Operator \"<\" not supported for \"None\"",
       "rule": "reportOptionalOperand",
       "severity": "error",
       "startCharacter": 16,
-      "startLine": 2258
+      "startLine": 2260
     },
     {
       "endCharacter": 42,
-      "endLine": 2262,
+      "endLine": 2264,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"str\" cannot be assigned to parameter \"side\" of type \"TradeDirection\" in function \"reversal_confirmed\"\n  Type \"str\" is not assignable to type \"TradeDirection\"\n    \"str\" is not assignable to type \"Literal['long']\"\n    \"str\" is not assignable to type \"Literal['short']\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 16,
-      "startLine": 2262
+      "startLine": 2264
     },
     {
       "endCharacter": 42,
-      "endLine": 2263,
+      "endLine": 2265,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"str\" cannot be assigned to parameter \"order\" of type \"OrderType\" in function \"reversal_confirmed\"\n  Type \"str\" is not assignable to type \"OrderType\"\n    \"str\" is not assignable to type \"Literal['entry']\"\n    \"str\" is not assignable to type \"Literal['exit']\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 16,
-      "startLine": 2263
+      "startLine": 2265
     },
     {
       "endCharacter": 69,
-      "endLine": 2265,
+      "endLine": 2267,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"int | float\" cannot be assigned to parameter \"lookback_period_candles\" of type \"int\" in function \"reversal_confirmed\"\n  Type \"int | float\" is not assignable to type \"int\"\n    \"float\" is not assignable to \"int\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 16,
-      "startLine": 2265
+      "startLine": 2267
     },
     {
       "endCharacter": 47,
-      "endLine": 2276,
+      "endLine": 2278,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Operator \">\" not supported for \"None\"",
       "rule": "reportOptionalOperand",
       "severity": "error",
       "startCharacter": 16,
-      "startLine": 2276
+      "startLine": 2278
     },
     {
       "endCharacter": 43,
-      "endLine": 2280,
+      "endLine": 2282,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"str\" cannot be assigned to parameter \"side\" of type \"TradeDirection\" in function \"reversal_confirmed\"\n  Type \"str\" is not assignable to type \"TradeDirection\"\n    \"str\" is not assignable to type \"Literal['long']\"\n    \"str\" is not assignable to type \"Literal['short']\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 16,
-      "startLine": 2280
+      "startLine": 2282
     },
     {
       "endCharacter": 42,
-      "endLine": 2281,
+      "endLine": 2283,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"str\" cannot be assigned to parameter \"order\" of type \"OrderType\" in function \"reversal_confirmed\"\n  Type \"str\" is not assignable to type \"OrderType\"\n    \"str\" is not assignable to type \"Literal['entry']\"\n    \"str\" is not assignable to type \"Literal['exit']\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 16,
-      "startLine": 2281
+      "startLine": 2283
     },
     {
       "endCharacter": 69,
-      "endLine": 2283,
+      "endLine": 2285,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"int | float\" cannot be assigned to parameter \"lookback_period_candles\" of type \"int\" in function \"reversal_confirmed\"\n  Type \"int | float\" is not assignable to type \"int\"\n    \"float\" is not assignable to \"int\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 16,
-      "startLine": 2283
+      "startLine": 2285
     },
     {
       "endCharacter": 52,
-      "endLine": 2312,
+      "endLine": 2314,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"datetime | None\" cannot be assigned to parameter \"current_candle_date\" of type \"datetime\" in function \"_normalize_final_take_profit_state\"\n  Type \"datetime | None\" is not assignable to type \"datetime\"\n    \"None\" is not assignable to \"datetime\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 36,
-      "startLine": 2312
+      "startLine": 2314
     },
     {
       "endCharacter": 96,
-      "endLine": 2432,
+      "endLine": 2434,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"timeframe\" of type \"str\" in function \"get_analyzed_dataframe\"\n  Type \"Any | None\" is not assignable to type \"str\"\n    \"None\" is not assignable to \"str\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 68,
-      "startLine": 2432
+      "startLine": 2434
     },
     {
       "endCharacter": 43,
-      "endLine": 2441,
+      "endLine": 2443,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"str\" cannot be assigned to parameter \"order\" of type \"OrderType\" in function \"reversal_confirmed\"\n  Type \"str\" is not assignable to type \"OrderType\"\n    \"str\" is not assignable to type \"Literal['entry']\"\n    \"str\" is not assignable to type \"Literal['exit']\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 16,
-      "startLine": 2441
+      "startLine": 2443
     },
     {
       "endCharacter": 69,
-      "endLine": 2443,
+      "endLine": 2445,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"int | float\" cannot be assigned to parameter \"lookback_period_candles\" of type \"int\" in function \"reversal_confirmed\"\n  Type \"int | float\" is not assignable to type \"int\"\n    \"float\" is not assignable to \"int\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 16,
-      "startLine": 2443
+      "startLine": 2445
     },
     {
       "endCharacter": 32,
-      "endLine": 2519,
+      "endLine": 2521,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"LocalTrade\" cannot be assigned to parameter \"trade\" of type \"Trade\" in function \"get_trade_annotation_line_start_date\"\n  \"LocalTrade\" is not assignable to \"Trade\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 27,
-      "startLine": 2519
+      "startLine": 2521
     },
     {
       "endCharacter": 72,
-      "endLine": 2522,
+      "endLine": 2524,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"LocalTrade\" cannot be assigned to parameter \"trade\" of type \"Trade\" in function \"get_trade_exit_stage\"\n  \"LocalTrade\" is not assignable to \"Trade\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 67,
-      "startLine": 2522
+      "startLine": 2524
     },
     {
       "endCharacter": 36,
-      "endLine": 2529,
+      "endLine": 2531,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"LocalTrade\" cannot be assigned to parameter \"trade\" of type \"Trade\" in function \"get_take_profit_target\"\n  \"LocalTrade\" is not assignable to \"Trade\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 31,
-      "startLine": 2529
+      "startLine": 2531
     },
     {
       "endCharacter": 71,
-      "endLine": 2560,
+      "endLine": 2562,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"LocalTrade\" cannot be assigned to parameter \"trade\" of type \"Trade\" in function \"get_trade_entry_date\"\n  \"LocalTrade\" is not assignable to \"Trade\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 66,
-      "startLine": 2560
+      "startLine": 2562
     },
     {
       "endCharacter": 32,
-      "endLine": 2591,
+      "endLine": 2593,
       "file": "quickadapter/user_data/strategies/QuickAdapterV3.py",
       "message": "Argument of type \"LocalTrade\" cannot be assigned to parameter \"trade\" of type \"Trade\" in function \"get_take_profit_target\"\n  \"LocalTrade\" is not assignable to \"Trade\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 27,
-      "startLine": 2591
+      "startLine": 2593
     },
     {
       "endCharacter": 34,
     },
     {
       "endCharacter": 33,
-      "endLine": 3754,
+      "endLine": 3758,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Argument of type \"Series[Any] | NDArray[floating[Any]]\" cannot be assigned to parameter \"series\" of type \"Series[Any]\" in function \"calculate_zero_lag\"\n  Type \"Series[Any] | NDArray[floating[Any]]\" is not assignable to type \"Series[Any]\"\n    \"ndarray[_AnyShape, dtype[floating[Any]]]\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 27,
-      "startLine": 3754
+      "startLine": 3758
     },
     {
       "endCharacter": 69,
-      "endLine": 3754,
+      "endLine": 3758,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Expected 1 more positional argument",
       "rule": "reportCallIssue",
       "severity": "error",
       "startCharacter": 59,
-      "startLine": 3754
+      "startLine": 3758
     },
     {
       "endCharacter": 40,
-      "endLine": 3809,
+      "endLine": 3813,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"series\" of type \"Series[Any]\" in function \"calculate_zero_lag\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 35,
-      "startLine": 3809
+      "startLine": 3813
     },
     {
       "endCharacter": 38,
-      "endLine": 3810,
+      "endLine": 3814,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"series\" of type \"Series[Any]\" in function \"calculate_zero_lag\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 34,
-      "startLine": 3810
+      "startLine": 3814
     },
     {
       "endCharacter": 42,
-      "endLine": 3811,
+      "endLine": 3815,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Argument of type \"Series[Any] | None\" cannot be assigned to parameter \"series\" of type \"Series[Any]\" in function \"calculate_zero_lag\"\n  Type \"Series[Any] | None\" is not assignable to type \"Series[Any]\"\n    \"None\" is not assignable to \"Series[Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 36,
-      "startLine": 3811
+      "startLine": 3815
     },
     {
       "endCharacter": 45,
-      "endLine": 3813,
+      "endLine": 3817,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "\"index\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 40,
-      "startLine": 3813
+      "startLine": 3817
     },
     {
       "endCharacter": 33,
-      "endLine": 3815,
+      "endLine": 3819,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "\"iloc\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 29,
-      "startLine": 3815
+      "startLine": 3819
     },
     {
       "endCharacter": 31,
-      "endLine": 3816,
+      "endLine": 3820,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "\"iloc\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 27,
-      "startLine": 3816
+      "startLine": 3820
     },
     {
       "endCharacter": 48,
-      "endLine": 3821,
+      "endLine": 3825,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "\"index\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 43,
-      "startLine": 3821
+      "startLine": 3825
     },
     {
       "endCharacter": 40,
-      "endLine": 3822,
+      "endLine": 3826,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "\"iloc\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 36,
-      "startLine": 3822
+      "startLine": 3826
     },
     {
       "endCharacter": 59,
-      "endLine": 3824,
+      "endLine": 3828,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Cannot access attribute \"iloc\" for class \"NDArray[Any]\"\n  Attribute \"iloc\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 55,
-      "startLine": 3824
+      "startLine": 3828
     },
     {
       "endCharacter": 34,
-      "endLine": 3826,
+      "endLine": 3830,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Cannot access attribute \"iloc\" for class \"NDArray[Any]\"\n  Attribute \"iloc\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 30,
-      "startLine": 3826
+      "startLine": 3830
     },
     {
       "endCharacter": 51,
-      "endLine": 3826,
+      "endLine": 3830,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "\"iloc\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 47,
-      "startLine": 3826
+      "startLine": 3830
     },
     {
       "endCharacter": 72,
-      "endLine": 3826,
+      "endLine": 3830,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Cannot access attribute \"iloc\" for class \"NDArray[Any]\"\n  Attribute \"iloc\" is unknown",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 68,
-      "startLine": 3826
+      "startLine": 3830
     },
     {
       "endCharacter": 40,
-      "endLine": 3893,
+      "endLine": 3897,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Type \"(Series[Any] | NDArray[floating[Any]], int) -> (Series[Any] | NDArray[floating[Any]])\" is not assignable to declared type \"(series: Unknown, timeperiod: Unknown) -> Series[Any]\"\n  Type \"(Series[Any] | NDArray[floating[Any]], int) -> (Series[Any] | NDArray[floating[Any]])\" is not assignable to type \"(series: Unknown, timeperiod: Unknown) -> Series[Any]\"\n    Missing keyword parameter \"series\"\n    Missing keyword parameter \"timeperiod\"\n      Position-only parameter mismatch; parameter \"series\" is not position-only\n      Position-only parameter mismatch; parameter \"timeperiod\" is not position-only\n      Position-only parameter mismatch; expected 2 but received 0\n      Function return type \"Series[Any] | NDArray[floating[Any]]\" is incompatible with type \"Series[Any]\"\n        Type \"Series[Any] | NDArray[floating[Any]]\" is not assignable to type \"Series[Any]\"\n  ...",
       "rule": "reportAssignmentType",
       "severity": "error",
       "startCharacter": 20,
-      "startLine": 3893
+      "startLine": 3897
     },
     {
       "endCharacter": 33,
-      "endLine": 3895,
+      "endLine": 3899,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Type \"(Series[Any] | NDArray[floating[Any]], int) -> (Series[Any] | NDArray[floating[Any]])\" is not assignable to declared type \"(series: Unknown, timeperiod: Unknown) -> Series[Any]\"\n  Type \"(Series[Any] | NDArray[floating[Any]], int) -> (Series[Any] | NDArray[floating[Any]])\" is not assignable to type \"(series: Unknown, timeperiod: Unknown) -> Series[Any]\"\n    Missing keyword parameter \"series\"\n    Missing keyword parameter \"timeperiod\"\n      Position-only parameter mismatch; parameter \"series\" is not position-only\n      Position-only parameter mismatch; parameter \"timeperiod\" is not position-only\n      Position-only parameter mismatch; expected 2 but received 0\n      Function return type \"Series[Any] | NDArray[floating[Any]]\" is incompatible with type \"Series[Any]\"\n        Type \"Series[Any] | NDArray[floating[Any]]\" is not assignable to type \"Series[Any]\"\n  ...",
       "rule": "reportAssignmentType",
       "severity": "error",
       "startCharacter": 16,
-      "startLine": 3895
+      "startLine": 3899
     },
     {
       "endCharacter": 35,
-      "endLine": 3941,
+      "endLine": 3945,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "\"to_numpy\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 27,
-      "startLine": 3941
+      "startLine": 3945
     },
     {
       "endCharacter": 33,
-      "endLine": 3942,
+      "endLine": 3946,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "\"to_numpy\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 25,
-      "startLine": 3942
+      "startLine": 3946
     },
     {
       "endCharacter": 37,
-      "endLine": 4054,
+      "endLine": 4058,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "\"to_numpy\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 29,
-      "startLine": 4054
+      "startLine": 4058
     },
     {
       "endCharacter": 35,
-      "endLine": 4055,
+      "endLine": 4059,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "\"to_numpy\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 27,
-      "startLine": 4055
+      "startLine": 4059
     },
     {
       "endCharacter": 33,
-      "endLine": 4056,
+      "endLine": 4060,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "\"to_numpy\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 25,
-      "startLine": 4056
+      "startLine": 4060
     },
     {
       "endCharacter": 39,
-      "endLine": 4076,
+      "endLine": 4080,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "\"to_numpy\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 31,
-      "startLine": 4076
+      "startLine": 4080
     },
     {
       "endCharacter": 92,
-      "endLine": 4435,
+      "endLine": 4439,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Type \"bool_ | bool\" is not assignable to return type \"bool\"\n  Type \"bool_ | bool\" is not assignable to type \"bool\"\n    \"numpy.bool[builtins.bool]\" is not assignable to \"bool\"",
       "rule": "reportReturnType",
       "severity": "error",
       "startCharacter": 15,
-      "startLine": 4435
+      "startLine": 4439
     },
     {
       "endCharacter": 85,
-      "endLine": 4819,
+      "endLine": 4840,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Argument of type \"XGBoostPruningCallback\" cannot be assigned to parameter \"object\" of type \"RegressorCallback\" in function \"append\"\n  Type \"XGBoostPruningCallback\" is not assignable to type \"RegressorCallback\"\n    Type \"XGBoostPruningCallback\" is not assignable to type \"(...) -> Any\"\n    \"XGBoostPruningCallback\" is not assignable to \"TrainingCallback\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 16,
-      "startLine": 4819
+      "startLine": 4840
     },
     {
       "endCharacter": 29,
-      "endLine": 4860,
+      "endLine": 4883,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Argument of type \"list[tuple[DataFrame, DataFrame]] | None\" cannot be assigned to parameter \"eval_set\" of type \"List[_LGBM_ScikitValidSet] | None\" in function \"fit\"\n  Type \"list[tuple[DataFrame, DataFrame]] | None\" is not assignable to type \"List[_LGBM_ScikitValidSet] | None\"\n    Type \"list[tuple[DataFrame, DataFrame]]\" is not assignable to type \"List[_LGBM_ScikitValidSet] | None\"\n      \"list[tuple[DataFrame, DataFrame]]\" is not assignable to \"List[_LGBM_ScikitValidSet]\"\n        Type parameter \"_T@list\" is invariant, but \"tuple[DataFrame, DataFrame]\" is not the same as \"_LGBM_ScikitValidSet\"\n        Consider switching from \"list\" to \"Sequence\" which is covariant\n      \"list[tuple[DataFrame, DataFrame]]\" is not assignable to \"None\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 21,
-      "startLine": 4860
+      "startLine": 4883
     },
     {
       "endCharacter": 43,
-      "endLine": 4861,
+      "endLine": 4884,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Argument of type \"list[NDArray[floating[Any]]] | None\" cannot be assigned to parameter \"eval_sample_weight\" of type \"List[_LGBM_WeightType] | None\" in function \"fit\"\n  Type \"list[NDArray[floating[Any]]] | None\" is not assignable to type \"List[_LGBM_WeightType] | None\"\n    Type \"list[NDArray[floating[Any]]]\" is not assignable to type \"List[_LGBM_WeightType] | None\"\n      \"list[NDArray[floating[Any]]]\" is not assignable to \"List[_LGBM_WeightType]\"\n        Type parameter \"_T@list\" is invariant, but \"NDArray[floating[Any]]\" is not the same as \"_LGBM_WeightType\"\n        Consider switching from \"list\" to \"Sequence\" which is covariant\n      \"list[NDArray[floating[Any]]]\" is not assignable to \"None\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 31,
-      "startLine": 4861
+      "startLine": 4884
     },
     {
       "endCharacter": 62,
-      "endLine": 4864,
+      "endLine": 4887,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Argument of type \"list[RegressorCallback] | None\" cannot be assigned to parameter \"callbacks\" of type \"List[(...) -> Unknown] | None\" in function \"fit\"\n  Type \"list[RegressorCallback] | None\" is not assignable to type \"List[(...) -> Unknown] | None\"\n    Type \"list[RegressorCallback]\" is not assignable to type \"List[(...) -> Unknown] | None\"\n      \"list[RegressorCallback]\" is not assignable to \"List[(...) -> Unknown]\"\n        Type parameter \"_T@list\" is invariant, but \"RegressorCallback\" is not the same as \"(...) -> Unknown\"\n        Consider switching from \"list\" to \"Sequence\" which is covariant\n      \"list[RegressorCallback]\" is not assignable to \"None\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 22,
-      "startLine": 4864
+      "startLine": 4887
     },
     {
       "endCharacter": 35,
-      "endLine": 4886,
+      "endLine": 4909,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Object of type \"None\" is not subscriptable",
       "rule": "reportOptionalSubscript",
       "severity": "error",
       "startCharacter": 27,
-      "startLine": 4886
+      "startLine": 4909
     },
     {
       "endCharacter": 35,
-      "endLine": 4932,
+      "endLine": 4955,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Object of type \"None\" is not subscriptable",
       "rule": "reportOptionalSubscript",
       "severity": "error",
       "startCharacter": 27,
-      "startLine": 4932
+      "startLine": 4955
     },
     {
       "endCharacter": 49,
-      "endLine": 4995,
+      "endLine": 5020,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Argument of type \"CatBoostPruningCallback\" cannot be assigned to parameter \"object\" of type \"RegressorCallback\" in function \"append\"\n  Type \"CatBoostPruningCallback\" is not assignable to type \"RegressorCallback\"\n    Type \"CatBoostPruningCallback\" is not assignable to type \"(...) -> Any\"\n    \"CatBoostPruningCallback\" is not assignable to \"TrainingCallback\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 33,
-      "startLine": 4995
+      "startLine": 5020
     },
     {
       "endCharacter": 75,
-      "endLine": 5237,
+      "endLine": 5262,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Operator \"<=\" not supported for \"None\"",
       "rule": "reportOptionalOperand",
       "severity": "error",
       "startCharacter": 54,
-      "startLine": 5237
+      "startLine": 5262
     },
     {
       "endCharacter": 23,
-      "endLine": 5400,
+      "endLine": 5425,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "\"best_params\" is possibly unbound",
       "rule": "reportPossiblyUnboundVariable",
       "severity": "error",
       "startCharacter": 12,
-      "startLine": 5400
+      "startLine": 5425
     },
     {
       "endCharacter": 38,
-      "endLine": 5407,
+      "endLine": 5432,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "\"best_params\" is possibly unbound",
       "rule": "reportPossiblyUnboundVariable",
       "severity": "error",
       "startCharacter": 27,
-      "startLine": 5407
+      "startLine": 5432
     },
     {
       "endCharacter": 22,
-      "endLine": 5419,
+      "endLine": 5444,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "\"best_params\" is possibly unbound",
       "rule": "reportPossiblyUnboundVariable",
       "severity": "error",
       "startCharacter": 11,
-      "startLine": 5419
+      "startLine": 5444
     },
     {
       "endCharacter": 22,
-      "endLine": 5574,
+      "endLine": 5602,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Declaration \"default_ranges\" is obscured by a declaration of the same name",
       "rule": "reportRedeclaration",
       "severity": "error",
       "startCharacter": 8,
-      "startLine": 5574
+      "startLine": 5602
     },
     {
       "endCharacter": 14,
-      "endLine": 5610,
+      "endLine": 5638,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Declaration \"params\" is obscured by a declaration of the same name",
       "rule": "reportRedeclaration",
       "severity": "error",
       "startCharacter": 8,
-      "startLine": 5610
+      "startLine": 5638
     },
     {
       "endCharacter": 22,
-      "endLine": 5694,
+      "endLine": 5722,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Declaration \"default_ranges\" is obscured by a declaration of the same name",
       "rule": "reportRedeclaration",
       "severity": "error",
       "startCharacter": 8,
-      "startLine": 5694
+      "startLine": 5722
     },
     {
       "endCharacter": 14,
-      "endLine": 5728,
+      "endLine": 5756,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Declaration \"params\" is obscured by a declaration of the same name",
       "rule": "reportRedeclaration",
       "severity": "error",
       "startCharacter": 8,
-      "startLine": 5728
+      "startLine": 5756
     },
     {
       "endCharacter": 22,
-      "endLine": 5799,
+      "endLine": 5827,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Declaration \"default_ranges\" is obscured by a declaration of the same name",
       "rule": "reportRedeclaration",
       "severity": "error",
       "startCharacter": 8,
-      "startLine": 5799
+      "startLine": 5827
     },
     {
       "endCharacter": 22,
-      "endLine": 5900,
+      "endLine": 5928,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Declaration \"default_ranges\" is obscured by a declaration of the same name",
       "rule": "reportRedeclaration",
       "severity": "error",
       "startCharacter": 8,
-      "startLine": 5900
+      "startLine": 5928
     },
     {
       "endCharacter": 26,
-      "endLine": 5983,
+      "endLine": 6011,
       "file": "quickadapter/user_data/strategies/Utils.py",
       "message": "Declaration \"default_ranges\" is obscured by a declaration of the same name",
       "rule": "reportRedeclaration",
       "severity": "error",
       "startCharacter": 12,
-      "startLine": 5983
+      "startLine": 6011
     }
   ],
   "filesAnalyzed": 5,
index e64494e0baa4ba5594a6cc2b8f302ba4a3e6c22a..28111f462f902d7d737a01f3c5d93ecbb01ce90c 100644 (file)
@@ -19,6 +19,7 @@ from typing import (
     NamedTuple,
     assert_never,
     cast,
+    get_args,
 )
 
 import numpy as np
@@ -267,6 +268,7 @@ ClusterMethod = Literal["kmeans", "kmeans2", "kmedoids"]
 DensityMethod = Literal["knn", "medoid"]
 SelectionMethod = DistanceMethod | ClusterMethod | DensityMethod
 ValidationMode = Literal["warn", "raise", "none"]
+_VALIDATION_MODES: Final[tuple[ValidationMode, ...]] = get_args(ValidationMode)
 SplitFn = Callable[[pd.DataFrame, pd.DataFrame, "SampleWeightInputs", pd.DataFrame], dict[str, Any]]
 warnings.simplefilter(action="ignore", category=FutureWarning)
 
@@ -450,6 +452,9 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
         "cluster": _CLUSTER_METHODS,
         "density": _DENSITY_METHODS,
     }
+    _CATEGORY_DISTANCE, _CATEGORY_CLUSTER, _CATEGORY_DENSITY = _SELECTION_CATEGORIES
+    _SUPPORT_POLICY_FALLBACK: Final[Literal["fallback"]] = LABEL_WEIGHT_SUPPORT_POLICIES[0]
+    _SUPPORT_POLICY_RAISE: Final[Literal["raise"]] = LABEL_WEIGHT_SUPPORT_POLICIES[1]
 
     _SELECTION_METHODS: Final[tuple[SelectionMethod, ...]] = (
         *_DISTANCE_METHODS,
@@ -492,6 +497,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
     # SciPy-compatible distance metrics: the first 8 entries of
     # ``_DISTANCE_METRICS`` route to ``scipy.spatial.distance.cdist``.
     _SCIPY_METRICS_SET: Final[frozenset[str]] = frozenset(_DISTANCE_METRICS[:8])
+    _STANDARDIZED_DISTANCE_METRICS_SET: Final[frozenset[str]] = frozenset(_DISTANCE_METRICS[5:7])
 
     _UNSUPPORTED_WEIGHTS_METRICS: Final[tuple[str, ...]] = (
         _DISTANCE_METRICS[6],  # "mahalanobis"
@@ -503,9 +509,9 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
     )
 
     _PROBABILITY_DISTANCE_METRICS: Final[tuple[str, ...]] = (
-        "jensenshannon",
-        "hellinger",
-        "shellinger",
+        _DISTANCE_METRICS[7],
+        _METRIC_HELLINGER,
+        _METRIC_SHELLINGER,
     )
     _PROBABILITY_DISTANCE_METRICS_SET: Final[frozenset[str]] = frozenset(
         _PROBABILITY_DISTANCE_METRICS
@@ -543,11 +549,11 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
     )
 
     _POWER_MEAN_MAP: Final[dict[str, float]] = {
-        "harmonic_mean": -1.0,
-        "geometric_mean": 0.0,
-        "arithmetic_mean": 1.0,
-        "quadratic_mean": 2.0,
-        "cubic_mean": 3.0,
+        _DISTANCE_METRICS[10]: -1.0,
+        _DISTANCE_METRICS[11]: 0.0,
+        _DISTANCE_METRICS[12]: 1.0,
+        _DISTANCE_METRICS[13]: 2.0,
+        _DISTANCE_METRICS[14]: 3.0,
     }
     _POWER_MEAN_METRICS_SET: Final[frozenset[str]] = frozenset(_POWER_MEAN_MAP)
 
@@ -781,7 +787,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
                 label_weights,
                 logger=logger,
                 context=context,
-                on_collapse="fallback",
+                on_collapse=LABEL_WEIGHT_SUPPORT_POLICIES[0],
             )
         except LabelWeightSupportError as exc:
             logger.warning(
@@ -808,12 +814,12 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
         """
         reason_text = "; ".join(reasons)
         match policy:
-            case "raise":
+            case QuickAdapterRegressorV3._SUPPORT_POLICY_RAISE:
                 raise ValueError(
                     f"{context}: label weighting support failed ({reason_text}); "
                     "support_policy='raise'"
                 )
-            case "fallback":
+            case QuickAdapterRegressorV3._SUPPORT_POLICY_FALLBACK:
                 logger.warning(
                     "%s: label weighting support failed (%s); "
                     "falling back to sanitized base weights (support_policy='fallback')",
@@ -1000,7 +1006,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
     ) -> float | None:
         if value is None:
             return None
-        if mode == "none":
+        if mode == _VALIDATION_MODES[2]:
             return (
                 float(value)
                 if (np.isfinite(value) and (predicate is None or predicate(value)))
@@ -1009,14 +1015,14 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
 
         if not np.isfinite(value):
             msg = f"Invalid {ctx} value {value!r}: must be finite"
-            if mode == "raise":
+            if mode == _VALIDATION_MODES[1]:
                 raise ValueError(msg)
             logger.warning(f"{msg}, using default")
             return None
 
         if predicate is not None and not predicate(value):
             msg = f"Invalid {ctx} value {value!r}: {constraint}"
-            if mode == "raise":
+            if mode == _VALIDATION_MODES[1]:
                 raise ValueError(msg)
             logger.warning(f"{msg}, using default")
             return None
@@ -1025,7 +1031,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
 
     @staticmethod
     def _validate_minkowski_p(
-        p: float | None, *, ctx: str, mode: ValidationMode = "raise"
+        p: float | None, *, ctx: str, mode: ValidationMode = _VALIDATION_MODES[1]
     ) -> float | None:
         return QuickAdapterRegressorV3._validate_scalar(
             p, ctx=ctx, mode=mode, predicate=lambda v: v > 0, constraint="must be > 0"
@@ -1036,7 +1042,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
         distance_metric: str,
         weights: NDArray[np.floating] | None = None,
         p: float | None = None,
-        mode: ValidationMode = "none",
+        mode: ValidationMode = _VALIDATION_MODES[2],
         metric_ctx: str = "distance_metric",
         p_ctx: str = "p",
         *,
@@ -1056,7 +1062,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
             if validated_p is not None:
                 kwargs["p"] = validated_p
 
-        if distance_metric in {"seuclidean", "mahalanobis"}:
+        if distance_metric in QuickAdapterRegressorV3._STANDARDIZED_DISTANCE_METRICS_SET:
             if reference_matrix.shape[0] < 2 or not np.all(np.isfinite(reference_matrix)):
                 raise ValueError(
                     "Standardized distances require a finite full front with at least two rows"
@@ -1066,7 +1072,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
                 raise ValueError(
                     "Standardized distances require positive active-objective variances"
                 )
-            if distance_metric == "seuclidean":
+            if distance_metric == QuickAdapterRegressorV3._DISTANCE_METRICS[5]:
                 kwargs["V"] = variances
             else:
                 covariance = np.atleast_2d(np.cov(reference_matrix, rowvar=False, ddof=1))
@@ -1078,7 +1084,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
 
     @staticmethod
     def _validate_quantile_q(
-        q: float | None, *, ctx: str, mode: ValidationMode = "raise"
+        q: float | None, *, ctx: str, mode: ValidationMode = _VALIDATION_MODES[1]
     ) -> float | None:
         return QuickAdapterRegressorV3._validate_scalar(
             q,
@@ -1090,22 +1096,22 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
 
     @staticmethod
     def _validate_power_mean_p(
-        p: float | None, *, ctx: str, mode: ValidationMode = "raise"
+        p: float | None, *, ctx: str, mode: ValidationMode = _VALIDATION_MODES[1]
     ) -> float | None:
         return QuickAdapterRegressorV3._validate_scalar(p, ctx=ctx, mode=mode)
 
     @staticmethod
     def _validate_metric_weights_support(
-        metric: str, *, ctx: str, mode: ValidationMode = "warn"
+        metric: str, *, ctx: str, mode: ValidationMode = _VALIDATION_MODES[0]
     ) -> str | None:
         if metric not in QuickAdapterRegressorV3._UNSUPPORTED_WEIGHTS_METRICS_SET:
             return metric
 
-        if mode == "none":
+        if mode == _VALIDATION_MODES[2]:
             return None
 
         msg = f"Invalid {ctx} value {metric!r}: does not support custom weights"
-        if mode == "raise":
+        if mode == _VALIDATION_MODES[1]:
             raise ValueError(msg)
         logger.warning(f"{msg}, using uniform weights")
         return None
@@ -1116,7 +1122,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
         n_objectives: int,
         *,
         ctx: str,
-        mode: ValidationMode = "raise",
+        mode: ValidationMode = _VALIDATION_MODES[1],
     ) -> NDArray[np.floating] | None:
         if weights is None:
             return np.full(n_objectives, 1.0 / n_objectives)
@@ -1144,9 +1150,9 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
                         return normalized
                     msg = f"Invalid {ctx} value: sum is zero"
 
-        if mode == "raise":
+        if mode == _VALIDATION_MODES[1]:
             raise ValueError(msg)
-        if mode == "warn":
+        if mode == _VALIDATION_MODES[0]:
             logger.warning(f"{msg}, using uniform weights")
         return np.full(n_objectives, 1.0 / n_objectives)
 
@@ -1157,17 +1163,17 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
         valid_options: tuple[str, ...],
         *,
         ctx: str,
-        mode: ValidationMode = "raise",
+        mode: ValidationMode = _VALIDATION_MODES[1],
         default: str | None = None,
     ) -> str | None:
         if isinstance(value, str) and value in valid_set:
             return value
 
-        if mode == "none":
+        if mode == _VALIDATION_MODES[2]:
             return default
 
         msg = enum_error_message(ctx, value, valid_options)
-        if mode == "raise":
+        if mode == _VALIDATION_MODES[1]:
             raise ValueError(msg)
         logger.warning(f"{msg}, using {default!r}")
         return default
@@ -1179,7 +1185,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
         ctx: str,
         default: str,
         aggregate_allowed: bool,
-        mode: ValidationMode = "warn",
+        mode: ValidationMode = _VALIDATION_MODES[0],
     ) -> str:
         if aggregate_allowed:
             valid_metrics = QuickAdapterRegressorV3._LABEL_SELECTION_DISTANCE_METRICS_SET
@@ -1210,7 +1216,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
         label_p_order: float | None,
         *,
         ctx: str,
-        mode: ValidationMode = "raise",
+        mode: ValidationMode = _VALIDATION_MODES[1],
     ) -> float | None:
         p = (
             label_p_order
@@ -1227,7 +1233,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
             QuickAdapterRegressorV3._SELECTION_METHODS_SET,
             QuickAdapterRegressorV3._SELECTION_METHODS,
             ctx="label_method",
-            mode="raise",
+            mode=_VALIDATION_MODES[1],
         )
 
         category = QuickAdapterRegressorV3._get_selection_category(label_method)
@@ -1236,7 +1242,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
             "method": label_method,
         }
 
-        if category == "distance":
+        if category == QuickAdapterRegressorV3._CATEGORY_DISTANCE:
             distance_metric = self.ft_params.get(
                 "label_distance_metric",
                 QuickAdapterRegressorV3.LABEL_DISTANCE_METRIC_DEFAULT,
@@ -1244,12 +1250,12 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
             distance_metric = QuickAdapterRegressorV3._validate_label_selection_metric(
                 distance_metric,
                 ctx="label_distance_metric",
-                mode="warn",
+                mode=_VALIDATION_MODES[0],
                 default=QuickAdapterRegressorV3.LABEL_DISTANCE_METRIC_DEFAULT,
                 aggregate_allowed=True,
             )
             config["distance_metric"] = distance_metric
-        elif category == "cluster":
+        elif category == QuickAdapterRegressorV3._CATEGORY_CLUSTER:
             distance_metric = self.ft_params.get(
                 "label_cluster_metric",
                 QuickAdapterRegressorV3.LABEL_CLUSTER_METRIC_DEFAULT,
@@ -1257,7 +1263,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
             distance_metric = QuickAdapterRegressorV3._validate_label_selection_metric(
                 distance_metric,
                 ctx="label_cluster_metric",
-                mode="warn",
+                mode=_VALIDATION_MODES[0],
                 default=QuickAdapterRegressorV3.LABEL_CLUSTER_METRIC_DEFAULT,
                 aggregate_allowed=False,
             )
@@ -1286,7 +1292,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
                 ctx="label_cluster_trial_selection_method",
             )
             config["trial_selection_method"] = trial_selection_method
-        elif category == "density":
+        elif category == QuickAdapterRegressorV3._CATEGORY_DENSITY:
             density_method = cast("DensityMethod", label_method)
             density_metric_default = QuickAdapterRegressorV3._get_label_density_metric_default(
                 density_method
@@ -1298,7 +1304,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
             distance_metric = QuickAdapterRegressorV3._validate_label_selection_metric(
                 distance_metric,
                 ctx="label_density_metric",
-                mode="warn",
+                mode=_VALIDATION_MODES[0],
                 default=density_metric_default,
                 aggregate_allowed=False,
             )
@@ -1903,7 +1909,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
             QuickAdapterRegressorV3._SCALER_TYPES_SET,
             QuickAdapterRegressorV3._SCALER_TYPES,
             ctx="scaler",
-            mode="raise",
+            mode=_VALIDATION_MODES[1],
         )
 
         feature_range = self.ft_params.get("range", QuickAdapterRegressorV3.RANGE_DEFAULT)
@@ -1973,9 +1979,9 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
         )
 
         match method:
-            case "train_test_split":
+            case QuickAdapterRegressorV3.DATA_SPLIT_METHOD_DEFAULT:
                 split_builder = self._make_train_test_split_datasets
-            case "timeseries_split":
+            case QuickAdapterRegressorV3._DATA_SPLIT_TIMESERIES:
                 split_builder = self._make_timeseries_split_datasets
             case _:
                 raise ValueError(
@@ -3634,7 +3640,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
         *,
         weights: NDArray[np.floating] | None = None,
         p: float | None = None,
-        mode: ValidationMode = "none",
+        mode: ValidationMode = _VALIDATION_MODES[2],
         p_ctx: str = "p",
     ) -> NDArray[np.floating]:
         if distance_metric in QuickAdapterRegressorV3._POWER_MEAN_METRICS_SET:
@@ -3701,7 +3707,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
                 distance_metric,
                 weights=weights,
                 p=p,
-                mode="warn",
+                mode=_VALIDATION_MODES[0],
                 p_ctx="label_distance_p",
             )
             return np.abs(distances) if apply_abs else distances
@@ -4336,7 +4342,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
             label_weights,
             n_objectives,
             ctx="label_weights",
-            mode="raise",
+            mode=_VALIDATION_MODES[1],
         )
 
         if n_samples == 1 and method in {
@@ -4350,14 +4356,17 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
 
         distance_metric = label_config["distance_metric"]
         p = QuickAdapterRegressorV3._resolve_p_order(
-            distance_metric, label_p_order, ctx=f"label_p_order for {method}", mode="none"
+            distance_metric,
+            label_p_order,
+            ctx=f"label_p_order for {method}",
+            mode=_VALIDATION_MODES[2],
         )
         distance_kwargs = (
             QuickAdapterRegressorV3._prepare_distance_kwargs(
                 distance_metric,
                 weights=weights,
                 p=p,
-                mode="warn",
+                mode=_VALIDATION_MODES[0],
                 metric_ctx=f"label_{category}_metric",
                 reference_matrix=normalized_matrix,
             )
@@ -4365,7 +4374,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
             else {}
         )
 
-        if category == "distance":
+        if category == QuickAdapterRegressorV3._CATEGORY_DISTANCE:
             if method == QuickAdapterRegressorV3._METHOD_COMPROMISE_PROGRAMMING:
                 return QuickAdapterRegressorV3._compromise_programming_scores(
                     normalized_matrix,
@@ -4383,7 +4392,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
                     distance_kwargs=distance_kwargs,
                 )
 
-        if category == "cluster":
+        if category == QuickAdapterRegressorV3._CATEGORY_CLUSTER:
             cluster_metric = label_config["distance_metric"]
             cluster_selection_method = label_config["selection_method"]
             trial_selection_method = label_config["trial_selection_method"]
@@ -4399,7 +4408,7 @@ class QuickAdapterRegressorV3(BaseRegressionModel):
                 distance_kwargs=distance_kwargs,
             )
 
-        if category == "density":
+        if category == QuickAdapterRegressorV3._CATEGORY_DENSITY:
             density_method = cast("DensityMethod", method)
             density_metric = label_config["distance_metric"]
 
index a6d35279992de0b72845e4d97ef859343215a78c..0bac06b01051553b26cdac2f0ff978f529f75e03 100644 (file)
@@ -99,7 +99,7 @@ FILL_BANDWIDTHS: Final[tuple[FillBandwidth, ...]] = (
 )
 
 LabelWeightSupportPolicy = Literal["fallback", "raise"]
-LABEL_WEIGHT_SUPPORT_POLICIES: Final[tuple[LabelWeightSupportPolicy, ...]] = (
+LABEL_WEIGHT_SUPPORT_POLICIES: Final[tuple[Literal["fallback"], Literal["raise"]]] = (
     "fallback",  # 0 - warn and use sanitized base weights (default)
     "raise",  # 1 - abort the fit with ValueError
 )
index 83e8bdf628b762d72651a1df2aaffb695a5edaa6..bd55d7aad9ea680a389387c8563bd29bbdc928be 100644 (file)
@@ -45,6 +45,8 @@ from Utils import (
     EXTREMA_WEIGHT_COLUMN,
     EXTREMA_WEIGHT_SMOOTHED_COLUMN,
     LABEL_COLUMNS,
+    MA_MODES,
+    PRICE_MODES,
     TRADE_NATR_METHODS,
     OptunaNamespace,
     alligator,
@@ -735,8 +737,8 @@ class QuickAdapterV3(IStrategy):
         )
         dataframe["%-ewo"] = ewo(
             dataframe=dataframe,
-            pricemode="close",
-            mamode="ema",
+            pricemode=PRICE_MODES[4],
+            mamode=MA_MODES[1],
             zero_lag=True,
             normalize=True,
             logger=logger,
@@ -776,7 +778,7 @@ class QuickAdapterV3(IStrategy):
         )
         dataframe["%-ibs"] = (closes - lows) / non_zero_diff(highs, lows)
         dataframe["jaw"], dataframe["teeth"], dataframe["lips"] = alligator(
-            dataframe, pricemode="median", zero_lag=True
+            dataframe, pricemode=PRICE_MODES[1], zero_lag=True
         )
         dataframe["%-dist_to_jaw"] = get_distance(closes, dataframe["jaw"])
         dataframe["%-dist_to_teeth"] = get_distance(closes, dataframe["teeth"])
@@ -1271,7 +1273,7 @@ class QuickAdapterV3(IStrategy):
         if label_natr is None or label_natr.empty:
             return None
         if trade_duration_candles >= 2:
-            zl_kama = get_zl_ma_fn("kama")
+            zl_kama = get_zl_ma_fn(MA_MODES[6])
             try:
                 trade_kama_natr_values = np.asarray(
                     zl_kama(label_natr, timeperiod=trade_duration_candles), dtype=float
@@ -1958,7 +1960,7 @@ class QuickAdapterV3(IStrategy):
         min_natr_multiplier_fraction: float,
         max_natr_multiplier_fraction: float,
         candle_idx: int = -1,
-        interpolation_direction: InterpolationDirection = "direct",
+        interpolation_direction: InterpolationDirection = _INTERPOLATION_DIRECTIONS[0],
         quantile_exponent: float = 1.5,
     ) -> float:
         df_signature = QuickAdapterV3._df_signature(df)
index 5065312b5478563a6183a0bda00d34c1d77de857..6b1af394a39d40bfc5b89fb3fc1d7319b09cdca6 100644 (file)
@@ -847,12 +847,12 @@ def _generate_extrema_label(
         series.loc[result.indices] = result.directions
 
     metrics: dict[str, list[float]] = {
-        "amplitude": result.amplitudes,
-        "amplitude_threshold_ratio": result.amplitude_threshold_ratios,
-        "volume_rate": result.volume_rates,
-        "speed": result.speeds,
-        "efficiency_ratio": result.efficiency_ratios,
-        "volume_weighted_efficiency_ratio": result.volume_weighted_efficiency_ratios,
+        COMBINED_METRICS[0]: result.amplitudes,
+        COMBINED_METRICS[1]: result.amplitude_threshold_ratios,
+        COMBINED_METRICS[2]: result.volume_rates,
+        COMBINED_METRICS[3]: result.speeds,
+        COMBINED_METRICS[4]: result.efficiency_ratios,
+        COMBINED_METRICS[5]: result.volume_weighted_efficiency_ratios,
     }
 
     known_at_lookahead = pd.Series(
@@ -947,7 +947,7 @@ def get_smoothing_kernel_half_width(
         return int(4.0 * sigma + 0.5)
     if method == SMOOTHING_METHODS[7]:  # "savgol"
         polyorder = max(int(config.get("polyorder", DEFAULTS_LABEL_SMOOTHING["polyorder"])), 0)
-        effective_window, _, _ = get_savgol_params(raw_window, polyorder, "mirror")
+        effective_window, _, _ = get_savgol_params(raw_window, polyorder, SMOOTHING_MODES[0])
     elif method == SMOOTHING_METHODS[3]:  # "kaiser_bessel_derived"
         effective_window = get_even_window(raw_window)
     else:
@@ -1010,7 +1010,7 @@ def compose_label_lookahead(
         center=True,
         min_periods=1,
     ).max()
-    if method == "savgol" and mode == "interp":
+    if method == SMOOTHING_METHODS[7] and mode == SMOOTHING_MODES[4]:
         smoothed_known_at_positions.iloc[:kernel_half_width] = known_at_positions.iloc[
             : 2 * kernel_half_width + 1
         ].max()
@@ -1843,7 +1843,7 @@ def compose_sample_weights(
     *,
     logger: Logger,
     context: str,
-    on_collapse: Literal["raise", "fallback"] = "raise",
+    on_collapse: Literal["raise", "fallback"] = LABEL_WEIGHT_SUPPORT_POLICIES[1],
 ) -> NDArray[np.floating]:
     """Combine base sample weights with the label importance weights.
 
@@ -3726,6 +3726,10 @@ def calculate_zero_lag(series: pd.Series, period: int) -> pd.Series:
     return 2 * series - series.shift(int(lag))
 
 
+MA_MODES: Final[tuple[str, ...]] = ("sma", "ema", "wma", "dema", "tema", "trima", "kama", "t3")
+PRICE_MODES: Final[tuple[str, ...]] = ("average", "median", "typical", "weighted-close", "close")
+
+
 @lru_cache(maxsize=_CACHE_MAXSIZE_SMALL)
 def get_ma_fn(
     mamode: str,
@@ -3734,16 +3738,16 @@ def get_ma_fn(
         str,
         Callable[[pd.Series | NDArray[np.floating], int], pd.Series | NDArray[np.floating]],
     ] = {
-        "sma": ta.SMA,
-        "ema": ta.EMA,
-        "wma": ta.WMA,
-        "dema": ta.DEMA,
-        "tema": ta.TEMA,
-        "trima": ta.TRIMA,
-        "kama": ta.KAMA,
-        "t3": ta.T3,
+        MA_MODES[0]: ta.SMA,
+        MA_MODES[1]: ta.EMA,
+        MA_MODES[2]: ta.WMA,
+        MA_MODES[3]: ta.DEMA,
+        MA_MODES[4]: ta.TEMA,
+        MA_MODES[5]: ta.TRIMA,
+        MA_MODES[6]: ta.KAMA,
+        MA_MODES[7]: ta.T3,
     }
-    return mamodes.get(mamode, mamodes["sma"])
+    return mamodes.get(mamode, mamodes[MA_MODES[0]])
 
 
 @lru_cache(maxsize=_CACHE_MAXSIZE_SMALL)
@@ -3860,21 +3864,21 @@ def smma(series: pd.Series, period: int, zero_lag=False, offset=0) -> pd.Series:
 @lru_cache(maxsize=_CACHE_MAXSIZE_SMALL)
 def get_price_fn(pricemode: str) -> Callable[[pd.DataFrame], pd.Series]:
     pricemodes = {
-        "average": ta.AVGPRICE,
-        "median": ta.MEDPRICE,
-        "typical": ta.TYPPRICE,
-        "weighted-close": ta.WCLPRICE,
-        "close": lambda df: df.get("close"),
+        PRICE_MODES[0]: ta.AVGPRICE,
+        PRICE_MODES[1]: ta.MEDPRICE,
+        PRICE_MODES[2]: ta.TYPPRICE,
+        PRICE_MODES[3]: ta.WCLPRICE,
+        PRICE_MODES[4]: lambda df: df.get("close"),
     }
-    return pricemodes.get(pricemode, pricemodes["close"])
+    return pricemodes.get(pricemode, pricemodes[PRICE_MODES[4]])
 
 
 def ewo(
     dataframe: pd.DataFrame,
     ma1_length: int = 5,
     ma2_length: int = 34,
-    pricemode: str = "close",
-    mamode: str = "sma",
+    pricemode: str = PRICE_MODES[4],
+    mamode: str = MA_MODES[0],
     zero_lag: bool = False,
     normalize: bool = False,
     *,
@@ -3886,7 +3890,7 @@ def ewo(
     prices = get_price_fn(pricemode)(dataframe)
 
     if zero_lag:
-        if mamode == "ema":
+        if mamode == MA_MODES[1]:
 
             def ma_fn(series, timeperiod):
                 return zlema(series, period=timeperiod)
@@ -3919,7 +3923,7 @@ def alligator(
     jaw_shift: int = 8,
     teeth_shift: int = 5,
     lips_shift: int = 3,
-    pricemode: str = "median",
+    pricemode: str = PRICE_MODES[1],
     zero_lag: bool = False,
 ) -> tuple[pd.Series, pd.Series, pd.Series]:
     """
@@ -4655,6 +4659,23 @@ RegressorCallback = Callable[..., Any] | XGBoostTrainingCallback
 
 _EARLY_STOPPING_ROUNDS_DEFAULT: Final[int] = 50
 
+_REGRESSOR_EVAL_METRIC: Final[str] = "rmse"
+_XGBOOST_BOOSTERS: Final[tuple[str, ...]] = ("gbtree", "dart")
+_XGBOOST_GROW_POLICIES: Final[tuple[str, ...]] = ("depthwise", "lossguide")
+_LIGHTGBM_BOOSTING_TYPES: Final[tuple[str, ...]] = ("gbdt", "dart")
+_NGBOOST_DISTRIBUTIONS: Final[tuple[str, ...]] = (
+    "normal",
+    "lognormal",
+    "exponential",
+    "laplace",
+    "t",
+)
+_CATBOOST_TASK_TYPES: Final[tuple[str, ...]] = ("CPU", "GPU")
+_CATBOOST_DEFAULT_LOSS: Final[str] = "RMSE"
+_CATBOOST_BOOTSTRAP_TYPES: Final[tuple[str, ...]] = ("Bayesian", "Bernoulli", "MVS")
+_CATBOOST_BOOSTING_TYPES: Final[tuple[str, ...]] = ("Plain", "Ordered")
+_CATBOOST_GROW_POLICIES: Final[tuple[str, ...]] = ("SymmetricTree", "Depthwise", "Lossguide")
+
 _CATBOOST_GPU_RSM_LOSS_FUNCTIONS: Final[tuple[str, ...]] = (
     "PairLogit",
     "PairLogitPairwise",
@@ -4688,11 +4709,11 @@ def get_ngboost_dist(dist_name: str) -> type:
     from ngboost.distns import Exponential, Laplace, LogNormal, Normal, T
 
     dist_map = {
-        "normal": Normal,
-        "lognormal": LogNormal,
-        "exponential": Exponential,
-        "laplace": Laplace,
-        "t": T,
+        _NGBOOST_DISTRIBUTIONS[0]: Normal,
+        _NGBOOST_DISTRIBUTIONS[1]: LogNormal,
+        _NGBOOST_DISTRIBUTIONS[2]: Exponential,
+        _NGBOOST_DISTRIBUTIONS[3]: Laplace,
+        _NGBOOST_DISTRIBUTIONS[4]: T,
     }
 
     if dist_name not in dist_map:
@@ -4809,7 +4830,7 @@ def fit_regressor(
             fit_callbacks.append(
                 EarlyStopping(
                     rounds=early_stopping_rounds,
-                    metric_name="rmse",
+                    metric_name=_REGRESSOR_EVAL_METRIC,
                     data_name="validation_0",
                     save_best=True,
                 )
@@ -4822,7 +4843,7 @@ def fit_regressor(
 
         model = XGBRegressor(
             objective="reg:squarederror",
-            eval_metric="rmse",
+            eval_metric=_REGRESSOR_EVAL_METRIC,
             callbacks=fit_callbacks if fit_callbacks else None,
             **model_training_parameters,
         )
@@ -4850,7 +4871,9 @@ def fit_regressor(
 
         if trial is not None and has_eval_set:
             fit_callbacks.append(
-                optuna.integration.LightGBMPruningCallback(trial, "rmse", valid_name="valid_0")
+                optuna.integration.LightGBMPruningCallback(
+                    trial, _REGRESSOR_EVAL_METRIC, valid_name="valid_0"
+                )
             )
 
         model = LGBMRegressor(objective="regression", **model_training_parameters)
@@ -4860,7 +4883,7 @@ def fit_regressor(
             sample_weight=train_weights,
             eval_set=eval_set,
             eval_sample_weight=eval_weights,
-            eval_metric="rmse",
+            eval_metric=_REGRESSOR_EVAL_METRIC,
             init_model=init_model,
             callbacks=fit_callbacks if fit_callbacks else None,
         )
@@ -4914,8 +4937,8 @@ def fit_regressor(
 
         early_stopping_rounds = _pop_early_stopping_rounds(model_training_parameters, has_eval_set)
 
-        dist = model_training_parameters.pop("dist", "normal")
-        if dist == "lognormal":
+        dist = model_training_parameters.pop("dist", _NGBOOST_DISTRIBUTIONS[0])
+        if dist == _NGBOOST_DISTRIBUTIONS[1]:
             label_sets = [y] + ([labels for _, labels in eval_set] if eval_set else [])
             if any(
                 not np.all(np.isfinite(values) & (values > 0))
@@ -4942,7 +4965,7 @@ def fit_regressor(
                 max_depth=model_training_parameters.pop("max_depth", None),
                 min_samples_split=model_training_parameters.pop("min_samples_split", 2),
                 min_samples_leaf=model_training_parameters.pop("min_samples_leaf", 1),
-                random_state=model_training_parameters["random_state"],
+                random_state=model_training_parameters[spec.seed_param],
             ),
             **model_training_parameters,
         )
@@ -4959,7 +4982,7 @@ def fit_regressor(
     elif regressor == _REGRESSOR_SPECS.catboost.name:
         from catboost import CatBoostRegressor, Pool
 
-        model_training_parameters.setdefault("loss_function", "RMSE")
+        model_training_parameters.setdefault("loss_function", _CATBOOST_DEFAULT_LOSS)
 
         if model_path is not None and "train_dir" not in model_training_parameters:
             if trial is not None:
@@ -4969,9 +4992,9 @@ def fit_regressor(
             else:
                 model_training_parameters["train_dir"] = str(model_path / "catboost_info")
 
-        task_type = model_training_parameters.get("task_type", "CPU")
-        loss_function = model_training_parameters.get("loss_function", "RMSE")
-        if task_type == "GPU":
+        task_type = model_training_parameters.get("task_type", _CATBOOST_TASK_TYPES[0])
+        loss_function = model_training_parameters.get("loss_function", _CATBOOST_DEFAULT_LOSS)
+        if task_type == _CATBOOST_TASK_TYPES[1]:
             model_training_parameters.pop("gpu_vram_gb", None)
             model_training_parameters.pop("n_jobs", None)
             model_training_parameters.setdefault("max_ctr_complexity", 4)
@@ -4991,8 +5014,10 @@ def fit_regressor(
         _apply_verbosity_alias(model_training_parameters)
 
         pruning_callback = None
-        if trial is not None and has_eval_set and task_type != "GPU":
-            pruning_callback = optuna.integration.CatBoostPruningCallback(trial, "RMSE")
+        if trial is not None and has_eval_set and task_type != _CATBOOST_TASK_TYPES[1]:
+            pruning_callback = optuna.integration.CatBoostPruningCallback(
+                trial, _CATBOOST_DEFAULT_LOSS
+            )
             fit_callbacks.append(pruning_callback)
 
         model = CatBoostRegressor(**model_training_parameters)
@@ -5514,7 +5539,10 @@ def optuna_save_best_params(
 def resolve_optuna_model_parameters(regressor: Regressor, params: dict[str, Any]) -> dict[str, Any]:
     """Reconstruct estimator parameters from replayable raw Optuna suggestions."""
     resolved = params.copy()
-    if regressor == _REGRESSOR_SPECS.xgboost.name and resolved.get("grow_policy") == "lossguide":
+    if (
+        regressor == _REGRESSOR_SPECS.xgboost.name
+        and resolved.get("grow_policy") == _XGBOOST_GROW_POLICIES[1]
+    ):
         resolved["max_depth"] = 0
     elif regressor == _REGRESSOR_SPECS.histgradientboostingregressor.name and resolved.pop(
         "l2_regularization_zero", False
@@ -5605,8 +5633,8 @@ def get_optuna_study_model_parameters(
 
         ranges = _build_ranges(default_ranges, log_scaled_params)
 
-        booster = trial.suggest_categorical("booster", ["gbtree", "dart"])
-        grow_policy = trial.suggest_categorical("grow_policy", ["depthwise", "lossguide"])
+        booster = trial.suggest_categorical("booster", _XGBOOST_BOOSTERS)
+        grow_policy = trial.suggest_categorical("grow_policy", _XGBOOST_GROW_POLICIES)
 
         params: dict[str, Any] = {
             # Boosting/Training
@@ -5629,7 +5657,7 @@ def get_optuna_study_model_parameters(
                         trial, "max_leaves", ranges["max_leaves"], min_val=2, log=True
                     ),
                 }
-                if grow_policy == "lossguide"
+                if grow_policy == _XGBOOST_GROW_POLICIES[1]
                 else {
                     "max_depth": _optuna_suggest_int_from_range(
                         trial, "max_depth", ranges["max_depth"], min_val=1
@@ -5676,7 +5704,7 @@ def get_optuna_study_model_parameters(
             ),
         }
 
-        if booster == "dart":
+        if booster == _XGBOOST_BOOSTERS[1]:
             params["sample_type"] = trial.suggest_categorical(
                 "sample_type", ["uniform", "weighted"]
             )
@@ -5724,7 +5752,7 @@ def get_optuna_study_model_parameters(
 
         ranges = _build_ranges(default_ranges, log_scaled_params)
 
-        boosting_type = trial.suggest_categorical("boosting_type", ["gbdt", "dart"])
+        boosting_type = trial.suggest_categorical("boosting_type", _LIGHTGBM_BOOSTING_TYPES)
 
         params: dict[str, Any] = {
             # Boosting/Training
@@ -5783,7 +5811,7 @@ def get_optuna_study_model_parameters(
             ),
         }
 
-        if boosting_type == "dart":
+        if boosting_type == _LIGHTGBM_BOOSTING_TYPES[1]:
             params["xgboost_dart_mode"] = trial.suggest_categorical(
                 "xgboost_dart_mode", [False, True]
             )
@@ -5960,15 +5988,15 @@ def get_optuna_study_model_parameters(
                 log=True,
             ),
             # Distribution
-            "dist": trial.suggest_categorical("dist", ["normal", "lognormal"]),
+            "dist": trial.suggest_categorical("dist", _NGBOOST_DISTRIBUTIONS[:2]),
         }
 
     elif regressor == _REGRESSOR_SPECS.catboost.name:
         # Parameter order: boosting -> tree structure -> regularization -> sampling
-        task_type = model_training_parameters.get("task_type", "CPU")
-        loss_function = model_training_parameters.get("loss_function", "RMSE")
+        task_type = model_training_parameters.get("task_type", _CATBOOST_TASK_TYPES[0])
+        loss_function = model_training_parameters.get("loss_function", _CATBOOST_DEFAULT_LOSS)
 
-        if task_type == "GPU":
+        if task_type == _CATBOOST_TASK_TYPES[1]:
             gpu_vram_gb = model_training_parameters.get("gpu_vram_gb", _CATBOOST_GPU_VRAM_DEFAULT)
             matched_vram_gb = max(
                 (v for v in _CATBOOST_GPU_VRAM_PARAM_RANGES if v <= gpu_vram_gb),
@@ -5999,8 +6027,8 @@ def get_optuna_study_model_parameters(
                 "rsm": (0.5, 1.0),
                 "subsample": (0.6, 1.0),
             }
-            bootstrap_options = ["Bayesian", "Bernoulli"]
-            boosting_type_options = ["Plain"]
+            bootstrap_options = _CATBOOST_BOOTSTRAP_TYPES[:2]
+            boosting_type_options = _CATBOOST_BOOSTING_TYPES[:1]
         else:  # CPU
             default_ranges: dict[str, tuple[float, float]] = {
                 # Boosting/Training
@@ -6018,8 +6046,8 @@ def get_optuna_study_model_parameters(
                 "rsm": (0.5, 1.0),
                 "subsample": (0.6, 1.0),
             }
-            bootstrap_options = ["Bayesian", "Bernoulli", "MVS"]
-            boosting_type_options = ["Plain", "Ordered"]
+            bootstrap_options = _CATBOOST_BOOTSTRAP_TYPES
+            boosting_type_options = _CATBOOST_BOOSTING_TYPES
 
         log_scaled_params = {
             "iterations",
@@ -6032,10 +6060,11 @@ def get_optuna_study_model_parameters(
 
         boosting_type = trial.suggest_categorical("boosting_type", boosting_type_options)
         bootstrap_type = trial.suggest_categorical("bootstrap_type", bootstrap_options)
-        grow_policy = trial.suggest_categorical(
-            "grow_policy", ["SymmetricTree", "Depthwise", "Lossguide"]
-        )
-        if boosting_type == "Ordered" and grow_policy != "SymmetricTree":
+        grow_policy = trial.suggest_categorical("grow_policy", _CATBOOST_GROW_POLICIES)
+        if (
+            boosting_type == _CATBOOST_BOOSTING_TYPES[1]
+            and grow_policy != _CATBOOST_GROW_POLICIES[0]
+        ):
             raise optuna.TrialPruned("Ordered boosting is not supported for nonsymmetric trees")
 
         params: dict[str, Any] = {
@@ -6081,28 +6110,31 @@ def get_optuna_study_model_parameters(
             ),
         }
 
-        if task_type == "CPU" or loss_function in _CATBOOST_GPU_RSM_LOSS_FUNCTIONS:
+        if (
+            task_type == _CATBOOST_TASK_TYPES[0]
+            or loss_function in _CATBOOST_GPU_RSM_LOSS_FUNCTIONS
+        ):
             params["rsm"] = trial.suggest_float(
                 "rsm",
                 ranges["rsm"][0],
                 ranges["rsm"][1],
             )
 
-        if bootstrap_type == "Bayesian":
+        if bootstrap_type == _CATBOOST_BOOTSTRAP_TYPES[0]:
             params["bagging_temperature"] = trial.suggest_float(
                 "bagging_temperature",
                 ranges["bagging_temperature"][0],
                 ranges["bagging_temperature"][1],
             )
 
-        if bootstrap_type in ["Bernoulli", "MVS"]:
+        if bootstrap_type in _CATBOOST_BOOTSTRAP_TYPES[1:]:
             params["subsample"] = trial.suggest_float(
                 "subsample",
                 ranges["subsample"][0],
                 ranges["subsample"][1],
             )
 
-        if task_type == "GPU":
+        if task_type == _CATBOOST_TASK_TYPES[1]:
             params["border_count"] = _optuna_suggest_int_from_range(
                 trial, "border_count", ranges["border_count"], min_val=1
             )