]> Piment Noir Git Repositories - freqai-strategies.git/commitdiff
fix(reforcexy): port applicable QuickAdapter PR #261 fixes (#263)
authorJérôme Benoit <jerome.benoit@piment-noir.org>
Fri, 18 Sep 2026 15:23:00 +0000 (17:23 +0200)
committerGitHub <noreply@github.com>
Fri, 18 Sep 2026 15:23:00 +0000 (17:23 +0200)
* fix(reforcexy): port applicable QuickAdapter PR #261 fixes

- Align prediction history to requested candle dates and exact strategy
  indexes (recorded/produced provenance, dedupe, exact-index attach).
- Freeze deployment feature coordinates for continual learning with
  independent cache/disk state restoration and explicit rejection of
  legacy or incompatible artifacts.
- Keep raw OHLC environment prices out of feature preprocessing; cold
  HPO trials use fresh candidate pipelines while the final continuation
  reuses the frozen deployment pipeline on the raw split.
- Return the current finite evaluation best checkpoint (best_model.zip)
  with final-policy fallback.
- Optional per-pair produced-observation action statistics with session
  warmup, numeric coercion and population standard deviation.
- Refresh BasedPyright snapshot; 2 argument-type errors resolved.

* fix(reforcexy): align resumed gamma and invalidate incompatible HPO state

* docs(reforcexy): clarify continuation and objective compatibility

* docs(reforcexy): condense continuation guidance

* fix(reforcexy): preserve replay buffer on best checkpoint selection

* chore(reforcexy): refresh basedpyright snapshot positions

README.md
ReforceXY/.basedpyright/diagnostics.json
ReforceXY/user_data/freqaimodels/ReforceXY.py

index 79801d66dabc3ee16c63dc1a239c3e59da1faf18..ab77e5429239e1242dd0300a0960c5ffdd190545 100644 (file)
--- a/README.md
+++ b/README.md
@@ -344,6 +344,15 @@ PPO, MaskablePPO, RecurrentPPO, DQN, QRDQN
 The documented list of model tunables is at the top of the
 [ReforceXY.py](./ReforceXY/user_data/freqaimodels/ReforceXY.py) file.
 
+Continual learning reuses the deployed policy and fitted feature pipeline.
+Reset trained models or use a new `freqai.identifier` to change feature
+coordinates or migrate incompatible artifacts. HPO studies and saved best
+parameters are reused only when their objective identity matches.
+
+Optional `fit_live_predictions_candles` statistics count produced observations
+per pair after session startup; restarts reset the warmup. See the model
+docstrings for continuation, HPO and statistics details.
+
 The rewarding logic and tunables are documented in the
 [reward space analysis](./ReforceXY/reward_space_analysis/README.md).
 
index bd7f0af82197849026197231d14a8dd2f92ce323..0d8404403471b48a52c2619724c69ad512fc39ed 100644 (file)
       "startCharacter": 4,
       "startLine": 4496
     },
-    {
-      "endCharacter": 51,
-      "endLine": 683,
-      "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 26,
-      "startLine": 683
-    },
-    {
-      "endCharacter": 51,
-      "endLine": 683,
-      "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 26,
-      "startLine": 683
-    },
     {
       "endCharacter": 60,
-      "endLine": 687,
+      "endLine": 755,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 30,
-      "startLine": 687
+      "startLine": 755
     },
     {
       "endCharacter": 60,
-      "endLine": 687,
+      "endLine": 755,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 30,
-      "startLine": 687
+      "startLine": 755
     },
     {
       "endCharacter": 22,
-      "endLine": 758,
+      "endLine": 827,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Cannot assign to attribute \"train_env\" for class \"ReforceXY*\"\n  Expression of type \"VecEnv\" cannot be assigned to attribute \"train_env\" of class \"ReforceXY\"\n    Type \"VecEnv\" is not assignable to type \"VecMonitor | SubprocVecEnv | Env[Unknown, Unknown]\"\n      \"VecEnv\" is not assignable to \"VecMonitor\"\n      \"VecEnv\" is not assignable to \"SubprocVecEnv\"\n      \"VecEnv\" is not assignable to \"Env[Unknown, Unknown]\"",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 13,
-      "startLine": 758
+      "startLine": 827
     },
     {
       "endCharacter": 37,
-      "endLine": 758,
+      "endLine": 827,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Cannot assign to attribute \"eval_env\" for class \"ReforceXY*\"\n  Expression of type \"VecEnv\" cannot be assigned to attribute \"eval_env\" of class \"ReforceXY\"\n    Type \"VecEnv\" is not assignable to type \"VecMonitor | SubprocVecEnv | Env[Unknown, Unknown]\"\n      \"VecEnv\" is not assignable to \"VecMonitor\"\n      \"VecEnv\" is not assignable to \"SubprocVecEnv\"\n      \"VecEnv\" is not assignable to \"Env[Unknown, Unknown]\"",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 29,
-      "startLine": 758
+      "startLine": 827
     },
     {
       "endCharacter": 38,
-      "endLine": 1033,
+      "endLine": 1260,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"obj\" of type \"Sized\" in function \"len\"\n  Type \"Any | None\" is not assignable to type \"Sized\"\n    \"None\" is incompatible with protocol \"Sized\"\n      \"__len__\" is not present",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 30,
-      "startLine": 1033
+      "startLine": 1260
     },
     {
       "endCharacter": 36,
-      "endLine": 1037,
+      "endLine": 1264,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"obj\" of type \"Sized\" in function \"len\"\n  Type \"Any | None\" is not assignable to type \"Sized\"\n    \"None\" is incompatible with protocol \"Sized\"\n      \"__len__\" is not present",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 29,
-      "startLine": 1037
+      "startLine": 1264
     },
     {
       "endCharacter": 80,
-      "endLine": 1040,
+      "endLine": 1267,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"timeframe\" of type \"str\" in function \"steps_to_days\"\n  Type \"Any | None\" is not assignable to type \"str\"\n    \"None\" is not assignable to \"str\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 52,
-      "startLine": 1040
+      "startLine": 1267
     },
     {
       "endCharacter": 78,
-      "endLine": 1041,
+      "endLine": 1268,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"timeframe\" of type \"str\" in function \"steps_to_days\"\n  Type \"Any | None\" is not assignable to type \"str\"\n    \"None\" is not assignable to \"str\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 50,
-      "startLine": 1041
+      "startLine": 1268
     },
     {
       "endCharacter": 80,
-      "endLine": 1042,
+      "endLine": 1269,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"timeframe\" of type \"str\" in function \"steps_to_days\"\n  Type \"Any | None\" is not assignable to type \"str\"\n    \"None\" is not assignable to \"str\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 52,
-      "startLine": 1042
+      "startLine": 1269
     },
     {
       "endCharacter": 83,
-      "endLine": 1110,
+      "endLine": 1341,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Argument of type \"Any | None\" cannot be assigned to parameter \"timeframe\" of type \"str\" in function \"steps_to_days\"\n  Type \"Any | None\" is not assignable to type \"str\"\n    \"None\" is not assignable to \"str\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 55,
-      "startLine": 1110
+      "startLine": 1341
     },
     {
       "endCharacter": 52,
-      "endLine": 1141,
+      "endLine": 1382,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Argument of type \"VecMonitor | SubprocVecEnv | Env[Unknown, Unknown]\" cannot be assigned to parameter \"eval_env\" of type \"BaseEnvironment\" in function \"get_callbacks\"\n  Type \"VecMonitor | SubprocVecEnv | Env[Unknown, Unknown]\" is not assignable to type \"BaseEnvironment\"\n    \"SubprocVecEnv\" is not assignable to \"BaseEnvironment\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 39,
-      "startLine": 1141
+      "startLine": 1382
     },
     {
       "endCharacter": 50,
-      "endLine": 1302,
+      "endLine": 1611,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Argument of type \"NDArray[float32]\" cannot be assigned to parameter \"x\" of type \"float32\" in function \"append\"\n  \"ndarray[_AnyShape, dtype[float32]]\" is not assignable to \"floating[_32Bit]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 36,
-      "startLine": 1302
+      "startLine": 1611
     },
     {
-      "endCharacter": 32,
-      "endLine": 2027,
+      "endCharacter": 44,
+      "endLine": 2372,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "\"best_trial_params\" is possibly unbound",
       "rule": "reportPossiblyUnboundVariable",
       "severity": "error",
-      "startCharacter": 15,
-      "startLine": 2027
+      "startCharacter": 27,
+      "startLine": 2372
     },
     {
       "endCharacter": 12,
-      "endLine": 2036,
+      "endLine": 2392,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Parameter declaration \"seed\" is obscured by a declaration of the same name",
       "rule": "reportRedeclaration",
       "severity": "error",
       "startCharacter": 8,
-      "startLine": 2036
+      "startLine": 2392
     },
     {
       "endCharacter": 16,
-      "endLine": 2037,
+      "endLine": 2393,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Parameter declaration \"env_info\" is obscured by a declaration of the same name",
       "rule": "reportRedeclaration",
       "severity": "error",
       "startCharacter": 8,
-      "startLine": 2037
+      "startLine": 2393
     },
     {
       "endCharacter": 47,
-      "endLine": 2082,
+      "endLine": 2432,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Argument of type \"list[() -> BaseEnvironment]\" cannot be assigned to parameter \"env_fns\" of type \"list[() -> Env[Unknown, Unknown]]\" in function \"__init__\"\n  \"list[() -> BaseEnvironment]\" is not assignable to \"list[() -> Env[Unknown, Unknown]]\"\n    Type parameter \"_T@list\" is invariant, but \"() -> BaseEnvironment\" is not the same as \"() -> Env[Unknown, Unknown]\"\n    Consider switching from \"list\" to \"Sequence\" which is covariant",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 38,
-      "startLine": 2082
+      "startLine": 2432
     },
     {
       "endCharacter": 45,
-      "endLine": 2084,
+      "endLine": 2434,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Argument of type \"list[() -> BaseEnvironment]\" cannot be assigned to parameter \"env_fns\" of type \"list[() -> Env[Unknown, Unknown]]\" in function \"__init__\"\n  \"list[() -> BaseEnvironment]\" is not assignable to \"list[() -> Env[Unknown, Unknown]]\"\n    Type parameter \"_T@list\" is invariant, but \"() -> BaseEnvironment\" is not the same as \"() -> Env[Unknown, Unknown]\"\n    Consider switching from \"list\" to \"Sequence\" which is covariant",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 36,
-      "startLine": 2084
+      "startLine": 2434
     },
     {
       "endCharacter": 45,
-      "endLine": 2086,
+      "endLine": 2436,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Argument of type \"list[() -> BaseEnvironment]\" cannot be assigned to parameter \"env_fns\" of type \"list[() -> Env[Unknown, Unknown]]\" in function \"__init__\"\n  \"list[() -> BaseEnvironment]\" is not assignable to \"list[() -> Env[Unknown, Unknown]]\"\n    Type parameter \"_T@list\" is invariant, but \"() -> BaseEnvironment\" is not the same as \"() -> Env[Unknown, Unknown]\"\n    Consider switching from \"list\" to \"Sequence\" which is covariant",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 37,
-      "startLine": 2086
+      "startLine": 2436
     },
     {
       "endCharacter": 43,
-      "endLine": 2088,
+      "endLine": 2438,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Argument of type \"list[() -> BaseEnvironment]\" cannot be assigned to parameter \"env_fns\" of type \"list[() -> Env[Unknown, Unknown]]\" in function \"__init__\"\n  \"list[() -> BaseEnvironment]\" is not assignable to \"list[() -> Env[Unknown, Unknown]]\"\n    Type parameter \"_T@list\" is invariant, but \"() -> BaseEnvironment\" is not the same as \"() -> Env[Unknown, Unknown]\"\n    Consider switching from \"list\" to \"Sequence\" which is covariant",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 35,
-      "startLine": 2088
+      "startLine": 2438
     },
     {
       "endCharacter": 22,
-      "endLine": 2129,
+      "endLine": 2486,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Operator \"*\" not supported for \"None\"",
       "rule": "reportOptionalOperand",
       "severity": "error",
       "startCharacter": 15,
-      "startLine": 2129
+      "startLine": 2486
     },
     {
       "endCharacter": 96,
-      "endLine": 2131,
+      "endLine": 2488,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Operator \"*\" not supported for \"None\"",
       "rule": "reportOptionalOperand",
       "severity": "error",
       "startCharacter": 89,
-      "startLine": 2131
+      "startLine": 2488
     },
     {
       "endCharacter": 23,
-      "endLine": 2134,
+      "endLine": 2491,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Operator \"*\" not supported for \"None\"",
       "rule": "reportOptionalOperand",
       "severity": "error",
       "startCharacter": 16,
-      "startLine": 2134
+      "startLine": 2491
     },
     {
       "endCharacter": 98,
-      "endLine": 2136,
+      "endLine": 2493,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Operator \"*\" not supported for \"None\"",
       "rule": "reportOptionalOperand",
       "severity": "error",
       "startCharacter": 91,
-      "startLine": 2136
+      "startLine": 2493
     },
     {
       "endCharacter": 44,
-      "endLine": 2148,
+      "endLine": 2505,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Operator \"*\" not supported for types \"Any | None\" and \"Any | int | None\"\n  Operator \"*\" not supported for types \"None\" and \"None\"\n  Operator \"*\" not supported for types \"None\" and \"int\"",
       "rule": "reportOperatorIssue",
       "severity": "error",
       "startCharacter": 15,
-      "startLine": 2148
+      "startLine": 2505
     },
     {
       "endCharacter": 133,
-      "endLine": 2150,
+      "endLine": 2507,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Operator \"*\" not supported for types \"Any | None\" and \"Any | int | None\"\n  Operator \"*\" not supported for types \"None\" and \"None\"\n  Operator \"*\" not supported for types \"None\" and \"int\"",
       "rule": "reportOperatorIssue",
       "severity": "error",
       "startCharacter": 106,
-      "startLine": 2150
+      "startLine": 2507
     },
     {
       "endCharacter": 30,
-      "endLine": 2153,
+      "endLine": 2510,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Operator \">\" not supported for \"None\"",
       "rule": "reportOptionalOperand",
       "severity": "error",
       "startCharacter": 15,
-      "startLine": 2153
+      "startLine": 2510
     },
     {
       "endCharacter": 47,
-      "endLine": 2197,
+      "endLine": 2560,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Argument of type \"VecEnv\" cannot be assigned to parameter \"eval_env\" of type \"BaseEnvironment\" in function \"get_callbacks\"\n  \"VecEnv\" is not assignable to \"BaseEnvironment\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 39,
-      "startLine": 2197
+      "startLine": 2560
     },
     {
       "endCharacter": 46,
-      "endLine": 2254,
+      "endLine": 2617,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "\"is_pruned\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 37,
-      "startLine": 2254
+      "startLine": 2617
     },
     {
       "endCharacter": 57,
-      "endLine": 2257,
+      "endLine": 2620,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "\"best_mean_reward\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 41,
-      "startLine": 2257
+      "startLine": 2620
     },
     {
       "endCharacter": 37,
-      "endLine": 2267,
+      "endLine": 2630,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Cannot assign to attribute \"train_env\" for class \"ReforceXY*\"\n  Type \"None\" is not assignable to type \"VecMonitor | SubprocVecEnv | Env[Unknown, Unknown]\"\n    \"None\" is not assignable to \"VecMonitor\"\n    \"None\" is not assignable to \"SubprocVecEnv\"\n    \"None\" is not assignable to \"Env[Unknown, Unknown]\"",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 33,
-      "startLine": 2267
+      "startLine": 2630
     },
     {
       "endCharacter": 36,
-      "endLine": 2272,
+      "endLine": 2635,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Cannot assign to attribute \"eval_env\" for class \"ReforceXY*\"\n  Type \"None\" is not assignable to type \"VecMonitor | SubprocVecEnv | Env[Unknown, Unknown]\"\n    \"None\" is not assignable to \"VecMonitor\"\n    \"None\" is not assignable to \"SubprocVecEnv\"\n    \"None\" is not assignable to \"Env[Unknown, Unknown]\"",
       "rule": "reportAttributeAccessIssue",
       "severity": "error",
       "startCharacter": 32,
-      "startLine": 2272
+      "startLine": 2635
     },
     {
       "endCharacter": 7,
-      "endLine": 2304,
+      "endLine": 2667,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Declaration \"MyRLEnv\" is obscured by a declaration of the same name",
       "rule": "reportRedeclaration",
       "severity": "error",
       "startCharacter": 0,
-      "startLine": 2304
+      "startLine": 2667
     },
     {
       "endCharacter": 34,
-      "endLine": 2316,
+      "endLine": 2679,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Declaration \"_last_closed_position\" is obscured by a declaration of the same name",
       "rule": "reportRedeclaration",
       "severity": "error",
       "startCharacter": 13,
-      "startLine": 2316
+      "startLine": 2679
     },
     {
       "endCharacter": 36,
-      "endLine": 2317,
+      "endLine": 2680,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Declaration \"_last_closed_trade_tick\" is obscured by a declaration of the same name",
       "rule": "reportRedeclaration",
       "severity": "error",
       "startCharacter": 13,
-      "startLine": 2317
+      "startLine": 2680
     },
     {
       "endCharacter": 13,
-      "endLine": 3153,
+      "endLine": 3516,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Method \"reset\" overrides class \"BaseEnvironment\" in an incompatible manner\n  Return type mismatch: base method returns type \"tuple[DataFrame, dict[Unknown, Unknown]]\", override returns type \"tuple[NDArray[float32], dict[str, Any]]\"\n    \"tuple[NDArray[float32], dict[str, Any]]\" is not assignable to \"tuple[DataFrame, dict[Unknown, Unknown]]\"\n      Tuple entry 1 is incorrect type\n        \"ndarray[_AnyShape, dtype[float32]]\" is not assignable to \"DataFrame\"",
       "rule": "reportIncompatibleMethodOverride",
       "severity": "error",
       "startCharacter": 8,
-      "startLine": 3153
+      "startLine": 3516
     },
     {
       "endCharacter": 26,
-      "endLine": 3175,
+      "endLine": 3538,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Type \"tuple[DataFrame, dict[Unknown, Unknown]]\" is not assignable to return type \"tuple[NDArray[float32], dict[str, Any]]\"\n  \"DataFrame\" is not assignable to \"ndarray[_AnyShape, dtype[float32]]\"",
       "rule": "reportReturnType",
       "severity": "error",
       "startCharacter": 15,
-      "startLine": 3175
+      "startLine": 3538
     },
     {
       "endCharacter": 55,
-      "endLine": 3504,
+      "endLine": 3867,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 44,
-      "startLine": 3504
+      "startLine": 3867
     },
     {
       "endCharacter": 55,
-      "endLine": 3504,
+      "endLine": 3867,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 44,
-      "startLine": 3504
+      "startLine": 3867
     },
     {
       "endCharacter": 59,
-      "endLine": 3528,
+      "endLine": 3891,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 48,
-      "startLine": 3528
+      "startLine": 3891
     },
     {
       "endCharacter": 59,
-      "endLine": 3528,
+      "endLine": 3891,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 48,
-      "startLine": 3528
+      "startLine": 3891
     },
     {
       "endCharacter": 24,
-      "endLine": 3573,
+      "endLine": 3936,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Method \"_get_observation\" overrides class \"BaseEnvironment\" in an incompatible manner\n  Return type mismatch: base method returns type \"DataFrame\", override returns type \"NDArray[float32]\"\n    \"ndarray[_AnyShape, dtype[float32]]\" is not assignable to \"DataFrame\"",
       "rule": "reportIncompatibleMethodOverride",
       "severity": "error",
       "startCharacter": 8,
-      "startLine": 3573
+      "startLine": 3936
     },
     {
       "endCharacter": 53,
-      "endLine": 3641,
+      "endLine": 4004,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "\"name\" is not a known attribute of \"None\"",
       "rule": "reportOptionalMemberAccess",
       "severity": "error",
       "startCharacter": 49,
-      "startLine": 3641
+      "startLine": 4004
     },
     {
       "endCharacter": 12,
-      "endLine": 3675,
+      "endLine": 4038,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Method \"step\" overrides class \"Base5ActionRLEnv\" in an incompatible manner\n  Return type mismatch: base method returns type \"tuple[DataFrame, float, bool, Literal[False], dict[str, Unknown]]\", override returns type \"tuple[NDArray[float32], float, bool, bool, dict[str, Any]]\"\n    \"tuple[NDArray[float32], float, bool, bool, dict[str, Any]]\" is not assignable to \"tuple[DataFrame, float, bool, Literal[False], dict[str, Unknown]]\"\n      Tuple entry 1 is incorrect type\n        \"ndarray[_AnyShape, dtype[float32]]\" is not assignable to \"DataFrame\"",
       "rule": "reportIncompatibleMethodOverride",
       "severity": "error",
       "startCharacter": 8,
-      "startLine": 3675
+      "startLine": 4038
     },
     {
       "endCharacter": 20,
-      "endLine": 3788,
+      "endLine": 4151,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Method \"action_masks\" overrides class \"BaseEnvironment\" in an incompatible manner\n  Return type mismatch: base method returns type \"list[bool]\", override returns type \"NDArray[bool_]\"\n    \"ndarray[_AnyShape, dtype[bool_]]\" is not assignable to \"list[bool]\"",
       "rule": "reportIncompatibleMethodOverride",
       "severity": "error",
       "startCharacter": 8,
-      "startLine": 3788
+      "startLine": 4151
     },
     {
       "endCharacter": 65,
-      "endLine": 3981,
+      "endLine": 4344,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Type \"Any | None\" is not assignable to return type \"float\"\n  Type \"Any | None\" is not assignable to type \"float\"\n    \"None\" is not assignable to \"float\"",
       "rule": "reportReturnType",
       "severity": "error",
       "startCharacter": 15,
-      "startLine": 3981
+      "startLine": 4344
     },
     {
       "endCharacter": 40,
-      "endLine": 4020,
+      "endLine": 4383,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "\"Figure\" is not exported from module \"matplotlib.pyplot\"",
       "rule": "reportPrivateImportUsage",
       "severity": "error",
       "startCharacter": 34,
-      "startLine": 4020
+      "startLine": 4383
     },
     {
       "endCharacter": 54,
-      "endLine": 4518,
+      "endLine": 4881,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 45,
-      "startLine": 4518
+      "startLine": 4881
     },
     {
       "endCharacter": 54,
-      "endLine": 4518,
+      "endLine": 4881,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 45,
-      "startLine": 4518
+      "startLine": 4881
     },
     {
       "endCharacter": 50,
-      "endLine": 4530,
+      "endLine": 4893,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Argument of type \"object\" cannot be assigned to parameter \"x\" of type \"ConvertibleToFloat\" in function \"__new__\"\n  Type \"object\" is not assignable to type \"ConvertibleToFloat\"\n    \"object\" is not assignable to \"str\"\n    \"object\" is incompatible with protocol \"Buffer\"\n      \"__buffer__\" is not present\n    \"object\" is incompatible with protocol \"SupportsFloat\"\n      \"__float__\" is not present\n    \"object\" is incompatible with protocol \"SupportsIndex\"\n      \"__index__\" is not present",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 37,
-      "startLine": 4530
+      "startLine": 4893
     },
     {
       "endCharacter": 72,
-      "endLine": 4541,
+      "endLine": 4904,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 70,
-      "startLine": 4541
+      "startLine": 4904
     },
     {
       "endCharacter": 72,
-      "endLine": 4541,
+      "endLine": 4904,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 70,
-      "startLine": 4541
+      "startLine": 4904
     },
     {
       "endCharacter": 73,
-      "endLine": 4550,
+      "endLine": 4913,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 71,
-      "startLine": 4550
+      "startLine": 4913
     },
     {
       "endCharacter": 73,
-      "endLine": 4550,
+      "endLine": 4913,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 71,
-      "startLine": 4550
+      "startLine": 4913
     },
     {
       "endCharacter": 58,
-      "endLine": 4559,
+      "endLine": 4922,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 56,
-      "startLine": 4559
+      "startLine": 4922
     },
     {
       "endCharacter": 58,
-      "endLine": 4559,
+      "endLine": 4922,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 56,
-      "startLine": 4559
+      "startLine": 4922
     },
     {
       "endCharacter": 50,
-      "endLine": 4783,
+      "endLine": 5146,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.py",
       "message": "Argument of type \"Mapping[Unknown, Unknown]\" cannot be assigned to parameter \"src\" of type \"dict[str, Any]\" in function \"deepmerge\"\n  \"Mapping[Unknown, Unknown]\" is not assignable to \"dict[str, Any]\"",
       "rule": "reportArgumentType",
       "severity": "error",
       "startCharacter": 49,
-      "startLine": 4783
+      "startLine": 5146
     },
     {
       "endCharacter": 20,
-      "endLine": 4960,
+      "endLine": 5323,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 18,
-      "startLine": 4960
+      "startLine": 5323
     },
     {
       "endCharacter": 20,
-      "endLine": 4960,
+      "endLine": 5323,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 18,
-      "startLine": 4960
+      "startLine": 5323
     },
     {
       "endCharacter": 59,
-      "endLine": 4965,
+      "endLine": 5328,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 31,
-      "startLine": 4965
+      "startLine": 5328
     },
     {
       "endCharacter": 59,
-      "endLine": 4965,
+      "endLine": 5328,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 31,
-      "startLine": 4965
+      "startLine": 5328
     },
     {
       "endCharacter": 65,
-      "endLine": 4966,
+      "endLine": 5329,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 34,
-      "startLine": 4966
+      "startLine": 5329
     },
     {
       "endCharacter": 65,
-      "endLine": 4966,
+      "endLine": 5329,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 34,
-      "startLine": 4966
+      "startLine": 5329
     },
     {
       "endCharacter": 57,
-      "endLine": 4967,
+      "endLine": 5330,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 31,
-      "startLine": 4967
+      "startLine": 5330
     },
     {
       "endCharacter": 57,
-      "endLine": 4967,
+      "endLine": 5330,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 31,
-      "startLine": 4967
+      "startLine": 5330
     },
     {
       "endCharacter": 63,
-      "endLine": 4969,
+      "endLine": 5332,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 34,
-      "startLine": 4969
+      "startLine": 5332
     },
     {
       "endCharacter": 63,
-      "endLine": 4969,
+      "endLine": 5332,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 34,
-      "startLine": 4969
+      "startLine": 5332
     },
     {
       "endCharacter": 61,
-      "endLine": 4971,
+      "endLine": 5334,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 32,
-      "startLine": 4971
+      "startLine": 5334
     },
     {
       "endCharacter": 61,
-      "endLine": 4971,
+      "endLine": 5334,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 32,
-      "startLine": 4971
+      "startLine": 5334
     },
     {
       "endCharacter": 67,
-      "endLine": 4972,
+      "endLine": 5335,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 36,
-      "startLine": 4972
+      "startLine": 5335
     },
     {
       "endCharacter": 67,
-      "endLine": 4972,
+      "endLine": 5335,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 36,
-      "startLine": 4972
+      "startLine": 5335
     },
     {
       "endCharacter": 73,
-      "endLine": 4973,
+      "endLine": 5336,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 39,
-      "startLine": 4973
+      "startLine": 5336
     },
     {
       "endCharacter": 73,
-      "endLine": 4973,
+      "endLine": 5336,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 39,
-      "startLine": 4973
+      "startLine": 5336
     },
     {
       "endCharacter": 61,
-      "endLine": 4974,
+      "endLine": 5337,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 33,
-      "startLine": 4974
+      "startLine": 5337
     },
     {
       "endCharacter": 61,
-      "endLine": 4974,
+      "endLine": 5337,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 33,
-      "startLine": 4974
+      "startLine": 5337
     },
     {
       "endCharacter": 76,
-      "endLine": 4978,
+      "endLine": 5341,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 46,
-      "startLine": 4978
+      "startLine": 5341
     },
     {
       "endCharacter": 76,
-      "endLine": 4978,
+      "endLine": 5341,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 46,
-      "startLine": 4978
+      "startLine": 5341
     },
     {
       "endCharacter": 89,
-      "endLine": 4980,
+      "endLine": 5343,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 52,
-      "startLine": 4980
+      "startLine": 5343
     },
     {
       "endCharacter": 89,
-      "endLine": 4980,
+      "endLine": 5343,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 52,
-      "startLine": 4980
+      "startLine": 5343
     },
     {
       "endCharacter": 83,
-      "endLine": 4981,
+      "endLine": 5344,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 49,
-      "startLine": 4981
+      "startLine": 5344
     },
     {
       "endCharacter": 83,
-      "endLine": 4981,
+      "endLine": 5344,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 49,
-      "startLine": 4981
+      "startLine": 5344
     },
     {
       "endCharacter": 57,
-      "endLine": 5006,
+      "endLine": 5369,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 31,
-      "startLine": 5006
+      "startLine": 5369
     },
     {
       "endCharacter": 57,
-      "endLine": 5006,
+      "endLine": 5369,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 31,
-      "startLine": 5006
+      "startLine": 5369
     },
     {
       "endCharacter": 65,
-      "endLine": 5007,
+      "endLine": 5370,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 34,
-      "startLine": 5007
+      "startLine": 5370
     },
     {
       "endCharacter": 65,
-      "endLine": 5007,
+      "endLine": 5370,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 34,
-      "startLine": 5007
+      "startLine": 5370
     },
     {
       "endCharacter": 67,
-      "endLine": 5009,
+      "endLine": 5372,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 35,
-      "startLine": 5009
+      "startLine": 5372
     },
     {
       "endCharacter": 67,
-      "endLine": 5009,
+      "endLine": 5372,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 35,
-      "startLine": 5009
+      "startLine": 5372
     },
     {
       "endCharacter": 87,
-      "endLine": 5012,
+      "endLine": 5375,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 46,
-      "startLine": 5012
+      "startLine": 5375
     },
     {
       "endCharacter": 87,
-      "endLine": 5012,
+      "endLine": 5375,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 46,
-      "startLine": 5012
+      "startLine": 5375
     },
     {
       "endCharacter": 93,
-      "endLine": 5013,
+      "endLine": 5376,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 49,
-      "startLine": 5013
+      "startLine": 5376
     },
     {
       "endCharacter": 93,
-      "endLine": 5013,
+      "endLine": 5376,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 49,
-      "startLine": 5013
+      "startLine": 5376
     },
     {
       "endCharacter": 89,
-      "endLine": 5014,
+      "endLine": 5377,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 47,
-      "startLine": 5014
+      "startLine": 5377
     },
     {
       "endCharacter": 89,
-      "endLine": 5014,
+      "endLine": 5377,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 47,
-      "startLine": 5014
+      "startLine": 5377
     },
     {
       "endCharacter": 89,
-      "endLine": 5015,
+      "endLine": 5378,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 46,
-      "startLine": 5015
+      "startLine": 5378
     },
     {
       "endCharacter": 89,
-      "endLine": 5015,
+      "endLine": 5378,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 46,
-      "startLine": 5015
+      "startLine": 5378
     },
     {
       "endCharacter": 75,
-      "endLine": 5016,
+      "endLine": 5379,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 39,
-      "startLine": 5016
+      "startLine": 5379
     },
     {
       "endCharacter": 75,
-      "endLine": 5016,
+      "endLine": 5379,
       "file": "ReforceXY/user_data/freqaimodels/ReforceXY.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": 39,
-      "startLine": 5016
+      "startLine": 5379
     },
     {
       "endCharacter": 33,
index 7c0344a91b46e7bb51c80b8fb2c979db1b8a4e8c..8fc752f0d30c95f452eafc8fb3edbc56fad79942 100644 (file)
@@ -32,8 +32,16 @@ import matplotlib.transforms as mtransforms
 import numpy as np
 import optunahub
 import pandas as pd
+import rapidjson
 import torch as th
-from freqtrade.freqai.data_drawer import FreqaiDataDrawer
+from datasieve.pipeline import Pipeline
+from freqtrade.exceptions import DependencyException
+from freqtrade.freqai.data_drawer import (
+    FEATURE_PIPELINE,
+    METADATA,
+    METADATA_NUMBER_MODE,
+    FreqaiDataDrawer,
+)
 from freqtrade.freqai.data_kitchen import FreqaiDataKitchen
 from freqtrade.freqai.RL.Base5ActionRLEnv import Actions, Base5ActionRLEnv, Positions
 from freqtrade.freqai.RL.BaseEnvironment import BaseEnvironment
@@ -43,6 +51,7 @@ from freqtrade.freqai.RL.BaseReinforcementLearningModel import (
 from freqtrade.freqai.tensorboard.TensorboardCallback import TensorboardCallback
 from freqtrade.strategy import timeframe_to_minutes
 from gymnasium.spaces import Box
+from joblib.externals import cloudpickle
 from matplotlib.lines import Line2D
 from numpy.typing import NDArray
 from optuna import Trial, TrialPruned, create_study, delete_study
@@ -81,6 +90,31 @@ from stable_baselines3.common.vec_env import (
 _DATE_PRED_DEDUP_SENTINEL = "_freqai_strategies_date_pred_repair_patched"
 
 
+def _recorded_prediction_mask(frame: pd.DataFrame) -> NDArray[np.bool_]:
+    """Identify recorded rows from metadata, never from prediction magnitudes."""
+    recorded = np.zeros(len(frame), dtype=bool)
+    if "close_price" in frame:
+        close = pd.to_numeric(frame["close_price"], errors="coerce")
+        recorded |= (close.gt(0) & close.lt(np.inf)).fillna(False).to_numpy(dtype=bool)
+    if "do_predict" in frame:
+        status = pd.to_numeric(frame["do_predict"], errors="coerce")
+        recorded |= (
+            (status.gt(-np.inf) & status.lt(np.inf) & status.ne(0))
+            .fillna(False)
+            .to_numpy(dtype=bool)
+        )
+    return recorded
+
+
+def _produced_prediction_mask(frame: pd.DataFrame) -> NDArray[np.bool_]:
+    """Exclude expired-model placeholders from recorded model observations."""
+    produced = _recorded_prediction_mask(frame)
+    if "do_predict" in frame:
+        status = pd.to_numeric(frame["do_predict"], errors="coerce")
+        produced &= status.ne(2).fillna(True).to_numpy(dtype=bool)
+    return produced
+
+
 def _dedupe_historic_predictions_on_date_pred(frame: pd.DataFrame) -> pd.DataFrame:
     """Normalize dates and retain the latest recorded row per candle, in date order.
 
@@ -99,13 +133,7 @@ def _dedupe_historic_predictions_on_date_pred(frame: pd.DataFrame) -> pd.DataFra
         result["date_pred"] = date_pred
         return result
 
-    recorded = np.zeros(len(frame), dtype=bool)
-    if "close_price" in frame:
-        close = pd.to_numeric(frame["close_price"], errors="coerce")
-        recorded |= (close.gt(0) & close.lt(np.inf)).fillna(False).to_numpy(dtype=bool)
-    if "do_predict" in frame:
-        status = pd.to_numeric(frame["do_predict"], errors="coerce")
-        recorded |= (status.notna() & status.ne(0)).to_numpy(dtype=bool)
+    recorded = _recorded_prediction_mask(frame)
     # Rank only metadata, without copying or coercing all prediction columns.
     order = pd.DataFrame(
         {"date_pred": date_pred.array, "recorded": recorded, "position": np.arange(len(frame))}
@@ -120,6 +148,21 @@ def _dedupe_historic_predictions_on_date_pred(frame: pd.DataFrame) -> pd.DataFra
     return result.reset_index(drop=True)
 
 
+def _align_historic_predictions(history: pd.DataFrame, dataframe: pd.DataFrame) -> pd.DataFrame:
+    """Align unique, normalized history to requested candle dates and exact index."""
+    dates = pd.to_datetime(dataframe["date"], utc=True, errors="coerce", format="mixed")
+    indexed = history.set_index("date_pred", drop=False)
+    aligned = indexed.reindex(pd.DatetimeIndex(dates))
+    missing = ~pd.DatetimeIndex(dates).isin(indexed.index)
+    aligned.index = dataframe.index
+    aligned["date_pred"] = dates.array
+    if "do_predict" in aligned:
+        aligned["do_predict"] = aligned["do_predict"].where(~missing, 0)
+    else:
+        aligned["do_predict"] = 0
+    return aligned
+
+
 def _install_date_pred_dedup_patch() -> None:
     """Repair persisted history and duplicates produced by older Freqtrade writers.
 
@@ -157,14 +200,12 @@ def _install_date_pred_dedup_patch() -> None:
         self.historic_predictions[pair] = _dedupe_historic_predictions_on_date_pred(
             self.historic_predictions[pair]
         )
-        original_set_initial(self, pair, pred_df, dataframe)
-        history = self.historic_predictions[pair]
-        repaired = _dedupe_historic_predictions_on_date_pred(history)
-        if repaired is not history:
-            self.historic_predictions[pair] = repaired
-            self.model_return_values[pair] = repaired.tail(len(dataframe.index)).reset_index(
-                drop=True
-            )
+        original_set_initial(
+            self, pair, pred_df.reset_index(drop=True), dataframe.reset_index(drop=True)
+        )
+        repaired = _dedupe_historic_predictions_on_date_pred(self.historic_predictions[pair])
+        self.historic_predictions[pair] = repaired
+        self.model_return_values[pair] = _align_historic_predictions(repaired, dataframe)
 
     @wraps(original_append)
     def append_model_predictions(
@@ -180,23 +221,24 @@ def _install_date_pred_dedup_patch() -> None:
         )
         if self.historic_predictions[pair].empty and not strat_df.empty:
             # Legacy append requires an initialized row; let upstream construct it.
-            original_set_initial(self, pair, pd.DataFrame(index=pd.RangeIndex(1)), strat_df.tail(1))
-        original_append(self, pair, predictions, do_preds, dk, strat_df)
-        history = self.historic_predictions[pair]
-        repaired = _dedupe_historic_predictions_on_date_pred(history)
-        if repaired is not history:
-            self.historic_predictions[pair] = repaired
-            self.model_return_values[pair] = repaired.tail(len(strat_df.index)).reset_index(
-                drop=True
+            original_set_initial(
+                self,
+                pair,
+                pd.DataFrame(index=pd.RangeIndex(1)),
+                strat_df.tail(1).reset_index(drop=True),
             )
+        original_append(self, pair, predictions, do_preds, dk, strat_df)
+        repaired = _dedupe_historic_predictions_on_date_pred(self.historic_predictions[pair])
+        self.historic_predictions[pair] = repaired
+        self.model_return_values[pair] = _align_historic_predictions(repaired, strat_df)
 
     @wraps(original_attach)
     def attach_return_values_to_return_dataframe(
         self, pair: str, dataframe: pd.DataFrame
     ) -> pd.DataFrame:
-        self.model_return_values[pair] = _dedupe_historic_predictions_on_date_pred(
-            self.model_return_values[pair]
-        )
+        repaired = _dedupe_historic_predictions_on_date_pred(self.historic_predictions[pair])
+        self.historic_predictions[pair] = repaired
+        self.model_return_values[pair] = _align_historic_predictions(repaired, dataframe)
         return original_attach(self, pair, dataframe)
 
     replacements = (
@@ -264,7 +306,14 @@ class ReforceXY(BaseReinforcementLearningModel):
         ...
         "freqai": {
             ...
-            "fit_live_predictions_candles": 0,      // Optional non-negative integer; omitted or 0 disables prediction statistics
+            "fit_live_predictions_candles": 0,      // Optional non-negative integer; omitted or 0 disables action statistics
+            // Live/dry-run: latest N produced observations per pair after session startup.
+            // Restart resets warmup; numeric mean/std are zero until N observations exist.
+            // Downtime and expired status 2 do not count; neutral/exit actions and recorded
+            // rejected predictions do. Backtests use the previous N rows, not the current row.
+            // Numeric objects are coerced; non-finite samples are ignored. Empty finite
+            // samples yield zeros; constants have zero spread; nonnumeric objects are skipped.
+            // Statistics do not gate RL actions. Population standard deviation is used.
             "model_training_parameters": {
                 "device": "auto",                   // PyTorch device (auto|cpu|cuda|cuda:0)
                 "gpu_memory_fraction": null,        // GPU VRAM fraction limit per process (0.0, 1.0], null disables
@@ -302,6 +351,20 @@ class ReforceXY(BaseReinforcementLearningModel):
             }
         }
     }
+
+    Continual learning keeps the deployed policy's fitted feature coordinates frozen,
+    including feature selection and scaling. Reset trained models or use a new
+    freqai.identifier to change those coordinates or migrate legacy artifacts.
+    First training and continual_learning=false use fresh pipelines and policies.
+    Hyperopt always uses fresh current-window pipelines and cold policies; final
+    continuation uses the original raw split in the deployed coordinates. Selected
+    constructor/network parameters do not rebuild an existing policy's architecture;
+    a resumed policy keeps its own discount gamma for environment reward shaping.
+    Raw OHLC prices are preserved separately for every environment. Noise augments
+    training features only, never evaluation or prediction features.
+    Prediction uses the best checkpoint selected by the current fit's evaluation,
+    falling back to the final policy if no usable current checkpoint was selected.
+
     Requirements:
         - pip install optuna optunahub -r https://hub.optuna.org/samplers/auto_sampler/requirements.txt
 
@@ -311,6 +374,9 @@ class ReforceXY(BaseReinforcementLearningModel):
 
     _LOG_2: Final[float] = math.log(2.0)
 
+    _DEPLOYMENT_COORDINATE_MARKER_KEY: Final[str] = "reforcexy_deployment_coordinates"
+    _DEPLOYMENT_COORDINATE_GENERATION: Final[str] = "frozen-pipelines-v1"
+
     DEFAULT_BASE_FACTOR: Final[float] = 100.0
 
     DEFAULT_MAX_TRADE_DURATION_CANDLES: Final[int] = 128
@@ -423,6 +489,8 @@ class ReforceXY(BaseReinforcementLearningModel):
     _QUARANTINE_TAG: Final[str] = "corrupt"
     _QUARANTINE_TIE_BREAK_LIMIT: Final[int] = 99
     _BEST_PARAMS_LOCK_FILENAME: Final[str] = ".hyperopt-best-params.lock"
+    # Bump on objective changes that make persisted trials or best params incompatible.
+    _OPTUNA_OBJECTIVE_IDENTITY: Final[str] = "raw-market-prices-v1"
     _PPO_N_STEPS: Final[tuple[int, ...]] = (512, 1024, 2048, 4096)
     _PPO_N_STEPS_MIN: Final[int] = min(_PPO_N_STEPS)
     _PPO_N_STEPS_MAX: Final[int] = max(_PPO_N_STEPS)
@@ -681,7 +749,7 @@ class ReforceXY(BaseReinforcementLearningModel):
         gamma: float | None = None
 
         if model_params and isinstance(model_params.get("gamma"), (int, float)):
-            gamma = float(model_params.get("gamma"))
+            gamma = float(model_params["gamma"])
         elif self.hyperopt:
             best_trial_params = self.load_best_trial_params(pair)
             if best_trial_params and isinstance(best_trial_params.get("gamma"), (int, float)):
@@ -712,6 +780,7 @@ class ReforceXY(BaseReinforcementLearningModel):
         prices_train: DataFrame,
         prices_test: DataFrame,
         dk: FreqaiDataKitchen,
+        model_params: dict[str, Any] | None = None,
     ) -> None:
         """
         Set training and evaluation environments
@@ -720,9 +789,9 @@ class ReforceXY(BaseReinforcementLearningModel):
             logger.info("Env [%s]: closing environments", dk.pair)
             self.close_envs()
 
-        train_df = data_dictionary.get("train_features")
-        test_df = data_dictionary.get("test_features")
-        env_dict = self.pack_env_dict(dk.pair)
+        train_df = data_dictionary["train_features"]
+        test_df = data_dictionary["test_features"]
+        env_dict = self.pack_env_dict(dk.pair, model_params=model_params)
         seed = self.get_model_params().get("seed", 42)
 
         if self.check_envs:
@@ -1022,7 +1091,165 @@ class ReforceXY(BaseReinforcementLearningModel):
             callbacks.append(self.optuna_eval_callback)
         return callbacks
 
-    def fit(self, data_dictionary: dict[str, Any], dk: FreqaiDataKitchen, **kwargs) -> Any:
+    def _resolve_deployment_state(
+        self, dk: FreqaiDataKitchen, pair: str
+    ) -> tuple[Any, Pipeline] | None:
+        """Restore the deployed policy and an independent fitted feature pipeline."""
+        if not self.continual_learning:
+            return None
+        model = self.dd.model_dictionary.get(pair)
+        previous = self.dd.pair_dict.get(pair, {})
+        if model is None and not previous.get("model_filename"):
+            return None
+        try:
+            cached = self.dd.meta_data_dictionary.get(pair, {})
+            metadata = cached.get(METADATA)
+            feature_pipeline = cached.get(FEATURE_PIPELINE)
+            if model is None or metadata is None or feature_pipeline is None:
+                # The current kitchen points to the new window, not deployed files.
+                previous_dk = copy.copy(dk)
+                previous_dk.data_path = Path(previous["data_path"])
+                previous_dk.model_filename = previous["model_filename"]
+                prefix = previous_dk.data_path / previous_dk.model_filename
+                if metadata is None:
+                    with Path(f"{prefix}_{METADATA}.json").open("r") as fp:
+                        metadata = rapidjson.load(fp, number_mode=METADATA_NUMBER_MODE)
+                if feature_pipeline is None:
+                    with Path(f"{prefix}_{FEATURE_PIPELINE}.pkl").open("rb") as fp:
+                        feature_pipeline = cloudpickle.load(fp)
+                if model is None:
+                    model = self.MODELCLASS.load(Path(f"{prefix}_model"))
+            if (
+                metadata.get(self._DEPLOYMENT_COORDINATE_MARKER_KEY)
+                != self._DEPLOYMENT_COORDINATE_GENERATION
+            ):
+                raise ValueError(
+                    "persisted deployment coordinate generation is missing or incompatible"
+                )
+            if not isinstance(model, self.MODELCLASS):
+                raise ValueError("persisted policy type differs from the configured model")
+            for name, expected, actual in (
+                ("features", dk.training_features_list, metadata["training_features_list"]),
+                ("labels", dk.label_list, metadata["label_list"]),
+                (
+                    "feature pipeline inputs",
+                    dk.training_features_list,
+                    feature_pipeline.features_in,
+                ),
+            ):
+                if list(expected) != list(actual):
+                    raise ValueError(f"persisted {name} differ in names or order")
+            state = model, copy.deepcopy(feature_pipeline)
+        except Exception as exc:
+            raise DependencyException(
+                f"[{pair}] Cannot continue training with matching persisted pipelines: {exc}. "
+                "Reset trained models or use a new freqai.identifier."
+            ) from exc
+        logger.info(
+            f"[{pair}] Continuing deployment in the persisted feature coordinate system; "
+            "reset trained models to change pipeline configuration"
+        )
+        return state
+
+    def _apply_training_pipeline(
+        self,
+        data_dictionary: dict[str, Any],
+        dk: FreqaiDataKitchen,
+        deployment_state: tuple[Any, Pipeline] | None = None,
+    ) -> dict[str, Any]:
+        """Preserve chronological raw splits; never transform RL action labels."""
+        dd = data_dictionary.copy()
+        dk.feature_pipeline = (
+            self.define_data_pipeline(threads=dk.thread_count)
+            if deployment_state is None
+            else deployment_state[1]
+        )
+        for split in ("train", "test"):
+            features = data_dictionary[f"{split}_features"]
+            labels = data_dictionary[f"{split}_labels"]
+            weights = data_dictionary[f"{split}_weights"]
+            if split == "test" and features.empty:
+                continue
+            transform = (
+                dk.feature_pipeline.fit_transform
+                if split == "train" and deployment_state is None
+                else dk.feature_pipeline.transform
+            )
+            transformed, transformed_labels, transformed_weights = transform(
+                features.copy(), labels.copy(), weights.copy()
+            )
+            transformed = cast("pd.DataFrame", transformed)
+            transformed_labels = cast("pd.DataFrame", transformed_labels)
+            transformed_weights = cast("NDArray[np.float64]", np.asarray(transformed_weights))
+            if len(transformed) != len(features) or len(transformed_weights) != len(features):
+                raise DependencyException(
+                    f"[{dk.pair}] RL preprocessing must preserve chronological rows "
+                    "and their alignment with raw prices."
+                )
+            # DataSieve reconstructs frames with RangeIndex while retaining row order.
+            transformed.index = features.index
+            transformed_labels.index = labels.index
+            if split == "train" and deployment_state is not None:
+                # Noise.transform is a no-op; only augmentation may be fitted.
+                for name, transformer in dk.feature_pipeline.steps:
+                    if name == "noise":
+                        noisy, _, _, _ = transformer.fit_transform(transformed.to_numpy(copy=True))
+                        transformed = pd.DataFrame(
+                            noisy, columns=transformed.columns, index=transformed.index
+                        )
+            dd[f"{split}_features"] = transformed
+            dd[f"{split}_labels"] = transformed_labels
+            dd[f"{split}_weights"] = transformed_weights
+        dk.data_dictionary = dd
+        return dd
+
+    def train(self, unfiltered_df: DataFrame, pair: str, dk: FreqaiDataKitchen, **kwargs) -> Any:
+        """Train cold candidates and continue only in persisted deployment coordinates."""
+        # Drawer metadata can alias this kitchen; never invalidate the deployed marker.
+        dk.data = dk.data.copy()
+        dk.data.pop(self._DEPLOYMENT_COORDINATE_MARKER_KEY, None)
+        logger.info(f"--------------------Starting training {pair} --------------------")
+        features_filtered, labels_filtered = dk.filter_features(
+            unfiltered_df, dk.training_features_list, dk.label_list, training_filter=True
+        )
+        raw_data = dk.make_train_test_datasets(features_filtered, labels_filtered)
+        self.df_raw = copy.deepcopy(raw_data["train_features"])
+        dk.fit_labels()
+        # Capture prices once, before normalization and optional raw-OHLC removal.
+        prices_train, prices_test = self.build_ohlc_price_dataframes(raw_data, pair, dk)
+        deployment_state = self._resolve_deployment_state(dk, pair)
+        dd = self._apply_training_pipeline(
+            raw_data, dk, deployment_state=None if self.hyperopt else deployment_state
+        )
+        logger.info(
+            f"Training model on {len(dd['train_features'].columns)}"
+            f" features and {len(dd['train_features'])} data points"
+        )
+        model = self.fit(
+            dd,
+            dk,
+            prices_train=prices_train,
+            prices_test=prices_test,
+            deployment_state=deployment_state,
+            raw_data_dictionary=raw_data if self.hyperopt and deployment_state else None,
+            **kwargs,
+        )
+        if model is not None:
+            dk.data[self._DEPLOYMENT_COORDINATE_MARKER_KEY] = self._DEPLOYMENT_COORDINATE_GENERATION
+        logger.info(f"--------------------done training {pair}--------------------")
+        return model
+
+    def fit(
+        self,
+        data_dictionary: dict[str, Any],
+        dk: FreqaiDataKitchen,
+        *,
+        prices_train: DataFrame,
+        prices_test: DataFrame,
+        deployment_state: tuple[Any, Pipeline] | None = None,
+        raw_data_dictionary: dict[str, Any] | None = None,
+        **kwargs,
+    ) -> Any:
         """
         Model fitting method
         :param data_dictionary: dict = common data dictionary containing all train/test features/labels/weights.
@@ -1075,7 +1302,7 @@ class ReforceXY(BaseReinforcementLearningModel):
 
         start_time = time.time()
         if self.hyperopt:
-            best_params = self.optimize(dk, total_timesteps)
+            best_params = self.optimize(dk, total_timesteps, prices_train, prices_test)
             if best_params is None:
                 logger.error(
                     "Hyperopt [%s]: optimization failed, using default model params",
@@ -1085,6 +1312,10 @@ class ReforceXY(BaseReinforcementLearningModel):
             model_params = best_params
         else:
             model_params = self.get_model_params()
+        if raw_data_dictionary is not None:
+            data_dictionary = self._apply_training_pipeline(
+                raw_data_dictionary, dk, deployment_state=deployment_state
+            )
         logger.info("Model [%s]: %s params: %s", dk.pair, self.model_type, model_params)
 
         # "PPO"
@@ -1117,18 +1348,28 @@ class ReforceXY(BaseReinforcementLearningModel):
         else:
             tensorboard_log_path = None
 
-        # Rebuild train and eval environments before training to sync model parameters
-        prices_train, prices_test = self.build_ohlc_price_dataframes(
-            dk.data_dictionary, dk.pair, dk
+        # Reward shaping must use the resumed policy's discount gamma,
+        # not the configured or HPO-selected value.
+        resumed_gamma: dict[str, Any] | None = None
+        if deployment_state is not None:
+            learner_gamma = getattr(deployment_state[0], "gamma", None)
+            if isinstance(learner_gamma, (int, float)) and np.isfinite(learner_gamma):
+                resumed_gamma = {"gamma": float(learner_gamma)}
+        self.set_train_and_eval_environments(
+            data_dictionary,
+            prices_train,
+            prices_test,
+            dk,
+            model_params=resumed_gamma,
         )
-        self.set_train_and_eval_environments(dk.data_dictionary, prices_train, prices_test, dk)
 
-        model = self.get_init_model(dk.pair)
+        model = deployment_state[0] if deployment_state is not None else None
         if model is not None:
             logger.info(
                 "Training [%s]: continual training activated, starting from previously trained model state",
                 dk.pair,
             )
+            model.tb_logger = getattr(self, "tb_logger", None)
             model.set_env(self.train_env)
         else:
             model = self.MODELCLASS(
@@ -1160,12 +1401,19 @@ class ReforceXY(BaseReinforcementLearningModel):
         time_spent = time.time() - start_time
         self.dd.update_metric_tracker("fit_time", time_spent, dk.pair)
 
-        model_filename = dk.model_filename if dk.model_filename else "best"
-        model_filepath = Path(dk.data_path / f"{model_filename}_model.zip")
-        if model_filepath.is_file():
+        model_filepath = Path(dk.data_path) / "best_model.zip"
+        current_best = np.isfinite(getattr(self.eval_callback, "best_mean_reward", np.nan))
+        if current_best and model_filepath.is_file():
             logger.info("Model [%s]: found best model at %s", dk.pair, model_filepath)
             try:
-                best_model = self.MODELCLASS.load(dk.data_path / f"{model_filename}_model")
+                best_model = self.MODELCLASS.load(model_filepath)
+                # SB3 archives exclude replay buffers; restore the final buffer so
+                # the next cached retrain keeps the experience accumulated this fit.
+                if (
+                    hasattr(model, "replay_buffer")
+                    and getattr(best_model, "replay_buffer", None) is not None
+                ):
+                    best_model.replay_buffer = model.replay_buffer
                 return best_model
             except Exception as e:
                 logger.error(
@@ -1176,13 +1424,74 @@ class ReforceXY(BaseReinforcementLearningModel):
                 )
 
         logger.warning(
-            "Model [%s]: best model not found at %s, using final model",
+            "Model [%s]: no usable current best checkpoint at %s, using final model",
             dk.pair,
             model_filepath,
         )
 
         return model
 
+    def fit_live_predictions(self, dk: FreqaiDataKitchen, pair: str) -> None:
+        """Compute optional action statistics from prior prediction observations."""
+        fit_live_predictions_candles = self.freqai_info.get("fit_live_predictions_candles", 0)
+        if not fit_live_predictions_candles:
+            return
+
+        warmed_up = True
+        history = self.dd.historic_predictions[pair]
+        if self.live:
+            history = _dedupe_historic_predictions_on_date_pred(history)
+            if not hasattr(self, "_prediction_session_cutoffs"):
+                self._prediction_session_cutoffs: dict[str, pd.Timestamp] = {}
+            if pair not in self._prediction_session_cutoffs:
+                initial_dates = pd.to_datetime(
+                    self.dd.model_return_values[pair]["date_pred"],
+                    utc=True,
+                    errors="coerce",
+                    format="mixed",
+                )
+                self._prediction_session_cutoffs[pair] = initial_dates.max()
+            cutoff = self._prediction_session_cutoffs[pair]
+            eligible = (
+                _produced_prediction_mask(history) & history["date_pred"].gt(cutoff).to_numpy()
+            )
+            history = history.loc[eligible]
+            remaining = fit_live_predictions_candles - len(history)
+            warmed_up = remaining <= 0
+            if not warmed_up:
+                logger.warning(
+                    f"[{pair}] Fit live predictions not warmed up: {remaining} produced observations until warmup completion"
+                )
+        pred_df = history.tail(fit_live_predictions_candles).reset_index(drop=True)
+
+        dk.data["labels_mean"], dk.data["labels_std"] = {}, {}
+        for label_col in dk.label_list + dk.unique_class_list:
+            raw_label = pred_df.get(label_col)
+            if raw_label is None:
+                continue
+            # Downtime filling can leave numeric predictions in object-typed columns.
+            pred_label = pd.to_numeric(raw_label, errors="coerce")
+            if raw_label.dtype == object and pred_label.isna().all():
+                continue
+            if not warmed_up:
+                f = [0.0, 0.0]
+            else:
+                values = pred_label.to_numpy(dtype=float, na_value=np.nan)
+                values = values[np.isfinite(values)]
+                if values.size == 0:
+                    f = (0.0, 0.0)
+                else:
+                    sample_mean = float(np.mean(values))
+                    sample_std = float(np.std(values, ddof=0))
+                    f = (
+                        sample_mean if np.isfinite(sample_mean) else 0.0,
+                        sample_std if np.isfinite(sample_std) else 0.0,
+                    )
+            dk.data["labels_mean"][label_col], dk.data["labels_std"][label_col] = (
+                f[0],
+                f[1],
+            )
+
     def rl_model_predict(
         self, dataframe: DataFrame, dk: FreqaiDataKitchen, model: Any
     ) -> DataFrame:
@@ -1648,9 +1957,16 @@ class ReforceXY(BaseReinforcementLearningModel):
             max(min_resource, ReforceXY._ceil_to_multiple(total_timesteps, rollout)),
         )
 
-    def optimize(self, dk: FreqaiDataKitchen, total_timesteps: int) -> dict[str, Any] | None:
+    def optimize(
+        self,
+        dk: FreqaiDataKitchen,
+        total_timesteps: int,
+        prices_train: DataFrame,
+        prices_test: DataFrame,
+    ) -> dict[str, Any] | None:
         """
         Runs hyperparameter optimization using Optuna and returns the best hyperparameters found merged with the user defined parameters
+        Only studies and best params with the current objective identity are reused.
         """
         identifier = self.freqai_info.get("identifier", "no_id_provided")
         study_name = f"{identifier}-{dk.pair}"
@@ -1693,6 +2009,25 @@ class ReforceXY(BaseReinforcementLearningModel):
 
         direction = StudyDirection.MAXIMIZE
         load_if_exists = not continuous and not pair_purge_triggered
+        if load_if_exists:
+            try:
+                existing_study_id = storage.get_study_id_from_name(study_name)
+            except KeyError:
+                pass
+            else:
+                existing_identity = storage.get_study_user_attrs(existing_study_id).get(
+                    "objective_identity"
+                )
+                if existing_identity != ReforceXY._OPTUNA_OBJECTIVE_IDENTITY:
+                    logger.warning(
+                        "Hyperopt [%s]: objective identity %r incompatible with %r; resetting study",
+                        study_name,
+                        existing_identity,
+                        ReforceXY._OPTUNA_OBJECTIVE_IDENTITY,
+                    )
+                    ReforceXY.delete_study(study_name, storage)
+                    # Fail closed if deletion failed rather than reload incompatible trials.
+                    load_if_exists = False
         study: Study = create_study(
             study_name=study_name,
             sampler=self.create_sampler(),
@@ -1701,6 +2036,8 @@ class ReforceXY(BaseReinforcementLearningModel):
             storage=storage,
             load_if_exists=load_if_exists,
         )
+        if study.user_attrs.get("objective_identity") != ReforceXY._OPTUNA_OBJECTIVE_IDENTITY:
+            study.set_user_attr("objective_identity", ReforceXY._OPTUNA_OBJECTIVE_IDENTITY)
         logger.info(
             "Hyperopt [%s]: study created (direction=%s, n_trials=%s, timeout=%s, continuous=%s, load_if_exists=%s)",
             study_name,
@@ -1729,7 +2066,7 @@ class ReforceXY(BaseReinforcementLearningModel):
         start_time = time.time()
         try:
             study.optimize(
-                lambda trial: self.objective(trial, dk, total_timesteps),
+                lambda trial: self.objective(trial, dk, total_timesteps, prices_train, prices_test),
                 n_trials=self.optuna_n_trials,
                 timeout=(
                     hours_to_seconds(self.optuna_timeout_hours)
@@ -1905,7 +2242,7 @@ class ReforceXY(BaseReinforcementLearningModel):
 
     def save_best_trial_params(self, best_trial_params: dict[str, Any], pair: str) -> None:
         """
-        Save the best trial hyperparameters found during hyperparameter optimization
+        Save the best trial hyperparameters with the current objective identity.
         """
         best_trial_params_path = self._best_trial_params_path(pair)
         logger.info("Hyperopt [%s]: saving best params to %s", pair, best_trial_params_path)
@@ -1958,7 +2295,14 @@ class ReforceXY(BaseReinforcementLearningModel):
                             write_file.fileno(),
                             stat.S_IMODE(existing_metadata.st_mode),
                         )
-                    json.dump(best_trial_params, write_file, indent=4)
+                    json.dump(
+                        {
+                            "objective_identity": ReforceXY._OPTUNA_OBJECTIVE_IDENTITY,
+                            "params": best_trial_params,
+                        },
+                        write_file,
+                        indent=4,
+                    )
                     write_file.flush()
                     os.fsync(write_file.fileno())
                 temporary_path.replace(best_trial_params_path)
@@ -1987,7 +2331,7 @@ class ReforceXY(BaseReinforcementLearningModel):
 
     def load_best_trial_params(self, pair: str) -> dict[str, Any] | None:
         """
-        Load the best trial hyperparameters found and saved during hyperparameter optimization
+        Load saved best trial hyperparameters only for the current objective identity.
         """
         best_trial_params_path = self._best_trial_params_path(pair)
         if not best_trial_params_path.parent.is_dir():
@@ -2025,26 +2369,32 @@ class ReforceXY(BaseReinforcementLearningModel):
                     if quarantined is None:
                         raise
                     return None
-        return best_trial_params
+        if (
+            not isinstance(best_trial_params, dict)
+            or best_trial_params.get("objective_identity") != ReforceXY._OPTUNA_OBJECTIVE_IDENTITY
+            or not isinstance(best_trial_params.get("params"), dict)
+        ):
+            logger.warning(
+                "Hyperopt [%s]: ignoring best params with missing or incompatible objective identity "
+                "(expected %r) or invalid params payload",
+                pair,
+                ReforceXY._OPTUNA_OBJECTIVE_IDENTITY,
+            )
+            return None
+        return best_trial_params["params"]
 
     def _get_train_and_eval_environments(
         self,
         dk: FreqaiDataKitchen,
-        train_df: DataFrame | None = None,
-        test_df: DataFrame | None = None,
-        prices_train: DataFrame | None = None,
-        prices_test: DataFrame | None = None,
+        train_df: DataFrame,
+        test_df: DataFrame,
+        prices_train: DataFrame,
+        prices_test: DataFrame,
         seed: int | None = None,
         env_info: dict[str, Any] | None = None,
         trial: Trial | None = None,
         model_params: dict[str, Any] | None = None,
     ) -> tuple[VecEnv, VecEnv]:
-        if train_df is None or test_df is None or prices_train is None or prices_test is None:
-            train_df = dk.data_dictionary["train_features"]
-            test_df = dk.data_dictionary["test_features"]
-            prices_train, prices_test = self.build_ohlc_price_dataframes(
-                dk.data_dictionary, dk.pair, dk
-            )
         seed: int = self.get_model_params().get("seed", 42) if seed is None else seed
         if trial is not None:
             seed += trial.number
@@ -2115,7 +2465,14 @@ class ReforceXY(BaseReinforcementLearningModel):
                 f"Hyperopt [{trial.study.study_name}]: model type '{self.model_type}' not supported"
             )
 
-    def objective(self, trial: Trial, dk: FreqaiDataKitchen, total_timesteps: int) -> float:
+    def objective(
+        self,
+        trial: Trial,
+        dk: FreqaiDataKitchen,
+        total_timesteps: int,
+        prices_train: DataFrame,
+        prices_test: DataFrame,
+    ) -> float:
         """
         Objective function for Optuna trials hyperparameter optimization
         """
@@ -2184,7 +2541,13 @@ class ReforceXY(BaseReinforcementLearningModel):
             tensorboard_log_path = None
 
         train_env, eval_env = self._get_train_and_eval_environments(
-            dk, trial=trial, model_params=params
+            dk,
+            train_df=dk.data_dictionary["train_features"],
+            test_df=dk.data_dictionary["test_features"],
+            prices_train=prices_train,
+            prices_test=prices_test,
+            trial=trial,
+            model_params=params,
         )
 
         model = self.MODELCLASS(